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; |
39 void OnStayAliveForTesting() override; | |
35 bool OnIPCClientDisconnect() override; | 40 bool OnIPCClientDisconnect() override; |
41 mojo::ScopedMessagePipeHandle CreateChannelMessagePipe() override; | |
36 | 42 |
37 int shutdown_calls = 0; | 43 int shutdown_calls = 0; |
38 int update_available_calls = 0; | 44 int update_available_calls = 0; |
39 int ipc_client_disconnect_calls = 0; | 45 int ipc_client_disconnect_calls = 0; |
46 mojo::ScopedMessagePipeHandle channel_handle; | |
Lei Zhang
2016/09/01 06:12:01
channel_handle_ ? Fix the over variables if you'd
Sam McNally
2016/09/01 06:58:45
Done.
| |
40 }; | 47 }; |
41 | 48 |
42 void FakeServiceIPCServerClient::OnShutdown() { | 49 void FakeServiceIPCServerClient::OnShutdown() { |
43 shutdown_calls++; | 50 shutdown_calls++; |
44 } | 51 } |
45 | 52 |
46 void FakeServiceIPCServerClient::OnUpdateAvailable() { | 53 void FakeServiceIPCServerClient::OnUpdateAvailable() { |
47 update_available_calls++; | 54 update_available_calls++; |
48 } | 55 } |
49 | 56 |
57 void FakeServiceIPCServerClient::OnStayAliveForTesting() {} | |
58 | |
50 bool FakeServiceIPCServerClient::OnIPCClientDisconnect() { | 59 bool FakeServiceIPCServerClient::OnIPCClientDisconnect() { |
51 ipc_client_disconnect_calls++; | 60 ipc_client_disconnect_calls++; |
52 | 61 |
53 // Always return true to indicate the server must continue listening for new | 62 // Always return true to indicate the server must continue listening for new |
54 // connections. | 63 // connections. |
55 return true; | 64 return true; |
56 } | 65 } |
57 | 66 |
67 mojo::ScopedMessagePipeHandle | |
68 FakeServiceIPCServerClient::CreateChannelMessagePipe() { | |
69 mojo::MessagePipe channel; | |
70 channel_handle = std::move(channel.handle0); | |
71 return std::move(channel.handle1); | |
72 } | |
73 | |
58 class FakeChannelListener : public IPC::Listener { | 74 class FakeChannelListener : public IPC::Listener { |
59 public: | 75 public: |
60 FakeChannelListener() {} | 76 FakeChannelListener() {} |
61 ~FakeChannelListener() override {} | 77 ~FakeChannelListener() override {} |
62 bool OnMessageReceived(const IPC::Message& message) override { return true; } | 78 bool OnMessageReceived(const IPC::Message& message) override { return true; } |
63 }; | 79 }; |
64 | 80 |
65 class FakeMessageHandler : public ServiceIPCServer::MessageHandler { | 81 class FakeMessageHandler : public ServiceIPCServer::MessageHandler { |
66 public: | 82 public: |
67 explicit FakeMessageHandler(bool should_handle); | 83 explicit FakeMessageHandler(bool should_handle); |
(...skipping 29 matching lines...) Expand all Loading... | |
97 | 113 |
98 // Sends |message| to the ServiceIPCServer. | 114 // Sends |message| to the ServiceIPCServer. |
99 void SendToServiceProcess(IPC::Message* message); | 115 void SendToServiceProcess(IPC::Message* message); |
100 | 116 |
101 IPC::SyncChannel* GetServerChannel() { | 117 IPC::SyncChannel* GetServerChannel() { |
102 return server_->channel_.get(); | 118 return server_->channel_.get(); |
103 } | 119 } |
104 | 120 |
105 protected: | 121 protected: |
106 FakeServiceIPCServerClient service_process_client_; | 122 FakeServiceIPCServerClient service_process_client_; |
107 IPC::ChannelHandle channel_handle_; | |
108 base::MessageLoopForUI main_message_loop_; | 123 base::MessageLoopForUI main_message_loop_; |
109 base::Thread io_thread_; | 124 base::Thread io_thread_; |
110 base::WaitableEvent shutdown_event_; | 125 base::WaitableEvent shutdown_event_; |
111 std::unique_ptr<ServiceIPCServer> server_; | 126 std::unique_ptr<ServiceIPCServer> server_; |
112 FakeChannelListener client_process_channel_listener_; | 127 FakeChannelListener client_process_channel_listener_; |
113 std::unique_ptr<IPC::SyncChannel> client_process_channel_; | 128 std::unique_ptr<IPC::SyncChannel> client_process_channel_; |
114 }; | 129 }; |
115 | 130 |
116 ServiceIPCServerTest::ServiceIPCServerTest() | 131 ServiceIPCServerTest::ServiceIPCServerTest() |
117 : channel_handle_(IPC::Channel::GenerateUniqueRandomChannelID()), | 132 : io_thread_("ServiceIPCServerTest IO"), |
118 io_thread_("ServiceIPCServerTest IO"), | |
119 shutdown_event_(base::WaitableEvent::ResetPolicy::MANUAL, | 133 shutdown_event_(base::WaitableEvent::ResetPolicy::MANUAL, |
120 base::WaitableEvent::InitialState::NOT_SIGNALED) {} | 134 base::WaitableEvent::InitialState::NOT_SIGNALED) {} |
121 | 135 |
122 void ServiceIPCServerTest::SetUp() { | 136 void ServiceIPCServerTest::SetUp() { |
123 base::Thread::Options options; | 137 base::Thread::Options options; |
138 mojo::MessagePipe channel; | |
124 options.message_loop_type = base::MessageLoop::TYPE_IO; | 139 options.message_loop_type = base::MessageLoop::TYPE_IO; |
125 ASSERT_TRUE(io_thread_.StartWithOptions(options)); | 140 ASSERT_TRUE(io_thread_.StartWithOptions(options)); |
126 | 141 |
127 server_.reset(new ServiceIPCServer(&service_process_client_, | 142 server_.reset(new ServiceIPCServer(&service_process_client_, |
128 io_thread_.task_runner(), | 143 io_thread_.task_runner(), |
129 channel_handle_, | |
130 &shutdown_event_)); | 144 &shutdown_event_)); |
131 server_->Init(); | 145 server_->Init(); |
132 } | 146 } |
133 | 147 |
134 void ServiceIPCServerTest::TearDown() { | 148 void ServiceIPCServerTest::TearDown() { |
135 // Close the ipc channels to prevent memory leaks. | 149 // Close the ipc channels to prevent memory leaks. |
136 if (client_process_channel_) { | 150 if (client_process_channel_) { |
137 client_process_channel_->Close(); | 151 client_process_channel_->Close(); |
138 PumpLoops(); | 152 PumpLoops(); |
139 } | 153 } |
140 if (GetServerChannel()) { | 154 if (GetServerChannel()) { |
141 GetServerChannel()->Close(); | 155 GetServerChannel()->Close(); |
142 PumpLoops(); | 156 PumpLoops(); |
143 } | 157 } |
144 io_thread_.Stop(); | 158 io_thread_.Stop(); |
145 } | 159 } |
146 | 160 |
147 void ServiceIPCServerTest::PumpLoops() { | 161 void ServiceIPCServerTest::PumpLoops() { |
148 base::RunLoop run_loop; | 162 base::RunLoop run_loop; |
149 io_thread_.task_runner()->PostTaskAndReply(FROM_HERE, | 163 io_thread_.task_runner()->PostTaskAndReply(FROM_HERE, |
150 base::Bind(&PumpCurrentLoop), | 164 base::Bind(&PumpCurrentLoop), |
151 run_loop.QuitClosure()); | 165 run_loop.QuitClosure()); |
152 run_loop.Run(); | 166 run_loop.Run(); |
153 PumpCurrentLoop(); | 167 PumpCurrentLoop(); |
154 } | 168 } |
155 | 169 |
156 void ServiceIPCServerTest::ConnectClientChannel() { | 170 void ServiceIPCServerTest::ConnectClientChannel() { |
157 client_process_channel_ = IPC::SyncChannel::Create( | 171 client_process_channel_ = IPC::SyncChannel::Create( |
158 channel_handle_, | 172 IPC::ChannelMojo::CreateClientFactory( |
159 IPC::Channel::MODE_NAMED_CLIENT, | 173 std::move(service_process_client_.channel_handle), |
160 &client_process_channel_listener_, | 174 io_thread_.task_runner()), |
161 io_thread_.task_runner(), | 175 &client_process_channel_listener_, io_thread_.task_runner(), |
162 true /* create_pipe_now */, | 176 true /* create_pipe_now */, &shutdown_event_); |
163 &shutdown_event_); | |
164 PumpLoops(); | 177 PumpLoops(); |
165 } | 178 } |
166 | 179 |
167 void ServiceIPCServerTest::DestroyClientChannel() { | 180 void ServiceIPCServerTest::DestroyClientChannel() { |
168 client_process_channel_.reset(); | 181 client_process_channel_.reset(); |
169 PumpLoops(); | 182 PumpLoops(); |
170 } | 183 } |
171 | 184 |
172 void ServiceIPCServerTest::SendToServiceProcess(IPC::Message* message) { | 185 void ServiceIPCServerTest::SendToServiceProcess(IPC::Message* message) { |
173 client_process_channel_->Send(message); | 186 client_process_channel_->Send(message); |
174 PumpLoops(); | 187 PumpLoops(); |
175 } | 188 } |
176 | 189 |
177 TEST_F(ServiceIPCServerTest, ConnectDisconnectReconnect) { | 190 TEST_F(ServiceIPCServerTest, ConnectDisconnectReconnect) { |
178 // Initially there is no ipc client connected. | 191 // Initially there is no ipc client connected. |
179 ASSERT_FALSE(server_->is_ipc_client_connected()); | 192 ASSERT_FALSE(server_->is_ipc_client_connected()); |
180 | 193 |
181 // When a channel is connected the server is notified via OnChannelConnected. | 194 // When a channel is connected the server is notified via OnChannelConnected. |
182 ConnectClientChannel(); | 195 ConnectClientChannel(); |
183 ASSERT_TRUE(server_->is_ipc_client_connected()); | 196 ASSERT_TRUE(server_->is_ipc_client_connected()); |
184 | 197 |
185 // When the channel is destroyed the server is notified via OnChannelError. | 198 // When the channel is destroyed the server is notified via OnChannelError. |
186 // In turn, the server notifies its service process client. | 199 // In turn, the server notifies its service process client. |
187 DestroyClientChannel(); | 200 DestroyClientChannel(); |
188 ASSERT_FALSE(server_->is_ipc_client_connected()); | 201 ASSERT_FALSE(server_->is_ipc_client_connected()); |
189 ASSERT_EQ(1, service_process_client_.ipc_client_disconnect_calls); | 202 ASSERT_EQ(1, service_process_client_.ipc_client_disconnect_calls); |
190 | 203 |
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(); | 204 ConnectClientChannel(); |
197 #if defined(OS_WIN) | |
198 ASSERT_TRUE(server_->is_ipc_client_connected()); | 205 ASSERT_TRUE(server_->is_ipc_client_connected()); |
199 #else | |
200 ASSERT_FALSE(server_->is_ipc_client_connected()); | |
201 #endif | |
202 SendToServiceProcess(new ServiceMsg_UpdateAvailable()); | 206 SendToServiceProcess(new ServiceMsg_UpdateAvailable()); |
203 ASSERT_TRUE(server_->is_ipc_client_connected()); | 207 ASSERT_TRUE(server_->is_ipc_client_connected()); |
204 | 208 |
205 // Destroy the client process channel again to verify the | 209 // Destroy the client process channel again to verify the |
206 // ServiceIPCServer::Client is notified again. This means that unlike | 210 // ServiceIPCServer::Client is notified again. This means that unlike |
207 // OnChannelConnected, OnChannelError is called more than once. | 211 // OnChannelConnected, OnChannelError is called more than once. |
208 DestroyClientChannel(); | 212 DestroyClientChannel(); |
209 ASSERT_FALSE(server_->is_ipc_client_connected()); | 213 ASSERT_FALSE(server_->is_ipc_client_connected()); |
210 ASSERT_EQ(2, service_process_client_.ipc_client_disconnect_calls); | 214 ASSERT_EQ(2, service_process_client_.ipc_client_disconnect_calls); |
211 } | 215 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
256 new FakeMessageHandler(true /* should_handle */); | 260 new FakeMessageHandler(true /* should_handle */); |
257 server_->AddMessageHandler(base::WrapUnique(handler2)); | 261 server_->AddMessageHandler(base::WrapUnique(handler2)); |
258 FakeMessageHandler* handler3 = | 262 FakeMessageHandler* handler3 = |
259 new FakeMessageHandler(true /* should_handle */); | 263 new FakeMessageHandler(true /* should_handle */); |
260 server_->AddMessageHandler(base::WrapUnique(handler3)); | 264 server_->AddMessageHandler(base::WrapUnique(handler3)); |
261 SendToServiceProcess(new ServiceMsg_DisableCloudPrintProxy()); | 265 SendToServiceProcess(new ServiceMsg_DisableCloudPrintProxy()); |
262 ASSERT_EQ(1, handler1->handle_message_calls_); | 266 ASSERT_EQ(1, handler1->handle_message_calls_); |
263 ASSERT_EQ(1, handler2->handle_message_calls_); | 267 ASSERT_EQ(1, handler2->handle_message_calls_); |
264 ASSERT_EQ(0, handler3->handle_message_calls_); | 268 ASSERT_EQ(0, handler3->handle_message_calls_); |
265 } | 269 } |
OLD | NEW |