diff options
author | yfriedman@chromium.org <yfriedman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-28 21:26:23 +0000 |
---|---|---|
committer | yfriedman@chromium.org <yfriedman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-28 21:26:23 +0000 |
commit | 30935368c9ced14f8f4db5c35a1ab592d3bea328 (patch) | |
tree | f3ffe6cce7c9a4806aeb97be8a337c9ec8b3dbb1 /content/browser/child_process_launcher.cc | |
parent | f928b89b660fe3ec965a19d784e80285c2957477 (diff) | |
download | chromium_src-30935368c9ced14f8f4db5c35a1ab592d3bea328.zip chromium_src-30935368c9ced14f8f4db5c35a1ab592d3bea328.tar.gz chromium_src-30935368c9ced14f8f4db5c35a1ab592d3bea328.tar.bz2 |
Upstream ChildProcessLauncher changes for Android.
Includes updates to SandboxedProcess* to support passing multiple FDs to child
processes.
Review URL: https://chromiumcodereview.appspot.com/10696025
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@144801 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/browser/child_process_launcher.cc')
-rw-r--r-- | content/browser/child_process_launcher.cc | 101 |
1 files changed, 83 insertions, 18 deletions
diff --git a/content/browser/child_process_launcher.cc b/content/browser/child_process_launcher.cc index 094ab1b..fb5ed46 100644 --- a/content/browser/child_process_launcher.cc +++ b/content/browser/child_process_launcher.cc @@ -25,6 +25,9 @@ #include "content/common/sandbox_policy.h" #elif defined(OS_MACOSX) #include "content/browser/mach_broker_mac.h" +#elif defined(OS_ANDROID) +#include "base/android/jni_android.h" +#include "content/browser/android/sandboxed_process_launcher.h" #elif defined(OS_POSIX) #include "base/memory/singleton.h" #include "content/browser/renderer_host/render_sandbox_host_linux.h" @@ -64,6 +67,8 @@ class ChildProcessLauncher::Context void Launch( #if defined(OS_WIN) const FilePath& exposed_dir, +#elif defined(OS_ANDROID) + int ipcfd, #elif defined(OS_POSIX) bool use_zygote, const base::EnvironmentVector& environ, @@ -75,6 +80,12 @@ class ChildProcessLauncher::Context CHECK(BrowserThread::GetCurrentThreadIdentifier(&client_thread_id_)); +#if defined(OS_ANDROID) + // We need to close the client end of the IPC channel to reliably detect + // child termination. We will close this fd after we create the child + // process which is asynchronous on Android. + ipcfd_ = ipcfd; +#endif BrowserThread::PostTask( BrowserThread::PROCESS_LAUNCHER, FROM_HERE, base::Bind( @@ -83,6 +94,8 @@ class ChildProcessLauncher::Context client_thread_id_, #if defined(OS_WIN) exposed_dir, +#elif defined(OS_ANDROID) + ipcfd, #elif defined(OS_POSIX) use_zygote, environ, @@ -91,6 +104,27 @@ class ChildProcessLauncher::Context cmd_line)); } +#if defined(OS_ANDROID) + static void OnSandboxedProcessStarted( + // |this_object| is NOT thread safe. Only use it to post a task back. + scoped_refptr<Context> this_object, + BrowserThread::ID client_thread_id, + base::ProcessHandle handle) { + if (BrowserThread::CurrentlyOn(client_thread_id)) { + // This is always invoked on the UI thread which is commonly the + // |client_thread_id| so we can shortcut one PostTask. + this_object->Notify(handle); + } else { + BrowserThread::PostTask( + client_thread_id, FROM_HERE, + base::Bind( + &ChildProcessLauncher::Context::Notify, + this_object, + handle)); + } + } +#endif + void ResetClient() { // No need for locking as this function gets called on the same thread that // client_ would be used. @@ -116,6 +150,8 @@ class ChildProcessLauncher::Context BrowserThread::ID client_thread_id, #if defined(OS_WIN) const FilePath& exposed_dir, +#elif defined(OS_ANDROID) + int ipcfd, #elif defined(OS_POSIX) bool use_zygote, const base::EnvironmentVector& env, @@ -124,10 +160,25 @@ class ChildProcessLauncher::Context CommandLine* cmd_line) { scoped_ptr<CommandLine> cmd_line_deleter(cmd_line); - base::ProcessHandle handle = base::kNullProcessHandle; #if defined(OS_WIN) - handle = sandbox::StartProcessWithAccess(cmd_line, exposed_dir); + base::ProcessHandle handle = sandbox::StartProcessWithAccess( + cmd_line, exposed_dir); +#elif defined(OS_ANDROID) + std::string process_type = + cmd_line->GetSwitchValueASCII(switches::kProcessType); + base::GlobalDescriptors::Mapping files_to_register; + files_to_register.push_back(std::pair<base::GlobalDescriptors::Key, int>( + kPrimaryIPCChannel, ipcfd)); + content::GetContentClient()->browser()-> + GetAdditionalMappedFilesForChildProcess(*cmd_line, &files_to_register); + + content::StartSandboxedProcess(cmd_line->argv(), + ipcfd, files_to_register, + base::Bind(&ChildProcessLauncher::Context::OnSandboxedProcessStarted, + this_object, client_thread_id)); + #elif defined(OS_POSIX) + base::ProcessHandle handle = base::kNullProcessHandle; // We need to close the client end of the IPC channel // to reliably detect child termination. file_util::ScopedFD ipcfd_closer(&ipcfd); @@ -137,7 +188,7 @@ class ChildProcessLauncher::Context base::GlobalDescriptors::Mapping files_to_register; files_to_register.push_back(std::pair<base::GlobalDescriptors::Key, int>( kPrimaryIPCChannel, ipcfd)); -#if !defined(OS_MACOSX) && !defined(OS_ANDROID) +#if !defined(OS_MACOSX) content::GetContentClient()->browser()-> GetAdditionalMappedFilesForChildProcess(*cmd_line, &files_to_register); if (use_zygote) { @@ -146,7 +197,7 @@ class ChildProcessLauncher::Context process_type); } else // Fall through to the normal posix case below when we're not zygoting. -#endif // defined(OS_MACOSX) && !defined(OS_ANDROID) +#endif // !defined(OS_MACOSX) { // Convert FD mapping to FileHandleMappingVector base::FileHandleMappingVector fds_to_map; @@ -158,7 +209,7 @@ class ChildProcessLauncher::Context id_file.first + base::GlobalDescriptors::kBaseDescriptor)); } -#if !defined(OS_MACOSX) && !defined(OS_ANDROID) +#if !defined(OS_MACOSX) if (process_type == switches::kRendererProcess) { const int sandbox_fd = RenderSandboxHostLinux::GetInstance()->GetRendererSocket(); @@ -166,7 +217,7 @@ class ChildProcessLauncher::Context sandbox_fd, kSandboxIPCChannel + base::GlobalDescriptors::kBaseDescriptor)); } -#endif // defined(OS_MACOSX) && !defined(OS_ANDROID) +#endif // defined(OS_MACOSX) // Actually launch the app. base::LaunchOptions options; @@ -204,16 +255,17 @@ class ChildProcessLauncher::Context handle = base::kNullProcessHandle; } #endif // else defined(OS_POSIX) - - BrowserThread::PostTask( - client_thread_id, FROM_HERE, - base::Bind( - &Context::Notify, - this_object.get(), -#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) - use_zygote, +#if !defined(OS_ANDROID) + BrowserThread::PostTask( + client_thread_id, FROM_HERE, + base::Bind( + &Context::Notify, + this_object.get(), +#if defined(OS_POSIX) && !defined(OS_MACOSX) + use_zygote, #endif - handle)); + handle)); +#endif // !defined(OS_ANDROID) } void Notify( @@ -221,6 +273,10 @@ class ChildProcessLauncher::Context bool zygote, #endif base::ProcessHandle handle) { +#if defined(OS_ANDROID) + // Finally close the ipcfd + file_util::ScopedFD ipcfd_closer(&ipcfd_); +#endif starting_ = false; process_.set_handle(handle); if (!handle) @@ -267,13 +323,17 @@ class ChildProcessLauncher::Context bool zygote, #endif base::ProcessHandle handle) { +#if defined(OS_ANDROID) + LOG(INFO) << "ChromeProcess: Stopping process with handle " << handle; + content::StopSandboxedProcess(handle); +#else base::Process process(handle); // Client has gone away, so just kill the process. Using exit code 0 // means that UMA won't treat this as a crash. process.Terminate(content::RESULT_CODE_NORMAL_EXIT); // On POSIX, we must additionally reap the child. #if defined(OS_POSIX) -#if !defined(OS_MACOSX) && !defined(OS_ANDROID) +#if !defined(OS_MACOSX) if (zygote) { // If the renderer was created via a zygote, we have to proxy the reaping // through the zygote process. @@ -285,6 +345,7 @@ class ChildProcessLauncher::Context } #endif // OS_POSIX process.Close(); +#endif // defined(OS_ANDROID) } Client* client_; @@ -296,8 +357,10 @@ class ChildProcessLauncher::Context // Controls whether the child process should be terminated on browser // shutdown. Default behavior is to terminate the child. bool terminate_child_on_shutdown_; - -#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID) +#if defined(OS_ANDROID) + // The fd to close after creating the process. + int ipcfd_; +#elif defined(OS_POSIX) && !defined(OS_MACOSX) bool zygote_; #endif }; @@ -317,6 +380,8 @@ ChildProcessLauncher::ChildProcessLauncher( context_->Launch( #if defined(OS_WIN) exposed_dir, +#elif defined(OS_ANDROID) + ipcfd, #elif defined(OS_POSIX) use_zygote, environ, |