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
--- 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