OLD | NEW |
(Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "base/compiler_specific.h" |
| 6 #include "base/message_loop/message_loop.h" |
| 7 #include "base/strings/string_tokenizer.h" |
| 8 #include "mojo/public/cpp/application/application.h" |
| 9 #include "mojo/services/public/interfaces/launcher/launcher.mojom.h" |
| 10 #include "mojo/services/public/interfaces/network/network_service.mojom.h" |
| 11 #include "mojo/services/public/interfaces/network/url_loader.mojom.h" |
| 12 |
| 13 namespace mojo { |
| 14 namespace launcher { |
| 15 |
| 16 class LauncherApp; |
| 17 |
| 18 class LauncherConnection : public InterfaceImpl<Launcher> { |
| 19 public: |
| 20 explicit LauncherConnection(LauncherApp* app) : app_(app) {} |
| 21 virtual ~LauncherConnection() {} |
| 22 |
| 23 private: |
| 24 // Overridden from Launcher: |
| 25 virtual void Launch(const String& url) OVERRIDE; |
| 26 |
| 27 LauncherApp* app_; |
| 28 |
| 29 DISALLOW_COPY_AND_ASSIGN(LauncherConnection); |
| 30 }; |
| 31 |
| 32 class Launch : public URLLoaderClient { |
| 33 public: |
| 34 Launch(LauncherApp* app, const String& url); |
| 35 virtual ~Launch() {} |
| 36 |
| 37 private: |
| 38 // Overridden from URLLoaderClient: |
| 39 virtual void OnReceivedRedirect(URLResponsePtr response, |
| 40 const String& new_url, |
| 41 const String& new_method) OVERRIDE { |
| 42 } |
| 43 virtual void OnReceivedResponse(URLResponsePtr response) OVERRIDE; |
| 44 virtual void OnReceivedError(NetworkErrorPtr error) OVERRIDE { |
| 45 ScheduleDestroy(); |
| 46 } |
| 47 virtual void OnReceivedEndOfResponseBody() OVERRIDE { |
| 48 ScheduleDestroy(); |
| 49 } |
| 50 |
| 51 std::string GetContentType(const Array<String>& headers) { |
| 52 for (size_t i = 0; i < headers.size(); ++i) { |
| 53 base::StringTokenizer t(headers[i], ": ;="); |
| 54 while (t.GetNext()) { |
| 55 if (!t.token_is_delim() && t.token() == "Content-Type") { |
| 56 while (t.GetNext()) { |
| 57 if (!t.token_is_delim()) |
| 58 return t.token(); |
| 59 } |
| 60 } |
| 61 } |
| 62 } |
| 63 return ""; |
| 64 } |
| 65 |
| 66 void ScheduleDestroy() { |
| 67 if (destroy_scheduled_) |
| 68 return; |
| 69 destroy_scheduled_ = true; |
| 70 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
| 71 } |
| 72 |
| 73 LauncherApp* app_; |
| 74 bool destroy_scheduled_; |
| 75 URLLoaderPtr url_loader_; |
| 76 ScopedDataPipeConsumerHandle response_body_stream_; |
| 77 LaunchablePtr launchable_; |
| 78 |
| 79 DISALLOW_COPY_AND_ASSIGN(Launch); |
| 80 }; |
| 81 |
| 82 class LauncherApp : public Application { |
| 83 public: |
| 84 LauncherApp() { |
| 85 handler_map_["text/html"] = "mojo:mojo_html_viewer"; |
| 86 handler_map_["image/png"] = "mojo:mojo_image_viewer"; |
| 87 } |
| 88 virtual ~LauncherApp() {} |
| 89 |
| 90 void LaunchURL(const String& url) { |
| 91 new Launch(this, url); |
| 92 } |
| 93 |
| 94 URLLoaderPtr CreateURLLoader() { |
| 95 URLLoaderPtr loader; |
| 96 network_service_->CreateURLLoader(Get(&loader)); |
| 97 return loader.Pass(); |
| 98 } |
| 99 |
| 100 std::string GetHandlerForContentType(const std::string& content_type) { |
| 101 HandlerMap::const_iterator it = handler_map_.find(content_type); |
| 102 return it != handler_map_.end() ? it->second : ""; |
| 103 } |
| 104 |
| 105 private: |
| 106 typedef std::map<std::string, std::string> HandlerMap; |
| 107 |
| 108 // Overridden from Application: |
| 109 virtual void Initialize() OVERRIDE { |
| 110 AddService<LauncherConnection>(this); |
| 111 ConnectTo("mojo:mojo_network_service", &network_service_); |
| 112 } |
| 113 |
| 114 HandlerMap handler_map_; |
| 115 |
| 116 NetworkServicePtr network_service_; |
| 117 |
| 118 DISALLOW_COPY_AND_ASSIGN(LauncherApp); |
| 119 }; |
| 120 |
| 121 void LauncherConnection::Launch(const String& url) { |
| 122 app_->LaunchURL(url); |
| 123 } |
| 124 |
| 125 Launch::Launch(LauncherApp* app, const String& url) |
| 126 : app_(app), |
| 127 destroy_scheduled_(false) { |
| 128 url_loader_ = app_->CreateURLLoader(); |
| 129 url_loader_.set_client(this); |
| 130 |
| 131 URLRequestPtr request(URLRequest::New()); |
| 132 request->url = url; |
| 133 request->method = "GET"; |
| 134 request->auto_follow_redirects = true; |
| 135 |
| 136 DataPipe data_pipe; |
| 137 response_body_stream_ = data_pipe.consumer_handle.Pass(); |
| 138 |
| 139 url_loader_->Start(request.Pass(), data_pipe.producer_handle.Pass()); |
| 140 } |
| 141 |
| 142 void Launch::OnReceivedResponse(URLResponsePtr response) { |
| 143 std::string content_type = GetContentType(response->headers); |
| 144 printf("content_type: %s\n", content_type.c_str()); |
| 145 std::string handler_url = app_->GetHandlerForContentType(content_type); |
| 146 if (!handler_url.empty()) { |
| 147 app_->ConnectTo(handler_url, &launchable_); |
| 148 launchable_->OnLaunch(response.Pass(), response_body_stream_.Pass()); |
| 149 } |
| 150 ScheduleDestroy(); |
| 151 } |
| 152 |
| 153 } // namespace launcher |
| 154 |
| 155 // static |
| 156 Application* Application::Create() { |
| 157 return new launcher::LauncherApp; |
| 158 } |
| 159 |
| 160 } // namespace mojo |
OLD | NEW |