| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include <stdint.h> | |
| 6 | |
| 7 #include <utility> | |
| 8 | |
| 9 #include "base/at_exit.h" | |
| 10 #include "base/bind.h" | |
| 11 #include "base/macros.h" | |
| 12 #include "base/memory/scoped_vector.h" | |
| 13 #include "base/message_loop/message_loop.h" | |
| 14 #include "base/path_service.h" | |
| 15 #include "base/run_loop.h" | |
| 16 #include "mojo/public/cpp/bindings/strong_binding.h" | |
| 17 #include "mojo/shell/application_loader.h" | |
| 18 #include "mojo/shell/application_manager.h" | |
| 19 #include "mojo/shell/connect_util.h" | |
| 20 #include "mojo/shell/fetcher.h" | |
| 21 #include "mojo/shell/package_manager/package_manager_impl.h" | |
| 22 #include "mojo/shell/public/cpp/interface_factory.h" | |
| 23 #include "mojo/shell/public/cpp/shell_client.h" | |
| 24 #include "mojo/shell/public/cpp/shell_connection.h" | |
| 25 #include "mojo/shell/public/interfaces/content_handler.mojom.h" | |
| 26 #include "mojo/shell/public/interfaces/interface_provider.mojom.h" | |
| 27 #include "mojo/shell/test_package_manager.h" | |
| 28 #include "testing/gtest/include/gtest/gtest.h" | |
| 29 | |
| 30 namespace mojo { | |
| 31 namespace shell { | |
| 32 namespace test { | |
| 33 namespace { | |
| 34 | |
| 35 const char kTestMimeType[] = "test/mime-type"; | |
| 36 | |
| 37 class TestFetcher : public Fetcher { | |
| 38 public: | |
| 39 TestFetcher(const FetchCallback& fetch_callback, | |
| 40 const GURL& url, | |
| 41 const std::string& mime_type) | |
| 42 : Fetcher(fetch_callback), url_(url), mime_type_(mime_type) { | |
| 43 loader_callback_.Run(make_scoped_ptr(this)); | |
| 44 } | |
| 45 ~TestFetcher() override {} | |
| 46 | |
| 47 // Fetcher: | |
| 48 const GURL& GetURL() const override { return url_; } | |
| 49 GURL GetRedirectURL() const override { return GURL("yyy"); } | |
| 50 GURL GetRedirectReferer() const override { return GURL(); } | |
| 51 URLResponsePtr AsURLResponse(base::TaskRunner* task_runner, | |
| 52 uint32_t skip) override { | |
| 53 return URLResponse::New(); | |
| 54 } | |
| 55 void AsPath( | |
| 56 base::TaskRunner* task_runner, | |
| 57 base::Callback<void(const base::FilePath&, bool)> callback) override {} | |
| 58 std::string MimeType() override { return mime_type_; } | |
| 59 bool HasMojoMagic() override { return false; } | |
| 60 bool PeekFirstLine(std::string* line) override { return false; } | |
| 61 | |
| 62 private: | |
| 63 const GURL url_; | |
| 64 const std::string mime_type_; | |
| 65 | |
| 66 DISALLOW_COPY_AND_ASSIGN(TestFetcher); | |
| 67 }; | |
| 68 | |
| 69 void QuitClosure(bool* value) { | |
| 70 *value = true; | |
| 71 base::MessageLoop::current()->QuitWhenIdle(); | |
| 72 } | |
| 73 | |
| 74 class TestContentHandler : public mojom::ContentHandler, | |
| 75 public ShellClient { | |
| 76 public: | |
| 77 TestContentHandler(Connection* connection, | |
| 78 InterfaceRequest<mojom::ContentHandler> request) | |
| 79 : binding_(this, std::move(request)) {} | |
| 80 | |
| 81 // ContentHandler: | |
| 82 void StartApplication( | |
| 83 InterfaceRequest<mojom::ShellClient> request, | |
| 84 URLResponsePtr response, | |
| 85 const Callback<void()>& destruct_callback) override { | |
| 86 shell_connections_.push_back(new ShellConnection(this, std::move(request))); | |
| 87 destruct_callback.Run(); | |
| 88 } | |
| 89 | |
| 90 private: | |
| 91 StrongBinding<mojom::ContentHandler> binding_; | |
| 92 ScopedVector<ShellConnection> shell_connections_; | |
| 93 | |
| 94 DISALLOW_COPY_AND_ASSIGN(TestContentHandler); | |
| 95 }; | |
| 96 | |
| 97 class TestApplicationLoader : public ApplicationLoader, | |
| 98 public ShellClient, | |
| 99 public InterfaceFactory<mojom::ContentHandler> { | |
| 100 public: | |
| 101 TestApplicationLoader() : num_loads_(0) {} | |
| 102 ~TestApplicationLoader() override {} | |
| 103 | |
| 104 int num_loads() const { return num_loads_; } | |
| 105 const GURL& last_requestor_url() const { return last_requestor_url_; } | |
| 106 | |
| 107 private: | |
| 108 // ApplicationLoader implementation. | |
| 109 void Load(const GURL& url, | |
| 110 InterfaceRequest<mojom::ShellClient> request) override { | |
| 111 ++num_loads_; | |
| 112 shell_connection_.reset(new ShellConnection(this, std::move(request))); | |
| 113 } | |
| 114 | |
| 115 // mojo::ShellClient implementation. | |
| 116 bool AcceptConnection(Connection* connection) override { | |
| 117 connection->AddInterface<mojom::ContentHandler>(this); | |
| 118 last_requestor_url_ = GURL(connection->GetRemoteApplicationURL()); | |
| 119 return true; | |
| 120 } | |
| 121 // InterfaceFactory<mojom::ContentHandler> implementation. | |
| 122 void Create(Connection* connection, | |
| 123 InterfaceRequest<mojom::ContentHandler> request) override { | |
| 124 new TestContentHandler(connection, std::move(request)); | |
| 125 } | |
| 126 | |
| 127 scoped_ptr<ShellConnection> shell_connection_; | |
| 128 int num_loads_; | |
| 129 GURL last_requestor_url_; | |
| 130 | |
| 131 DISALLOW_COPY_AND_ASSIGN(TestApplicationLoader); | |
| 132 }; | |
| 133 | |
| 134 class TestPackageManagerImpl : public PackageManagerImpl { | |
| 135 public: | |
| 136 explicit TestPackageManagerImpl(const base::FilePath& package_path) | |
| 137 : PackageManagerImpl(package_path, nullptr, nullptr), | |
| 138 mime_type_(kTestMimeType) {} | |
| 139 ~TestPackageManagerImpl() override {} | |
| 140 | |
| 141 void set_mime_type(const std::string& mime_type) { | |
| 142 mime_type_ = mime_type; | |
| 143 } | |
| 144 | |
| 145 // PackageManagerImpl: | |
| 146 void FetchRequest( | |
| 147 URLRequestPtr request, | |
| 148 const Fetcher::FetchCallback& loader_callback) override { | |
| 149 new TestFetcher(loader_callback, GURL(request->url.get()), mime_type_); | |
| 150 } | |
| 151 | |
| 152 private: | |
| 153 std::string mime_type_; | |
| 154 | |
| 155 DISALLOW_COPY_AND_ASSIGN(TestPackageManagerImpl); | |
| 156 }; | |
| 157 | |
| 158 } // namespace | |
| 159 | |
| 160 class ContentHandlerTest : public testing::Test { | |
| 161 public: | |
| 162 ContentHandlerTest() | |
| 163 : content_handler_url_("http://test.content.handler"), | |
| 164 requestor_url_("http://requestor.url") {} | |
| 165 ~ContentHandlerTest() override {} | |
| 166 | |
| 167 void SetUp() override { | |
| 168 base::FilePath shell_dir; | |
| 169 PathService::Get(base::DIR_MODULE, &shell_dir); | |
| 170 test_package_manager_ = new TestPackageManagerImpl(shell_dir); | |
| 171 test_package_manager_->RegisterContentHandler(kTestMimeType, | |
| 172 content_handler_url_); | |
| 173 application_manager_.reset(new ApplicationManager( | |
| 174 make_scoped_ptr(test_package_manager_), true)); | |
| 175 } | |
| 176 | |
| 177 void TearDown() override { | |
| 178 test_package_manager_ = nullptr; | |
| 179 application_manager_.reset(); | |
| 180 } | |
| 181 | |
| 182 protected: | |
| 183 const GURL content_handler_url_; | |
| 184 const GURL requestor_url_; | |
| 185 | |
| 186 base::MessageLoop loop_; | |
| 187 scoped_ptr<ApplicationManager> application_manager_; | |
| 188 // Owned by ApplicationManager. | |
| 189 TestPackageManagerImpl* test_package_manager_; | |
| 190 | |
| 191 DISALLOW_COPY_AND_ASSIGN(ContentHandlerTest); | |
| 192 }; | |
| 193 | |
| 194 TEST_F(ContentHandlerTest, ContentHandlerConnectionGetsRequestorURL) { | |
| 195 TestApplicationLoader* loader = new TestApplicationLoader; | |
| 196 application_manager_->SetLoaderForURL( | |
| 197 scoped_ptr<ApplicationLoader>(loader), | |
| 198 content_handler_url_); | |
| 199 | |
| 200 bool called = false; | |
| 201 scoped_ptr<ConnectToApplicationParams> params(new ConnectToApplicationParams); | |
| 202 params->set_source(Identity(requestor_url_)); | |
| 203 params->SetTargetURL(GURL("test:test")); | |
| 204 params->set_on_application_end( | |
| 205 base::Bind(&QuitClosure, base::Unretained(&called))); | |
| 206 application_manager_->ConnectToApplication(std::move(params)); | |
| 207 loop_.Run(); | |
| 208 EXPECT_TRUE(called); | |
| 209 | |
| 210 ASSERT_EQ(1, loader->num_loads()); | |
| 211 EXPECT_EQ(requestor_url_, loader->last_requestor_url()); | |
| 212 } | |
| 213 | |
| 214 TEST_F(ContentHandlerTest, | |
| 215 MultipleConnectionsToContentHandlerGetSameContentHandlerId) { | |
| 216 TestApplicationLoader* content_handler_loader = new TestApplicationLoader; | |
| 217 application_manager_->SetLoaderForURL( | |
| 218 scoped_ptr<ApplicationLoader>(content_handler_loader), | |
| 219 content_handler_url_); | |
| 220 | |
| 221 uint32_t content_handler_id; | |
| 222 { | |
| 223 base::RunLoop run_loop; | |
| 224 scoped_ptr<ConnectToApplicationParams> params( | |
| 225 new ConnectToApplicationParams); | |
| 226 params->set_source(Identity(requestor_url_)); | |
| 227 params->SetTargetURL(GURL("test:test")); | |
| 228 params->set_connect_callback( | |
| 229 [&content_handler_id, &run_loop](uint32_t, uint32_t t) { | |
| 230 content_handler_id = t; | |
| 231 run_loop.Quit(); | |
| 232 }); | |
| 233 application_manager_->ConnectToApplication(std::move(params)); | |
| 234 run_loop.Run(); | |
| 235 EXPECT_NE(mojom::Shell::kInvalidApplicationID, content_handler_id); | |
| 236 } | |
| 237 | |
| 238 uint32_t content_handler_id2; | |
| 239 { | |
| 240 base::RunLoop run_loop; | |
| 241 scoped_ptr<ConnectToApplicationParams> params( | |
| 242 new ConnectToApplicationParams); | |
| 243 params->set_source(Identity(requestor_url_)); | |
| 244 params->SetTargetURL(GURL("test:test")); | |
| 245 params->set_connect_callback( | |
| 246 [&content_handler_id2, &run_loop](uint32_t, uint32_t t) { | |
| 247 content_handler_id2 = t; | |
| 248 run_loop.Quit(); | |
| 249 }); | |
| 250 application_manager_->ConnectToApplication(std::move(params)); | |
| 251 run_loop.Run(); | |
| 252 EXPECT_NE(mojom::Shell::kInvalidApplicationID, content_handler_id2); | |
| 253 } | |
| 254 EXPECT_EQ(content_handler_id, content_handler_id2); | |
| 255 } | |
| 256 | |
| 257 TEST_F(ContentHandlerTest, DifferedContentHandlersGetDifferentIDs) { | |
| 258 TestApplicationLoader* content_handler_loader = new TestApplicationLoader; | |
| 259 application_manager_->SetLoaderForURL( | |
| 260 scoped_ptr<ApplicationLoader>(content_handler_loader), | |
| 261 content_handler_url_); | |
| 262 | |
| 263 uint32_t content_handler_id; | |
| 264 { | |
| 265 base::RunLoop run_loop; | |
| 266 scoped_ptr<ConnectToApplicationParams> params( | |
| 267 new ConnectToApplicationParams); | |
| 268 params->set_source(Identity(requestor_url_)); | |
| 269 params->SetTargetURL(GURL("test:test")); | |
| 270 params->set_connect_callback( | |
| 271 [&content_handler_id, &run_loop](uint32_t, uint32_t t) { | |
| 272 content_handler_id = t; | |
| 273 run_loop.Quit(); | |
| 274 }); | |
| 275 application_manager_->ConnectToApplication(std::move(params)); | |
| 276 run_loop.Run(); | |
| 277 EXPECT_NE(mojom::Shell::kInvalidApplicationID, content_handler_id); | |
| 278 } | |
| 279 | |
| 280 const std::string mime_type2 = "test/mime-type2"; | |
| 281 const GURL content_handler_url2("http://test.content.handler2"); | |
| 282 test_package_manager_->set_mime_type(mime_type2); | |
| 283 test_package_manager_->RegisterContentHandler(mime_type2, | |
| 284 content_handler_url2); | |
| 285 | |
| 286 TestApplicationLoader* content_handler_loader2 = new TestApplicationLoader; | |
| 287 application_manager_->SetLoaderForURL( | |
| 288 scoped_ptr<ApplicationLoader>(content_handler_loader2), | |
| 289 content_handler_url2); | |
| 290 | |
| 291 uint32_t content_handler_id2; | |
| 292 { | |
| 293 base::RunLoop run_loop; | |
| 294 scoped_ptr<ConnectToApplicationParams> params( | |
| 295 new ConnectToApplicationParams); | |
| 296 params->set_source(Identity(requestor_url_)); | |
| 297 params->SetTargetURL(GURL("test2:test2")); | |
| 298 params->set_connect_callback( | |
| 299 [&content_handler_id2, &run_loop](uint32_t, uint32_t t) { | |
| 300 content_handler_id2 = t; | |
| 301 run_loop.Quit(); | |
| 302 }); | |
| 303 application_manager_->ConnectToApplication(std::move(params)); | |
| 304 run_loop.Run(); | |
| 305 EXPECT_NE(mojom::Shell::kInvalidApplicationID, content_handler_id2); | |
| 306 } | |
| 307 EXPECT_NE(content_handler_id, content_handler_id2); | |
| 308 } | |
| 309 | |
| 310 TEST_F(ContentHandlerTest, | |
| 311 ConnectWithNoContentHandlerGetsInvalidContentHandlerId) { | |
| 312 application_manager_->SetLoaderForURL( | |
| 313 scoped_ptr<ApplicationLoader>(new TestApplicationLoader), | |
| 314 GURL("test:test")); | |
| 315 | |
| 316 uint32_t content_handler_id = 1u; | |
| 317 scoped_ptr<ConnectToApplicationParams> params( | |
| 318 new ConnectToApplicationParams); | |
| 319 params->SetTargetURL(GURL("test:test")); | |
| 320 params->set_connect_callback( | |
| 321 [&content_handler_id](uint32_t, uint32_t t) { content_handler_id = t; }); | |
| 322 application_manager_->ConnectToApplication(std::move(params)); | |
| 323 EXPECT_EQ(0u, content_handler_id); | |
| 324 } | |
| 325 | |
| 326 } // namespace test | |
| 327 } // namespace package_manager | |
| 328 } // namespace mojo | |
| OLD | NEW |