Bug 1510823 - Update GeckoView CrashReporter sendCrashReport() to return the crash ID r=snorp,agi
authorRandall Barker <rbarker@mozilla.com>
Thu, 29 Nov 2018 21:23:48 +0000
changeset 448858 840ea0c4fbfedb6d965326354c0793895a678b03
parent 448857 9094a8f08747e68db0d406b2abd2fc993a3ce0d6
child 448859 2f64401a8c87071cb2f5943f02b8a62f89111c09
push id35129
push usernerli@mozilla.com
push dateFri, 30 Nov 2018 09:34:14 +0000
treeherdermozilla-central@c5b713000513 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssnorp, agi
bugs1510823
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1510823 - Update GeckoView CrashReporter sendCrashReport() to return the crash ID r=snorp,agi Differential Revision: https://phabricator.services.mozilla.com/D13339
mobile/android/geckoview/CHANGELOG.md
mobile/android/geckoview/api.txt
mobile/android/geckoview/src/main/java/org/mozilla/geckoview/CrashReporter.java
--- a/mobile/android/geckoview/CHANGELOG.md
+++ b/mobile/android/geckoview/CHANGELOG.md
@@ -21,10 +21,12 @@
   classifier.
 - Added a `protected` empty constructor to all field-only classes so that apps
   can mock these classes in tests.
 - Added `ContentDelegate.ContextElement` to extend the information passed to
   `ContentDelegate#onContextMenu`. Extended information includes the element's
   title and alt attributes.
 - Changed `ContentDelegate.ContextElement` TYPE_ constants to public access.
   Changed `ContentDelegate.ContextElement` to non-final class.
+- Update `CrashReporter.sendCrashReport()` to return the crash ID as a
+  GeckoResult<String>.
 
