summaryrefslogtreecommitdiffstats
path: root/chrome/browser/service
diff options
context:
space:
mode:
authordmaclach@chromium.org <dmaclach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-24 17:14:36 +0000
committerdmaclach@chromium.org <dmaclach@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-24 17:14:36 +0000
commit56f0f264ff866052ebcb24e75147cb600e6547a1 (patch)
tree8b16bded93f914cacbf3cb130fae3539ad4bb268 /chrome/browser/service
parent04a8454da64b62bfad5091efd5cf1143443283f0 (diff)
downloadchromium_src-56f0f264ff866052ebcb24e75147cb600e6547a1.zip
chromium_src-56f0f264ff866052ebcb24e75147cb600e6547a1.tar.gz
chromium_src-56f0f264ff866052ebcb24e75147cb600e6547a1.tar.bz2
Get service process running standalone on the mac by hooking it into launchd.
BUG=NONE TEST=BUILD Review URL: http://codereview.chromium.org/6482016 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@75893 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/service')
-rw-r--r--chrome/browser/service/service_process_control.cc137
-rw-r--r--chrome/browser/service/service_process_control.h30
-rw-r--r--chrome/browser/service/service_process_control_browsertest.cc15
-rw-r--r--chrome/browser/service/service_process_control_mac.mm25
4 files changed, 128 insertions, 79 deletions
diff --git a/chrome/browser/service/service_process_control.cc b/chrome/browser/service/service_process_control.cc
index 09bc1ad..eb7a983 100644
--- a/chrome/browser/service/service_process_control.cc
+++ b/chrome/browser/service/service_process_control.cc
@@ -21,79 +21,6 @@
#include "chrome/common/service_process_util.h"
#include "ui/base/ui_base_switches.h"
-// ServiceProcessControl::Launcher implementation.
-// This class is responsible for launching the service process on the
-// PROCESS_LAUNCHER thread.
-class ServiceProcessControl::Launcher
- : public base::RefCountedThreadSafe<ServiceProcessControl::Launcher> {
- public:
- Launcher(ServiceProcessControl* process, CommandLine* cmd_line)
- : process_(process),
- cmd_line_(cmd_line),
- launched_(false),
- retry_count_(0) {
- }
-
- // Execute the command line to start the process asynchronously.
- // After the comamnd is executed |task| is called with the process handle on
- // the UI thread.
- void Run(Task* task) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
-
- notify_task_.reset(task);
- BrowserThread::PostTask(BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
- NewRunnableMethod(this, &Launcher::DoRun));
- }
-
- bool launched() const { return launched_; }
-
- private:
- void DoRun() {
- DCHECK(notify_task_.get());
- base::LaunchApp(*cmd_line_.get(), false, true, NULL);
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- NewRunnableMethod(this, &Launcher::DoDetectLaunched));
- }
-
- void DoDetectLaunched() {
- DCHECK(notify_task_.get());
- const uint32 kMaxLaunchDetectRetries = 10;
-
- {
- // We should not be doing blocking disk IO from this thread!
- // Temporarily allowed until we fix
- // http://code.google.com/p/chromium/issues/detail?id=60207
- base::ThreadRestrictions::ScopedAllowIO allow_io;
- launched_ = CheckServiceProcessReady();
- }
-
- if (launched_ || (retry_count_ >= kMaxLaunchDetectRetries)) {
- BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
- NewRunnableMethod(this, &Launcher::Notify));
- return;
- }
- retry_count_++;
- // If the service process is not launched yet then check again in 2 seconds.
- const int kDetectLaunchRetry = 2000;
- MessageLoop::current()->PostDelayedTask(
- FROM_HERE,
- NewRunnableMethod(this, &Launcher::DoDetectLaunched),
- kDetectLaunchRetry);
- }
-
- void Notify() {
- DCHECK(notify_task_.get());
- notify_task_->Run();
- notify_task_.reset();
- }
-
- ServiceProcessControl* process_;
- scoped_ptr<CommandLine> cmd_line_;
- scoped_ptr<Task> notify_task_;
- bool launched_;
- uint32 retry_count_;
-};
// ServiceProcessControl implementation.
ServiceProcessControl::ServiceProcessControl(Profile* profile)
@@ -120,7 +47,7 @@ void ServiceProcessControl::ConnectInternal() {
base::Thread* io_thread = g_browser_process->io_thread();
// TODO(hclam): Handle error connecting to channel.
- const std::string channel_id = GetServiceProcessChannelName();
+ const IPC::ChannelHandle channel_id = GetServiceProcessChannel();
channel_.reset(
new IPC::SyncChannel(channel_id, IPC::Channel::MODE_NAMED_CLIENT, this,
io_thread->message_loop(), true,
@@ -201,10 +128,19 @@ void ServiceProcessControl::Launch(Task* success_task, Task* failure_task) {
if (!logging_level.empty())
cmd_line->AppendSwitchASCII(switches::kLoggingLevel, logging_level);
+ std::string v_level = browser_command_line.GetSwitchValueASCII(
+ switches::kV);
+ if (!v_level.empty())
+ cmd_line->AppendSwitchASCII(switches::kV, v_level);
+
if (browser_command_line.HasSwitch(switches::kWaitForDebuggerChildren)) {
cmd_line->AppendSwitch(switches::kWaitForDebugger);
}
+ if (browser_command_line.HasSwitch(switches::kEnableLogging)) {
+ cmd_line->AppendSwitch(switches::kEnableLogging);
+ }
+
std::string locale = g_browser_process->GetApplicationLocale();
cmd_line->AppendSwitchASCII(switches::kLang, locale);
@@ -341,3 +277,56 @@ void ServiceProcessControl::RemoveMessageHandler(
}
DISABLE_RUNNABLE_METHOD_REFCOUNT(ServiceProcessControl);
+
+ServiceProcessControl::Launcher::Launcher(ServiceProcessControl* process,
+ CommandLine* cmd_line)
+ : process_(process),
+ cmd_line_(cmd_line),
+ launched_(false),
+ retry_count_(0) {
+}
+
+// Execute the command line to start the process asynchronously.
+// After the command is executed, |task| is called with the process handle on
+// the UI thread.
+void ServiceProcessControl::Launcher::Run(Task* task) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ notify_task_.reset(task);
+ BrowserThread::PostTask(BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
+ NewRunnableMethod(this, &Launcher::DoRun));
+}
+
+void ServiceProcessControl::Launcher::Notify() {
+ DCHECK(notify_task_.get());
+ notify_task_->Run();
+ notify_task_.reset();
+}
+
+#if !defined(OS_MACOSX)
+void ServiceProcessControl::Launcher::DoDetectLaunched() {
+ DCHECK(notify_task_.get());
+ const uint32 kMaxLaunchDetectRetries = 10;
+ launched_ = CheckServiceProcessReady();
+ if (launched_ || (retry_count_ >= kMaxLaunchDetectRetries)) {
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ NewRunnableMethod(this, &Launcher::Notify));
+ return;
+ }
+ retry_count_++;
+
+ // If the service process is not launched yet then check again in 2 seconds.
+ const int kDetectLaunchRetry = 2000;
+ MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ NewRunnableMethod(this, &Launcher::DoDetectLaunched),
+ kDetectLaunchRetry);
+}
+
+void ServiceProcessControl::Launcher::DoRun() {
+ DCHECK(notify_task_.get());
+ base::LaunchApp(*cmd_line_.get(), false, true, NULL);
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ NewRunnableMethod(this, &Launcher::DoDetectLaunched));
+}
+#endif // !OS_MACOSX
diff --git a/chrome/browser/service/service_process_control.h b/chrome/browser/service/service_process_control.h
index c2f18ba..d5e43e0 100644
--- a/chrome/browser/service/service_process_control.h
+++ b/chrome/browser/service/service_process_control.h
@@ -10,6 +10,7 @@
#include <string>
#include <vector>
+#include "base/basictypes.h"
#include "base/id_map.h"
#include "base/callback.h"
#include "base/process.h"
@@ -20,6 +21,7 @@
#include "ipc/ipc_sync_channel.h"
class Profile;
+class CommandLine;
namespace remoting {
struct ChromotingHostInfo;
@@ -126,7 +128,33 @@ class ServiceProcessControl : public IPC::Channel::Sender,
void RemoveMessageHandler(MessageHandler* message_handler);
private:
- class Launcher;
+ // This class is responsible for launching the service process on the
+ // PROCESS_LAUNCHER thread.
+ class Launcher
+ : public base::RefCountedThreadSafe<ServiceProcessControl::Launcher> {
+ public:
+ Launcher(ServiceProcessControl* process, CommandLine* cmd_line);
+ // Execute the command line to start the process asynchronously.
+ // After the comamnd is executed |task| is called with the process handle on
+ // the UI thread.
+ void Run(Task* task);
+
+ bool launched() const { return launched_; }
+
+ private:
+#if !defined(OS_MACOSX)
+ void DoDetectLaunched();
+#endif // !OS_MACOSX
+
+ void DoRun();
+ void Notify();
+ ServiceProcessControl* process_;
+ scoped_ptr<CommandLine> cmd_line_;
+ scoped_ptr<Task> notify_task_;
+ bool launched_;
+ uint32 retry_count_;
+ };
+
typedef std::vector<Task*> TaskList;
// Helper method to invoke all the callbacks based on success on failure.
diff --git a/chrome/browser/service/service_process_control_browsertest.cc b/chrome/browser/service/service_process_control_browsertest.cc
index a0dee5d..ff6e514 100644
--- a/chrome/browser/service/service_process_control_browsertest.cc
+++ b/chrome/browser/service/service_process_control_browsertest.cc
@@ -25,6 +25,13 @@ class ServiceProcessControlBrowserTest
ServiceProcessControlManager::GetInstance()->Shutdown();
}
+#if defined(OS_MACOSX)
+ virtual void TearDown() {
+ // ForceServiceProcessShutdown removes the process from launchd on Mac.
+ ForceServiceProcessShutdown("", 0);
+ }
+#endif // OS_MACOSX
+
protected:
void LaunchServiceProcessControl() {
ServiceProcessControl* process =
@@ -72,7 +79,7 @@ class ServiceProcessControlBrowserTest
void ProcessControlLaunched() {
base::ProcessId service_pid;
- EXPECT_TRUE(GetServiceProcessSharedData(NULL, &service_pid));
+ EXPECT_TRUE(GetServiceProcessData(NULL, &service_pid));
EXPECT_NE(static_cast<base::ProcessId>(0), service_pid);
EXPECT_TRUE(base::OpenProcessHandleWithAccess(
service_pid,
@@ -194,7 +201,7 @@ IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest,
// Make sure we are connected to the service process.
EXPECT_TRUE(process()->is_connected());
base::ProcessId service_pid;
- EXPECT_TRUE(GetServiceProcessSharedData(NULL, &service_pid));
+ EXPECT_TRUE(GetServiceProcessData(NULL, &service_pid));
EXPECT_NE(static_cast<base::ProcessId>(0), service_pid);
chrome::VersionInfo version_info;
ForceServiceProcessShutdown(version_info.Version(), service_pid);
@@ -203,10 +210,10 @@ IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest,
IN_PROC_BROWSER_TEST_F(ServiceProcessControlBrowserTest, CheckPid) {
base::ProcessId service_pid;
- EXPECT_FALSE(GetServiceProcessSharedData(NULL, &service_pid));
+ EXPECT_FALSE(GetServiceProcessData(NULL, &service_pid));
// Launch the service process.
LaunchServiceProcessControl();
- EXPECT_TRUE(GetServiceProcessSharedData(NULL, &service_pid));
+ EXPECT_TRUE(GetServiceProcessData(NULL, &service_pid));
EXPECT_NE(static_cast<base::ProcessId>(0), service_pid);
}
diff --git a/chrome/browser/service/service_process_control_mac.mm b/chrome/browser/service/service_process_control_mac.mm
new file mode 100644
index 0000000..ebb2f2d
--- /dev/null
+++ b/chrome/browser/service/service_process_control_mac.mm
@@ -0,0 +1,25 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/service/service_process_control.h"
+
+#include "base/command_line.h"
+#include "base/mac/scoped_cftyperef.h"
+#include "chrome/browser/browser_thread.h"
+#include "chrome/common/service_process_util_posix.h"
+#include "third_party/GTM/Foundation/GTMServiceManagement.h"
+
+void ServiceProcessControl::Launcher::DoRun() {
+ base::mac::ScopedCFTypeRef<CFDictionaryRef> launchd_plist(
+ CreateServiceProcessLaunchdPlist(cmd_line_.get()));
+ CFErrorRef error = NULL;
+ if (!GTMSMJobSubmit(launchd_plist, &error)) {
+ LOG(ERROR) << error;
+ CFRelease(error);
+ } else {
+ launched_ = true;
+ }
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ NewRunnableMethod(this, &Launcher::Notify));
+}