| Index: android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java
|
| diff --git a/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java b/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java
|
| index 797f8437fa712cf50ed02b2a1343fe477c0e7ec7..656ad9f914fe4daacaf8144bde8fc362e0159ae5 100644
|
| --- a/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java
|
| +++ b/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java
|
| @@ -4,10 +4,18 @@
|
|
|
| package org.chromium.android_webview;
|
|
|
| +import android.content.ComponentName;
|
| import android.content.Context;
|
| +import android.content.Intent;
|
| +import android.content.ServiceConnection;
|
| import android.os.AsyncTask;
|
| +import android.os.IBinder;
|
| +import android.os.ParcelFileDescriptor;
|
| +import android.os.RemoteException;
|
| import android.os.StrictMode;
|
|
|
| +import org.chromium.android_webview.crash.CrashReceiverService;
|
| +import org.chromium.android_webview.crash.ICrashReceiverService;
|
| import org.chromium.android_webview.policy.AwPolicyProvider;
|
| import org.chromium.base.CommandLine;
|
| import org.chromium.base.ContextUtils;
|
| @@ -18,12 +26,14 @@ import org.chromium.base.ThreadUtils;
|
| import org.chromium.base.library_loader.LibraryLoader;
|
| import org.chromium.base.library_loader.LibraryProcessType;
|
| import org.chromium.base.library_loader.ProcessInitException;
|
| +import org.chromium.components.minidump_uploader.CrashFileManager;
|
| import org.chromium.content.browser.BrowserStartupController;
|
| import org.chromium.content.browser.ChildProcessCreationParams;
|
| import org.chromium.content.browser.ChildProcessLauncher;
|
| import org.chromium.policy.CombinedPolicyProvider;
|
|
|
| import java.io.File;
|
| +import java.io.FileNotFoundException;
|
| import java.io.IOException;
|
| import java.io.RandomAccessFile;
|
| import java.nio.channels.FileLock;
|
| @@ -39,6 +49,8 @@ public abstract class AwBrowserProcess {
|
| private static RandomAccessFile sLockFile;
|
| private static FileLock sExclusiveFileLock;
|
|
|
| + private static final int MAX_MINIDUMP_UPLOAD_TRIES = 3;
|
| +
|
| /**
|
| * Loads the native library, and performs basic static construction of objects needed
|
| * to run webview in this process. Does not create threads; safe to call from zygote.
|
| @@ -161,4 +173,78 @@ public abstract class AwBrowserProcess {
|
| StrictMode.setThreadPolicy(oldPolicy);
|
| }
|
| }
|
| +
|
| + /**
|
| + * Pass Minidumps to a separate Service declared in the WebView provider package.
|
| + * That Service will copy the Minidumps to its own data directory - at which point we can delete
|
| + * our copies in the app directory.
|
| + */
|
| + public static void handleMinidumps(final String webViewPackageName) {
|
| + new AsyncTask<Void, Void, Void>() {
|
| + @Override
|
| + protected Void doInBackground(Void... params) {
|
| + final Context appContext = ContextUtils.getApplicationContext();
|
| + final CrashFileManager crashFileManager =
|
| + new CrashFileManager(appContext.getCacheDir());
|
| + final File[] minidumpFiles =
|
| + crashFileManager.getAllMinidumpFiles(MAX_MINIDUMP_UPLOAD_TRIES);
|
| + if (minidumpFiles.length == 0) return null;
|
| +
|
| + final Intent intent = new Intent();
|
| + intent.setClassName(webViewPackageName, CrashReceiverService.class.getName());
|
| +
|
| + ServiceConnection connection = new ServiceConnection() {
|
| + @Override
|
| + public void onServiceConnected(ComponentName className, IBinder service) {
|
| + // Pass file descriptors, pointing to our minidumps, to the minidump-copying
|
| + // service so that the contents of the minidumps will be copied to WebView's
|
| + // data directory. Delete our direct File-references to the minidumps after
|
| + // creating the file-descriptors to resign from retrying to copy the
|
| + // minidumps if anything goes wrong - this makes sense given that a failure
|
| + // to copy a file usually means that retrying won't succeed either, e.g. the
|
| + // disk being full, or the file system being corrupted.
|
| + final ParcelFileDescriptor[] minidumpFds =
|
| + new ParcelFileDescriptor[minidumpFiles.length];
|
| + try {
|
| + for (int i = 0; i < minidumpFiles.length; ++i) {
|
| + try {
|
| + minidumpFds[i] = ParcelFileDescriptor.open(
|
| + minidumpFiles[i], ParcelFileDescriptor.MODE_READ_ONLY);
|
| + } catch (FileNotFoundException e) {
|
| + minidumpFds[i] = null; // This is slightly ugly :)
|
| + }
|
| + if (!minidumpFiles[i].delete()) {
|
| + Log.w(TAG, "Couldn't delete file "
|
| + + minidumpFiles[i].getAbsolutePath());
|
| + }
|
| + }
|
| + try {
|
| + ICrashReceiverService.Stub.asInterface(service).transmitCrashes(
|
| + minidumpFds);
|
| + } catch (RemoteException e) {
|
| + // TODO(gsennton): add a UMA metric here to ensure we aren't losing
|
| + // too many minidumps because of this.
|
| + }
|
| + } finally {
|
| + // Close FDs
|
| + for (int i = 0; i < minidumpFds.length; ++i) {
|
| + try {
|
| + if (minidumpFds[i] != null) minidumpFds[i].close();
|
| + } catch (IOException e) {
|
| + }
|
| + }
|
| + appContext.unbindService(this);
|
| + }
|
| + }
|
| +
|
| + @Override
|
| + public void onServiceDisconnected(ComponentName className) {}
|
| + };
|
| + if (!appContext.bindService(intent, connection, Context.BIND_AUTO_CREATE)) {
|
| + Log.w(TAG, "Could not bind to Minidump-copying Service " + intent);
|
| + }
|
| + return null;
|
| + }
|
| + }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
| + }
|
| }
|
|
|