summaryrefslogtreecommitdiffstats
path: root/content/browser/child_process_launcher.cc
diff options
context:
space:
mode:
authoryfriedman@chromium.org <yfriedman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-28 21:26:23 +0000
committeryfriedman@chromium.org <yfriedman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-06-28 21:26:23 +0000
commit30935368c9ced14f8f4db5c35a1ab592d3bea328 (patch)
treef3ffe6cce7c9a4806aeb97be8a337c9ec8b3dbb1 /content/browser/child_process_launcher.cc
parentf928b89b660fe3ec965a19d784e80285c2957477 (diff)
downloadchromium_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.cc101
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,