OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 <utility> |
| 8 |
7 #include "base/bind.h" | 9 #include "base/bind.h" |
8 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
9 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
10 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
11 #include "base/run_loop.h" | 13 #include "base/run_loop.h" |
12 #include "base/single_thread_task_runner.h" | 14 #include "base/single_thread_task_runner.h" |
13 #include "base/synchronization/waitable_event.h" | 15 #include "base/synchronization/waitable_event.h" |
14 #include "base/threading/thread.h" | 16 #include "base/threading/thread.h" |
15 #include "build/build_config.h" | 17 #include "build/build_config.h" |
16 #include "chrome/common/service_messages.h" | 18 #include "chrome/common/service_messages.h" |
17 #include "ipc/ipc_channel.h" | 19 #include "ipc/ipc_channel.h" |
18 #include "ipc/ipc_channel_handle.h" | 20 #include "ipc/ipc_channel_handle.h" |
| 21 #include "ipc/ipc_channel_mojo.h" |
| 22 #include "mojo/public/cpp/system/message_pipe.h" |
19 #include "testing/gtest/include/gtest/gtest.h" | 23 #include "testing/gtest/include/gtest/gtest.h" |
20 | 24 |
21 namespace { | 25 namespace { |
22 | 26 |
23 void PumpCurrentLoop() { | 27 void PumpCurrentLoop() { |
24 base::MessageLoop::ScopedNestableTaskAllower nestable_task_allower( | 28 base::MessageLoop::ScopedNestableTaskAllower nestable_task_allower( |
25 base::MessageLoop::current()); | 29 base::MessageLoop::current()); |
26 base::RunLoop().RunUntilIdle(); | 30 base::RunLoop().RunUntilIdle(); |
27 } | 31 } |
28 | 32 |
29 class FakeServiceIPCServerClient : public ServiceIPCServer::Client { | 33 class FakeServiceIPCServerClient : public ServiceIPCServer::Client { |
30 public: | 34 public: |
31 FakeServiceIPCServerClient() {} | 35 FakeServiceIPCServerClient() {} |
32 ~FakeServiceIPCServerClient() override {} | 36 ~FakeServiceIPCServerClient() override {} |
33 void OnShutdown() override; | 37 void OnShutdown() override; |
34 void OnUpdateAvailable() override; | 38 void OnUpdateAvailable() override; |
35 bool OnIPCClientDisconnect() override; | 39 bool OnIPCClientDisconnect() override; |
| 40 mojo::ScopedMessagePipeHandle CreateChannelMessagePipe() override; |
36 | 41 |
37 int shutdown_calls = 0; | 42 int shutdown_calls_ = 0; |
38 int update_available_calls = 0; | 43 int update_available_calls_ = 0; |
39 int ipc_client_disconnect_calls = 0; | 44 int ipc_client_disconnect_calls_ = 0; |
| 45 mojo::ScopedMessagePipeHandle channel_handle_; |
40 }; | 46 }; |
41 | 47 |
42 void FakeServiceIPCServerClient::OnShutdown() { | 48 void FakeServiceIPCServerClient::OnShutdown() { |
43 shutdown_calls++; | 49 shutdown_calls_++; |
44 } | 50 } |
45 | 51 |
46 void FakeServiceIPCServerClient::OnUpdateAvailable() { | 52 void FakeServiceIPCServerClient::OnUpdateAvailable() { |
47 update_available_calls++; | 53 update_available_calls_++; |
48 } | 54 } |
49 | 55 |
50 bool FakeServiceIPCServerClient::OnIPCClientDisconnect() { | 56 bool FakeServiceIPCServerClient::OnIPCClientDisconnect() { |
51 ipc_client_disconnect_calls++; | 57 ipc_client_disconnect_calls_++; |
52 | 58 |
53 // Always return true to indicate the server must continue listening for new | 59 // Always return true to indicate the server must continue listening for new |
54 // connections. | 60 // connections. |
55 return true; | 61 return true; |
56 } | 62 } |
57 | 63 |
| 64 mojo::ScopedMessagePipeHandle |
| 65 FakeServiceIPCServerClient::CreateChannelMessagePipe() { |
| 66 mojo::MessagePipe channel; |
| 67 channel_handle_ = std::move(channel.handle0); |
| 68 return std::move(channel.handle1); |
| 69 } |
| 70 |
58 class FakeChannelListener : public IPC::Listener { | 71 class FakeChannelListener : public IPC::Listener { |
59 public: | 72 public: |
60 FakeChannelListener() {} | 73 FakeChannelListener() {} |
61 ~FakeChannelListener() override {} | 74 ~FakeChannelListener() override {} |
62 bool OnMessageReceived(const IPC::Message& message) override { return true; } | 75 bool OnMessageReceived(const IPC::Message& message) override { return true; } |
63 }; | 76 }; |
64 | 77 |
65 class FakeMessageHandler : public ServiceIPCServer::MessageHandler { | 78 class FakeMessageHandler : public ServiceIPCServer::MessageHandler { |
66 public: | 79 public: |
67 explicit FakeMessageHandler(bool should_handle); | 80 explicit FakeMessageHandler(bool should_handle); |
(...skipping 29 matching lines...) Expand all Loading... |
97 | 110 |
98 // Sends |message| to the ServiceIPCServer. | 111 // Sends |message| to the ServiceIPCServer. |
99 void SendToServiceProcess(IPC::Message* message); | 112 void SendToServiceProcess(IPC::Message* message); |
100 | 113 |
101 IPC::SyncChannel* GetServerChannel() { | 114 IPC::SyncChannel* GetServerChannel() { |
102 return server_->channel_.get(); | 115 return server_->channel_.get(); |
103 } | 116 } |
104 | 117 |
105 protected: | 118 protected: |
106 FakeServiceIPCServerClient service_process_client_; | 119 FakeServiceIPCServerClient service_process_client_; |
107 IPC::ChannelHandle channel_handle_; | |
108 base::MessageLoopForUI main_message_loop_; | 120 base::MessageLoopForUI main_message_loop_; |
109 base::Thread io_thread_; | 121 base::Thread io_thread_; |
110 base::WaitableEvent shutdown_event_; | 122 base::WaitableEvent shutdown_event_; |
111 std::unique_ptr<ServiceIPCServer> server_; | 123 std::unique_ptr<ServiceIPCServer> server_; |
112 FakeChannelListener client_process_channel_listener_; | 124 FakeChannelListener client_process_channel_listener_; |
113 std::unique_ptr<IPC::SyncChannel> client_process_channel_; | 125 std::unique_ptr<IPC::SyncChannel> client_process_channel_; |
114 }; | 126 }; |
115 | 127 |
116 ServiceIPCServerTest::ServiceIPCServerTest() | 128 ServiceIPCServerTest::ServiceIPCServerTest() |
117 : channel_handle_(IPC::Channel::GenerateUniqueRandomChannelID()), | 129 : io_thread_("ServiceIPCServerTest IO"), |
118 io_thread_("ServiceIPCServerTest IO"), | |
119 shutdown_event_(base::WaitableEvent::ResetPolicy::MANUAL, | 130 shutdown_event_(base::WaitableEvent::ResetPolicy::MANUAL, |
120 base::WaitableEvent::InitialState::NOT_SIGNALED) {} | 131 base::WaitableEvent::InitialState::NOT_SIGNALED) {} |
121 | 132 |
122 void ServiceIPCServerTest::SetUp() { | 133 void ServiceIPCServerTest::SetUp() { |
123 base::Thread::Options options; | 134 base::Thread::Options options; |
| 135 mojo::MessagePipe channel; |
124 options.message_loop_type = base::MessageLoop::TYPE_IO; | 136 options.message_loop_type = base::MessageLoop::TYPE_IO; |
125 ASSERT_TRUE(io_thread_.StartWithOptions(options)); | 137 ASSERT_TRUE(io_thread_.StartWithOptions(options)); |
126 | 138 |
127 server_.reset(new ServiceIPCServer(&service_process_client_, | 139 server_.reset(new ServiceIPCServer(&service_process_client_, |
128 io_thread_.task_runner(), | 140 io_thread_.task_runner(), |
129 channel_handle_, | |
130 &shutdown_event_)); | 141 &shutdown_event_)); |
131 server_->Init(); | 142 server_->Init(); |
132 } | 143 } |
133 | 144 |
134 void ServiceIPCServerTest::TearDown() { | 145 void ServiceIPCServerTest::TearDown() { |
135 // Close the ipc channels to prevent memory leaks. | 146 // Close the ipc channels to prevent memory leaks. |
136 if (client_process_channel_) { | 147 if (client_process_channel_) { |
137 client_process_channel_->Close(); | 148 client_process_channel_->Close(); |
138 PumpLoops(); | 149 PumpLoops(); |
139 } | 150 } |
140 if (GetServerChannel()) { | 151 if (GetServerChannel()) { |
141 GetServerChannel()->Close(); | 152 GetServerChannel()->Close(); |
142 PumpLoops(); | 153 PumpLoops(); |
143 } | 154 } |
144 io_thread_.Stop(); | 155 io_thread_.Stop(); |
145 } | 156 } |
146 | 157 |
147 void ServiceIPCServerTest::PumpLoops() { | 158 void ServiceIPCServerTest::PumpLoops() { |
148 base::RunLoop run_loop; | 159 base::RunLoop run_loop; |
149 io_thread_.task_runner()->PostTaskAndReply(FROM_HERE, | 160 io_thread_.task_runner()->PostTaskAndReply(FROM_HERE, |
150 base::Bind(&PumpCurrentLoop), | 161 base::Bind(&PumpCurrentLoop), |
151 run_loop.QuitClosure()); | 162 run_loop.QuitClosure()); |
152 run_loop.Run(); | 163 run_loop.Run(); |
153 PumpCurrentLoop(); | 164 PumpCurrentLoop(); |
154 } | 165 } |
155 | 166 |
156 void ServiceIPCServerTest::ConnectClientChannel() { | 167 void ServiceIPCServerTest::ConnectClientChannel() { |
157 client_process_channel_ = IPC::SyncChannel::Create( | 168 client_process_channel_ = IPC::SyncChannel::Create( |
158 channel_handle_, | 169 IPC::ChannelMojo::CreateClientFactory( |
159 IPC::Channel::MODE_NAMED_CLIENT, | 170 std::move(service_process_client_.channel_handle_), |
160 &client_process_channel_listener_, | 171 io_thread_.task_runner()), |
161 io_thread_.task_runner(), | 172 &client_process_channel_listener_, io_thread_.task_runner(), |
162 true /* create_pipe_now */, | 173 true /* create_pipe_now */, &shutdown_event_); |
163 &shutdown_event_); | |
164 PumpLoops(); | 174 PumpLoops(); |
165 } | 175 } |
166 | 176 |
167 void ServiceIPCServerTest::DestroyClientChannel() { | 177 void ServiceIPCServerTest::DestroyClientChannel() { |
168 client_process_channel_.reset(); | 178 client_process_channel_.reset(); |
169 PumpLoops(); | 179 PumpLoops(); |
170 } | 180 } |
171 | 181 |
172 void ServiceIPCServerTest::SendToServiceProcess(IPC::Message* message) { | 182 void ServiceIPCServerTest::SendToServiceProcess(IPC::Message* message) { |
173 client_process_channel_->Send(message); | 183 client_process_channel_->Send(message); |
174 PumpLoops(); | 184 PumpLoops(); |
175 } | 185 } |
176 | 186 |
177 TEST_F(ServiceIPCServerTest, ConnectDisconnectReconnect) { | 187 TEST_F(ServiceIPCServerTest, ConnectDisconnectReconnect) { |
178 // Initially there is no ipc client connected. | 188 // Initially there is no ipc client connected. |
179 ASSERT_FALSE(server_->is_ipc_client_connected()); | 189 ASSERT_FALSE(server_->is_ipc_client_connected()); |
180 | 190 |
181 // When a channel is connected the server is notified via OnChannelConnected. | 191 // When a channel is connected the server is notified via OnChannelConnected. |
182 ConnectClientChannel(); | 192 ConnectClientChannel(); |
183 ASSERT_TRUE(server_->is_ipc_client_connected()); | 193 ASSERT_TRUE(server_->is_ipc_client_connected()); |
184 | 194 |
185 // When the channel is destroyed the server is notified via OnChannelError. | 195 // When the channel is destroyed the server is notified via OnChannelError. |
186 // In turn, the server notifies its service process client. | 196 // In turn, the server notifies its service process client. |
187 DestroyClientChannel(); | 197 DestroyClientChannel(); |
188 ASSERT_FALSE(server_->is_ipc_client_connected()); | 198 ASSERT_FALSE(server_->is_ipc_client_connected()); |
189 ASSERT_EQ(1, service_process_client_.ipc_client_disconnect_calls); | 199 ASSERT_EQ(1, service_process_client_.ipc_client_disconnect_calls_); |
190 | 200 |
191 // On Windows only, the server recreates its channel in OnChannelError, if the | |
192 // service process client tells it to continue listening. On other platforms | |
193 // the channel is reused for subsequent reconnects by the client process. This | |
194 // means however that OnChannelConnected is not called again and the server is | |
195 // only aware of being connected once an IPC message is received. | |
196 ConnectClientChannel(); | 201 ConnectClientChannel(); |
197 #if defined(OS_WIN) | |
198 ASSERT_TRUE(server_->is_ipc_client_connected()); | 202 ASSERT_TRUE(server_->is_ipc_client_connected()); |
199 #else | |
200 ASSERT_FALSE(server_->is_ipc_client_connected()); | |
201 #endif | |
202 SendToServiceProcess(new ServiceMsg_UpdateAvailable()); | 203 SendToServiceProcess(new ServiceMsg_UpdateAvailable()); |
203 ASSERT_TRUE(server_->is_ipc_client_connected()); | 204 ASSERT_TRUE(server_->is_ipc_client_connected()); |
204 | 205 |
205 // Destroy the client process channel again to verify the | 206 // Destroy the client process channel again to verify the |
206 // ServiceIPCServer::Client is notified again. This means that unlike | 207 // ServiceIPCServer::Client is notified again. This means that unlike |
207 // OnChannelConnected, OnChannelError is called more than once. | 208 // OnChannelConnected, OnChannelError is called more than once. |
208 DestroyClientChannel(); | 209 DestroyClientChannel(); |
209 ASSERT_FALSE(server_->is_ipc_client_connected()); | 210 ASSERT_FALSE(server_->is_ipc_client_connected()); |
210 ASSERT_EQ(2, service_process_client_.ipc_client_disconnect_calls); | 211 ASSERT_EQ(2, service_process_client_.ipc_client_disconnect_calls_); |
211 } | 212 } |
212 | 213 |
213 TEST_F(ServiceIPCServerTest, Shutdown) { | 214 TEST_F(ServiceIPCServerTest, Shutdown) { |
214 ConnectClientChannel(); | 215 ConnectClientChannel(); |
215 ASSERT_TRUE(server_->is_ipc_client_connected()); | 216 ASSERT_TRUE(server_->is_ipc_client_connected()); |
216 | 217 |
217 // When a shutdown message is received, the ServiceIPCServer::Client is | 218 // When a shutdown message is received, the ServiceIPCServer::Client is |
218 // notified. | 219 // notified. |
219 SendToServiceProcess(new ServiceMsg_Shutdown()); | 220 SendToServiceProcess(new ServiceMsg_Shutdown()); |
220 ASSERT_EQ(1, service_process_client_.shutdown_calls); | 221 ASSERT_EQ(1, service_process_client_.shutdown_calls_); |
221 } | 222 } |
222 | 223 |
223 TEST_F(ServiceIPCServerTest, UpdateAvailable) { | 224 TEST_F(ServiceIPCServerTest, UpdateAvailable) { |
224 ConnectClientChannel(); | 225 ConnectClientChannel(); |
225 ASSERT_TRUE(server_->is_ipc_client_connected()); | 226 ASSERT_TRUE(server_->is_ipc_client_connected()); |
226 | 227 |
227 // When a product update message is received, the ServiceIPCServer::Client is | 228 // When a product update message is received, the ServiceIPCServer::Client is |
228 // notified. | 229 // notified. |
229 SendToServiceProcess(new ServiceMsg_UpdateAvailable()); | 230 SendToServiceProcess(new ServiceMsg_UpdateAvailable()); |
230 ASSERT_EQ(1, service_process_client_.update_available_calls); | 231 ASSERT_EQ(1, service_process_client_.update_available_calls_); |
231 } | 232 } |
232 | 233 |
233 TEST_F(ServiceIPCServerTest, SingleMessageHandler) { | 234 TEST_F(ServiceIPCServerTest, SingleMessageHandler) { |
234 ConnectClientChannel(); | 235 ConnectClientChannel(); |
235 ASSERT_TRUE(server_->is_ipc_client_connected()); | 236 ASSERT_TRUE(server_->is_ipc_client_connected()); |
236 | 237 |
237 // Verify that a message handler is offered messages not handled by the server | 238 // Verify that a message handler is offered messages not handled by the server |
238 // itself. | 239 // itself. |
239 FakeMessageHandler* handler = | 240 FakeMessageHandler* handler = |
240 new FakeMessageHandler(true /* should_handle */); | 241 new FakeMessageHandler(true /* should_handle */); |
(...skipping 15 matching lines...) Expand all Loading... |
256 new FakeMessageHandler(true /* should_handle */); | 257 new FakeMessageHandler(true /* should_handle */); |
257 server_->AddMessageHandler(base::WrapUnique(handler2)); | 258 server_->AddMessageHandler(base::WrapUnique(handler2)); |
258 FakeMessageHandler* handler3 = | 259 FakeMessageHandler* handler3 = |
259 new FakeMessageHandler(true /* should_handle */); | 260 new FakeMessageHandler(true /* should_handle */); |
260 server_->AddMessageHandler(base::WrapUnique(handler3)); | 261 server_->AddMessageHandler(base::WrapUnique(handler3)); |
261 SendToServiceProcess(new ServiceMsg_DisableCloudPrintProxy()); | 262 SendToServiceProcess(new ServiceMsg_DisableCloudPrintProxy()); |
262 ASSERT_EQ(1, handler1->handle_message_calls_); | 263 ASSERT_EQ(1, handler1->handle_message_calls_); |
263 ASSERT_EQ(1, handler2->handle_message_calls_); | 264 ASSERT_EQ(1, handler2->handle_message_calls_); |
264 ASSERT_EQ(0, handler3->handle_message_calls_); | 265 ASSERT_EQ(0, handler3->handle_message_calls_); |
265 } | 266 } |
OLD | NEW |