Bug 1101031 - Report UpdateService crashes; r=snorp
authorJim Chen <nchen@mozilla.com>
Tue, 25 Nov 2014 15:02:32 -0800
changeset 217654 a0664ef9c64f3845b4eff244014ed2ab73d573c7
parent 217653 48e460577514322a0d6875230a75464bbec37fcb
child 217655 ce5a390e46a9a394b81d88c55ecaf0f17eff9f79
push id27887
push userryanvm@gmail.com
push dateThu, 27 Nov 2014 02:08:38 +0000
treeherdermozilla-central@c63e741bca2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssnorp
bugs1101031
milestone36.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 1101031 - Report UpdateService crashes; r=snorp
mobile/android/base/CrashHandler.java
mobile/android/base/updater/UpdateService.java
--- a/mobile/android/base/CrashHandler.java
+++ b/mobile/android/base/CrashHandler.java
@@ -22,17 +22,17 @@ import android.content.Intent;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
 import android.os.Process;
 import android.util.Log;
 
-class CrashHandler implements Thread.UncaughtExceptionHandler {
+public class CrashHandler implements Thread.UncaughtExceptionHandler {
 
     private static final String LOGTAG = "GeckoCrashHandler";
     private static final Thread MAIN_THREAD = Thread.currentThread();
     private static final String DEFAULT_SERVER_URL =
         "https://crash-reports.mozilla.com/submit?id=%1$s&version=%2$s&buildid=%3$s";
 
     // Context for getting device information
     protected final Context appContext;
@@ -229,17 +229,17 @@ class CrashHandler implements Thread.Unc
         extras.putLong("StartupTime", getStartupTime());
 
         if (context != null) {
             final PackageManager pkgMgr = context.getPackageManager();
             try {
                 final PackageInfo pkgInfo = pkgMgr.getPackageInfo(pkgName, 0);
                 extras.putString("Version", pkgInfo.versionName);
                 extras.putInt("BuildID", pkgInfo.versionCode);
-                extras.putLong("InstallTime", pkgInfo.firstInstallTime / 1000);
+                extras.putLong("InstallTime", pkgInfo.lastUpdateTime / 1000);
             } catch (final PackageManager.NameNotFoundException e) {
                 Log.i(LOGTAG, "Error getting package info", e);
             }
         }
 
         extras.putString("JavaStackTrace", getExceptionStackTrace(exc));
         return extras;
     }
@@ -434,9 +434,35 @@ class CrashHandler implements Thread.Unc
             if (systemUncaughtHandler != null) {
                 // Follow the chain of uncaught handlers.
                 systemUncaughtHandler.uncaughtException(thread, exc);
             }
         } finally {
             terminateProcess();
         }
     }
+
+    public static CrashHandler createDefaultCrashHandler(final Context context) {
+        return new CrashHandler(context) {
+            @Override
+            protected Bundle getCrashExtras(final Thread thread, final Throwable exc) {
+                final Bundle extras = super.getCrashExtras(thread, exc);
+
+                extras.putString("ProductName", AppConstants.MOZ_APP_BASENAME);
+                extras.putString("ProductID", AppConstants.MOZ_APP_ID);
+                extras.putString("Version", AppConstants.MOZ_APP_VERSION);
+                extras.putString("BuildID", AppConstants.MOZ_APP_BUILDID);
+                extras.putString("Vendor", AppConstants.MOZ_APP_VENDOR);
+                extras.putString("ReleaseChannel", AppConstants.MOZ_UPDATE_CHANNEL);
+                return extras;
+            }
+
+            @Override
+            public boolean reportException(final Thread thread, final Throwable exc) {
+                if (AppConstants.MOZ_CRASHREPORTER && AppConstants.MOZILLA_OFFICIAL) {
+                    // Only use Java crash reporter if enabled on official build.
+                    return super.reportException(thread, exc);
+                }
+                return false;
+            }
+        };
+    }
 }
--- a/mobile/android/base/updater/UpdateService.java
+++ b/mobile/android/base/updater/UpdateService.java
@@ -1,16 +1,17 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.updater;
 
 import org.mozilla.gecko.AppConstants;
+import org.mozilla.gecko.CrashHandler;
 import org.mozilla.gecko.R;
 
 import org.mozilla.apache.commons.codec.binary.Hex;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
@@ -75,31 +76,41 @@ public class UpdateService extends Inten
     private NotificationManager mNotificationManager;
     private ConnectivityManager mConnectivityManager;
     private Builder mBuilder;
 
     private boolean mDownloading;
     private boolean mCancelDownload;
     private boolean mApplyImmediately;
 
+    private CrashHandler mCrashHandler;
+
     public UpdateService() {
         super("updater");
     }
 
     @Override
     public void onCreate () {
+        mCrashHandler = CrashHandler.createDefaultCrashHandler(getApplicationContext());
+
         super.onCreate();
 
         mPrefs = getSharedPreferences(PREFS_NAME, 0);
         mNotificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
         mConnectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
         mCancelDownload = false;
     }
 
     @Override
+    public void onDestroy() {
+        mCrashHandler.unregister();
+        mCrashHandler = null;
+    }
+
+    @Override
     public synchronized int onStartCommand (Intent intent, int flags, int startId) {
         // If we are busy doing a download, the new Intent here would normally be queued for
         // execution once that is done. In this case, however, we want to flip the boolean
         // while that is running, so handle that now.
         if (mDownloading && UpdateServiceHelper.ACTION_APPLY_UPDATE.equals(intent.getAction())) {
             Log.i(LOGTAG, "will apply update when download finished");
 
             mApplyImmediately = true;