OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 <string> | 5 #include <string> |
6 #include <vector> | 6 #include <vector> |
7 | 7 |
8 #include "base/auto_reset.h" | 8 #include "base/auto_reset.h" |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 RunMainLoop(); | 130 RunMainLoop(); |
131 return result; | 131 return result; |
132 } | 132 } |
133 void GetNodeTree(Id node_id, std::vector<TestNode>* nodes) { | 133 void GetNodeTree(Id node_id, std::vector<TestNode>* nodes) { |
134 changes_.clear(); | 134 changes_.clear(); |
135 view_manager_->GetNodeTree(node_id, | 135 view_manager_->GetNodeTree(node_id, |
136 base::Bind(&ViewManagerProxy::GotNodeTree, | 136 base::Bind(&ViewManagerProxy::GotNodeTree, |
137 base::Unretained(this), nodes)); | 137 base::Unretained(this), nodes)); |
138 RunMainLoop(); | 138 RunMainLoop(); |
139 } | 139 } |
140 bool Connect(const std::vector<Id>& nodes) { | 140 bool Embed(const std::vector<Id>& nodes) { |
141 changes_.clear(); | 141 changes_.clear(); |
142 base::AutoReset<bool> auto_reset(&in_connect_, true); | 142 base::AutoReset<bool> auto_reset(&in_embed_, true); |
143 bool result = false; | 143 bool result = false; |
144 view_manager_->Connect(kTestServiceURL, Array<Id>::From(nodes), | 144 view_manager_->Embed(kTestServiceURL, Array<Id>::From(nodes), |
145 base::Bind(&ViewManagerProxy::GotResult, | 145 base::Bind(&ViewManagerProxy::GotResult, |
146 base::Unretained(this), &result)); | 146 base::Unretained(this), &result)); |
147 RunMainLoop(); | 147 RunMainLoop(); |
148 return result; | 148 return result; |
149 } | 149 } |
150 bool DeleteNode(Id node_id) { | 150 bool DeleteNode(Id node_id) { |
151 changes_.clear(); | 151 changes_.clear(); |
152 bool result = false; | 152 bool result = false; |
153 view_manager_->DeleteNode(node_id, | 153 view_manager_->DeleteNode(node_id, |
154 base::Bind(&ViewManagerProxy::GotResult, | 154 base::Bind(&ViewManagerProxy::GotResult, |
155 base::Unretained(this), &result)); | 155 base::Unretained(this), &result)); |
156 RunMainLoop(); | 156 RunMainLoop(); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 | 199 |
200 void CopyChangesFromTracker() { | 200 void CopyChangesFromTracker() { |
201 std::vector<Change> changes; | 201 std::vector<Change> changes; |
202 tracker_->changes()->swap(changes); | 202 tracker_->changes()->swap(changes); |
203 changes_.swap(changes); | 203 changes_.swap(changes); |
204 } | 204 } |
205 | 205 |
206 static void SetInstance(ViewManagerProxy* instance) { | 206 static void SetInstance(ViewManagerProxy* instance) { |
207 DCHECK(!instance_); | 207 DCHECK(!instance_); |
208 instance_ = instance; | 208 instance_ = instance; |
209 // Connect() runs its own run loop that is quit when the result is | 209 // Embed() runs its own run loop that is quit when the result is |
210 // received. Connect() also results in a new instance. If we quit here while | 210 // received. Embed() also results in a new instance. If we quit here while |
211 // waiting for a Connect() we would prematurely return before we got the | 211 // waiting for a Embed() we would prematurely return before we got the |
212 // result from Connect(). | 212 // result from Embed(). |
213 if (!in_connect_ && main_run_loop_) | 213 if (!in_embed_ && main_run_loop_) |
214 main_run_loop_->Quit(); | 214 main_run_loop_->Quit(); |
215 } | 215 } |
216 | 216 |
217 // Callbacks from the various IViewManager functions. | 217 // Callbacks from the various IViewManager functions. |
218 void GotResult(bool* result_cache, bool result) { | 218 void GotResult(bool* result_cache, bool result) { |
219 *result_cache = result; | 219 *result_cache = result; |
220 DCHECK(main_run_loop_); | 220 DCHECK(main_run_loop_); |
221 main_run_loop_->Quit(); | 221 main_run_loop_->Quit(); |
222 } | 222 } |
223 | 223 |
224 void GotNodeTree(std::vector<TestNode>* nodes, Array<INodePtr> results) { | 224 void GotNodeTree(std::vector<TestNode>* nodes, Array<INodePtr> results) { |
225 INodesToTestNodes(results, nodes); | 225 INodesToTestNodes(results, nodes); |
226 DCHECK(main_run_loop_); | 226 DCHECK(main_run_loop_); |
227 main_run_loop_->Quit(); | 227 main_run_loop_->Quit(); |
228 } | 228 } |
229 | 229 |
230 // TestChangeTracker::Delegate: | 230 // TestChangeTracker::Delegate: |
231 virtual void OnChangeAdded() OVERRIDE { | 231 virtual void OnChangeAdded() OVERRIDE { |
232 if (quit_count_ > 0 && --quit_count_ == 0) | 232 if (quit_count_ > 0 && --quit_count_ == 0) |
233 QuitCountReached(); | 233 QuitCountReached(); |
234 } | 234 } |
235 | 235 |
236 static ViewManagerProxy* instance_; | 236 static ViewManagerProxy* instance_; |
237 static base::RunLoop* main_run_loop_; | 237 static base::RunLoop* main_run_loop_; |
238 static bool in_connect_; | 238 static bool in_embed_; |
239 | 239 |
240 TestChangeTracker* tracker_; | 240 TestChangeTracker* tracker_; |
241 | 241 |
242 // MessageLoop of the test. | 242 // MessageLoop of the test. |
243 base::MessageLoop* main_loop_; | 243 base::MessageLoop* main_loop_; |
244 | 244 |
245 IViewManager* view_manager_; | 245 IViewManager* view_manager_; |
246 | 246 |
247 // Number of changes we're waiting on until we quit the current loop. | 247 // Number of changes we're waiting on until we quit the current loop. |
248 size_t quit_count_; | 248 size_t quit_count_; |
249 | 249 |
250 std::vector<Change> changes_; | 250 std::vector<Change> changes_; |
251 | 251 |
252 mojo::internal::Router* router_; | 252 mojo::internal::Router* router_; |
253 | 253 |
254 DISALLOW_COPY_AND_ASSIGN(ViewManagerProxy); | 254 DISALLOW_COPY_AND_ASSIGN(ViewManagerProxy); |
255 }; | 255 }; |
256 | 256 |
257 // static | 257 // static |
258 ViewManagerProxy* ViewManagerProxy::instance_ = NULL; | 258 ViewManagerProxy* ViewManagerProxy::instance_ = NULL; |
259 | 259 |
260 // static | 260 // static |
261 base::RunLoop* ViewManagerProxy::main_run_loop_ = NULL; | 261 base::RunLoop* ViewManagerProxy::main_run_loop_ = NULL; |
262 | 262 |
263 // static | 263 // static |
264 bool ViewManagerProxy::in_connect_ = false; | 264 bool ViewManagerProxy::in_embed_ = false; |
265 | 265 |
266 class TestViewManagerClientConnection | 266 class TestViewManagerClientConnection |
267 : public InterfaceImpl<IViewManagerClient> { | 267 : public InterfaceImpl<IViewManagerClient> { |
268 public: | 268 public: |
269 TestViewManagerClientConnection() : connection_(&tracker_) { | 269 TestViewManagerClientConnection() : connection_(&tracker_) { |
270 tracker_.set_delegate(&connection_); | 270 tracker_.set_delegate(&connection_); |
271 } | 271 } |
272 | 272 |
273 // InterfaceImp: | 273 // InterfaceImp: |
274 virtual void OnConnectionEstablished() OVERRIDE { | 274 virtual void OnConnectionEstablished() OVERRIDE { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 tracker_.OnViewInputEvent(view_id, event.Pass()); | 321 tracker_.OnViewInputEvent(view_id, event.Pass()); |
322 } | 322 } |
323 | 323 |
324 private: | 324 private: |
325 TestChangeTracker tracker_; | 325 TestChangeTracker tracker_; |
326 ViewManagerProxy connection_; | 326 ViewManagerProxy connection_; |
327 | 327 |
328 DISALLOW_COPY_AND_ASSIGN(TestViewManagerClientConnection); | 328 DISALLOW_COPY_AND_ASSIGN(TestViewManagerClientConnection); |
329 }; | 329 }; |
330 | 330 |
331 // Used with IViewManager::Connect(). Creates a TestViewManagerClientConnection, | 331 // Used with IViewManager::Embed(). Creates a TestViewManagerClientConnection, |
332 // which creates and owns the ViewManagerProxy. | 332 // which creates and owns the ViewManagerProxy. |
333 class ConnectServiceLoader : public ServiceLoader { | 333 class EmbedServiceLoader : public ServiceLoader { |
334 public: | 334 public: |
335 ConnectServiceLoader() {} | 335 EmbedServiceLoader() {} |
336 virtual ~ConnectServiceLoader() {} | 336 virtual ~EmbedServiceLoader() {} |
337 | 337 |
338 // ServiceLoader: | 338 // ServiceLoader: |
339 virtual void LoadService(ServiceManager* manager, | 339 virtual void LoadService(ServiceManager* manager, |
340 const GURL& url, | 340 const GURL& url, |
341 ScopedMessagePipeHandle shell_handle) OVERRIDE { | 341 ScopedMessagePipeHandle shell_handle) OVERRIDE { |
342 scoped_ptr<Application> app(new Application(shell_handle.Pass())); | 342 scoped_ptr<Application> app(new Application(shell_handle.Pass())); |
343 app->AddService<TestViewManagerClientConnection>(); | 343 app->AddService<TestViewManagerClientConnection>(); |
344 apps_.push_back(app.release()); | 344 apps_.push_back(app.release()); |
345 } | 345 } |
346 virtual void OnServiceError(ServiceManager* manager, | 346 virtual void OnServiceError(ServiceManager* manager, |
347 const GURL& url) OVERRIDE { | 347 const GURL& url) OVERRIDE { |
348 } | 348 } |
349 | 349 |
350 private: | 350 private: |
351 ScopedVector<Application> apps_; | 351 ScopedVector<Application> apps_; |
352 | 352 |
353 DISALLOW_COPY_AND_ASSIGN(ConnectServiceLoader); | 353 DISALLOW_COPY_AND_ASSIGN(EmbedServiceLoader); |
354 }; | 354 }; |
355 | 355 |
356 // Creates an id used for transport from the specified parameters. | 356 // Creates an id used for transport from the specified parameters. |
357 Id BuildNodeId(ConnectionSpecificId connection_id, | 357 Id BuildNodeId(ConnectionSpecificId connection_id, |
358 ConnectionSpecificId node_id) { | 358 ConnectionSpecificId node_id) { |
359 return (connection_id << 16) | node_id; | 359 return (connection_id << 16) | node_id; |
360 } | 360 } |
361 | 361 |
362 // Creates an id used for transport from the specified parameters. | 362 // Creates an id used for transport from the specified parameters. |
363 Id BuildViewId(ConnectionSpecificId connection_id, | 363 Id BuildViewId(ConnectionSpecificId connection_id, |
364 ConnectionSpecificId view_id) { | 364 ConnectionSpecificId view_id) { |
365 return (connection_id << 16) | view_id; | 365 return (connection_id << 16) | view_id; |
366 } | 366 } |
367 | 367 |
368 // Callback from ViewManagerInitConnect(). |result| is the result of the | 368 // Callback from EmbedRoot(). |result| is the result of the |
369 // Connect() call and |run_loop| the nested RunLoop. | 369 // Embed() call and |run_loop| the nested RunLoop. |
370 void ViewManagerInitConnectCallback(bool* result_cache, | 370 void EmbedRootCallback(bool* result_cache, |
371 base::RunLoop* run_loop, | 371 base::RunLoop* run_loop, |
372 bool result) { | 372 bool result) { |
373 *result_cache = result; | 373 *result_cache = result; |
374 run_loop->Quit(); | 374 run_loop->Quit(); |
375 } | 375 } |
376 | 376 |
377 // Resposible for establishing connection to the viewmanager. Blocks until get | 377 // Resposible for establishing the initial IViewManager connection. Blocks until |
378 // back result. | 378 // result is determined. |
379 bool ViewManagerInitConnect(IViewManagerInit* view_manager_init, | 379 bool EmbedRoot(IViewManagerInit* view_manager_init, const std::string& url) { |
380 const std::string& url) { | |
381 bool result = false; | 380 bool result = false; |
382 base::RunLoop run_loop; | 381 base::RunLoop run_loop; |
383 view_manager_init->Connect(url, | 382 view_manager_init->EmbedRoot(url, base::Bind(&EmbedRootCallback, |
384 base::Bind(&ViewManagerInitConnectCallback, | 383 &result, &run_loop)); |
385 &result, &run_loop)); | |
386 run_loop.Run(); | 384 run_loop.Run(); |
387 return result; | 385 return result; |
388 } | 386 } |
389 | 387 |
390 } // namespace | 388 } // namespace |
391 | 389 |
392 typedef std::vector<std::string> Changes; | 390 typedef std::vector<std::string> Changes; |
393 | 391 |
394 class ViewManagerConnectionTest : public testing::Test { | 392 class ViewManagerConnectionTest : public testing::Test { |
395 public: | 393 public: |
396 ViewManagerConnectionTest() : connection_(NULL), connection2_(NULL) {} | 394 ViewManagerConnectionTest() : connection_(NULL), connection2_(NULL) {} |
397 | 395 |
398 virtual void SetUp() OVERRIDE { | 396 virtual void SetUp() OVERRIDE { |
399 test_helper_.Init(); | 397 test_helper_.Init(); |
400 | 398 |
401 test_helper_.SetLoaderForURL( | 399 test_helper_.SetLoaderForURL( |
402 scoped_ptr<ServiceLoader>(new ConnectServiceLoader()), | 400 scoped_ptr<ServiceLoader>(new EmbedServiceLoader()), |
403 GURL(kTestServiceURL)); | 401 GURL(kTestServiceURL)); |
404 | 402 |
405 ConnectToService(test_helper_.service_provider(), | 403 ConnectToService(test_helper_.service_provider(), |
406 "mojo:mojo_view_manager", | 404 "mojo:mojo_view_manager", |
407 &view_manager_init_); | 405 &view_manager_init_); |
408 ASSERT_TRUE(ViewManagerInitConnect(view_manager_init_.get(), | 406 ASSERT_TRUE(EmbedRoot(view_manager_init_.get(), kTestServiceURL)); |
409 kTestServiceURL)); | |
410 | 407 |
411 connection_ = ViewManagerProxy::WaitForInstance(); | 408 connection_ = ViewManagerProxy::WaitForInstance(); |
412 ASSERT_TRUE(connection_ != NULL); | 409 ASSERT_TRUE(connection_ != NULL); |
413 connection_->DoRunLoopUntilChangesCount(1); | 410 connection_->DoRunLoopUntilChangesCount(1); |
414 } | 411 } |
415 | 412 |
416 virtual void TearDown() OVERRIDE { | 413 virtual void TearDown() OVERRIDE { |
417 if (connection2_) | 414 if (connection2_) |
418 connection2_->Destroy(); | 415 connection2_->Destroy(); |
419 if (connection_) | 416 if (connection_) |
420 connection_->Destroy(); | 417 connection_->Destroy(); |
421 } | 418 } |
422 | 419 |
423 protected: | 420 protected: |
424 void EstablishSecondConnectionWithRoots(Id id1, Id id2) { | 421 void EstablishSecondConnectionWithRoots(Id id1, Id id2) { |
425 std::vector<Id> node_ids; | 422 std::vector<Id> node_ids; |
426 node_ids.push_back(id1); | 423 node_ids.push_back(id1); |
427 if (id2 != 0) | 424 if (id2 != 0) |
428 node_ids.push_back(id2); | 425 node_ids.push_back(id2); |
429 ASSERT_TRUE(connection_->Connect(node_ids)); | 426 ASSERT_TRUE(connection_->Embed(node_ids)); |
430 connection2_ = ViewManagerProxy::WaitForInstance(); | 427 connection2_ = ViewManagerProxy::WaitForInstance(); |
431 ASSERT_TRUE(connection2_ != NULL); | 428 ASSERT_TRUE(connection2_ != NULL); |
432 connection2_->DoRunLoopUntilChangesCount(1); | 429 connection2_->DoRunLoopUntilChangesCount(1); |
433 ASSERT_EQ(1u, connection2_->changes().size()); | 430 ASSERT_EQ(1u, connection2_->changes().size()); |
434 } | 431 } |
435 | 432 |
436 // Creates a second connection to the viewmanager. | 433 // Creates a second connection to the viewmanager. |
437 void EstablishSecondConnection(bool create_initial_node) { | 434 void EstablishSecondConnection(bool create_initial_node) { |
438 if (create_initial_node) | 435 if (create_initial_node) |
439 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1))); | 436 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1))); |
(...skipping 759 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1199 TEST_F(ViewManagerConnectionTest, ConnectTwice) { | 1196 TEST_F(ViewManagerConnectionTest, ConnectTwice) { |
1200 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1))); | 1197 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 1))); |
1201 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2))); | 1198 ASSERT_TRUE(connection_->CreateNode(BuildNodeId(1, 2))); |
1202 ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false)); | 1199 ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false)); |
1203 | 1200 |
1204 // Try to connect again to 1,1, this should fail as already connected to that | 1201 // Try to connect again to 1,1, this should fail as already connected to that |
1205 // root. | 1202 // root. |
1206 { | 1203 { |
1207 std::vector<Id> node_ids; | 1204 std::vector<Id> node_ids; |
1208 node_ids.push_back(BuildNodeId(1, 1)); | 1205 node_ids.push_back(BuildNodeId(1, 1)); |
1209 ASSERT_FALSE(connection_->Connect(node_ids)); | 1206 ASSERT_FALSE(connection_->Embed(node_ids)); |
1210 } | 1207 } |
1211 | 1208 |
1212 // Connecting to 1,2 should succeed and end up in connection2. | 1209 // Connecting to 1,2 should succeed and end up in connection2. |
1213 { | 1210 { |
1214 std::vector<Id> node_ids; | 1211 std::vector<Id> node_ids; |
1215 node_ids.push_back(BuildNodeId(1, 2)); | 1212 node_ids.push_back(BuildNodeId(1, 2)); |
1216 ASSERT_TRUE(connection_->Connect(node_ids)); | 1213 ASSERT_TRUE(connection_->Embed(node_ids)); |
1217 connection2_->DoRunLoopUntilChangesCount(1); | 1214 connection2_->DoRunLoopUntilChangesCount(1); |
1218 const Changes changes(ChangesToDescription1(connection2_->changes())); | 1215 const Changes changes(ChangesToDescription1(connection2_->changes())); |
1219 ASSERT_EQ(1u, changes.size()); | 1216 ASSERT_EQ(1u, changes.size()); |
1220 EXPECT_EQ("OnRootsAdded", changes[0]); | 1217 EXPECT_EQ("OnRootsAdded", changes[0]); |
1221 EXPECT_EQ("[node=1,2 parent=null view=null]", | 1218 EXPECT_EQ("[node=1,2 parent=null view=null]", |
1222 ChangeNodeDescription(connection2_->changes())); | 1219 ChangeNodeDescription(connection2_->changes())); |
1223 } | 1220 } |
1224 } | 1221 } |
1225 | 1222 |
1226 // TODO(sky): add coverage of test that destroys connections and ensures other | 1223 // TODO(sky): add coverage of test that destroys connections and ensures other |
1227 // connections get deletion notification (or advanced server id). | 1224 // connections get deletion notification (or advanced server id). |
1228 | 1225 |
1229 // TODO(sky): need to better track changes to initial connection. For example, | 1226 // TODO(sky): need to better track changes to initial connection. For example, |
1230 // that SetBounsdNodes/AddNode and the like don't result in messages to the | 1227 // that SetBounsdNodes/AddNode and the like don't result in messages to the |
1231 // originating connection. | 1228 // originating connection. |
1232 | 1229 |
1233 } // namespace service | 1230 } // namespace service |
1234 } // namespace view_manager | 1231 } // namespace view_manager |
1235 } // namespace mojo | 1232 } // namespace mojo |
OLD | NEW |