| Index: content/browser/child_process_launcher.cc
|
| diff --git a/content/browser/child_process_launcher.cc b/content/browser/child_process_launcher.cc
|
| index 094ab1b4cdec89cdf87f931626d770b75e92202f..fb5ed467cb50629adaf8e2430defa8b31d98beeb 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,
|
|
|