1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
|
// 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.
#ifndef SHELL_APPLICATION_MANAGER_APPLICATION_MANAGER_H_
#define SHELL_APPLICATION_MANAGER_APPLICATION_MANAGER_H_
#include <map>
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "mojo/application/public/interfaces/application.mojom.h"
#include "mojo/application/public/interfaces/service_provider.mojom.h"
#include "mojo/public/cpp/bindings/interface_ptr_info.h"
#include "mojo/public/cpp/bindings/interface_request.h"
#include "mojo/services/network/public/interfaces/network_service.mojom.h"
#include "mojo/shell/application_loader.h"
#include "mojo/shell/fetcher.h"
#include "mojo/shell/identity.h"
#include "mojo/shell/native_runner.h"
#include "url/gurl.h"
namespace base {
class FilePath;
class SequencedWorkerPool;
}
namespace mojo {
namespace shell {
class ShellImpl;
class ApplicationManager {
public:
class Delegate {
public:
// Gives the delegate a chance to apply any mappings for the specified url.
// This should not resolve 'mojo' urls, that is done by ResolveMojoURL().
virtual GURL ResolveMappings(const GURL& url) = 0;
// Used to map a url with the scheme 'mojo' to the appropriate url. Return
// |url| if the scheme is not 'mojo'.
virtual GURL ResolveMojoURL(const GURL& url) = 0;
// Asks the delegate to create a Fetcher for the specified url. Return
// true on success, false if the default fetcher should be created.
virtual bool CreateFetcher(
const GURL& url,
const Fetcher::FetchCallback& loader_callback) = 0;
protected:
virtual ~Delegate() {}
};
// API for testing.
class TestAPI {
public:
explicit TestAPI(ApplicationManager* manager);
~TestAPI();
// Returns true if the shared instance has been created.
static bool HasCreatedInstance();
// Returns true if there is a ShellImpl for this URL.
bool HasFactoryForURL(const GURL& url) const;
private:
ApplicationManager* manager_;
DISALLOW_COPY_AND_ASSIGN(TestAPI);
};
explicit ApplicationManager(Delegate* delegate);
~ApplicationManager();
// Loads a service if necessary and establishes a new client connection.
void ConnectToApplication(const GURL& application_url,
const GURL& requestor_url,
InterfaceRequest<ServiceProvider> services,
ServiceProviderPtr exposed_services,
const base::Closure& on_application_end);
template <typename Interface>
inline void ConnectToService(const GURL& application_url,
InterfacePtr<Interface>* ptr) {
ScopedMessagePipeHandle service_handle =
ConnectToServiceByName(application_url, Interface::Name_);
ptr->Bind(InterfacePtrInfo<Interface>(service_handle.Pass(), 0u));
}
ScopedMessagePipeHandle ConnectToServiceByName(
const GURL& application_url,
const std::string& interface_name);
void RegisterContentHandler(const std::string& mime_type,
const GURL& content_handler_url);
// Registers a package alias. When attempting to load |alias|, it will
// instead redirect to |content_handler_package|, which is a content handler
// which will be passed the |alias| as the URLResponse::url. Different values
// of |alias| with the same |qualifier| that are in the same
// |content_handler_package| will run in the same process in multi-process
// mode.
void RegisterApplicationPackageAlias(const GURL& alias,
const GURL& content_handler_package,
const std::string& qualifier);
// Sets the default Loader to be used if not overridden by SetLoaderForURL()
// or SetLoaderForScheme().
void set_default_loader(scoped_ptr<ApplicationLoader> loader) {
default_loader_ = loader.Pass();
}
void set_native_runner_factory(
scoped_ptr<NativeRunnerFactory> runner_factory) {
native_runner_factory_ = runner_factory.Pass();
}
void set_blocking_pool(base::SequencedWorkerPool* blocking_pool) {
blocking_pool_ = blocking_pool;
}
void set_disable_cache(bool disable_cache) { disable_cache_ = disable_cache; }
// Sets a Loader to be used for a specific url.
void SetLoaderForURL(scoped_ptr<ApplicationLoader> loader, const GURL& url);
// Sets a Loader to be used for a specific url scheme.
void SetLoaderForScheme(scoped_ptr<ApplicationLoader> loader,
const std::string& scheme);
// These options will be used in running any native application at |url|
// (which shouldn't contain a query string). (|url| will be mapped and
// resolved, and any application whose base resolved URL matches it will have
// |options| applied.)
// TODO(vtl): This may not do what's desired if the resolved URL results in an
// HTTP redirect. Really, we want options to be identified with a particular
// implementation, maybe via a signed manifest or something like that.
void SetNativeOptionsForURL(const NativeRunnerFactory::Options& options,
const GURL& url);
// Destroys all Shell-ends of connections established with Applications.
// Applications connected by this ApplicationManager will observe pipe errors
// and have a chance to shutdown.
void TerminateShellConnections();
// Removes a ShellImpl when it encounters an error.
void OnShellImplError(ShellImpl* shell_impl);
private:
class ContentHandlerConnection;
using ApplicationPackagedAlias = std::map<GURL, std::pair<GURL, std::string>>;
using IdentityToShellImplMap = std::map<Identity, ShellImpl*>;
using MimeTypeToURLMap = std::map<std::string, GURL>;
using SchemeToLoaderMap = std::map<std::string, ApplicationLoader*>;
using URLToContentHandlerMap =
std::map<std::pair<GURL, std::string>, ContentHandlerConnection*>;
using URLToLoaderMap = std::map<GURL, ApplicationLoader*>;
using URLToNativeOptionsMap = std::map<GURL, NativeRunnerFactory::Options>;
void ConnectToApplicationWithParameters(
const GURL& application_url,
const std::string& qualifier,
const GURL& requestor_url,
InterfaceRequest<ServiceProvider> services,
ServiceProviderPtr exposed_services,
const base::Closure& on_application_end,
const std::vector<std::string>& pre_redirect_parameters);
bool ConnectToRunningApplication(const GURL& resolved_url,
const std::string& qualifier,
const GURL& requestor_url,
InterfaceRequest<ServiceProvider>* services,
ServiceProviderPtr* exposed_services);
bool ConnectToApplicationWithLoader(
const GURL& requested_url,
const std::string& qualifier,
const GURL& resolved_url,
const GURL& requestor_url,
InterfaceRequest<ServiceProvider>* services,
ServiceProviderPtr* exposed_services,
const base::Closure& on_application_end,
const std::vector<std::string>& parameters,
ApplicationLoader* loader);
InterfaceRequest<Application> RegisterShell(
const GURL& app_url,
const std::string& qualifier,
const GURL& requestor_url,
InterfaceRequest<ServiceProvider> services,
ServiceProviderPtr exposed_services,
const base::Closure& on_application_end,
const std::vector<std::string>& parameters);
ShellImpl* GetShellImpl(const GURL& url, const std::string& qualifier);
void ConnectToClient(ShellImpl* shell_impl,
const GURL& resolved_url,
const GURL& requestor_url,
InterfaceRequest<ServiceProvider> services,
ServiceProviderPtr exposed_services);
// Called once |fetcher| has found app. |requested_url| is the url of the
// requested application before any mappings/resolution have been applied.
void HandleFetchCallback(const GURL& requested_url,
const std::string& qualifier,
const GURL& requestor_url,
InterfaceRequest<ServiceProvider> services,
ServiceProviderPtr exposed_services,
const base::Closure& on_application_end,
const std::vector<std::string>& parameters,
NativeApplicationCleanup cleanup,
scoped_ptr<Fetcher> fetcher);
void RunNativeApplication(InterfaceRequest<Application> application_request,
const NativeRunnerFactory::Options& options,
NativeApplicationCleanup cleanup,
scoped_ptr<Fetcher> fetcher,
const base::FilePath& file_path,
bool path_exists);
void LoadWithContentHandler(const GURL& content_handler_url,
const GURL& requestor_url,
const std::string& qualifier,
InterfaceRequest<Application> application_request,
URLResponsePtr url_response);
// Returns the appropriate loader for |url|, or null if there is no loader
// configured for the URL.
ApplicationLoader* GetLoaderForURL(const GURL& url);
// Removes a ContentHandler when it encounters an error.
void OnContentHandlerError(ContentHandlerConnection* content_handler);
void CleanupRunner(NativeRunner* runner);
Delegate* const delegate_;
// Loader management.
// Loaders are chosen in the order they are listed here.
URLToLoaderMap url_to_loader_;
SchemeToLoaderMap scheme_to_loader_;
scoped_ptr<ApplicationLoader> default_loader_;
scoped_ptr<NativeRunnerFactory> native_runner_factory_;
ApplicationPackagedAlias application_package_alias_;
IdentityToShellImplMap identity_to_shell_impl_;
URLToContentHandlerMap url_to_content_handler_;
// Note: The keys are URLs after mapping and resolving.
URLToNativeOptionsMap url_to_native_options_;
base::SequencedWorkerPool* blocking_pool_;
NetworkServicePtr network_service_;
MimeTypeToURLMap mime_type_to_url_;
ScopedVector<NativeRunner> native_runners_;
bool disable_cache_;
base::WeakPtrFactory<ApplicationManager> weak_ptr_factory_;
DISALLOW_COPY_AND_ASSIGN(ApplicationManager);
};
} // namespace shell
} // namespace mojo
#endif // SHELL_APPLICATION_MANAGER_APPLICATION_MANAGER_H_
|