OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/service/service_process.h" | 5 #include "chrome/service/service_process.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
119 ServiceProcess::ServiceProcess() | 119 ServiceProcess::ServiceProcess() |
120 : shutdown_event_(true, false), | 120 : shutdown_event_(true, false), |
121 main_message_loop_(NULL), | 121 main_message_loop_(NULL), |
122 enabled_services_(0), | 122 enabled_services_(0), |
123 update_available_(false) { | 123 update_available_(false) { |
124 DCHECK(!g_service_process); | 124 DCHECK(!g_service_process); |
125 g_service_process = this; | 125 g_service_process = this; |
126 } | 126 } |
127 | 127 |
128 bool ServiceProcess::Initialize(MessageLoopForUI* message_loop, | 128 bool ServiceProcess::Initialize(MessageLoopForUI* message_loop, |
129 const CommandLine& command_line) { | 129 const CommandLine& command_line, |
| 130 ServiceProcessState* state) { |
130 #if defined(TOOLKIT_USES_GTK) | 131 #if defined(TOOLKIT_USES_GTK) |
131 // TODO(jamiewalch): Calling GtkInitFromCommandLine here causes the process | 132 // TODO(jamiewalch): Calling GtkInitFromCommandLine here causes the process |
132 // to abort if run headless. The correct fix for this is to refactor the | 133 // to abort if run headless. The correct fix for this is to refactor the |
133 // service process to be more modular, a task that is currently underway. | 134 // service process to be more modular, a task that is currently underway. |
134 // However, since this problem is blocking cloud print, the following quick | 135 // However, since this problem is blocking cloud print, the following quick |
135 // hack will have to do. Note that the situation with this hack in place is | 136 // hack will have to do. Note that the situation with this hack in place is |
136 // no worse than it was when we weren't initializing GTK at all. | 137 // no worse than it was when we weren't initializing GTK at all. |
137 int argc = 1; | 138 int argc = 1; |
138 scoped_array<char*> argv(new char*[2]); | 139 scoped_array<char*> argv(new char*[2]); |
139 argv[0] = strdup(command_line.argv()[0].c_str()); | 140 argv[0] = strdup(command_line.argv()[0].c_str()); |
140 argv[1] = NULL; | 141 argv[1] = NULL; |
141 char **argv_pointer = argv.get(); | 142 char **argv_pointer = argv.get(); |
142 gtk_init_check(&argc, &argv_pointer); | 143 gtk_init_check(&argc, &argv_pointer); |
143 free(argv[0]); | 144 free(argv[0]); |
144 #endif | 145 #endif |
145 main_message_loop_ = message_loop; | 146 main_message_loop_ = message_loop; |
| 147 service_process_state_.reset(state); |
146 network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); | 148 network_change_notifier_.reset(net::NetworkChangeNotifier::Create()); |
147 base::Thread::Options options; | 149 base::Thread::Options options; |
148 options.message_loop_type = MessageLoop::TYPE_IO; | 150 options.message_loop_type = MessageLoop::TYPE_IO; |
149 io_thread_.reset(new ServiceIOThread("ServiceProcess_IO")); | 151 io_thread_.reset(new ServiceIOThread("ServiceProcess_IO")); |
150 file_thread_.reset(new base::Thread("ServiceProcess_File")); | 152 file_thread_.reset(new base::Thread("ServiceProcess_File")); |
151 if (!io_thread_->StartWithOptions(options) || | 153 if (!io_thread_->StartWithOptions(options) || |
152 !file_thread_->StartWithOptions(options)) { | 154 !file_thread_->StartWithOptions(options)) { |
153 NOTREACHED(); | 155 NOTREACHED(); |
154 Teardown(); | 156 Teardown(); |
155 return false; | 157 return false; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
214 // Then check if the cloud print proxy was previously enabled. | 216 // Then check if the cloud print proxy was previously enabled. |
215 service_prefs_->GetBoolean(prefs::kCloudPrintProxyEnabled, | 217 service_prefs_->GetBoolean(prefs::kCloudPrintProxyEnabled, |
216 &cloud_print_proxy_enabled); | 218 &cloud_print_proxy_enabled); |
217 } | 219 } |
218 | 220 |
219 if (cloud_print_proxy_enabled) { | 221 if (cloud_print_proxy_enabled) { |
220 GetCloudPrintProxy()->EnableForUser(lsid); | 222 GetCloudPrintProxy()->EnableForUser(lsid); |
221 } | 223 } |
222 | 224 |
223 VLOG(1) << "Starting Service Process IPC Server"; | 225 VLOG(1) << "Starting Service Process IPC Server"; |
224 ServiceProcessState* state = ServiceProcessState::GetInstance(); | 226 ipc_server_.reset(new ServiceIPCServer( |
225 ipc_server_.reset(new ServiceIPCServer(state->GetServiceProcessChannel())); | 227 service_process_state_->GetServiceProcessChannel())); |
226 ipc_server_->Init(); | 228 ipc_server_->Init(); |
227 | 229 |
228 // After the IPC server has started we signal that the service process is | 230 // After the IPC server has started we signal that the service process is |
229 // ready. | 231 // ready. |
230 if (!state->SignalReady(io_thread_->message_loop_proxy(), | 232 if (!state->SignalReady(io_thread_->message_loop_proxy(), |
231 NewRunnableMethod(this, &ServiceProcess::Shutdown))) { | 233 NewRunnableMethod(this, &ServiceProcess::Shutdown))) { |
232 return false; | 234 return false; |
233 } | 235 } |
234 | 236 |
235 // See if we need to stay running. | 237 // See if we need to stay running. |
236 ScheduleShutdownCheck(); | 238 ScheduleShutdownCheck(); |
237 return true; | 239 return true; |
238 } | 240 } |
239 | 241 |
240 bool ServiceProcess::Teardown() { | 242 bool ServiceProcess::Teardown() { |
241 service_prefs_.reset(); | 243 service_prefs_.reset(); |
242 cloud_print_proxy_.reset(); | 244 cloud_print_proxy_.reset(); |
243 | 245 |
244 ipc_server_.reset(); | 246 ipc_server_.reset(); |
245 // Signal this event before shutting down the service process. That way all | 247 // Signal this event before shutting down the service process. That way all |
246 // background threads can cleanup. | 248 // background threads can cleanup. |
247 shutdown_event_.Signal(); | 249 shutdown_event_.Signal(); |
248 io_thread_.reset(); | 250 io_thread_.reset(); |
249 file_thread_.reset(); | 251 file_thread_.reset(); |
250 // The NetworkChangeNotifier must be destroyed after all other threads that | 252 // The NetworkChangeNotifier must be destroyed after all other threads that |
251 // might use it have been shut down. | 253 // might use it have been shut down. |
252 network_change_notifier_.reset(); | 254 network_change_notifier_.reset(); |
253 | 255 |
254 ServiceProcessState::GetInstance()->SignalStopped(); | 256 service_process_state_->SignalStopped(); |
255 return true; | 257 return true; |
256 } | 258 } |
257 | 259 |
258 #if defined(ENABLE_REMOTING) | 260 #if defined(ENABLE_REMOTING) |
259 static void QuitMessageLoop(MessageLoop* message_loop) { | 261 static void QuitMessageLoop(MessageLoop* message_loop) { |
260 message_loop->PostTask(FROM_HERE, new MessageLoop::QuitTask()); | 262 message_loop->PostTask(FROM_HERE, new MessageLoop::QuitTask()); |
261 } | 263 } |
262 #endif | 264 #endif |
263 | 265 |
264 // This method is called when a shutdown command is received from IPC channel | 266 // This method is called when a shutdown command is received from IPC channel |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
326 ServiceProcess::GetServiceURLRequestContextGetter() { | 328 ServiceProcess::GetServiceURLRequestContextGetter() { |
327 DCHECK(request_context_getter_.get()); | 329 DCHECK(request_context_getter_.get()); |
328 return request_context_getter_.get(); | 330 return request_context_getter_.get(); |
329 } | 331 } |
330 | 332 |
331 void ServiceProcess::OnServiceEnabled() { | 333 void ServiceProcess::OnServiceEnabled() { |
332 enabled_services_++; | 334 enabled_services_++; |
333 if ((1 == enabled_services_) && | 335 if ((1 == enabled_services_) && |
334 !CommandLine::ForCurrentProcess()->HasSwitch( | 336 !CommandLine::ForCurrentProcess()->HasSwitch( |
335 switches::kNoServiceAutorun)) { | 337 switches::kNoServiceAutorun)) { |
336 ServiceProcessState::GetInstance()->AddToAutoRun(); | 338 if (!service_process_state_->AddToAutoRun()) { |
| 339 // TODO(scottbyer/sanjeevr/dmaclach): Handle error condition |
| 340 LOG(ERROR) << "Unable to AddToAutoRun"; |
| 341 } |
337 } | 342 } |
338 } | 343 } |
339 | 344 |
340 void ServiceProcess::OnServiceDisabled() { | 345 void ServiceProcess::OnServiceDisabled() { |
341 DCHECK_NE(enabled_services_, 0); | 346 DCHECK_NE(enabled_services_, 0); |
342 enabled_services_--; | 347 enabled_services_--; |
343 if (0 == enabled_services_) { | 348 if (0 == enabled_services_) { |
344 ServiceProcessState::GetInstance()->RemoveFromAutoRun(); | 349 if (!service_process_state_->RemoveFromAutoRun()) { |
| 350 // TODO(scottbyer/sanjeevr/dmaclach): Handle error condition |
| 351 LOG(ERROR) << "Unable to RemoveFromAutoRun"; |
| 352 } |
345 // We will wait for some time to respond to IPCs before shutting down. | 353 // We will wait for some time to respond to IPCs before shutting down. |
346 ScheduleShutdownCheck(); | 354 ScheduleShutdownCheck(); |
347 } | 355 } |
348 } | 356 } |
349 | 357 |
350 void ServiceProcess::ScheduleShutdownCheck() { | 358 void ServiceProcess::ScheduleShutdownCheck() { |
351 MessageLoop::current()->PostDelayedTask( | 359 MessageLoop::current()->PostDelayedTask( |
352 FROM_HERE, | 360 FROM_HERE, |
353 NewRunnableMethod(this, &ServiceProcess::ShutdownIfNeeded), | 361 NewRunnableMethod(this, &ServiceProcess::ShutdownIfNeeded), |
354 kShutdownDelay); | 362 kShutdownDelay); |
(...skipping 14 matching lines...) Expand all Loading... |
369 } | 377 } |
370 | 378 |
371 ServiceProcess::~ServiceProcess() { | 379 ServiceProcess::~ServiceProcess() { |
372 Teardown(); | 380 Teardown(); |
373 g_service_process = NULL; | 381 g_service_process = NULL; |
374 } | 382 } |
375 | 383 |
376 // Disable refcounting for runnable method because it is really not needed | 384 // Disable refcounting for runnable method because it is really not needed |
377 // when we post tasks on the main message loop. | 385 // when we post tasks on the main message loop. |
378 DISABLE_RUNNABLE_METHOD_REFCOUNT(ServiceProcess); | 386 DISABLE_RUNNABLE_METHOD_REFCOUNT(ServiceProcess); |
OLD | NEW |