| 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 |