| 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/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| 11 #include "base/run_loop.h" | 11 #include "base/run_loop.h" |
| 12 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
| 13 #include "mojo/common/common_type_converters.h" |
| 13 #include "mojo/public/cpp/bindings/allocation_scope.h" | 14 #include "mojo/public/cpp/bindings/allocation_scope.h" |
| 14 #include "mojo/public/cpp/environment/environment.h" | 15 #include "mojo/public/cpp/environment/environment.h" |
| 15 #include "mojo/public/cpp/shell/connect.h" | 16 #include "mojo/public/cpp/shell/connect.h" |
| 16 #include "mojo/services/public/cpp/view_manager/util.h" | 17 #include "mojo/services/public/cpp/view_manager/util.h" |
| 17 #include "mojo/services/public/cpp/view_manager/view_manager_types.h" | 18 #include "mojo/services/public/cpp/view_manager/view_manager_types.h" |
| 18 #include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h" | 19 #include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h" |
| 19 #include "mojo/shell/shell_test_helper.h" | 20 #include "mojo/shell/shell_test_helper.h" |
| 20 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
| 21 | 22 |
| 22 namespace mojo { | 23 namespace mojo { |
| 24 |
| 25 // TODO(sky): remove this when Darin is done with cleanup. |
| 26 template <typename T> |
| 27 class MOJO_COMMON_EXPORT TypeConverter<T, T> { |
| 28 public: |
| 29 static T ConvertFrom(T input, Buffer* buf) { |
| 30 return input; |
| 31 } |
| 32 static T ConvertTo(T input) { |
| 33 return input; |
| 34 } |
| 35 |
| 36 MOJO_ALLOW_IMPLICIT_TYPE_CONVERSION(); |
| 37 }; |
| 38 |
| 23 namespace view_manager { | 39 namespace view_manager { |
| 24 namespace service { | 40 namespace service { |
| 25 | 41 |
| 26 namespace { | 42 namespace { |
| 27 | 43 |
| 28 base::RunLoop* current_run_loop = NULL; | 44 base::RunLoop* current_run_loop = NULL; |
| 29 | 45 |
| 30 // Sets |current_run_loop| and runs it. It is expected that someone else quits | 46 // Sets |current_run_loop| and runs it. It is expected that someone else quits |
| 31 // the loop. | 47 // the loop. |
| 32 void DoRunLoop() { | 48 void DoRunLoop() { |
| 49 DCHECK(!current_run_loop); |
| 50 |
| 33 base::RunLoop run_loop; | 51 base::RunLoop run_loop; |
| 34 current_run_loop = &run_loop; | 52 current_run_loop = &run_loop; |
| 35 current_run_loop->Run(); | 53 current_run_loop->Run(); |
| 36 current_run_loop = NULL; | 54 current_run_loop = NULL; |
| 37 } | 55 } |
| 38 | 56 |
| 39 // Converts |id| into a string. | 57 // Converts |id| into a string. |
| 40 std::string NodeIdToString(TransportNodeId id) { | 58 std::string NodeIdToString(TransportNodeId id) { |
| 41 return (id == 0) ? "null" : | 59 return (id == 0) ? "null" : |
| 42 base::StringPrintf("%d,%d", HiWord(id), LoWord(id)); | 60 base::StringPrintf("%d,%d", HiWord(id), LoWord(id)); |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 bool SetView(IViewManager* view_manager, | 186 bool SetView(IViewManager* view_manager, |
| 169 TransportNodeId node_id, | 187 TransportNodeId node_id, |
| 170 TransportViewId view_id) { | 188 TransportViewId view_id) { |
| 171 bool result = false; | 189 bool result = false; |
| 172 view_manager->SetView(node_id, view_id, | 190 view_manager->SetView(node_id, view_id, |
| 173 base::Bind(&BooleanCallback, &result)); | 191 base::Bind(&BooleanCallback, &result)); |
| 174 DoRunLoop(); | 192 DoRunLoop(); |
| 175 return result; | 193 return result; |
| 176 } | 194 } |
| 177 | 195 |
| 196 bool SetRoots(IViewManager* view_manager, |
| 197 TransportConnectionId connection_id, |
| 198 const std::vector<uint32_t>& node_ids) { |
| 199 bool result = false; |
| 200 view_manager->SetRoots(connection_id, |
| 201 Array<uint32_t>::From(node_ids), |
| 202 base::Bind(&BooleanCallback, &result)); |
| 203 DoRunLoop(); |
| 204 return result; |
| 205 } |
| 206 |
| 178 } // namespace | 207 } // namespace |
| 179 | 208 |
| 180 typedef std::vector<std::string> Changes; | 209 typedef std::vector<std::string> Changes; |
| 181 | 210 |
| 182 class ViewManagerClientImpl : public IViewManagerClient { | 211 class ViewManagerClientImpl : public IViewManagerClient { |
| 183 public: | 212 public: |
| 184 ViewManagerClientImpl() | 213 ViewManagerClientImpl() |
| 185 : id_(0), | 214 : id_(0), |
| 186 next_server_change_id_(0), | 215 next_server_change_id_(0), |
| 187 quit_count_(0) {} | 216 quit_count_(0) {} |
| 188 | 217 |
| 189 TransportConnectionId id() const { return id_; } | 218 TransportConnectionId id() const { return id_; } |
| 190 | 219 |
| 191 TransportChangeId next_server_change_id() const { | 220 TransportChangeId next_server_change_id() const { |
| 192 return next_server_change_id_; | 221 return next_server_change_id_; |
| 193 } | 222 } |
| 194 const std::vector<TestNode>& initial_nodes() const { | 223 const std::vector<TestNode>& initial_nodes() const { |
| 195 return initial_nodes_; | 224 return initial_nodes_; |
| 196 } | 225 } |
| 197 const std::vector<TestNode>& hierarchy_changed_nodes() const { | 226 const std::vector<TestNode>& hierarchy_changed_nodes() const { |
| 198 return hierarchy_changed_nodes_; | 227 return hierarchy_changed_nodes_; |
| 199 } | 228 } |
| 200 | 229 |
| 201 Changes GetAndClearChanges() { | 230 Changes GetAndClearChanges() { |
| 202 Changes changes; | 231 Changes changes; |
| 203 changes.swap(changes_); | 232 changes.swap(changes_); |
| 204 return changes; | 233 return changes; |
| 205 } | 234 } |
| 206 | 235 |
| 236 void ClearId() { |
| 237 id_ = 0; |
| 238 } |
| 239 |
| 207 void WaitForId() { | 240 void WaitForId() { |
| 208 if (id_ == 0) | 241 DCHECK_EQ(0, id_); |
| 209 DoRunLoop(); | 242 DoRunLoopUntilChangesCount(1); |
| 210 } | 243 } |
| 211 | 244 |
| 212 void DoRunLoopUntilChangesCount(size_t count) { | 245 void DoRunLoopUntilChangesCount(size_t count) { |
| 213 if (changes_.size() >= count) | 246 if (changes_.size() >= count) |
| 214 return; | 247 return; |
| 215 quit_count_ = count - changes_.size(); | 248 quit_count_ = count - changes_.size(); |
| 216 DoRunLoop(); | 249 DoRunLoop(); |
| 217 } | 250 } |
| 218 | 251 |
| 219 private: | 252 private: |
| 220 // IViewManagerClient overrides: | 253 // IViewManagerClient overrides: |
| 221 virtual void OnConnectionEstablished( | 254 virtual void OnConnectionEstablished( |
| 222 TransportConnectionId connection_id, | 255 TransportConnectionId connection_id, |
| 223 TransportChangeId next_server_change_id, | 256 TransportChangeId next_server_change_id, |
| 224 const mojo::Array<INode>& nodes) OVERRIDE { | 257 const mojo::Array<INode>& nodes) OVERRIDE { |
| 225 id_ = connection_id; | 258 id_ = connection_id; |
| 226 next_server_change_id_ = next_server_change_id; | 259 next_server_change_id_ = next_server_change_id; |
| 260 initial_nodes_.clear(); |
| 227 INodesToTestNodes(nodes, &initial_nodes_); | 261 INodesToTestNodes(nodes, &initial_nodes_); |
| 228 if (current_run_loop) | 262 changes_.push_back("OnConnectionEstablished"); |
| 229 current_run_loop->Quit(); | 263 QuitIfNecessary(); |
| 230 } | 264 } |
| 231 virtual void OnServerChangeIdAdvanced( | 265 virtual void OnServerChangeIdAdvanced( |
| 232 uint32_t next_server_change_id) OVERRIDE { | 266 uint32_t next_server_change_id) OVERRIDE { |
| 233 changes_.push_back( | 267 changes_.push_back( |
| 234 base::StringPrintf( | 268 base::StringPrintf( |
| 235 "ServerChangeIdAdvanced %d", | 269 "ServerChangeIdAdvanced %d", |
| 236 static_cast<int>(next_server_change_id))); | 270 static_cast<int>(next_server_change_id))); |
| 237 QuitIfNecessary(); | 271 QuitIfNecessary(); |
| 238 } | 272 } |
| 239 virtual void OnNodeHierarchyChanged( | 273 virtual void OnNodeHierarchyChanged( |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 public: | 341 public: |
| 308 ViewManagerConnectionTest() {} | 342 ViewManagerConnectionTest() {} |
| 309 | 343 |
| 310 virtual void SetUp() OVERRIDE { | 344 virtual void SetUp() OVERRIDE { |
| 311 test_helper_.Init(); | 345 test_helper_.Init(); |
| 312 | 346 |
| 313 ConnectTo(test_helper_.shell(), "mojo:mojo_view_manager", &view_manager_); | 347 ConnectTo(test_helper_.shell(), "mojo:mojo_view_manager", &view_manager_); |
| 314 view_manager_->SetClient(&client_); | 348 view_manager_->SetClient(&client_); |
| 315 | 349 |
| 316 client_.WaitForId(); | 350 client_.WaitForId(); |
| 351 client_.GetAndClearChanges(); |
| 317 } | 352 } |
| 318 | 353 |
| 319 protected: | 354 protected: |
| 320 // Creates a second connection to the viewmanager. | 355 // Creates a second connection to the viewmanager. |
| 321 void EstablishSecondConnection() { | 356 void EstablishSecondConnection() { |
| 322 ConnectTo(test_helper_.shell(), "mojo:mojo_view_manager", &view_manager2_); | 357 ConnectTo(test_helper_.shell(), "mojo:mojo_view_manager", &view_manager2_); |
| 323 view_manager2_->SetClient(&client2_); | 358 view_manager2_->SetClient(&client2_); |
| 324 | 359 |
| 325 client2_.WaitForId(); | 360 client2_.WaitForId(); |
| 361 client2_.GetAndClearChanges(); |
| 326 } | 362 } |
| 327 | 363 |
| 328 void DestroySecondConnection() { | 364 void DestroySecondConnection() { |
| 329 view_manager2_.reset(); | 365 view_manager2_.reset(); |
| 330 } | 366 } |
| 331 | 367 |
| 332 base::MessageLoop loop_; | 368 base::MessageLoop loop_; |
| 333 shell::ShellTestHelper test_helper_; | 369 shell::ShellTestHelper test_helper_; |
| 334 | 370 |
| 335 ViewManagerClientImpl client_; | 371 ViewManagerClientImpl client_; |
| (...skipping 749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1085 { | 1121 { |
| 1086 AllocationScope scope; | 1122 AllocationScope scope; |
| 1087 std::vector<TestNode> nodes; | 1123 std::vector<TestNode> nodes; |
| 1088 GetNodeTree(view_manager2_.get(), CreateNodeId(1, 1), &nodes); | 1124 GetNodeTree(view_manager2_.get(), CreateNodeId(1, 1), &nodes); |
| 1089 ASSERT_EQ(2u, nodes.size()); | 1125 ASSERT_EQ(2u, nodes.size()); |
| 1090 EXPECT_EQ("node=1,1 parent=0,1 view=null", nodes[0].ToString()); | 1126 EXPECT_EQ("node=1,1 parent=0,1 view=null", nodes[0].ToString()); |
| 1091 EXPECT_EQ("node=1,11 parent=1,1 view=1,51", nodes[1].ToString()); | 1127 EXPECT_EQ("node=1,11 parent=1,1 view=1,51", nodes[1].ToString()); |
| 1092 } | 1128 } |
| 1093 } | 1129 } |
| 1094 | 1130 |
| 1131 TEST_F(ViewManagerConnectionTest, SetRoots) { |
| 1132 // Create 1, 2, and 3 in the first connection. |
| 1133 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 1)); |
| 1134 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 2)); |
| 1135 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 3)); |
| 1136 |
| 1137 // Parent 1 to the root. |
| 1138 ASSERT_TRUE(AddNode(view_manager_.get(), |
| 1139 CreateNodeId(0, 1), |
| 1140 CreateNodeId(client_.id(), 1), |
| 1141 1)); |
| 1142 |
| 1143 // Establish the second connection and give it the roots 1 and 3. |
| 1144 EstablishSecondConnection(); |
| 1145 client2_.ClearId(); |
| 1146 { |
| 1147 AllocationScope scope; |
| 1148 std::vector<uint32_t> roots; |
| 1149 roots.push_back(CreateNodeId(1, 1)); |
| 1150 roots.push_back(CreateNodeId(1, 3)); |
| 1151 ASSERT_TRUE(SetRoots(view_manager_.get(), 2, roots)); |
| 1152 client2_.DoRunLoopUntilChangesCount(1); |
| 1153 Changes changes(client2_.GetAndClearChanges()); |
| 1154 ASSERT_EQ(1u, changes.size()); |
| 1155 EXPECT_EQ("OnConnectionEstablished", changes[0]); |
| 1156 ASSERT_NE(0u, client2_.id()); |
| 1157 const std::vector<TestNode>& nodes(client2_.initial_nodes()); |
| 1158 ASSERT_EQ(2u, nodes.size()); |
| 1159 EXPECT_EQ("node=1,1 parent=null view=null", nodes[0].ToString()); |
| 1160 EXPECT_EQ("node=1,3 parent=null view=null", nodes[1].ToString()); |
| 1161 } |
| 1162 |
| 1163 // Create 4 and add it to the root, connection 2 should only get id advanced. |
| 1164 { |
| 1165 ASSERT_TRUE(CreateNode(view_manager_.get(), 1, 4)); |
| 1166 ASSERT_TRUE(AddNode(view_manager_.get(), |
| 1167 CreateNodeId(0, 1), |
| 1168 CreateNodeId(client_.id(), 4), |
| 1169 2)); |
| 1170 client2_.DoRunLoopUntilChangesCount(1); |
| 1171 Changes changes(client2_.GetAndClearChanges()); |
| 1172 ASSERT_EQ(1u, changes.size()); |
| 1173 EXPECT_EQ("ServerChangeIdAdvanced 3", changes[0]); |
| 1174 } |
| 1175 |
| 1176 // Move 4 under 3, this should expose 4 to the client. |
| 1177 { |
| 1178 ASSERT_TRUE(AddNode(view_manager_.get(), |
| 1179 CreateNodeId(1, 3), |
| 1180 CreateNodeId(1, 4), |
| 1181 3)); |
| 1182 client2_.DoRunLoopUntilChangesCount(1); |
| 1183 Changes changes(client2_.GetAndClearChanges()); |
| 1184 ASSERT_EQ(1u, changes.size()); |
| 1185 EXPECT_EQ( |
| 1186 "HierarchyChanged change_id=3 node=1,4 new_parent=1,3 " |
| 1187 "old_parent=null", changes[0]); |
| 1188 const std::vector<TestNode>& nodes(client2_.hierarchy_changed_nodes()); |
| 1189 ASSERT_EQ(1u, nodes.size()); |
| 1190 EXPECT_EQ("node=1,4 parent=1,3 view=null", nodes[0].ToString()); |
| 1191 } |
| 1192 |
| 1193 // Move 4 under 2, since 2 isn't a root client should get a delete. |
| 1194 { |
| 1195 ASSERT_TRUE(AddNode(view_manager_.get(), |
| 1196 CreateNodeId(1, 2), |
| 1197 CreateNodeId(1, 4), |
| 1198 4)); |
| 1199 client2_.DoRunLoopUntilChangesCount(1); |
| 1200 Changes changes(client2_.GetAndClearChanges()); |
| 1201 ASSERT_EQ(1u, changes.size()); |
| 1202 EXPECT_EQ("NodeDeleted change_id=4 node=1,4", changes[0]); |
| 1203 } |
| 1204 |
| 1205 // Delete 4, client shouldn't receive a delete since it should no longer know |
| 1206 // about 4. |
| 1207 { |
| 1208 ASSERT_TRUE(DeleteNode(view_manager_.get(), CreateNodeId(client_.id(), 4))); |
| 1209 ASSERT_TRUE(client_.GetAndClearChanges().empty()); |
| 1210 |
| 1211 client2_.DoRunLoopUntilChangesCount(1); |
| 1212 Changes changes(client2_.GetAndClearChanges()); |
| 1213 ASSERT_EQ(1u, changes.size()); |
| 1214 EXPECT_EQ("ServerChangeIdAdvanced 6", changes[0]); |
| 1215 } |
| 1216 } |
| 1217 |
| 1218 // TODO: add tests that verify can't manipulate trees of uknown nodes. |
| 1219 |
| 1095 } // namespace service | 1220 } // namespace service |
| 1096 } // namespace view_manager | 1221 } // namespace view_manager |
| 1097 } // namespace mojo | 1222 } // namespace mojo |
| OLD | NEW |