| Index: mojo/services/launcher/launcher.cc
|
| diff --git a/mojo/services/launcher/launcher.cc b/mojo/services/launcher/launcher.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..5a6bba42888c88d949fabe67c4b3b0b6359ba400
|
| --- /dev/null
|
| +++ b/mojo/services/launcher/launcher.cc
|
| @@ -0,0 +1,160 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "base/compiler_specific.h"
|
| +#include "base/message_loop/message_loop.h"
|
| +#include "base/strings/string_tokenizer.h"
|
| +#include "mojo/public/cpp/application/application.h"
|
| +#include "mojo/services/public/interfaces/launcher/launcher.mojom.h"
|
| +#include "mojo/services/public/interfaces/network/network_service.mojom.h"
|
| +#include "mojo/services/public/interfaces/network/url_loader.mojom.h"
|
| +
|
| +namespace mojo {
|
| +namespace launcher {
|
| +
|
| +class LauncherApp;
|
| +
|
| +class LauncherConnection : public InterfaceImpl<Launcher> {
|
| + public:
|
| + explicit LauncherConnection(LauncherApp* app) : app_(app) {}
|
| + virtual ~LauncherConnection() {}
|
| +
|
| + private:
|
| + // Overridden from Launcher:
|
| + virtual void Launch(const String& url) OVERRIDE;
|
| +
|
| + LauncherApp* app_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(LauncherConnection);
|
| +};
|
| +
|
| +class Launch : public URLLoaderClient {
|
| + public:
|
| + Launch(LauncherApp* app, const String& url);
|
| + virtual ~Launch() {}
|
| +
|
| + private:
|
| + // Overridden from URLLoaderClient:
|
| + virtual void OnReceivedRedirect(URLResponsePtr response,
|
| + const String& new_url,
|
| + const String& new_method) OVERRIDE {
|
| + }
|
| + virtual void OnReceivedResponse(URLResponsePtr response) OVERRIDE;
|
| + virtual void OnReceivedError(NetworkErrorPtr error) OVERRIDE {
|
| + ScheduleDestroy();
|
| + }
|
| + virtual void OnReceivedEndOfResponseBody() OVERRIDE {
|
| + ScheduleDestroy();
|
| + }
|
| +
|
| + std::string GetContentType(const Array<String>& headers) {
|
| + for (size_t i = 0; i < headers.size(); ++i) {
|
| + base::StringTokenizer t(headers[i], ": ;=");
|
| + while (t.GetNext()) {
|
| + if (!t.token_is_delim() && t.token() == "Content-Type") {
|
| + while (t.GetNext()) {
|
| + if (!t.token_is_delim())
|
| + return t.token();
|
| + }
|
| + }
|
| + }
|
| + }
|
| + return "";
|
| + }
|
| +
|
| + void ScheduleDestroy() {
|
| + if (destroy_scheduled_)
|
| + return;
|
| + destroy_scheduled_ = true;
|
| + base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
|
| + }
|
| +
|
| + LauncherApp* app_;
|
| + bool destroy_scheduled_;
|
| + URLLoaderPtr url_loader_;
|
| + ScopedDataPipeConsumerHandle response_body_stream_;
|
| + LaunchablePtr launchable_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(Launch);
|
| +};
|
| +
|
| +class LauncherApp : public Application {
|
| + public:
|
| + LauncherApp() {
|
| + handler_map_["text/html"] = "mojo:mojo_html_viewer";
|
| + handler_map_["image/png"] = "mojo:mojo_image_viewer";
|
| + }
|
| + virtual ~LauncherApp() {}
|
| +
|
| + void LaunchURL(const String& url) {
|
| + new Launch(this, url);
|
| + }
|
| +
|
| + URLLoaderPtr CreateURLLoader() {
|
| + URLLoaderPtr loader;
|
| + network_service_->CreateURLLoader(Get(&loader));
|
| + return loader.Pass();
|
| + }
|
| +
|
| + std::string GetHandlerForContentType(const std::string& content_type) {
|
| + HandlerMap::const_iterator it = handler_map_.find(content_type);
|
| + return it != handler_map_.end() ? it->second : "";
|
| + }
|
| +
|
| + private:
|
| + typedef std::map<std::string, std::string> HandlerMap;
|
| +
|
| + // Overridden from Application:
|
| + virtual void Initialize() OVERRIDE {
|
| + AddService<LauncherConnection>(this);
|
| + ConnectTo("mojo:mojo_network_service", &network_service_);
|
| + }
|
| +
|
| + HandlerMap handler_map_;
|
| +
|
| + NetworkServicePtr network_service_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(LauncherApp);
|
| +};
|
| +
|
| +void LauncherConnection::Launch(const String& url) {
|
| + app_->LaunchURL(url);
|
| +}
|
| +
|
| +Launch::Launch(LauncherApp* app, const String& url)
|
| + : app_(app),
|
| + destroy_scheduled_(false) {
|
| + url_loader_ = app_->CreateURLLoader();
|
| + url_loader_.set_client(this);
|
| +
|
| + URLRequestPtr request(URLRequest::New());
|
| + request->url = url;
|
| + request->method = "GET";
|
| + request->auto_follow_redirects = true;
|
| +
|
| + DataPipe data_pipe;
|
| + response_body_stream_ = data_pipe.consumer_handle.Pass();
|
| +
|
| + url_loader_->Start(request.Pass(), data_pipe.producer_handle.Pass());
|
| +}
|
| +
|
| +void Launch::OnReceivedResponse(URLResponsePtr response) {
|
| + std::string content_type = GetContentType(response->headers);
|
| + printf("content_type: %s\n", content_type.c_str());
|
| + std::string handler_url = app_->GetHandlerForContentType(content_type);
|
| + if (!handler_url.empty()) {
|
| + app_->ConnectTo(handler_url, &launchable_);
|
| + launchable_->OnLaunch(response.Pass(), response_body_stream_.Pass());
|
| + }
|
| + ScheduleDestroy();
|
| +}
|
| +
|
| +} // namespace launcher
|
| +
|
| +// static
|
| +Application* Application::Create() {
|
| + return new launcher::LauncherApp;
|
| +}
|
| +
|
| +} // namespace mojo
|
|
|