Backed out 3 changesets (Bug 1433968) for causing Bug 1459349. a=backout

Backed out changeset 82b765c5a02f (bug 1433968)
Backed out changeset 73ec9bb3e17e (bug 1433968)
Backed out changeset 0812ac0376da (bug 1433968)

--HG--
extra : amend_source : 2748b297418eea9b7d3c2be11a8e7e300f8d709c
extra : histedit_source : 6428453bbe80ad044661d01e5127d924fffed1a3%2Cd2e712ac6c597784343ff08f75199851c07be4e7
This commit is contained in:
Narcis Beleuzu 2018-05-07 17:06:30 +03:00
Родитель f666a32b44
Коммит 323d4a4185
22 изменённых файлов: 99 добавлений и 662 удалений

Просмотреть файл

@ -122,7 +122,7 @@ android {
}
if (!mozconfig.substs.MOZ_CRASHREPORTER) {
exclude 'org/mozilla/gecko/CrashReporterActivity.java'
exclude 'org/mozilla/gecko/CrashReporter.java'
}
if (!mozconfig.substs.MOZ_NATIVE_DEVICES) {

Просмотреть файл

@ -64,7 +64,7 @@
</issue>
<!-- We fixed all "Registered" lint errors. However the current gradle plugin has a bug where
it ignores @SuppressLint annotations for this check. See CrashReporterActivity class and
it ignores @SuppressLint annotations for this check. See CrashReporter class and
https://code.google.com/p/android/issues/detail?id=204846 -->
<issue id="Registered" severity="warning" />

Просмотреть файл

@ -272,7 +272,7 @@
#include ../services/manifests/FxAccountAndroidManifest_activities.xml.in
#ifdef MOZ_CRASHREPORTER
<activity android:name="org.mozilla.gecko.CrashReporterActivity"
<activity android:name="org.mozilla.gecko.CrashReporter"
android:process="@ANDROID_PACKAGE_NAME@.CrashReporter"
android:label="@string/crash_reporter_title"
android:icon="@drawable/crash_reporter"

Просмотреть файл

@ -28,6 +28,7 @@ import java.security.MessageDigest;
import java.util.zip.GZIPOutputStream;
import org.mozilla.gecko.AppConstants.Versions;
import org.mozilla.gecko.GeckoProfile;
import org.mozilla.gecko.mozglue.GeckoLoader;
import org.mozilla.gecko.mozglue.MinidumpAnalyzer;
import org.mozilla.gecko.telemetry.pingbuilders.TelemetryCrashPingBuilder;
@ -56,7 +57,7 @@ import android.widget.EditText;
// Registered: This activity is only registered in the manifest if MOZ_CRASHREPORTER is set.
// CutPasteId: This lint is not worth fixing. To fix it, cache all the findViewById results.
@SuppressLint("Registered,CutPasteId")
public class CrashReporterActivity extends AppCompatActivity
public class CrashReporter extends AppCompatActivity
{
private static final String LOGTAG = "GeckoCrashReporter";
@ -209,7 +210,7 @@ public class CrashReporterActivity extends AppCompatActivity
final EditText commentsEditText = (EditText) findViewById(R.id.comment);
final EditText emailEditText = (EditText) findViewById(R.id.email);
// Load CrashReporterActivity preferences to avoid redundant user input.
// Load CrashReporter preferences to avoid redundant user input.
SharedPreferences prefs = GeckoSharedPrefs.forCrashReporter(this);
final boolean sendReport = prefs.getBoolean(PREFS_SEND_REPORT, true);
final boolean includeUrl = prefs.getBoolean(PREFS_INCLUDE_URL, false);
@ -270,7 +271,7 @@ public class CrashReporterActivity extends AppCompatActivity
builder.setPositiveButton(R.string.button_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
CrashReporterActivity.this.finish();
CrashReporter.this.finish();
}
});
builder.show();
@ -292,7 +293,7 @@ public class CrashReporterActivity extends AppCompatActivity
public void run() {
sendReport(mPendingMinidumpFile, mExtrasStringMap, mPendingExtrasFile);
}
}, "CrashReporterActivity Thread").start();
}, "CrashReporter Thread").start();
}
private void savePrefs() {

Просмотреть файл

@ -135,10 +135,6 @@ android {
exclude 'org/mozilla/gecko/media/Utils.java'
}
if (!mozconfig.substs.MOZ_CRASHREPORTER) {
exclude 'org/mozilla/gecko/CrashReporterService.java'
}
if (mozconfig.substs.MOZ_WEBRTC) {
srcDir "${topsrcdir}/media/webrtc/trunk/webrtc/base/java/src"
srcDir "${topsrcdir}/media/webrtc/trunk/webrtc/modules/audio_device/android/java/src"

Просмотреть файл

@ -120,10 +120,6 @@ public class TestRunnerActivity extends Activity {
runtimeSettingsBuilder.extras(extras);
}
runtimeSettingsBuilder
.nativeCrashReportingEnabled(true)
.javaCrashReportingEnabled(true);
sRuntime = GeckoRuntime.create(this, runtimeSettingsBuilder.build());
sRuntime.setDelegate(new GeckoRuntime.Delegate() {
@Override

Просмотреть файл

@ -847,10 +847,7 @@ public class GeckoSessionTestRule extends UiThreadTestRule {
final GeckoRuntimeSettings.Builder runtimeSettingsBuilder =
new GeckoRuntimeSettings.Builder();
runtimeSettingsBuilder.arguments(new String[] { "-purgecaches" })
.extras(InstrumentationRegistry.getArguments())
.nativeCrashReportingEnabled(true)
.javaCrashReportingEnabled(true);
.extras(InstrumentationRegistry.getArguments());
sRuntime = GeckoRuntime.create(
InstrumentationRegistry.getTargetContext(),
runtimeSettingsBuilder.build());

Просмотреть файл

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.mozilla.geckoview">
package="org.mozilla.geckoview">
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
@ -13,88 +12,62 @@
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-feature
android:name="android.hardware.location"
android:required="false"/>
<uses-feature
android:name="android.hardware.location.gps"
android:required="false"/>
<uses-feature android:name="android.hardware.location" android:required="false"/>
<uses-feature android:name="android.hardware.location.gps" android:required="false"/>
<uses-feature android:name="android.hardware.touchscreen"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature
android:name="android.hardware.camera"
android:required="false"/>
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false"/>
<!-- #ifdef MOZ_WEBRTC -->
<!--
TODO preprocess AndroidManifest.xml so that we can
conditionally include WebRTC permissions based on MOZ_WEBRTC.
-->
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
-->
<uses-feature
android:name="android.hardware.audio.low_latency"
android:required="false"/>
-->
<uses-feature
android:name="android.hardware.microphone"
android:required="false"/>
-->
<uses-feature
android:name="android.hardware.camera.any"
android:required="false"/>
-->
<!-- #endif -->
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
<!--#ifdef MOZ_WEBRTC-->
<!-- TODO preprocess AndroidManifest.xml so that we can
conditionally include WebRTC permissions based on MOZ_WEBRTC. -->
<uses-permission android:name="android.permission.RECORD_AUDIO"/>-->
<uses-feature android:name="android.hardware.audio.low_latency" android:required="false"/>-->
<uses-feature android:name="android.hardware.microphone" android:required="false"/>-->
<uses-feature android:name="android.hardware.camera.any" android:required="false"/>-->
<!--#endif-->
<!-- App requires OpenGL ES 2.0 -->
<uses-feature
android:glEsVersion="0x00020000"
android:required="true"/>
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
<application>
<!-- New child services must also be added to the Fennec AndroidManifest.xml.in -->
<service
android:name="org.mozilla.gecko.media.MediaManager"
android:enabled="true"
android:exported="false"
android:isolatedProcess="false"
android:process=":media">
android:name="org.mozilla.gecko.media.MediaManager"
android:enabled="true"
android:exported="false"
android:process=":media"
android:isolatedProcess="false">
</service>
<service
android:name="org.mozilla.gecko.process.GeckoServiceChildProcess$geckomediaplugin"
android:enabled="true"
android:exported="false"
android:isolatedProcess="false"
android:process=":geckomediaplugin">
</service>
<service
android:name="org.mozilla.gecko.process.GeckoServiceChildProcess$tab"
android:enabled="true"
android:exported="false"
android:isolatedProcess="false"
android:process=":tab">
</service>
<service
android:name="org.mozilla.gecko.gfx.SurfaceAllocatorService"
android:enabled="true"
android:exported="false"
android:isolatedProcess="false">
</service>
<service
android:name="org.mozilla.gecko.CrashReporterService"
android:exported="false"
android:process=":crashreporter">
</service>
</application>
</manifest>
<service
android:name="org.mozilla.gecko.process.GeckoServiceChildProcess$geckomediaplugin"
android:enabled="true"
android:exported="false"
android:process=":geckomediaplugin"
android:isolatedProcess="false">
</service>
<service
android:name="org.mozilla.gecko.process.GeckoServiceChildProcess$tab"
android:enabled="true"
android:exported="false"
android:process=":tab"
android:isolatedProcess="false">
</service>
<service
android:name="org.mozilla.gecko.gfx.SurfaceAllocatorService"
android:enabled="true"
android:exported="false"
android:isolatedProcess="false">
</service>
</application>
</manifest>

Просмотреть файл

@ -11,7 +11,7 @@ import android.os.ParcelFileDescriptor;
interface IChildProcess {
int getPid();
boolean start(in IProcessManager procMan, in String[] args, in Bundle extras, int flags,
boolean start(in IProcessManager procMan, in String[] args, in Bundle extras,
in ParcelFileDescriptor prefsPfd, in ParcelFileDescriptor ipcPfd,
in ParcelFileDescriptor crashReporterPfd,
in ParcelFileDescriptor crashAnnotationPfd);

Просмотреть файл

@ -297,7 +297,7 @@ public class CrashHandler implements Thread.UncaughtExceptionHandler {
final Context context = getAppContext();
final String javaPkg = getJavaPackageName();
final String pkg = getAppPackageName();
final String component = javaPkg + ".CrashReporterService";
final String component = javaPkg + ".CrashReporter";
final String action = javaPkg + ".reportCrash";
final ProcessBuilder pb;
@ -305,7 +305,8 @@ public class CrashHandler implements Thread.UncaughtExceptionHandler {
final Intent intent = new Intent(action);
intent.setComponent(new ComponentName(pkg, component));
intent.putExtra("minidumpPath", dumpFile);
context.startService(intent);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
return true;
}

Просмотреть файл

@ -1,373 +0,0 @@
package org.mozilla.gecko;
import org.mozilla.gecko.mozglue.GeckoLoader;
import org.mozilla.gecko.mozglue.MinidumpAnalyzer;
import org.mozilla.gecko.util.INIParser;
import org.mozilla.gecko.util.INISection;
import org.mozilla.gecko.util.ProxySelector;
import android.app.IntentService;
import android.content.Intent;
import android.os.Build;
import android.util.Log;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLDecoder;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.GZIPOutputStream;
public class CrashReporterService extends IntentService {
private static final String LOGTAG = "CrashReporter";
private static final String ACTION_REPORT_CRASH = "org.mozilla.gecko.reportCrash";
private static final String PASSED_MINI_DUMP_KEY = "minidumpPath";
private static final String PASSED_MINI_DUMP_SUCCESS_KEY = "minidumpSuccess";
private static final String MINI_DUMP_PATH_KEY = "upload_file_minidump";
private static final String PAGE_URL_KEY = "URL";
private static final String NOTES_KEY = "Notes";
private static final String SERVER_URL_KEY = "ServerURL";
private static final String CRASH_REPORT_SUFFIX = "/mozilla/Crash Reports/";
private static final String PENDING_SUFFIX = CRASH_REPORT_SUFFIX + "pending";
private static final String SUBMITTED_SUFFIX = CRASH_REPORT_SUFFIX + "submitted";
private File mPendingMinidumpFile;
private File mPendingExtrasFile;
private HashMap<String, String> mExtrasStringMap;
private boolean mMinidumpSucceeded;
public CrashReporterService() {
super("CrashReporterService");
}
@Override
protected void onHandleIntent(Intent intent) {
if (intent == null || !intent.getAction().equals(ACTION_REPORT_CRASH)) {
Log.d(LOGTAG, "Invalid or unknown action");
return;
}
Class<?> reporterActivityCls = getFennecReporterActivity();
if (reporterActivityCls != null) {
intent.setClass(this, reporterActivityCls);
startActivity(intent);
return;
}
submitCrash(intent);
}
private Class<?> getFennecReporterActivity() {
try {
return Class.forName("org.mozilla.gecko.CrashReporterActivity");
} catch (ClassNotFoundException e) {
return null;
}
}
private boolean moveFile(File inFile, File outFile) {
Log.i(LOGTAG, "moving " + inFile + " to " + outFile);
if (inFile.renameTo(outFile))
return true;
try {
outFile.createNewFile();
Log.i(LOGTAG, "couldn't rename minidump file");
// so copy it instead
FileChannel inChannel = new FileInputStream(inFile).getChannel();
FileChannel outChannel = new FileOutputStream(outFile).getChannel();
long transferred = inChannel.transferTo(0, inChannel.size(), outChannel);
inChannel.close();
outChannel.close();
if (transferred > 0)
inFile.delete();
} catch (Exception e) {
Log.e(LOGTAG, "exception while copying minidump file: ", e);
return false;
}
return true;
}
private void submitCrash(Intent intent) {
mMinidumpSucceeded = intent.getBooleanExtra(PASSED_MINI_DUMP_SUCCESS_KEY, false);
if (!mMinidumpSucceeded) {
Log.i(LOGTAG, "Failed to get minidump.");
}
String passedMinidumpPath = intent.getStringExtra(PASSED_MINI_DUMP_KEY);
File passedMinidumpFile = new File(passedMinidumpPath);
File pendingDir = new File(getFilesDir(), PENDING_SUFFIX);
pendingDir.mkdirs();
mPendingMinidumpFile = new File(pendingDir, passedMinidumpFile.getName());
moveFile(passedMinidumpFile, mPendingMinidumpFile);
File extrasFile = new File(passedMinidumpPath.replaceAll("\\.dmp", ".extra"));
mPendingExtrasFile = new File(pendingDir, extrasFile.getName());
moveFile(extrasFile, mPendingExtrasFile);
// Compute the minidump hash and generate the stack traces
computeMinidumpHash(mPendingExtrasFile, mPendingMinidumpFile);
try {
GeckoLoader.loadMozGlue(this);
if (!MinidumpAnalyzer.GenerateStacks(mPendingMinidumpFile.getPath(), /* fullStacks */ false)) {
Log.e(LOGTAG, "Could not generate stacks for this minidump: " + passedMinidumpPath);
}
} catch (UnsatisfiedLinkError e) {
Log.e(LOGTAG, "Could not load libmozglue.so, stacks for this crash won't be generated");
}
// Extract the annotations from the .extra file
mExtrasStringMap = new HashMap<String, String>();
readStringsFromFile(mPendingExtrasFile.getPath(), mExtrasStringMap);
try {
// Find the profile name and path. Since we don't have any other way of getting it within
// this context we extract it from the crash dump path.
final File profileDir = passedMinidumpFile.getParentFile().getParentFile();
final String profileName = getProfileName(profileDir);
if (profileName != null) {
// Extract the crash dump ID and telemetry client ID, we need profile access for the latter.
final String passedMinidumpName = passedMinidumpFile.getName();
// Strip the .dmp suffix from the minidump name to obtain the crash ID.
final String crashId = passedMinidumpName.substring(0, passedMinidumpName.length() - 4);
final GeckoProfile profile = GeckoProfile.get(this, profileName, profileDir);
final String clientId = profile.getClientId();
}
} catch (GeckoProfileDirectories.NoMozillaDirectoryException | IOException e) {
Log.e(LOGTAG, "Cannot send the crash ping: ", e);
}
// Notify GeckoApp that we've crashed, so it can react appropriately during the next start.
try {
File crashFlag = new File(GeckoProfileDirectories.getMozillaDirectory(this), "CRASHED");
crashFlag.createNewFile();
} catch (GeckoProfileDirectories.NoMozillaDirectoryException | IOException e) {
Log.e(LOGTAG, "Cannot set crash flag: ", e);
}
sendReport(mPendingMinidumpFile, mExtrasStringMap, mPendingExtrasFile);
}
private String getProfileName(File profileDir) throws GeckoProfileDirectories.NoMozillaDirectoryException {
final File mozillaDir = GeckoProfileDirectories.getMozillaDirectory(this);
final INIParser parser = GeckoProfileDirectories.getProfilesINI(mozillaDir);
String profileName = null;
if (parser.getSections() != null) {
for (Enumeration<INISection> e = parser.getSections().elements(); e.hasMoreElements(); ) {
final INISection section = e.nextElement();
final String path = section.getStringProperty("Path");
final boolean isRelative = (section.getIntProperty("IsRelative") == 1);
if ((isRelative && path.equals(profileDir.getName())) ||
path.equals(profileDir.getPath())) {
profileName = section.getStringProperty("Name");
break;
}
}
}
return profileName;
}
private void computeMinidumpHash(File extraFile, File minidump) {
try {
FileInputStream stream = new FileInputStream(minidump);
MessageDigest md = MessageDigest.getInstance("SHA-256");
try {
byte[] buffer = new byte[4096];
int readBytes;
while ((readBytes = stream.read(buffer)) != -1) {
md.update(buffer, 0, readBytes);
}
} finally {
stream.close();
}
byte[] digest = md.digest();
StringBuilder hash = new StringBuilder(84);
hash.append("MinidumpSha256Hash=");
for (int i = 0; i < digest.length; i++) {
hash.append(Integer.toHexString((digest[i] & 0xf0) >> 4));
hash.append(Integer.toHexString(digest[i] & 0x0f));
}
hash.append('\n');
FileWriter writer = new FileWriter(extraFile, /* append */ true);
try {
writer.write(hash.toString());
} finally {
writer.close();
}
} catch (Exception e) {
Log.e(LOGTAG, "exception while computing the minidump hash: ", e);
}
}
private boolean readStringsFromFile(String filePath, Map<String, String> stringMap) {
try {
BufferedReader reader = new BufferedReader(new FileReader(filePath));
return readStringsFromReader(reader, stringMap);
} catch (Exception e) {
Log.e(LOGTAG, "exception while reading strings: ", e);
return false;
}
}
private boolean readStringsFromReader(BufferedReader reader, Map<String, String> stringMap) throws IOException {
String line;
while ((line = reader.readLine()) != null) {
int equalsPos = -1;
if ((equalsPos = line.indexOf('=')) != -1) {
String key = line.substring(0, equalsPos);
String val = unescape(line.substring(equalsPos + 1));
stringMap.put(key, val);
}
}
reader.close();
return true;
}
private String generateBoundary() {
// Generate some random numbers to fill out the boundary
int r0 = (int)(Integer.MAX_VALUE * Math.random());
int r1 = (int)(Integer.MAX_VALUE * Math.random());
return String.format("---------------------------%08X%08X", r0, r1);
}
private void sendPart(OutputStream os, String boundary, String name, String data) {
try {
os.write(("--" + boundary + "\r\n" +
"Content-Disposition: form-data; name=\"" + name + "\"\r\n" +
"\r\n" +
data + "\r\n"
).getBytes());
} catch (Exception ex) {
Log.e(LOGTAG, "Exception when sending \"" + name + "\"", ex);
}
}
private void sendFile(OutputStream os, String boundary, String name, File file) throws IOException {
os.write(("--" + boundary + "\r\n" +
"Content-Disposition: form-data; name=\"" + name + "\"; " +
"filename=\"" + file.getName() + "\"\r\n" +
"Content-Type: application/octet-stream\r\n" +
"\r\n"
).getBytes());
FileChannel fc = new FileInputStream(file).getChannel();
fc.transferTo(0, fc.size(), Channels.newChannel(os));
fc.close();
}
private void sendReport(File minidumpFile, Map<String, String> extras, File extrasFile) {
Log.i(LOGTAG, "sendReport: " + minidumpFile.getPath());
String spec = extras.get(SERVER_URL_KEY);
if (spec == null) {
return;
}
try {
final URL url = new URL(URLDecoder.decode(spec, "UTF-8"));
final URI uri = new URI(url.getProtocol(), url.getUserInfo(),
url.getHost(), url.getPort(),
url.getPath(), url.getQuery(), url.getRef());
HttpURLConnection conn = (HttpURLConnection) ProxySelector.openConnectionWithProxy(uri);
conn.setRequestMethod("POST");
String boundary = generateBoundary();
conn.setDoOutput(true);
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
conn.setRequestProperty("Content-Encoding", "gzip");
OutputStream os = new GZIPOutputStream(conn.getOutputStream());
for (String key : extras.keySet()) {
if (!key.equals(SERVER_URL_KEY) && !key.equals(NOTES_KEY)) {
sendPart(os, boundary, key, extras.get(key));
}
}
StringBuilder sb = new StringBuilder();
sb.append(extras.containsKey(NOTES_KEY) ? extras.get(NOTES_KEY) + "\n" : "");
sb.append(Build.MANUFACTURER).append(' ')
.append(Build.MODEL).append('\n')
.append(Build.FINGERPRINT);
sendPart(os, boundary, NOTES_KEY, sb.toString());
sendPart(os, boundary, "Android_Manufacturer", Build.MANUFACTURER);
sendPart(os, boundary, "Android_Model", Build.MODEL);
sendPart(os, boundary, "Android_Board", Build.BOARD);
sendPart(os, boundary, "Android_Brand", Build.BRAND);
sendPart(os, boundary, "Android_Device", Build.DEVICE);
sendPart(os, boundary, "Android_Display", Build.DISPLAY);
sendPart(os, boundary, "Android_Fingerprint", Build.FINGERPRINT);
sendPart(os, boundary, "Android_CPU_ABI", Build.CPU_ABI);
try {
sendPart(os, boundary, "Android_CPU_ABI2", Build.CPU_ABI2);
sendPart(os, boundary, "Android_Hardware", Build.HARDWARE);
} catch (Exception ex) {
Log.e(LOGTAG, "Exception while sending SDK version 8 keys", ex);
}
sendPart(os, boundary, "Android_Version", Build.VERSION.SDK_INT + " (" + Build.VERSION.CODENAME + ")");
sendPart(os, boundary, PASSED_MINI_DUMP_SUCCESS_KEY, mMinidumpSucceeded ? "True" : "False");
sendFile(os, boundary, MINI_DUMP_PATH_KEY, minidumpFile);
os.write(("\r\n--" + boundary + "--\r\n").getBytes());
os.flush();
os.close();
BufferedReader br = new BufferedReader(
new InputStreamReader(conn.getInputStream()));
HashMap<String, String> responseMap = new HashMap<String, String>();
readStringsFromReader(br, responseMap);
if (conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
File submittedDir = new File(getFilesDir(),
SUBMITTED_SUFFIX);
submittedDir.mkdirs();
minidumpFile.delete();
extrasFile.delete();
String crashid = responseMap.get("CrashID");
File file = new File(submittedDir, crashid + ".txt");
FileOutputStream fos = new FileOutputStream(file);
fos.write("Crash ID: ".getBytes());
fos.write(crashid.getBytes());
fos.close();
Log.i(LOGTAG, "Successfully sent crash report: " + crashid);
} else {
Log.w(LOGTAG, "Received failure HTTP response code from server: " + conn.getResponseCode());
}
} catch (IOException e) {
Log.e(LOGTAG, "exception during send: ", e);
} catch (URISyntaxException e) {
Log.e(LOGTAG, "exception during new URI: ", e);
}
}
private String unescape(String string) {
return string.replaceAll("\\\\\\\\", "\\").replaceAll("\\\\n", "\n").replaceAll("\\\\t", "\t");
}
}

Просмотреть файл

@ -111,7 +111,7 @@ public class GeckoAppShell
// We have static members only.
private GeckoAppShell() { }
private static class GeckoCrashHandler extends CrashHandler {
private static final CrashHandler CRASH_HANDLER = new CrashHandler() {
@Override
protected String getAppPackageName() {
final Context appContext = getAppContext();
@ -174,18 +174,10 @@ public class GeckoAppShell
};
private static String sAppNotes;
private static CrashHandler sCrashHandler;
public static synchronized CrashHandler ensureCrashHandling() {
if (sCrashHandler == null) {
sCrashHandler = new GeckoCrashHandler();
}
return sCrashHandler;
}
public static synchronized boolean isCrashHandlingEnabled() {
return sCrashHandler != null;
public static CrashHandler ensureCrashHandling() {
// Crash handling is automatically enabled when GeckoAppShell is loaded.
return CRASH_HANDLER;
}
@WrapForJNI(exceptionMode = "ignore")
@ -288,10 +280,8 @@ public class GeckoAppShell
}
@WrapForJNI(exceptionMode = "ignore")
private static synchronized void handleUncaughtException(Throwable e) {
if (sCrashHandler != null) {
sCrashHandler.uncaughtException(null, e);
}
private static void handleUncaughtException(Throwable e) {
CRASH_HANDLER.uncaughtException(null, e);
}
private static float getLocationAccuracy(Location location) {

Просмотреть файл

@ -12,7 +12,6 @@ import org.mozilla.gecko.process.GeckoProcessManager;
import org.mozilla.gecko.util.GeckoBundle;
import org.mozilla.gecko.util.FileUtils;
import org.mozilla.gecko.util.ThreadUtils;
import org.mozilla.geckoview.BuildConfig;
import android.content.Context;
import android.content.res.Configuration;
@ -28,10 +27,10 @@ import android.text.TextUtils;
import android.util.Log;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.StringTokenizer;
@ -125,10 +124,8 @@ public class GeckoThread extends Thread {
private static int uiThreadId;
// Main process parameters
public static final int FLAG_DEBUGGING = 1 << 0; // Debugging mode.
public static final int FLAG_PRELOAD_CHILD = 1 << 1; // Preload child during main thread start.
public static final int FLAG_ENABLE_NATIVE_CRASHREPORTER = 1 << 2; // Enable native crash reporting
public static final int FLAG_ENABLE_JAVA_CRASHREPORTER = 1 << 3; // Enable java crash reporting
public static final int FLAG_DEBUGGING = 1; // Debugging mode.
public static final int FLAG_PRELOAD_CHILD = 2; // Preload child during main thread start.
private static final String EXTRA_ARGS = "args";
private static final String EXTRA_PREFS_FD = "prefsFd";
@ -184,14 +181,11 @@ public class GeckoThread extends Thread {
/* fd */ -1, /* fd */ -1, /* fd */ -1);
}
public static boolean initChildProcess(final String[] args,
final Bundle extras,
final int flags,
final int prefsFd,
final int ipcFd,
public static boolean initChildProcess(final String[] args, final Bundle extras,
final int prefsFd, final int ipcFd,
final int crashFd,
final int crashAnnotationFd) {
return INSTANCE.init(/* profile */ null, args, extras, flags,
return INSTANCE.init(/* profile */ null, args, extras, /* flags */ 0,
prefsFd, ipcFd, crashFd, crashAnnotationFd);
}
@ -383,40 +377,10 @@ public class GeckoThread extends Thread {
if (!INSTANCE.mInitialized) {
return null;
}
return new Bundle(INSTANCE.mExtras);
return INSTANCE.mExtras;
}
}
public static int getActiveFlags() {
synchronized (INSTANCE) {
if (!INSTANCE.mInitialized) {
return 0;
}
return INSTANCE.mFlags;
}
}
private static ArrayList<String> getEnvFromExtras(final Bundle extras) {
if (extras == null) {
return new ArrayList<>();
}
ArrayList<String> result = new ArrayList<>();
if (extras != null) {
String env = extras.getString("env0");
for (int c = 1; env != null; c++) {
if (BuildConfig.DEBUG) {
Log.d(LOGTAG, "env var: " + env);
}
result.add(env);
env = extras.getString("env" + c);
}
}
return result;
}
@Override
public void run() {
Log.i(LOGTAG, "preparing to run Gecko");
@ -478,21 +442,7 @@ public class GeckoThread extends Thread {
Log.i(LOGTAG, "RunGecko - args = " + TextUtils.join(" ", args));
}
final List<String> env = getEnvFromExtras(mExtras);
// In Gecko, the native crash reporter is enabled by default in opt builds, and
// disabled by default in debug builds.
if ((mFlags & FLAG_ENABLE_NATIVE_CRASHREPORTER) == 0 && !BuildConfig.DEBUG_BUILD) {
env.add(0, "MOZ_CRASHREPORTER_DISABLE=1");
} else if ((mFlags & FLAG_ENABLE_NATIVE_CRASHREPORTER) != 0 && BuildConfig.DEBUG_BUILD) {
env.add(0, "MOZ_CRASHREPORTER=1");
}
if ((mFlags & FLAG_ENABLE_JAVA_CRASHREPORTER) != 0) {
GeckoAppShell.ensureCrashHandling();
}
GeckoLoader.setupGeckoEnvironment(context, context.getFilesDir().getPath(), env);
GeckoLoader.setupGeckoEnvironment(context, context.getFilesDir().getPath(), mExtras);
// And go.
GeckoLoader.nativeRun(args,

Просмотреть файл

@ -8,7 +8,6 @@ package org.mozilla.gecko.mozglue;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.Collection;
import java.util.Locale;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
@ -93,9 +92,17 @@ public final class GeckoLoader {
public synchronized static void setupGeckoEnvironment(final Context context,
final String profilePath,
final Collection<String> env) {
for (final String e : env) {
putenv(e);
final Bundle extras) {
// if we have an intent (we're being launched by an activity)
// read in any environmental variables from it here
if (extras != null) {
String env = extras.getString("env0");
Log.d(LOGTAG, "Gecko environment env0: " + env);
for (int c = 1; env != null; c++) {
putenv(env);
env = extras.getString("env" + c);
Log.d(LOGTAG, "env" + c + ": " + env);
}
}
try {

Просмотреть файл

@ -181,11 +181,6 @@ public final class GeckoProcessManager extends IProcessManager.Stub {
return INSTANCE.start(type, args, prefsFd, ipcFd, crashFd, crashAnnotationFd, /* retry */ false);
}
private int filterFlagsForChild(int flags) {
return flags & (GeckoThread.FLAG_ENABLE_JAVA_CRASHREPORTER |
GeckoThread.FLAG_ENABLE_NATIVE_CRASHREPORTER);
}
private int start(final String type, final String[] args, final int prefsFd,
final int ipcFd, final int crashFd,
final int crashAnnotationFd, final boolean retry) {
@ -210,11 +205,9 @@ public final class GeckoProcessManager extends IProcessManager.Stub {
return 0;
}
final int flags = filterFlagsForChild(GeckoThread.getActiveFlags());
boolean started = false;
try {
started = child.start(this, args, extras, flags, prefsPfd, ipcPfd, crashPfd,
started = child.start(this, args, extras, prefsPfd, ipcPfd, crashPfd,
crashAnnotationPfd);
} catch (final RemoteException e) {
}

Просмотреть файл

@ -24,7 +24,9 @@ import android.os.RemoteException;
import android.util.Log;
public class GeckoServiceChildProcess extends Service {
private static final String LOGTAG = "GeckoServiceChildProcess";
private static IProcessManager sProcessManager;
@WrapForJNI(calledFrom = "gecko")
@ -42,6 +44,7 @@ public class GeckoServiceChildProcess extends Service {
public void onCreate() {
super.onCreate();
GeckoAppShell.ensureCrashHandling();
GeckoAppShell.setApplicationContext(getApplicationContext());
}
@ -60,7 +63,6 @@ public class GeckoServiceChildProcess extends Service {
public boolean start(final IProcessManager procMan,
final String[] args,
final Bundle extras,
final int flags,
final ParcelFileDescriptor prefsPfd,
final ParcelFileDescriptor ipcPfd,
final ParcelFileDescriptor crashReporterPfd,
@ -83,7 +85,7 @@ public class GeckoServiceChildProcess extends Service {
ThreadUtils.postToUiThread(new Runnable() {
@Override
public void run() {
if (GeckoThread.initChildProcess(args, extras, flags, prefsFd, ipcFd, crashReporterFd,
if (GeckoThread.initChildProcess(args, extras, prefsFd, ipcFd, crashReporterFd,
crashAnnotationFd)) {
GeckoThread.launch();
}

Просмотреть файл

@ -84,19 +84,9 @@ public final class GeckoRuntime implements Parcelable {
if (DEBUG) {
Log.d(LOGTAG, "init");
}
int flags = 0;
if (settings.getUseContentProcessHint()) {
flags |= GeckoThread.FLAG_PRELOAD_CHILD;
}
if (settings.getNativeCrashReportingEnabled()) {
flags |= GeckoThread.FLAG_ENABLE_NATIVE_CRASHREPORTER;
}
if (settings.getJavaCrashReportingEnabled()) {
flags |= GeckoThread.FLAG_ENABLE_JAVA_CRASHREPORTER;
}
final int flags = settings.getUseContentProcessHint()
? GeckoThread.FLAG_PRELOAD_CHILD
: 0;
if (GeckoThread.initMainProcess(/* profile */ null,
settings.getArguments(),
settings.getExtras(),

Просмотреть файл

@ -40,9 +40,7 @@ public final class GeckoRuntimeSettings implements Parcelable {
* Set the content process hint flag.
*
* @param use If true, this will reload the content process for future use.
* Default is false.
* @return This Builder instance.
*/
public @NonNull Builder useContentProcessHint(final boolean use) {
mSettings.mUseContentProcess = use;
@ -81,7 +79,6 @@ public final class GeckoRuntimeSettings implements Parcelable {
* Set whether JavaScript support should be enabled.
*
* @param flag A flag determining whether JavaScript should be enabled.
* Default is true.
* @return This Builder instance.
*/
public @NonNull Builder javaScriptEnabled(final boolean flag) {
@ -104,41 +101,12 @@ public final class GeckoRuntimeSettings implements Parcelable {
* Set whether support for web fonts should be enabled.
*
* @param flag A flag determining whether web fonts should be enabled.
* Default is true.
* @return This Builder instance.
*/
public @NonNull Builder webFontsEnabled(final boolean flag) {
mSettings.mWebFonts.set(flag);
return this;
}
/**
* Set whether crash reporting for native code should be enabled. This will cause
* a SIGSEGV handler to be installed, and any crash encountered there will be
* reported to Mozilla.
*
* @param enabled A flag determining whether native crash reporting should be enabled.
* Defaults to false.
* @return This Builder.
*/
public @NonNull Builder nativeCrashReportingEnabled(final boolean enabled) {
mSettings.mNativeCrashReporting = enabled;
return this;
}
/**
* Set whether crash reporting for Java code should be enabled. This will cause
* a default unhandled exception handler to be installed, and any exceptions encountered
* will automatically reported to Mozilla.
*
* @param enabled A flag determining whether Java crash reporting should be enabled.
* Defaults to false.
* @return This Builder.
*/
public @NonNull Builder javaCrashReportingEnabled(final boolean enabled) {
mSettings.mJavaCrashReporting = enabled;
return this;
}
}
/* package */ GeckoRuntime runtime;
@ -182,8 +150,6 @@ public final class GeckoRuntimeSettings implements Parcelable {
"devtools.debugger.remote-enabled", false);
/* package */ Pref<Boolean> mWebFonts = new Pref<Boolean>(
"browser.display.use_document_fonts", true);
/* package */ boolean mNativeCrashReporting;
/* package */ boolean mJavaCrashReporting;
private final Pref<?>[] mPrefs = new Pref<?>[] {
mJavaScript, mRemoteDebugging, mWebFonts
@ -214,9 +180,6 @@ public final class GeckoRuntimeSettings implements Parcelable {
final Pref<Object> uncheckedPref = (Pref<Object>) mPrefs[i];
uncheckedPref.set(settings.mPrefs[i].get());
}
mNativeCrashReporting = settings.mNativeCrashReporting;
mJavaCrashReporting = settings.mJavaCrashReporting;
}
/* package */ void flush() {
@ -312,24 +275,6 @@ public final class GeckoRuntimeSettings implements Parcelable {
return this;
}
/**
* Get whether native crash reporting is enabled or not.
*
* @return True if native crash reporting is enabled.
*/
public boolean getNativeCrashReportingEnabled() {
return mNativeCrashReporting;
}
/**
* Get whether Java crash reporting is enabled or not.
*
* @return True if Java crash reporting is enabled.
*/
public boolean getJavaCrashReportingEnabled() {
return mJavaCrashReporting;
}
@Override // Parcelable
public int describeContents() {
return 0;
@ -337,21 +282,18 @@ public final class GeckoRuntimeSettings implements Parcelable {
@Override // Parcelable
public void writeToParcel(Parcel out, int flags) {
ParcelableUtils.writeBoolean(out, mUseContentProcess);
out.writeByte((byte) (mUseContentProcess ? 1 : 0));
out.writeStringArray(mArgs);
mExtras.writeToParcel(out, flags);
for (final Pref<?> pref : mPrefs) {
out.writeValue(pref.get());
}
ParcelableUtils.writeBoolean(out, mNativeCrashReporting);
ParcelableUtils.writeBoolean(out, mJavaCrashReporting);
}
// AIDL code may call readFromParcel even though it's not part of Parcelable.
public void readFromParcel(final Parcel source) {
mUseContentProcess = ParcelableUtils.readBoolean(source);
mUseContentProcess = source.readByte() == 1;
mArgs = source.createStringArray();
mExtras.readFromParcel(source);
@ -361,9 +303,6 @@ public final class GeckoRuntimeSettings implements Parcelable {
final Pref<Object> uncheckedPref = (Pref<Object>) pref;
uncheckedPref.set(source.readValue(getClass().getClassLoader()));
}
mNativeCrashReporting = ParcelableUtils.readBoolean(source);
mJavaCrashReporting = ParcelableUtils.readBoolean(source);
}
public static final Parcelable.Creator<GeckoRuntimeSettings> CREATOR

Просмотреть файл

@ -1,19 +0,0 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
* vim: ts=4 sw=4 expandtab:
* 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.geckoview;
import android.os.Parcel;
class ParcelableUtils {
public static void writeBoolean(Parcel out, boolean val) {
out.writeByte((byte) (val ? 1 : 0));
}
public static boolean readBoolean(Parcel source) {
return source.readByte() == 1;
}
}

Просмотреть файл

@ -67,12 +67,7 @@ public class GeckoViewActivity extends Activity {
if (extras != null) {
runtimeSettingsBuilder.extras(extras);
}
runtimeSettingsBuilder
.useContentProcessHint(useMultiprocess)
.nativeCrashReportingEnabled(true)
.javaCrashReportingEnabled(true);
runtimeSettingsBuilder.useContentProcessHint(useMultiprocess);
sGeckoRuntime = GeckoRuntime.create(this, runtimeSettingsBuilder.build());
}

Просмотреть файл

@ -840,7 +840,7 @@ LaunchCrashReporterActivity(XP_CHAR* aProgramPath, XP_CHAR* aMinidumpPath,
if (androidUserSerial) {
Unused << execlp("/system/bin/am",
"/system/bin/am",
"startservice",
"start",
"--user", androidUserSerial,
"-a", "org.mozilla.gecko.reportCrash",
"-n", aProgramPath,
@ -850,7 +850,7 @@ LaunchCrashReporterActivity(XP_CHAR* aProgramPath, XP_CHAR* aMinidumpPath,
} else {
Unused << execlp("/system/bin/am",
"/system/bin/am",
"startservice",
"start",
"-a", "org.mozilla.gecko.reportCrash",
"-n", aProgramPath,
"--es", "minidumpPath", aMinidumpPath,
@ -1544,10 +1544,10 @@ nsresult SetExceptionHandler(nsIFile* aXREDirectory,
const char* androidPackageName = PR_GetEnv("MOZ_ANDROID_PACKAGE_NAME");
if (androidPackageName != nullptr) {
nsCString package(androidPackageName);
package.AppendLiteral("/org.mozilla.gecko.CrashReporterService");
package.AppendLiteral("/org.mozilla.gecko.CrashReporter");
crashReporterPath = ToNewCString(package);
} else {
nsCString package(ANDROID_PACKAGE_NAME "/org.mozilla.gecko.CrashReporterService");
nsCString package(ANDROID_PACKAGE_NAME "/org.mozilla.gecko.CrashReporter");
crashReporterPath = ToNewCString(package);
}
#endif // !defined(MOZ_WIDGET_ANDROID)

Просмотреть файл

@ -406,7 +406,6 @@ nsAppShell::nsAppShell()
if (!XRE_IsParentProcess()) {
if (jni::IsAvailable()) {
GeckoAppShellSupport::Init();
GeckoThreadSupport::Init();
// Set the corresponding state in GeckoThread.