Because of UID isolation on Android, crash dump generation has to happen
in-process for renderers as well (as the browser cannot access all the
necessary states of the renderer process).
Breakpad has support for generating minidumps to a passed FD (as the renderer
process on Android does not have permission to create file), so the flow on
Android is:
- when a render process is created the browser creates a file and passes its FD
  to the process
- the renderer process initializes Breakpad with that FD
- if there is a crash, Breakpad generates the minidump to that FD.
- when the browser process detects a renderer stopped it checks the minidump
  file. If it's empty it deletes the file. If it's not empty, it means there
  was a crasher in which case it moves it to the crash dump folder for it to be
  picked up and uploaded by the Java side.
    
BUG=None
TEST=Test that minidumps are generated and uploaded when visiting about:crash
     and about:crashbrowserforrealz on Android and desktop Chrome.


Review URL: https://chromiumcodereview.appspot.com/11189068

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@163917 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
index 9c0cd25..e3fb7458 100644
--- a/chrome/browser/chrome_content_browser_client.cc
+++ b/chrome/browser/chrome_content_browser_client.cc
@@ -120,6 +120,7 @@
 #elif defined(OS_LINUX)
 #include "chrome/browser/chrome_browser_main_linux.h"
 #elif defined(OS_ANDROID)
+#include "chrome/browser/android/crash_dump_manager.h"
 #include "chrome/browser/chrome_browser_main_android.h"
 #include "chrome/common/descriptors_android.h"
 #elif defined(OS_POSIX)
@@ -571,6 +572,10 @@
   RendererContentSettingRules rules;
   GetRendererContentSettingRules(profile->GetHostContentSettingsMap(), &rules);
   host->Send(new ChromeViewMsg_SetContentSettingRules(rules));
+
+#if defined(OS_ANDROID) && defined(USE_LINUX_BREAKPAD)
+  InitCrashDumpManager();
+#endif
 }
 
 void ChromeContentBrowserClient::BrowserChildProcessHostCreated(
@@ -1759,13 +1764,8 @@
 #if defined(OS_POSIX) && !defined(OS_MACOSX)
 void ChromeContentBrowserClient::GetAdditionalMappedFilesForChildProcess(
     const CommandLine& command_line,
+    int child_process_id,
     std::vector<FileDescriptorInfo>* mappings) {
-  int crash_signal_fd = GetCrashSignalFD(command_line);
-  if (crash_signal_fd >= 0) {
-    mappings->push_back(FileDescriptorInfo(kCrashDumpSignal,
-                                           FileDescriptor(crash_signal_fd,
-                                                          false)));
-  }
 #if defined(OS_ANDROID)
   FilePath data_path;
   PathService::Get(ui::DIR_RESOURCE_PAKS_ANDROID, &data_path);
@@ -1793,6 +1793,25 @@
   DCHECK(f != base::kInvalidPlatformFileValue);
   mappings->push_back(FileDescriptorInfo(kAndroidLocalePakDescriptor,
                                          FileDescriptor(f, true)));
+
+#if defined(USE_LINUX_BREAKPAD)
+  f = crash_dump_manager_->CreateMinidumpFile(child_process_id);
+  if (f == base::kInvalidPlatformFileValue) {
+    LOG(ERROR) << "Failed to create file for minidump, crash reporting will be "
+        "disabled for this process.";
+  } else {
+    mappings->push_back(FileDescriptorInfo(kAndroidMinidumpDescriptor,
+                                           FileDescriptor(f, true)));
+  }
+#endif  // defined(USE_LINUX_BREAKPAD)
+
+#else
+  int crash_signal_fd = GetCrashSignalFD(command_line);
+  if (crash_signal_fd >= 0) {
+    mappings->push_back(FileDescriptorInfo(kCrashDumpSignal,
+                                           FileDescriptor(crash_signal_fd,
+                                                          false)));
+  }
 #endif  // defined(OS_ANDROID)
 }
 #endif  // defined(OS_POSIX) && !defined(OS_MACOSX)
@@ -1803,6 +1822,13 @@
 }
 #endif
 
+#if defined(OS_ANDROID)
+void ChromeContentBrowserClient::InitCrashDumpManager() {
+  if (!crash_dump_manager_.get())
+    crash_dump_manager_.reset(new CrashDumpManager());
+}
+#endif
+
 #if defined(USE_NSS)
 crypto::CryptoModuleBlockingPasswordDelegate*
     ChromeContentBrowserClient::GetCryptoPasswordDelegate(