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