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); |
105 IPC_MESSAGE_UNHANDLED(handled = false) | 88 IPC_MESSAGE_UNHANDLED(handled = false) |
106 IPC_END_MESSAGE_MAP() | 89 IPC_END_MESSAGE_MAP() |
107 | 90 |
108 if (!handled) { | 91 if (!handled) { |
109 // Make a copy of the handlers to prevent modification during iteration. | 92 // Make a copy of the handlers to prevent modification during iteration. |
110 std::vector<MessageHandler*> temp_handlers = message_handlers_.get(); | 93 std::vector<MessageHandler*> temp_handlers = message_handlers_.get(); |
(...skipping 20 matching lines...) Expand all Loading... |
131 channel_->Send(new ServiceHostMsg_Histograms(deltas)); | 114 channel_->Send(new ServiceHostMsg_Histograms(deltas)); |
132 } | 115 } |
133 | 116 |
134 void ServiceIPCServer::OnShutdown() { | 117 void ServiceIPCServer::OnShutdown() { |
135 client_->OnShutdown(); | 118 client_->OnShutdown(); |
136 } | 119 } |
137 | 120 |
138 void ServiceIPCServer::OnUpdateAvailable() { | 121 void ServiceIPCServer::OnUpdateAvailable() { |
139 client_->OnUpdateAvailable(); | 122 client_->OnUpdateAvailable(); |
140 } | 123 } |
OLD | NEW |