OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "shell/context.h" | 5 #include "shell/context.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/base_switches.h" | 9 #include "base/base_switches.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
48 embedder::Init(scoped_ptr<mojo::embedder::PlatformSupport>( | 48 embedder::Init(scoped_ptr<mojo::embedder::PlatformSupport>( |
49 new mojo::embedder::SimplePlatformSupport())); | 49 new mojo::embedder::SimplePlatformSupport())); |
50 } | 50 } |
51 | 51 |
52 ~Setup() {} | 52 ~Setup() {} |
53 | 53 |
54 private: | 54 private: |
55 DISALLOW_COPY_AND_ASSIGN(Setup); | 55 DISALLOW_COPY_AND_ASSIGN(Setup); |
56 }; | 56 }; |
57 | 57 |
| 58 bool ConfigureURLMappings(const base::CommandLine& command_line, |
| 59 Context* context) { |
| 60 URLResolver* resolver = context->url_resolver(); |
| 61 |
| 62 // Configure the resolution of unknown mojo: URLs. |
| 63 GURL base_url; |
| 64 if (command_line.HasSwitch(switches::kOrigin)) |
| 65 base_url = GURL(command_line.GetSwitchValueASCII(switches::kOrigin)); |
| 66 else |
| 67 // Use the shell's file root if the base was not specified. |
| 68 base_url = context->ResolveShellFileURL(""); |
| 69 |
| 70 if (!base_url.is_valid()) |
| 71 return false; |
| 72 |
| 73 resolver->SetMojoBaseURL(base_url); |
| 74 |
| 75 // The network service must be loaded from the filesystem. |
| 76 // This mapping is done before the command line URL mapping are processed, so |
| 77 // that it can be overridden. |
| 78 resolver->AddURLMapping( |
| 79 GURL("mojo:network_service"), |
| 80 context->ResolveShellFileURL("file:network_service.mojo")); |
| 81 |
| 82 // Temporary mapping to avoid workflow breakages after app rename. |
| 83 resolver->AddURLMapping(GURL("mojo:sample_app"), GURL("mojo:spinning_cube")); |
| 84 |
| 85 // Command line URL mapping. |
| 86 std::vector<URLResolver::OriginMapping> origin_mappings = |
| 87 URLResolver::GetOriginMappings(command_line.argv()); |
| 88 for (const auto& origin_mapping : origin_mappings) |
| 89 resolver->AddOriginMapping(GURL(origin_mapping.origin), |
| 90 GURL(origin_mapping.base_url)); |
| 91 |
| 92 if (command_line.HasSwitch(switches::kURLMappings)) { |
| 93 const std::string mappings = |
| 94 command_line.GetSwitchValueASCII(switches::kURLMappings); |
| 95 |
| 96 base::StringPairs pairs; |
| 97 if (!base::SplitStringIntoKeyValuePairs(mappings, '=', ',', &pairs)) |
| 98 return false; |
| 99 using StringPair = std::pair<std::string, std::string>; |
| 100 for (const StringPair& pair : pairs) { |
| 101 const GURL from(pair.first); |
| 102 const GURL to = context->ResolveCommandLineURL(pair.second); |
| 103 if (!from.is_valid() || !to.is_valid()) |
| 104 return false; |
| 105 resolver->AddURLMapping(from, to); |
| 106 } |
| 107 } |
| 108 return true; |
| 109 } |
| 110 |
58 void InitContentHandlers(ApplicationManager* manager, | 111 void InitContentHandlers(ApplicationManager* manager, |
59 base::CommandLine* command_line) { | 112 const base::CommandLine& command_line) { |
60 // Default content handlers. | 113 // Default content handlers. |
61 manager->RegisterContentHandler("application/pdf", GURL("mojo:pdf_viewer")); | 114 manager->RegisterContentHandler("application/pdf", GURL("mojo:pdf_viewer")); |
62 manager->RegisterContentHandler("image/png", GURL("mojo:png_viewer")); | 115 manager->RegisterContentHandler("image/png", GURL("mojo:png_viewer")); |
63 manager->RegisterContentHandler("text/html", GURL("mojo:html_viewer")); | 116 manager->RegisterContentHandler("text/html", GURL("mojo:html_viewer")); |
64 | 117 |
65 // Command-line-specified content handlers. | 118 // Command-line-specified content handlers. |
66 std::string handlers_spec = | 119 std::string handlers_spec = |
67 command_line->GetSwitchValueASCII(switches::kContentHandlers); | 120 command_line.GetSwitchValueASCII(switches::kContentHandlers); |
68 if (handlers_spec.empty()) | 121 if (handlers_spec.empty()) |
69 return; | 122 return; |
70 | 123 |
71 #if defined(OS_ANDROID) | 124 #if defined(OS_ANDROID) |
72 // TODO(eseidel): On Android we pass command line arguments is via the | 125 // TODO(eseidel): On Android we pass command line arguments is via the |
73 // 'parameters' key on the intent, which we specify during 'am shell start' | 126 // 'parameters' key on the intent, which we specify during 'am shell start' |
74 // via --esa, however that expects comma-separated values and says: | 127 // via --esa, however that expects comma-separated values and says: |
75 // am shell --help: | 128 // am shell --help: |
76 // [--esa <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]] | 129 // [--esa <EXTRA_KEY> <EXTRA_STRING_VALUE>[,<EXTRA_STRING_VALUE...]] |
77 // (to embed a comma into a string escape it using "\,") | 130 // (to embed a comma into a string escape it using "\,") |
(...skipping 17 matching lines...) Expand all Loading... |
95 LOG(ERROR) << "Invalid value for switch " << switches::kContentHandlers | 148 LOG(ERROR) << "Invalid value for switch " << switches::kContentHandlers |
96 << ": '" << parts[i + 1] << "' is not a valid URL."; | 149 << ": '" << parts[i + 1] << "' is not a valid URL."; |
97 return; | 150 return; |
98 } | 151 } |
99 // TODO(eseidel): We should also validate that the mimetype is valid | 152 // TODO(eseidel): We should also validate that the mimetype is valid |
100 // net/base/mime_util.h could do this, but we don't want to depend on net. | 153 // net/base/mime_util.h could do this, but we don't want to depend on net. |
101 manager->RegisterContentHandler(parts[i], url); | 154 manager->RegisterContentHandler(parts[i], url); |
102 } | 155 } |
103 } | 156 } |
104 | 157 |
105 bool ConfigureURLMappings(base::CommandLine* command_line, Context* context) { | 158 void InitNativeOptions(ApplicationManager* manager, |
106 URLResolver* resolver = context->url_resolver(); | 159 const base::CommandLine& command_line) { |
| 160 std::vector<std::string> force_in_process_url_list; |
| 161 base::SplitString(command_line.GetSwitchValueASCII(switches::kForceInProcess), |
| 162 ',', &force_in_process_url_list); |
| 163 for (const auto& force_in_process_url : force_in_process_url_list) { |
| 164 GURL gurl(force_in_process_url); |
| 165 if (!gurl.is_valid()) { |
| 166 LOG(ERROR) << "Invalid value for switch " << switches::kForceInProcess |
| 167 << ": '" << force_in_process_url << "'is not a valid URL."; |
| 168 return; |
| 169 } |
107 | 170 |
108 // Configure the resolution of unknown mojo: URLs. | 171 NativeRunnerFactory::Options options; |
109 GURL base_url; | 172 options.force_in_process = true; |
110 if (command_line->HasSwitch(switches::kOrigin)) | 173 manager->SetNativeOptionsForURL(options, gurl); |
111 base_url = GURL(command_line->GetSwitchValueASCII(switches::kOrigin)); | |
112 else | |
113 // Use the shell's file root if the base was not specified. | |
114 base_url = context->ResolveShellFileURL(""); | |
115 | |
116 if (!base_url.is_valid()) | |
117 return false; | |
118 | |
119 resolver->SetMojoBaseURL(base_url); | |
120 | |
121 // The network service must be loaded from the filesystem. | |
122 // This mapping is done before the command line URL mapping are processed, so | |
123 // that it can be overridden. | |
124 resolver->AddURLMapping( | |
125 GURL("mojo:network_service"), | |
126 context->ResolveShellFileURL("file:network_service.mojo")); | |
127 | |
128 // Temporary mapping to avoid workflow breakages after app rename. | |
129 resolver->AddURLMapping(GURL("mojo:sample_app"), GURL("mojo:spinning_cube")); | |
130 | |
131 // Command line URL mapping. | |
132 std::vector<URLResolver::OriginMapping> origin_mappings = | |
133 URLResolver::GetOriginMappings(command_line->argv()); | |
134 for (const auto& origin_mapping : origin_mappings) | |
135 resolver->AddOriginMapping(GURL(origin_mapping.origin), | |
136 GURL(origin_mapping.base_url)); | |
137 | |
138 if (command_line->HasSwitch(switches::kURLMappings)) { | |
139 const std::string mappings = | |
140 command_line->GetSwitchValueASCII(switches::kURLMappings); | |
141 | |
142 base::StringPairs pairs; | |
143 if (!base::SplitStringIntoKeyValuePairs(mappings, '=', ',', &pairs)) | |
144 return false; | |
145 using StringPair = std::pair<std::string, std::string>; | |
146 for (const StringPair& pair : pairs) { | |
147 const GURL from(pair.first); | |
148 const GURL to = context->ResolveCommandLineURL(pair.second); | |
149 if (!from.is_valid() || !to.is_valid()) | |
150 return false; | |
151 resolver->AddURLMapping(from, to); | |
152 } | |
153 } | 174 } |
154 return true; | |
155 } | 175 } |
156 | 176 |
157 class TracingServiceProvider : public ServiceProvider { | 177 class TracingServiceProvider : public ServiceProvider { |
158 public: | 178 public: |
159 explicit TracingServiceProvider(InterfaceRequest<ServiceProvider> request) | 179 explicit TracingServiceProvider(InterfaceRequest<ServiceProvider> request) |
160 : binding_(this, request.Pass()) {} | 180 : binding_(this, request.Pass()) {} |
161 ~TracingServiceProvider() override {} | 181 ~TracingServiceProvider() override {} |
162 | 182 |
163 void ConnectToService(const mojo::String& service_name, | 183 void ConnectToService(const mojo::String& service_name, |
164 ScopedMessagePipeHandle client_handle) override { | 184 ScopedMessagePipeHandle client_handle) override { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 | 231 |
212 void Context::SetCommandLineCWD(const base::FilePath& path) { | 232 void Context::SetCommandLineCWD(const base::FilePath& path) { |
213 command_line_cwd_ = AddTrailingSlashIfNeeded(FilePathToFileURL(path)); | 233 command_line_cwd_ = AddTrailingSlashIfNeeded(FilePathToFileURL(path)); |
214 } | 234 } |
215 | 235 |
216 GURL Context::ResolveCommandLineURL(const std::string& path) { | 236 GURL Context::ResolveCommandLineURL(const std::string& path) { |
217 return command_line_cwd_.Resolve(path); | 237 return command_line_cwd_.Resolve(path); |
218 } | 238 } |
219 | 239 |
220 bool Context::Init() { | 240 bool Context::Init() { |
221 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); | 241 const base::CommandLine& command_line = |
| 242 *base::CommandLine::ForCurrentProcess(); |
222 | 243 |
223 if (command_line->HasSwitch(switches::kWaitForDebugger)) | 244 if (command_line.HasSwitch(switches::kWaitForDebugger)) |
224 base::debug::WaitForDebugger(60, true); | 245 base::debug::WaitForDebugger(60, true); |
225 | 246 |
226 EnsureEmbedderIsInitialized(); | 247 EnsureEmbedderIsInitialized(); |
227 task_runners_.reset( | 248 task_runners_.reset( |
228 new TaskRunners(base::MessageLoop::current()->message_loop_proxy())); | 249 new TaskRunners(base::MessageLoop::current()->message_loop_proxy())); |
229 | 250 |
230 // TODO(vtl): Probably these failures should be checked before |Init()|, and | 251 // TODO(vtl): Probably these failures should be checked before |Init()|, and |
231 // this function simply shouldn't fail. | 252 // this function simply shouldn't fail. |
232 if (!shell_file_root_.is_valid()) | 253 if (!shell_file_root_.is_valid()) |
233 return false; | 254 return false; |
234 if (!ConfigureURLMappings(command_line, this)) | 255 if (!ConfigureURLMappings(command_line, this)) |
235 return false; | 256 return false; |
236 | 257 |
237 // TODO(vtl): This should be MASTER, not NONE. | 258 // TODO(vtl): This should be MASTER, not NONE. |
238 embedder::InitIPCSupport( | 259 embedder::InitIPCSupport( |
239 embedder::ProcessType::NONE, task_runners_->shell_runner(), this, | 260 embedder::ProcessType::NONE, task_runners_->shell_runner(), this, |
240 task_runners_->io_runner(), embedder::ScopedPlatformHandle()); | 261 task_runners_->io_runner(), embedder::ScopedPlatformHandle()); |
241 | 262 |
242 if (command_line->HasSwitch(switches::kEnableExternalApplications)) { | 263 if (command_line.HasSwitch(switches::kEnableExternalApplications)) { |
243 listener_.reset(new ExternalApplicationListener( | 264 listener_.reset(new ExternalApplicationListener( |
244 task_runners_->shell_runner(), task_runners_->io_runner())); | 265 task_runners_->shell_runner(), task_runners_->io_runner())); |
245 | 266 |
246 base::FilePath socket_path = | 267 base::FilePath socket_path = |
247 command_line->GetSwitchValuePath(switches::kEnableExternalApplications); | 268 command_line.GetSwitchValuePath(switches::kEnableExternalApplications); |
248 if (socket_path.empty()) | 269 if (socket_path.empty()) |
249 socket_path = ExternalApplicationListener::ConstructDefaultSocketPath(); | 270 socket_path = ExternalApplicationListener::ConstructDefaultSocketPath(); |
250 | 271 |
251 listener_->ListenInBackground( | 272 listener_->ListenInBackground( |
252 socket_path, | 273 socket_path, |
253 base::Bind(&ApplicationManager::RegisterExternalApplication, | 274 base::Bind(&ApplicationManager::RegisterExternalApplication, |
254 base::Unretained(&application_manager_))); | 275 base::Unretained(&application_manager_))); |
255 } | 276 } |
256 | 277 |
257 scoped_ptr<NativeRunnerFactory> runner_factory; | 278 scoped_ptr<NativeRunnerFactory> runner_factory; |
258 if (command_line->HasSwitch(switches::kEnableMultiprocess)) | 279 if (command_line.HasSwitch(switches::kEnableMultiprocess)) |
259 runner_factory.reset(new OutOfProcessDynamicServiceRunnerFactory(this)); | 280 runner_factory.reset(new OutOfProcessDynamicServiceRunnerFactory(this)); |
260 else | 281 else |
261 runner_factory.reset(new InProcessDynamicServiceRunnerFactory(this)); | 282 runner_factory.reset(new InProcessDynamicServiceRunnerFactory(this)); |
262 application_manager_.set_blocking_pool(task_runners_->blocking_pool()); | 283 application_manager_.set_blocking_pool(task_runners_->blocking_pool()); |
263 application_manager_.set_native_runner_factory(runner_factory.Pass()); | 284 application_manager_.set_native_runner_factory(runner_factory.Pass()); |
264 application_manager_.set_disable_cache( | 285 application_manager_.set_disable_cache( |
265 base::CommandLine::ForCurrentProcess()->HasSwitch( | 286 base::CommandLine::ForCurrentProcess()->HasSwitch( |
266 switches::kDisableCache)); | 287 switches::kDisableCache)); |
267 | 288 |
268 InitContentHandlers(&application_manager_, command_line); | 289 InitContentHandlers(&application_manager_, command_line); |
| 290 InitNativeOptions(&application_manager_, command_line); |
269 | 291 |
270 ServiceProviderPtr tracing_service_provider_ptr; | 292 ServiceProviderPtr tracing_service_provider_ptr; |
271 new TracingServiceProvider(GetProxy(&tracing_service_provider_ptr)); | 293 new TracingServiceProvider(GetProxy(&tracing_service_provider_ptr)); |
272 application_manager_.ConnectToApplication( | 294 application_manager_.ConnectToApplication( |
273 GURL("mojo:tracing"), GURL(""), nullptr, | 295 GURL("mojo:tracing"), GURL(""), nullptr, |
274 tracing_service_provider_ptr.Pass()); | 296 tracing_service_provider_ptr.Pass()); |
275 | 297 |
276 if (listener_) | 298 if (listener_) |
277 listener_->WaitForListening(); | 299 listener_->WaitForListening(); |
278 | 300 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
324 ScopedMessagePipeHandle Context::ConnectToServiceByName( | 346 ScopedMessagePipeHandle Context::ConnectToServiceByName( |
325 const GURL& application_url, | 347 const GURL& application_url, |
326 const std::string& service_name) { | 348 const std::string& service_name) { |
327 app_urls_.insert(application_url); | 349 app_urls_.insert(application_url); |
328 return application_manager_.ConnectToServiceByName(application_url, | 350 return application_manager_.ConnectToServiceByName(application_url, |
329 service_name).Pass(); | 351 service_name).Pass(); |
330 } | 352 } |
331 | 353 |
332 } // namespace shell | 354 } // namespace shell |
333 } // namespace mojo | 355 } // namespace mojo |
OLD | NEW |