Bug 1467461 - Migrate CrashReportingService to JobIntentService; r?snorp draft
authorPetru Lingurar <petru.lingurar@softvision.ro>
Mon, 11 Jun 2018 14:19:32 +0300
changeset 806730 18cc7471f0b54908336b8a881e2d5464a939192d
parent 806729 8c3f4bbf78a481cfc7e10e5960370d62aecabde7
push id112922
push userplingurar@mozilla.com
push dateMon, 11 Jun 2018 11:21:03 +0000
reviewerssnorp
bugs1467461
milestone62.0a1
Bug 1467461 - Migrate CrashReportingService to JobIntentService; r?snorp Use a stub service to actually start our crash reporter. On 26+ devices it will be called with "am start-foreground-service". This ensures it can be started even from background and the crash reporting process would work as before but ActivityManager will post an ANR error to logcat after 5 seconds because we aren't calling Service.startForeground() (which would mean a user visible notification). MozReview-Commit-ID: 6UUOKrUhuqj
mobile/android/geckoview/src/main/java/org/mozilla/gecko/CrashReporterStarterService.java
mobile/android/geckoview/src/main/java/org/mozilla/gecko/mozglue/GeckoLoader.java
mobile/android/services/src/main/java/org/mozilla/gecko/background/JobIdsConstants.java
toolkit/crashreporter/nsExceptionHandler.cpp
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/CrashReporterStarterService.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/CrashReporterStarterService.java
@@ -26,29 +26,19 @@ import android.support.annotation.Nullab
  * as a background service.<br>
  * We do not though call <a href="http://dev.w3.org/html5/webvtt">startForeground(..)</a> immediately
  * and accept that after the 5 seconds the system would automatically stop us.<br>
  * (We should have started {@link CrashReporterService} a long time before that anyway.)
  */
 public class CrashReporterStarterService extends Service {
     @Override
     public int onStartCommand(Intent intent, int flags, int startId) {
-        final Class<?> reporterServiceClass = getFennecReporterService();
-        if (reporterServiceClass != null) {
-            CrashReporterService.enqueueWork(this, intent);
-        }
+        CrashReporterService.enqueueWork(this, intent);
+
         return Service.START_NOT_STICKY;
     }
 
     @Nullable
     @Override
     public IBinder onBind(Intent intent) {
         return null;
     }
-
-    private Class<?> getFennecReporterService() {
-        try {
-            return Class.forName("org.mozilla.gecko.CrashReporterService");
-        } catch (ClassNotFoundException e) {
-            return null;
-        }
-    }
 }
--- a/mobile/android/geckoview/src/main/java/org/mozilla/gecko/mozglue/GeckoLoader.java
+++ b/mobile/android/geckoview/src/main/java/org/mozilla/gecko/mozglue/GeckoLoader.java
@@ -133,16 +133,18 @@ public final class GeckoLoader {
                 putenv("MOZ_ANDROID_USER_SERIAL_NUMBER=" + um.getSerialNumberForUser(android.os.Process.myUserHandle()));
             } else {
                 Log.d(LOGTAG, "Unable to obtain user manager service on a device with SDK version " + Build.VERSION.SDK_INT);
             }
         }
 
         putenv("LANG=" + Locale.getDefault().toString());
 
