| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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 <stddef.h> | 5 #include <stddef.h> |
| 6 #include <stdint.h> | 6 #include <stdint.h> |
| 7 | 7 |
| 8 #include <utility> | 8 #include <utility> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 // the package's manifest and are thus registered with the PackageManager. | 22 // the package's manifest and are thus registered with the PackageManager. |
| 23 | 23 |
| 24 namespace mojo { | 24 namespace mojo { |
| 25 namespace shell { | 25 namespace shell { |
| 26 namespace { | 26 namespace { |
| 27 const char kTestPackageName[] = "mojo:connect_test_package"; | 27 const char kTestPackageName[] = "mojo:connect_test_package"; |
| 28 const char kTestAppName[] = "mojo:connect_test_app"; | 28 const char kTestAppName[] = "mojo:connect_test_app"; |
| 29 const char kTestAppAName[] = "mojo:connect_test_a"; | 29 const char kTestAppAName[] = "mojo:connect_test_a"; |
| 30 const char kTestAppBName[] = "mojo:connect_test_b"; | 30 const char kTestAppBName[] = "mojo:connect_test_b"; |
| 31 | 31 |
| 32 void ReceiveOneString(std::string* out_string, | 32 void ReceiveTitle(std::string* out_name, |
| 33 base::RunLoop* loop, | 33 base::RunLoop* loop, |
| 34 const String& in_string) { | 34 const String& name) { |
| 35 *out_string = in_string; | 35 *out_name = name; |
| 36 loop->Quit(); | 36 loop->Quit(); |
| 37 } | 37 } |
| 38 | 38 |
| 39 void ReceiveTwoStrings(std::string* out_string_1, std::string* out_string_2, | |
| 40 base::RunLoop* loop, | |
| 41 const String& in_string_1, const String& in_string_2) { | |
| 42 *out_string_1 = in_string_1; | |
| 43 *out_string_2 = in_string_2; | |
| 44 loop->Quit(); | |
| 45 } | |
| 46 | |
| 47 void QuitLoop(base::RunLoop* loop) { | 39 void QuitLoop(base::RunLoop* loop) { |
| 48 loop->Quit(); | 40 loop->Quit(); |
| 49 } | 41 } |
| 50 | 42 |
| 51 } // namespace | 43 } // namespace |
| 52 | 44 |
| 53 class ConnectTest : public mojo::test::ShellTest, | 45 class ConnectTest : public mojo::test::ShellTest, |
| 54 public InterfaceFactory<test::mojom::ExposedInterface>, | 46 public InterfaceFactory<test::mojom::ExposedInterface>, |
| 55 public test::mojom::ExposedInterface { | 47 public test::mojom::ExposedInterface { |
| 56 public: | 48 public: |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 void SetUp() override { | 86 void SetUp() override { |
| 95 mojo::test::ShellTest::SetUp(); | 87 mojo::test::ShellTest::SetUp(); |
| 96 // We need to connect to the package first to force the shell to read the | 88 // We need to connect to the package first to force the shell to read the |
| 97 // package app's manifest and register aliases for the applications it | 89 // package app's manifest and register aliases for the applications it |
| 98 // provides. | 90 // provides. |
| 99 test::mojom::ConnectTestServicePtr root_service; | 91 test::mojom::ConnectTestServicePtr root_service; |
| 100 scoped_ptr<Connection> connection = connector()->Connect(kTestPackageName); | 92 scoped_ptr<Connection> connection = connector()->Connect(kTestPackageName); |
| 101 connection->GetInterface(&root_service); | 93 connection->GetInterface(&root_service); |
| 102 base::RunLoop run_loop; | 94 base::RunLoop run_loop; |
| 103 std::string root_name; | 95 std::string root_name; |
| 104 root_service->GetTitle( | 96 root_service->GetTitle(base::Bind(&ReceiveTitle, &root_name, &run_loop)); |
| 105 base::Bind(&ReceiveOneString, &root_name, &run_loop)); | |
| 106 run_loop.Run(); | 97 run_loop.Run(); |
| 107 } | 98 } |
| 108 | 99 |
| 109 // InterfaceFactory<test::mojom::ExposedInterface>: | 100 // InterfaceFactory<test::mojom::ExposedInterface>: |
| 110 void Create(Connection* connection, | 101 void Create(Connection* connection, |
| 111 test::mojom::ExposedInterfaceRequest request) override { | 102 test::mojom::ExposedInterfaceRequest request) override { |
| 112 bindings_.AddBinding(this, std::move(request)); | 103 bindings_.AddBinding(this, std::move(request)); |
| 113 } | 104 } |
| 114 void ConnectionAccepted(test::mojom::ConnectionStatePtr state) override { | 105 void ConnectionAccepted(test::mojom::ConnectionStatePtr state) override { |
| 115 connection_state_ = std::move(state); | 106 connection_state_ = std::move(state); |
| 116 ping_callback_.Run(); | 107 ping_callback_.Run(); |
| 117 } | 108 } |
| 118 | 109 |
| 119 base::Closure ping_callback_; | 110 base::Closure ping_callback_; |
| 120 test::mojom::ConnectionStatePtr connection_state_; | 111 test::mojom::ConnectionStatePtr connection_state_; |
| 121 | 112 |
| 122 BindingSet<test::mojom::ExposedInterface> bindings_; | 113 BindingSet<test::mojom::ExposedInterface> bindings_; |
| 123 | 114 |
| 124 DISALLOW_COPY_AND_ASSIGN(ConnectTest); | 115 DISALLOW_COPY_AND_ASSIGN(ConnectTest); |
| 125 }; | 116 }; |
| 126 | 117 |
| 127 // Ensure the connection was properly established and that a round trip | 118 // Ensure the connection was properly established and that a round trip |
| 128 // method call/response is completed. | 119 // method call/response is completed. |
| 129 TEST_F(ConnectTest, Connect) { | 120 TEST_F(ConnectTest, Connect) { |
| 130 scoped_ptr<Connection> connection = connector()->Connect(kTestAppName); | 121 scoped_ptr<Connection> connection = connector()->Connect(kTestAppName); |
| 131 test::mojom::ConnectTestServicePtr service; | 122 test::mojom::ConnectTestServicePtr service; |
| 132 connection->GetInterface(&service); | 123 connection->GetInterface(&service); |
| 133 base::RunLoop run_loop; | 124 base::RunLoop run_loop; |
| 134 std::string title; | 125 std::string title; |
| 135 service->GetTitle(base::Bind(&ReceiveOneString, &title, &run_loop)); | 126 service->GetTitle(base::Bind(&ReceiveTitle, &title, &run_loop)); |
| 136 run_loop.Run(); | 127 run_loop.Run(); |
| 137 EXPECT_EQ("APP", title); | 128 EXPECT_EQ("APP", title); |
| 138 EXPECT_FALSE(connection->IsPending()); | 129 EXPECT_FALSE(connection->IsPending()); |
| 139 EXPECT_NE(mojom::kInvalidInstanceID, connection->GetRemoteInstanceID()); | 130 EXPECT_NE(mojom::kInvalidInstanceID, connection->GetRemoteInstanceID()); |
| 140 EXPECT_EQ(connection->GetRemoteIdentity().name(), kTestAppName); | 131 EXPECT_EQ(connection->GetRemoteIdentity().name(), kTestAppName); |
| 141 } | 132 } |
| 142 | 133 |
| 143 TEST_F(ConnectTest, Instances) { | 134 TEST_F(ConnectTest, Instances) { |
| 144 Connector::ConnectParams params_a( | 135 Connector::ConnectParams params_a( |
| 145 Identity(kTestAppName, mojom::kInheritUserID, "A")); | 136 Identity(kTestAppName, mojom::kInheritUserID, "A")); |
| 146 scoped_ptr<Connection> connection_a1 = ConnectTo(¶ms_a); | 137 scoped_ptr<Connection> connection_a1 = ConnectTo(¶ms_a); |
| 147 scoped_ptr<Connection> connection_a2 = ConnectTo(¶ms_a); | 138 scoped_ptr<Connection> connection_a2 = ConnectTo(¶ms_a); |
| 148 std::string instance_a1, instance_a2; | 139 std::string instance_a1, instance_a2; |
| 149 test::mojom::ConnectTestServicePtr service_a1; | 140 test::mojom::ConnectTestServicePtr service_a1; |
| 150 { | 141 { |
| 151 connection_a1->GetInterface(&service_a1); | 142 connection_a1->GetInterface(&service_a1); |
| 152 base::RunLoop loop; | 143 base::RunLoop loop; |
| 153 service_a1->GetInstance(base::Bind(&ReceiveOneString, &instance_a1, &loop)); | 144 service_a1->GetInstance(base::Bind(&ReceiveTitle, &instance_a1, &loop)); |
| 154 loop.Run(); | 145 loop.Run(); |
| 155 } | 146 } |
| 156 test::mojom::ConnectTestServicePtr service_a2; | 147 test::mojom::ConnectTestServicePtr service_a2; |
| 157 { | 148 { |
| 158 connection_a2->GetInterface(&service_a2); | 149 connection_a2->GetInterface(&service_a2); |
| 159 base::RunLoop loop; | 150 base::RunLoop loop; |
| 160 service_a2->GetInstance(base::Bind(&ReceiveOneString, &instance_a2, &loop)); | 151 service_a2->GetInstance(base::Bind(&ReceiveTitle, &instance_a2, &loop)); |
| 161 loop.Run(); | 152 loop.Run(); |
| 162 } | 153 } |
| 163 EXPECT_EQ(instance_a1, instance_a2); | 154 EXPECT_EQ(instance_a1, instance_a2); |
| 164 | 155 |
| 165 Connector::ConnectParams params_b( | 156 Connector::ConnectParams params_b( |
| 166 Identity(kTestAppName, mojom::kInheritUserID, "B")); | 157 Identity(kTestAppName, mojom::kInheritUserID, "B")); |
| 167 scoped_ptr<Connection> connection_b = ConnectTo(¶ms_b); | 158 scoped_ptr<Connection> connection_b = ConnectTo(¶ms_b); |
| 168 std::string instance_b; | 159 std::string instance_b; |
| 169 test::mojom::ConnectTestServicePtr service_b; | 160 test::mojom::ConnectTestServicePtr service_b; |
| 170 { | 161 { |
| 171 connection_b->GetInterface(&service_b); | 162 connection_b->GetInterface(&service_b); |
| 172 base::RunLoop loop; | 163 base::RunLoop loop; |
| 173 service_b->GetInstance(base::Bind(&ReceiveOneString, &instance_b, &loop)); | 164 service_b->GetInstance(base::Bind(&ReceiveTitle, &instance_b, &loop)); |
| 174 loop.Run(); | 165 loop.Run(); |
| 175 } | 166 } |
| 176 | 167 |
| 177 EXPECT_NE(instance_a1, instance_b); | 168 EXPECT_NE(instance_a1, instance_b); |
| 178 } | 169 } |
| 179 | 170 |
| 180 // When both the unresolved and resolved instance names are their default | 171 // When both the unresolved and resolved instance names are their default |
| 181 // values, the instance name from the unresolved name must be used. | 172 // values, the instance name from the unresolved name must be used. |
| 182 // (The case where the instance names differ is covered by | 173 // (The case where the instance names differ is covered by |
| 183 // LifecycleTest.PackagedApp_CrashCrashesOtherProvidedApp). | 174 // LifecycleTest.PackagedApp_CrashCrashesOtherProvidedApp). |
| 184 TEST_F(ConnectTest, PreferUnresolvedDefaultInstanceName) { | 175 TEST_F(ConnectTest, PreferUnresolvedDefaultInstanceName) { |
| 185 // Connect to an app with no manifest-supplied instance name provided by a | 176 // Connect to an app with no manifest-supplied instance name provided by a |
| 186 // package, the instance name must be derived from the application instance | 177 // package, the instance name must be derived from the application instance |
| 187 // name, not the package. | 178 // name, not the package. |
| 188 scoped_ptr<Connection> connection = connector()->Connect(kTestAppName); | 179 scoped_ptr<Connection> connection = connector()->Connect(kTestAppName); |
| 189 { | 180 { |
| 190 base::RunLoop loop; | 181 base::RunLoop loop; |
| 191 connection->AddConnectionCompletedClosure(base::Bind(&QuitLoop, &loop)); | 182 connection->AddConnectionCompletedClosure(base::Bind(&QuitLoop, &loop)); |
| 192 loop.Run(); | 183 loop.Run(); |
| 193 } | 184 } |
| 194 | 185 |
| 195 std::string instance; | 186 std::string instance; |
| 196 { | 187 { |
| 197 test::mojom::ConnectTestServicePtr service; | 188 test::mojom::ConnectTestServicePtr service; |
| 198 connection->GetInterface(&service); | 189 connection->GetInterface(&service); |
| 199 base::RunLoop loop; | 190 base::RunLoop loop; |
| 200 service->GetInstance(base::Bind(&ReceiveOneString, &instance, &loop)); | 191 service->GetInstance(base::Bind(&ReceiveTitle, &instance, &loop)); |
| 201 loop.Run(); | 192 loop.Run(); |
| 202 } | 193 } |
| 203 EXPECT_EQ(GetNamePath(kTestAppName), instance); | 194 EXPECT_EQ(GetNamePath(kTestAppName), instance); |
| 204 } | 195 } |
| 205 | 196 |
| 206 // BlockedInterface should not be exposed to this application because it is not | 197 // BlockedInterface should not be exposed to this application because it is not |
| 207 // in our CapabilityFilter whitelist. | 198 // in our CapabilityFilter whitelist. |
| 208 TEST_F(ConnectTest, BlockedInterface) { | 199 TEST_F(ConnectTest, BlockedInterface) { |
| 209 scoped_ptr<Connection> connection = connector()->Connect(kTestAppName); | 200 scoped_ptr<Connection> connection = connector()->Connect(kTestAppName); |
| 210 base::RunLoop run_loop; | 201 base::RunLoop run_loop; |
| 211 test::mojom::BlockedInterfacePtr blocked; | 202 test::mojom::BlockedInterfacePtr blocked; |
| 212 connection->GetInterface(&blocked); | 203 connection->GetInterface(&blocked); |
| 213 blocked.set_connection_error_handler(base::Bind(&QuitLoop, &run_loop)); | 204 blocked.set_connection_error_handler(base::Bind(&QuitLoop, &run_loop)); |
| 214 std::string title = "unchanged"; | 205 std::string title = "unchanged"; |
| 215 blocked->GetTitleBlocked(base::Bind(&ReceiveOneString, &title, &run_loop)); | 206 blocked->GetTitleBlocked(base::Bind(&ReceiveTitle, &title, &run_loop)); |
| 216 run_loop.Run(); | 207 run_loop.Run(); |
| 217 EXPECT_EQ("unchanged", title); | 208 EXPECT_EQ("unchanged", title); |
| 218 } | 209 } |
| 219 | 210 |
| 220 // Connects to an app provided by a package. | 211 // Connects to an app provided by a package. |
| 221 TEST_F(ConnectTest, PackagedApp) { | 212 TEST_F(ConnectTest, PackagedApp) { |
| 222 scoped_ptr<Connection> connection = connector()->Connect(kTestAppAName); | 213 scoped_ptr<Connection> connection = connector()->Connect(kTestAppAName); |
| 223 test::mojom::ConnectTestServicePtr service_a; | 214 test::mojom::ConnectTestServicePtr service_a; |
| 224 connection->GetInterface(&service_a); | 215 connection->GetInterface(&service_a); |
| 225 base::RunLoop run_loop; | 216 base::RunLoop run_loop; |
| 226 std::string a_name; | 217 std::string a_name; |
| 227 service_a->GetTitle(base::Bind(&ReceiveOneString, &a_name, &run_loop)); | 218 service_a->GetTitle(base::Bind(&ReceiveTitle, &a_name, &run_loop)); |
| 228 run_loop.Run(); | 219 run_loop.Run(); |
| 229 EXPECT_EQ("A", a_name); | 220 EXPECT_EQ("A", a_name); |
| 230 EXPECT_FALSE(connection->IsPending()); | 221 EXPECT_FALSE(connection->IsPending()); |
| 231 EXPECT_NE(mojom::kInvalidInstanceID, connection->GetRemoteInstanceID()); | 222 EXPECT_NE(mojom::kInvalidInstanceID, connection->GetRemoteInstanceID()); |
| 232 EXPECT_EQ(connection->GetRemoteIdentity().name(), kTestAppAName); | 223 EXPECT_EQ(connection->GetRemoteIdentity().name(), kTestAppAName); |
| 233 } | 224 } |
| 234 | 225 |
| 235 // Ask the target application to attempt to connect to a third application | 226 // Ask the target application to attempt to connect to a third application |
| 236 // provided by a package whose id is permitted by the primary target's | 227 // provided by a package whose id is permitted by the primary target's |
| 237 // CapabilityFilter but whose package is not. The connection should be | 228 // CapabilityFilter but whose package is not. The connection should be |
| 238 // blocked and the returned title should be "uninitialized". | 229 // blocked and the returned title should be "uninitialized". |
| 239 TEST_F(ConnectTest, BlockedPackage) { | 230 TEST_F(ConnectTest, BlockedPackage) { |
| 240 scoped_ptr<Connection> connection = connector()->Connect(kTestAppName); | 231 scoped_ptr<Connection> connection = connector()->Connect(kTestAppName); |
| 241 test::mojom::StandaloneAppPtr standalone_app; | 232 test::mojom::StandaloneAppPtr standalone_app; |
| 242 connection->GetInterface(&standalone_app); | 233 connection->GetInterface(&standalone_app); |
| 243 base::RunLoop run_loop; | 234 base::RunLoop run_loop; |
| 244 std::string title; | 235 std::string title; |
| 245 standalone_app->ConnectToAllowedAppInBlockedPackage( | 236 standalone_app->ConnectToAllowedAppInBlockedPackage( |
| 246 base::Bind(&ReceiveOneString, &title, &run_loop)); | 237 base::Bind(&ReceiveTitle, &title, &run_loop)); |
| 247 run_loop.Run(); | 238 run_loop.Run(); |
| 248 EXPECT_EQ("uninitialized", title); | 239 EXPECT_EQ("uninitialized", title); |
| 249 } | 240 } |
| 250 | 241 |
| 251 // BlockedInterface should not be exposed to this application because it is not | 242 // BlockedInterface should not be exposed to this application because it is not |
| 252 // in our CapabilityFilter whitelist. | 243 // in our CapabilityFilter whitelist. |
| 253 TEST_F(ConnectTest, PackagedApp_BlockedInterface) { | 244 TEST_F(ConnectTest, PackagedApp_BlockedInterface) { |
| 254 scoped_ptr<Connection> connection = connector()->Connect(kTestAppAName); | 245 scoped_ptr<Connection> connection = connector()->Connect(kTestAppAName); |
| 255 base::RunLoop run_loop; | 246 base::RunLoop run_loop; |
| 256 test::mojom::BlockedInterfacePtr blocked; | 247 test::mojom::BlockedInterfacePtr blocked; |
| 257 connection->GetInterface(&blocked); | 248 connection->GetInterface(&blocked); |
| 258 blocked.set_connection_error_handler(base::Bind(&QuitLoop, &run_loop)); | 249 blocked.set_connection_error_handler(base::Bind(&QuitLoop, &run_loop)); |
| 259 run_loop.Run(); | 250 run_loop.Run(); |
| 260 } | 251 } |
| 261 | 252 |
| 262 // Connection to another application provided by the same package, blocked | 253 // Connection to another application provided by the same package, blocked |
| 263 // because it's not in the capability filter whitelist. | 254 // because it's not in the capability filter whitelist. |
| 264 TEST_F(ConnectTest, BlockedPackagedApplication) { | 255 TEST_F(ConnectTest, BlockedPackagedApplication) { |
| 265 scoped_ptr<Connection> connection = connector()->Connect(kTestAppBName); | 256 scoped_ptr<Connection> connection = connector()->Connect(kTestAppBName); |
| 266 test::mojom::ConnectTestServicePtr service_b; | 257 test::mojom::ConnectTestServicePtr service_b; |
| 267 connection->GetInterface(&service_b); | 258 connection->GetInterface(&service_b); |
| 268 base::RunLoop run_loop; | 259 base::RunLoop run_loop; |
| 269 connection->SetConnectionLostClosure(base::Bind(&QuitLoop, &run_loop)); | 260 connection->SetConnectionLostClosure(base::Bind(&QuitLoop, &run_loop)); |
| 270 run_loop.Run(); | 261 run_loop.Run(); |
| 271 EXPECT_FALSE(connection->IsPending()); | 262 EXPECT_FALSE(connection->IsPending()); |
| 272 EXPECT_EQ(mojom::ConnectResult::ACCESS_DENIED, connection->GetResult()); | 263 EXPECT_EQ(mojom::ConnectResult::ACCESS_DENIED, connection->GetResult()); |
| 273 EXPECT_EQ(mojom::kInvalidInstanceID, connection->GetRemoteInstanceID()); | 264 EXPECT_EQ(mojom::kInvalidInstanceID, connection->GetRemoteInstanceID()); |
| 274 } | 265 } |
| 275 | 266 |
| 276 TEST_F(ConnectTest, CapabilityClasses) { | |
| 277 scoped_ptr<Connection> connection = connector()->Connect(kTestAppName); | |
| 278 test::mojom::StandaloneAppPtr standalone_app; | |
| 279 connection->GetInterface(&standalone_app); | |
| 280 std::string string1, string2; | |
| 281 base::RunLoop loop; | |
| 282 standalone_app->ConnectToClassInterface( | |
| 283 base::Bind(&ReceiveTwoStrings, &string1, &string2, &loop)); | |
| 284 loop.Run(); | |
| 285 EXPECT_EQ("PONG", string1); | |
| 286 EXPECT_EQ("CLASS APP", string2); | |
| 287 } | |
| 288 | |
| 289 // Tests that we can expose an interface to targets on outbound connections. | 267 // Tests that we can expose an interface to targets on outbound connections. |
| 290 // TODO(beng): Currently all interfaces on outbound connections are exposed. | 268 // TODO(beng): Currently all interfaces on outbound connections are exposed. |
| 291 // See ConnectorImpl::Connect(). | 269 // See ConnectorImpl::Connect(). |
| 292 TEST_F(ConnectTest, LocalInterface) { | 270 TEST_F(ConnectTest, LocalInterface) { |
| 293 // Connect to a standalone application. | 271 // Connect to a standalone application. |
| 294 { | 272 { |
| 295 test::mojom::ConnectTestServicePtr service; | 273 test::mojom::ConnectTestServicePtr service; |
| 296 scoped_ptr<Connection> connection = connector()->Connect(kTestAppName); | 274 scoped_ptr<Connection> connection = connector()->Connect(kTestAppName); |
| 297 connection->GetInterface(&service); | 275 connection->GetInterface(&service); |
| 298 connection->AddInterface<test::mojom::ExposedInterface>(this); | 276 connection->AddInterface<test::mojom::ExposedInterface>(this); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 347 CompareConnectionState( | 325 CompareConnectionState( |
| 348 kTestAppAName, test_name(), test_userid(), test_instance_id(), | 326 kTestAppAName, test_name(), test_userid(), test_instance_id(), |
| 349 kTestAppAName, connection->GetRemoteIdentity().user_id(), remote_id); | 327 kTestAppAName, connection->GetRemoteIdentity().user_id(), remote_id); |
| 350 } | 328 } |
| 351 | 329 |
| 352 } | 330 } |
| 353 } | 331 } |
| 354 | 332 |
| 355 } // namespace shell | 333 } // namespace shell |
| 356 } // namespace mojo | 334 } // namespace mojo |
| OLD | NEW |