-[api-version]: 01a6677fc7645b27d9824a2ebd3a6ab54c5e192a
+[api-version]: d6c40ef4886c7818a446fb7b7a1cdbde706025ab
--- a/mobile/android/geckoview/api.txt
+++ b/mobile/android/geckoview/api.txt
@@ -48,20 +48,20 @@ package org.mozilla.geckoview {
   }
 
   public static interface CompositorController.GetPixelsCallback {
     method public void onPixelsResult(int, int, java.nio.IntBuffer);
   }
 
   public class CrashReporter {
     ctor public CrashReporter();
-    method public static void sendCrashReport(android.content.Context, android.content.Intent, java.lang.String);
-    method public static void sendCrashReport(android.content.Context, android.os.Bundle, java.lang.String);
-    method public static void sendCrashReport(android.content.Context, java.io.File, java.io.File, boolean, java.lang.String);
-    method public static void sendCrashReport(android.content.Context, java.io.File, java.util.Map<java.lang.String,java.lang.String>, boolean, java.lang.String);
+    method public static org.mozilla.geckoview.GeckoResult<java.lang.String> sendCrashReport(android.content.Context, android.content.Intent, java.lang.String);
+    method public static org.mozilla.geckoview.GeckoResult<java.lang.String> sendCrashReport(android.content.Context, android.os.Bundle, java.lang.String);
+    method public static org.mozilla.geckoview.GeckoResult<java.lang.String> sendCrashReport(android.content.Context, java.io.File, java.io.File, boolean, java.lang.String);
+    method public static org.mozilla.geckoview.GeckoResult<java.lang.String> sendCrashReport(android.content.Context, java.io.File, java.util.Map<java.lang.String,java.lang.String>, boolean, java.lang.String);
   }
 
   public final class DynamicToolbarAnimator {
     method public org.mozilla.geckoview.DynamicToolbarAnimator.ToolbarChromeProxy getToolbarChromeProxy();
     method public void hideToolbar(boolean);
     method public boolean isPinned();
     method public boolean isPinnedBy(org.mozilla.geckoview.DynamicToolbarAnimator.PinReason);
     method public void setMaxToolbarHeight(int);
--- a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/CrashReporter.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/CrashReporter.java
@@ -60,47 +60,49 @@ public class CrashReporter {
      * <a href="https://bugzilla.mozilla.org/enter_bug.cgi?product=Socorro">File a bug</a>
      * if you would like to get your app added to the whitelist.
      *
      * @param context The current Context
      * @param intent The Intent sent to the {@link GeckoRuntime} crash handler
      * @param appName A human-readable app name.
      * @throws IOException This can be thrown if there was a networking error while sending the report.
      * @throws URISyntaxException This can be thrown if the crash server URI from the extra data was invalid.
+     * @return A GeckoResult containing the crash ID as a String.
      * @see GeckoRuntimeSettings.Builder#crashHandler(Class)
      * @see GeckoRuntime#ACTION_CRASHED
      */
-    public static void sendCrashReport(Context context, Intent intent, String appName)
+    public static GeckoResult<String> sendCrashReport(Context context, Intent intent, String appName)
             throws IOException, URISyntaxException {
-        sendCrashReport(context, intent.getExtras(), appName);
+        return sendCrashReport(context, intent.getExtras(), appName);
     }
 
     /**
      * Sends a crash report to the Mozilla  <a href="https://wiki.mozilla.org/Socorro">Socorro</a>
      * crash report server.
      * <br>
      * The {@code appName} needs to be whitelisted for the server to accept the crash.
      * <a href="https://bugzilla.mozilla.org/enter_bug.cgi?product=Socorro">File a bug</a>
      * if you would like to get your app added to the whitelist.
      *
      * @param context The current Context
      * @param intentExtras The Bundle of extras attached to the Intent received by a crash handler.
      * @param appName A human-readable app name.
      * @throws IOException This can be thrown if there was a networking error while sending the report.
      * @throws URISyntaxException This can be thrown if the crash server URI from the extra data was invalid.
+     * @return A GeckoResult containing the crash ID as a String.
      * @see GeckoRuntimeSettings.Builder#crashHandler(Class)
      * @see GeckoRuntime#ACTION_CRASHED
      */
-    public static void sendCrashReport(Context context, Bundle intentExtras, String appName)
+    public static GeckoResult<String> sendCrashReport(Context context, Bundle intentExtras, String appName)
             throws IOException, URISyntaxException {
         final File dumpFile = new File(intentExtras.getString(GeckoRuntime.EXTRA_MINIDUMP_PATH));
         final File extrasFile = new File(intentExtras.getString(GeckoRuntime.EXTRA_EXTRAS_PATH));
         final boolean success = intentExtras.getBoolean(GeckoRuntime.EXTRA_MINIDUMP_SUCCESS, false);
 
-        sendCrashReport(context, dumpFile, extrasFile, success, appName);
+        return sendCrashReport(context, dumpFile, extrasFile, success, appName);
     }
 
     /**
      * Sends a crash report to the Mozilla  <a href="https://wiki.mozilla.org/Socorro">Socorro</a>
      * crash report server.
      * <br>
      * The {@code appName} needs to be whitelisted for the server to accept the crash.
      * <a href="https://bugzilla.mozilla.org/enter_bug.cgi?product=Socorro">File a bug</a>
@@ -108,52 +110,54 @@ public class CrashReporter {
      *
      * @param context The current {@link Context}
      * @param minidumpFile A {@link File} referring to the minidump.
      * @param extrasFile A {@link File} referring to the extras file.
      * @param success A boolean indicating whether the dump was successfully generated.
      * @param appName A human-readable app name.
      * @throws IOException This can be thrown if there was a networking error while sending the report.
      * @throws URISyntaxException This can be thrown if the crash server URI from the extra data was invalid.
+     * @return A GeckoResult containing the crash ID as a String.
      * @see GeckoRuntimeSettings.Builder#crashHandler(Class)
      * @see GeckoRuntime#ACTION_CRASHED
      */
-    public static void sendCrashReport(Context context, File minidumpFile, File extrasFile,
+    public static GeckoResult<String> sendCrashReport(Context context, File minidumpFile, File extrasFile,
                                        boolean success, String appName) throws IOException, URISyntaxException {
         // Compute the minidump hash and generate the stack traces
         computeMinidumpHash(extrasFile, minidumpFile);
 
         // Extract the annotations from the .extra file
         HashMap<String, String> extrasMap = readStringsFromFile(extrasFile.getPath());
 
-        sendCrashReport(context, minidumpFile, extrasMap, success, appName);
+        return sendCrashReport(context, minidumpFile, extrasMap, success, appName);
     }
 
     /**
      * Sends a crash report to the Mozilla  <a href="https://wiki.mozilla.org/Socorro">Socorro</a>
      * crash report server.
      *
      * @param context The current {@link Context}
      * @param minidumpFile A {@link File} referring to the minidump.
      * @param extras A {@link HashMap} with the parsed key-value pairs from the extras file.
      * @param success A boolean indicating whether the dump was successfully generated.
      * @param appName A human-readable app name.
      * @throws IOException This can be thrown if there was a networking error while sending the report.
      * @throws URISyntaxException This can be thrown if the crash server URI from the extra data was invalid.
+     * @return A GeckoResult containing the crash ID as a String.
      * @see GeckoRuntimeSettings.Builder#crashHandler(Class)
      * @see GeckoRuntime#ACTION_CRASHED
      */
-    public static void sendCrashReport(Context context, File minidumpFile,
+    public static GeckoResult<String> sendCrashReport(Context context, File minidumpFile,
                                        Map<String, String> extras, boolean success,
                                        String appName) throws IOException, URISyntaxException {
         Log.d(LOGTAG, "Sending crash report: " + minidumpFile.getPath());
 
         String spec = extras.get(SERVER_URL_KEY);
         if (spec == null) {
-            return;
+            return GeckoResult.fromException(new Exception("No server url present"));
         }
 
         extras.put(PRODUCT_NAME_KEY, appName);
         extras.put(PRODUCT_ID_KEY, PRODUCT_ID);
 
         HttpURLConnection conn = null;
         try {
             final URL url = new URL(URLDecoder.decode(spec, "UTF-8"));
@@ -211,35 +215,42 @@ public class CrashReporter {
                 br = new BufferedReader(
                         new InputStreamReader(conn.getInputStream()));
                 HashMap<String, String> responseMap = readStringsFromReader(br);
 
                 if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
                     String crashid = responseMap.get("CrashID");
                     if (crashid != null) {
                         Log.i(LOGTAG, "Successfully sent crash report: " + crashid);
+                        return GeckoResult.fromValue(crashid);
                     } else {
                         Log.i(LOGTAG, "Server rejected crash report");
                     }
                 } else {
                     Log.w(LOGTAG, "Received failure HTTP response code from server: " + conn.getResponseCode());
                 }
+            } catch (Exception e) {
+                return GeckoResult.fromException(new Exception("Failed to submit crash report", e));
             } finally {
                 try {
                     if (br != null) {
                         br.close();
                     }
                 } catch (IOException e) {
+                    return GeckoResult.fromException(new Exception("Failed to submit crash report", e));
                 }
             }
+        } catch (Exception e) {
+            return GeckoResult.fromException(new Exception("Failed to submit crash report", e));
         } finally {
             if (conn != null) {
                 conn.disconnect();
             }
         }
+        return GeckoResult.fromException(new Exception("Failed to submit crash report"));
     }
 
     private static void computeMinidumpHash(File extraFile, File minidump) {
         try {
             FileInputStream stream = new FileInputStream(minidump);
             MessageDigest md = MessageDigest.getInstance("SHA-256");
 
             try {