| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_ipc_server.h" | 5 #include "chrome/service/service_ipc_server.h" |
| 6 | 6 |
| 7 #include "base/metrics/histogram_delta_serialization.h" | 7 #include "base/metrics/histogram_delta_serialization.h" |
| 8 #include "build/build_config.h" | 8 #include "build/build_config.h" |
| 9 #include "chrome/common/service_messages.h" | 9 #include "chrome/common/service_messages.h" |
| 10 #include "ipc/ipc_channel_mojo.h" |
| 10 #include "ipc/ipc_logging.h" | 11 #include "ipc/ipc_logging.h" |
| 11 | 12 |
| 12 ServiceIPCServer::ServiceIPCServer( | 13 ServiceIPCServer::ServiceIPCServer( |
| 13 Client* client, | 14 Client* client, |
| 14 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, | 15 const scoped_refptr<base::SingleThreadTaskRunner>& io_task_runner, |
| 15 const IPC::ChannelHandle& channel_handle, | |
| 16 base::WaitableEvent* shutdown_event) | 16 base::WaitableEvent* shutdown_event) |
| 17 : client_(client), | 17 : client_(client), |
| 18 io_task_runner_(io_task_runner), | 18 io_task_runner_(io_task_runner), |
| 19 channel_handle_(channel_handle), | 19 shutdown_event_(shutdown_event) { |
| 20 shutdown_event_(shutdown_event), | |
| 21 ipc_client_connected_(false) { | |
| 22 DCHECK(client); | 20 DCHECK(client); |
| 23 DCHECK(shutdown_event); | 21 DCHECK(shutdown_event); |
| 24 } | 22 } |
| 25 | 23 |
| 26 bool ServiceIPCServer::Init() { | 24 bool ServiceIPCServer::Init() { |
| 27 #ifdef IPC_MESSAGE_LOG_ENABLED | 25 #ifdef IPC_MESSAGE_LOG_ENABLED |
| 28 IPC::Logging::GetInstance()->SetIPCSender(this); | 26 IPC::Logging::GetInstance()->SetIPCSender(this); |
| 29 #endif | 27 #endif |
| 30 CreateChannel(); | 28 CreateChannel(); |
| 31 return true; | 29 return true; |
| 32 } | 30 } |
| 33 | 31 |
| 34 void ServiceIPCServer::CreateChannel() { | 32 void ServiceIPCServer::CreateChannel() { |
| 35 channel_.reset(); // Tear down the existing channel, if any. | 33 channel_.reset(); // Tear down the existing channel, if any. |
| 36 channel_ = IPC::SyncChannel::Create( | 34 channel_ = IPC::SyncChannel::Create( |
| 37 channel_handle_, | 35 IPC::ChannelMojo::CreateServerFactory(client_->CreateChannelMessagePipe(), |
| 38 IPC::Channel::MODE_NAMED_SERVER, | 36 io_task_runner_), |
| 39 this /* listener */, | 37 this /* listener */, io_task_runner_, true /* create_pipe_now */, |
| 40 io_task_runner_, | |
| 41 true /* create_pipe_now */, | |
| 42 shutdown_event_); | 38 shutdown_event_); |
| 43 } | 39 } |
| 44 | 40 |
| 45 ServiceIPCServer::~ServiceIPCServer() { | 41 ServiceIPCServer::~ServiceIPCServer() { |
| 46 #ifdef IPC_MESSAGE_LOG_ENABLED | 42 #ifdef IPC_MESSAGE_LOG_ENABLED |
| 47 IPC::Logging::GetInstance()->SetIPCSender(NULL); | 43 IPC::Logging::GetInstance()->SetIPCSender(NULL); |
| 48 #endif | 44 #endif |
| 49 } | 45 } |
| 50 | 46 |
| 51 void ServiceIPCServer::OnChannelConnected(int32_t peer_pid) { | 47 void ServiceIPCServer::OnChannelConnected(int32_t peer_pid) { |
| 52 DCHECK(!ipc_client_connected_); | 48 DCHECK(!ipc_client_connected_); |
| 53 ipc_client_connected_ = true; | 49 ipc_client_connected_ = true; |
| 54 } | 50 } |
| 55 | 51 |
| 56 void ServiceIPCServer::OnChannelError() { | 52 void ServiceIPCServer::OnChannelError() { |
| 57 // When an IPC client (typically a browser process) disconnects, the pipe is | 53 // When an IPC client (typically a browser process) disconnects, the pipe is |
| 58 // closed and we get an OnChannelError. If we want to keep servicing requests, | 54 // closed and we get an OnChannelError. If we want to keep servicing requests, |
| 59 // we will recreate the channel if necessary. | 55 // we will recreate the channel. |
| 60 bool client_was_connected = ipc_client_connected_; | 56 bool client_was_connected = ipc_client_connected_; |
| 61 ipc_client_connected_ = false; | 57 ipc_client_connected_ = false; |
| 62 if (client_was_connected) { | 58 if (client_was_connected) { |
| 63 if (client_->OnIPCClientDisconnect()) { | 59 if (client_->OnIPCClientDisconnect()) |
| 64 #if defined(OS_WIN) | |
| 65 // On Windows, once an error on a named pipe occurs, the named pipe is no | |
| 66 // longer valid and must be re-created. This is not the case on Mac or | |
| 67 // Linux. | |
| 68 CreateChannel(); | 60 CreateChannel(); |
| 69 #endif | 61 } else if (!ipc_client_connected_) { |
| 70 } | |
| 71 } else { | |
| 72 // If the client was never even connected we had an error connecting. | 62 // If the client was never even connected we had an error connecting. |
| 73 if (!ipc_client_connected_) { | 63 LOG(ERROR) << "Unable to open service ipc channel"; |
| 74 LOG(ERROR) << "Unable to open service ipc channel " | |
| 75 << "named: " << channel_handle_.name; | |
| 76 } | |
| 77 } | 64 } |
| 78 } | 65 } |
| 79 | 66 |
| 80 bool ServiceIPCServer::Send(IPC::Message* msg) { | 67 bool ServiceIPCServer::Send(IPC::Message* msg) { |
| 81 if (!channel_.get()) { | 68 if (!channel_.get()) { |
| 82 delete msg; | 69 delete msg; |
| 83 return false; | 70 return false; |
| 84 } | 71 } |
| 85 | 72 |
| 86 return channel_->Send(msg); | 73 return channel_->Send(msg); |
| 87 } | 74 } |
| 88 | 75 |
| 89 void ServiceIPCServer::AddMessageHandler( | 76 void ServiceIPCServer::AddMessageHandler( |
| 90 std::unique_ptr<MessageHandler> handler) { | 77 std::unique_ptr<MessageHandler> handler) { |
| 91 message_handlers_.push_back(handler.release()); | 78 message_handlers_.push_back(handler.release()); |
| 92 } | 79 } |
| 93 | 80 |
| 94 bool ServiceIPCServer::OnMessageReceived(const IPC::Message& msg) { | 81 bool ServiceIPCServer::OnMessageReceived(const IPC::Message& msg) { |
| 82 DCHECK(ipc_client_connected_); |
| 95 bool handled = true; | 83 bool handled = true; |
| 96 // When we get a message, always mark the IPC client as connected. The | |
| 97 // ChannelProxy::Context is only letting OnChannelConnected get called once, | |
| 98 // so on Mac and Linux, we never would set ipc_client_connected_ to true | |
| 99 // again on subsequent connections. | |
| 100 ipc_client_connected_ = true; | |
| 101 IPC_BEGIN_MESSAGE_MAP(ServiceIPCServer, msg) | 84 IPC_BEGIN_MESSAGE_MAP(ServiceIPCServer, msg) |
| 102 IPC_MESSAGE_HANDLER(ServiceMsg_GetHistograms, OnGetHistograms) | 85 IPC_MESSAGE_HANDLER(ServiceMsg_GetHistograms, OnGetHistograms) |
| 103 IPC_MESSAGE_HANDLER(ServiceMsg_Shutdown, OnShutdown); | 86 IPC_MESSAGE_HANDLER(ServiceMsg_Shutdown, OnShutdown); |
| 104 IPC_MESSAGE_HANDLER(ServiceMsg_UpdateAvailable, OnUpdateAvailable); | 87 IPC_MESSAGE_HANDLER(ServiceMsg_UpdateAvailable, OnUpdateAvailable); |
| 88 IPC_MESSAGE_HANDLER(ServiceMsg_StayAliveForTesting, OnStayAliveForTesting); |
| 105 IPC_MESSAGE_UNHANDLED(handled = false) | 89 IPC_MESSAGE_UNHANDLED(handled = false) |
| 106 IPC_END_MESSAGE_MAP() | 90 IPC_END_MESSAGE_MAP() |
| 107 | 91 |
| 108 if (!handled) { | 92 if (!handled) { |
| 109 // Make a copy of the handlers to prevent modification during iteration. | 93 // Make a copy of the handlers to prevent modification during iteration. |
| 110 std::vector<MessageHandler*> temp_handlers = message_handlers_.get(); | 94 std::vector<MessageHandler*> temp_handlers = message_handlers_.get(); |
| 111 for (const auto& handler : temp_handlers) { | 95 for (const auto& handler : temp_handlers) { |
| 112 handled = handler->HandleMessage(msg); | 96 handled = handler->HandleMessage(msg); |
| 113 if (handled) | 97 if (handled) |
| 114 break; | 98 break; |
| (...skipping 16 matching lines...) Expand all Loading... |
| 131 channel_->Send(new ServiceHostMsg_Histograms(deltas)); | 115 channel_->Send(new ServiceHostMsg_Histograms(deltas)); |
| 132 } | 116 } |
| 133 | 117 |
| 134 void ServiceIPCServer::OnShutdown() { | 118 void ServiceIPCServer::OnShutdown() { |
| 135 client_->OnShutdown(); | 119 client_->OnShutdown(); |
| 136 } | 120 } |
| 137 | 121 |
| 138 void ServiceIPCServer::OnUpdateAvailable() { | 122 void ServiceIPCServer::OnUpdateAvailable() { |
| 139 client_->OnUpdateAvailable(); | 123 client_->OnUpdateAvailable(); |
| 140 } | 124 } |
| 125 |
| 126 void ServiceIPCServer::OnStayAliveForTesting() { |
| 127 client_->OnStayAliveForTesting(); |
| 128 } |
| OLD | NEW |