+        putenv("MOZ_ANDROID_DEVICE_SDK_VERSION=" + Build.VERSION.SDK_INT);
+
         // env from extras could have reset out linker flags; set them again.
         loadLibsSetupLocked(context);
     }
 
     private static void loadLibsSetupLocked(Context context) {
         // setup the libs cache
         putenv("GRE_HOME=" + getGREDir(context).getPath());
         putenv("MOZ_LINKER_CACHE=" + getCacheDir(context).getPath());
--- a/mobile/android/services/src/main/java/org/mozilla/gecko/background/JobIdsConstants.java
+++ b/mobile/android/services/src/main/java/org/mozilla/gecko/background/JobIdsConstants.java
@@ -23,13 +23,13 @@ public class JobIdsConstants {
 
     public static final int JOB_ID_FILE_CLEANUP = -9;
 
     public static final int JOB_ID_UPDATES_REGISTER = -10;
     public static final int JOB_ID_UPDATES_CHECK_FOR = -11;
     public static final int JOB_ID_UPDATES_DOWNLOAD = -12;
     public static final int JOB_ID_UPDATES_APPLY = -13;
 
-    // Our package is unavailable to org.mozilla.gecko classes.
+    // Our package is unavailable to geckoview classes.
     // Currently used in org.mozilla.gecko classes.CrashReporterService
     // The id is kept here to ensure unicity between all job ids.
     private static final int JOB_ID_CRASH_REPORTER = -14;
 }
--- a/toolkit/crashreporter/nsExceptionHandler.cpp
+++ b/toolkit/crashreporter/nsExceptionHandler.cpp
@@ -215,16 +215,20 @@ static time_t lastCrashTime = 0;
 // The pathname of a file to store the crash time in
 static XP_CHAR lastCrashTimeFilename[XP_PATH_MAX] = {0};
 
 #if defined(MOZ_WIDGET_ANDROID)
 // on Android 4.2 and above there is a user serial number associated
 // with the current process that gets lost when we fork so we need to
 // explicitly pass it to am
 static char* androidUserSerial = nullptr;
+
+// Before Android 8 we needed to use "startservice" to start the crash reporting service.
+// After Android 8 we need to use "start-foreground-service"
+static char* startServiceCommand = nullptr;
 #endif
 
 // this holds additional data sent via the API
 static Mutex* crashReporterAPILock;
 static Mutex* notesFieldLock;
 static AnnotationTable* crashReporterAPIData_Hash;
 static nsCString* crashReporterAPIData = nullptr;
 static nsCString* crashEventAPIData = nullptr;
@@ -835,27 +839,27 @@ LaunchCrashReporterActivity(XP_CHAR* aPr
 
   if (pid == -1)
     return false;
   else if (pid == 0) {
     // Invoke the reportCrash activity using am
     if (androidUserSerial) {
       Unused << execlp("/system/bin/am",
                        "/system/bin/am",
-                       "start-foreground-service",
+                       startServiceCommand,
                        "--user", androidUserSerial,
                        "-a", "org.mozilla.gecko.reportCrash",
                        "-n", aProgramPath,
                        "--es", "minidumpPath", aMinidumpPath,
                        "--ez", "minidumpSuccess", aSucceeded ? "true" : "false",
                        (char*)0);
     } else {
       Unused << execlp("/system/bin/am",
                        "/system/bin/am",
-                       "start-foreground-service",
+                       startServiceCommand,
                        "-a", "org.mozilla.gecko.reportCrash",
                        "-n", aProgramPath,
                        "--es", "minidumpPath", aMinidumpPath,
                        "--ez", "minidumpSuccess", aSucceeded ? "true" : "false",
                        (char*)0);
     }
     _exit(1);
 
@@ -1545,16 +1549,23 @@ nsresult SetExceptionHandler(nsIFile* aX
   if (androidPackageName != nullptr) {
     nsCString package(androidPackageName);
     package.AppendLiteral("/org.mozilla.gecko.CrashReporterStarterService");
     crashReporterPath = ToNewCString(package);
   } else {
     nsCString package(ANDROID_PACKAGE_NAME "/org.mozilla.gecko.CrashReporterStarterService");
     crashReporterPath = ToNewCString(package);
   }
+
+  const int deviceSdkVersion = std::stoi(getenv("MOZ_ANDROID_DEVICE_SDK_VERSION"));
+  if (deviceSdkVersion >= 26) {
+    startServiceCommand = (char*)"start-foreground-service";
+  } else {
+    startServiceCommand = (char*)"startservice";
+  }
 #endif // !defined(MOZ_WIDGET_ANDROID)
 
   // get temp path to use for minidump path
 #if defined(XP_WIN32)
   nsString tempPath;
 #else
   nsCString tempPath;
 #endif