// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/bind.h"
#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 "base/strings/string_util.h"
+#include "mojo/public/cpp/application/application_connection.h"
+#include "mojo/public/cpp/application/application_delegate.h"
+#include "mojo/public/cpp/application/application_impl.h"
+#include "mojo/public/cpp/application/interface_factory_impl.h"
#include "mojo/services/public/cpp/view_manager/types.h"
#include "mojo/services/public/interfaces/launcher/launcher.mojom.h"
#include "mojo/services/public/interfaces/network/network_service.mojom.h"
#include "url/gurl.h"
namespace mojo {
-namespace launcher {
+
+namespace {
+
+typedef mojo::Callback<void(String handler_url, String view_url,
+ ResponseDetailsPtr response)> LaunchCallback;
+
+}
class LauncherApp;
private:
// Overridden from Launcher:
- virtual void Launch(const String& url) OVERRIDE;
+ virtual void Launch(NavigationDetailsPtr nav_details,
+ const LaunchCallback& callback) OVERRIDE;
LauncherApp* app_;
DISALLOW_COPY_AND_ASSIGN(LauncherConnection);
};
-class LaunchInstance : public URLLoaderClient {
+class LaunchInstance {
public:
LaunchInstance(LauncherApp* app,
- LauncherClient* client,
- const String& url);
+ const LaunchCallback& callback,
+ NavigationDetailsPtr nav_details);
virtual ~LaunchInstance() {}
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();
- }
+ void OnReceivedResponse(URLResponsePtr response);
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") {
+ if (!t.token_is_delim() &&
+ LowerCaseEqualsASCII(t.token(), "content-type")) {
while (t.GetNext()) {
if (!t.token_is_delim())
return t.token();
LauncherApp* app_;
bool destroy_scheduled_;
- LauncherClient* client_;
+ const LaunchCallback callback_;
URLLoaderPtr url_loader_;
ScopedDataPipeConsumerHandle response_body_stream_;
DISALLOW_COPY_AND_ASSIGN(LaunchInstance);
};
-class LauncherApp : public Application {
+class LauncherApp : public ApplicationDelegate {
public:
- LauncherApp() {
+ LauncherApp() : launcher_connection_factory_(this) {
handler_map_["text/html"] = "mojo:mojo_html_viewer";
- handler_map_["image/png"] = "mojo:mojo_image_viewer";
+ handler_map_["image/png"] = "mojo:mojo_media_viewer";
}
virtual ~LauncherApp() {}
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_);
+ // Overridden from ApplicationDelegate:
+ virtual void Initialize(ApplicationImpl* app) MOJO_OVERRIDE {
+ app->ConnectToService("mojo:mojo_network_service", &network_service_);
}
- HandlerMap handler_map_;
+ virtual bool ConfigureIncomingConnection(ApplicationConnection* connection)
+ MOJO_OVERRIDE {
+ connection->AddService(&launcher_connection_factory_);
+ return true;
+ }
+ InterfaceFactoryImplWithContext<LauncherConnection, LauncherApp>
+ launcher_connection_factory_;
+
+ HandlerMap handler_map_;
NetworkServicePtr network_service_;
DISALLOW_COPY_AND_ASSIGN(LauncherApp);
};
-void LauncherConnection::Launch(const String& url_string) {
- GURL url(url_string.To<std::string>());
+void LauncherConnection::Launch(NavigationDetailsPtr nav_details,
+ const LaunchCallback& callback) {
+ GURL url(nav_details->request->url.To<std::string>());
// For Mojo URLs, the handler can always be found at the origin.
// TODO(aa): Return error for invalid URL?
if (url.is_valid() && url.SchemeIs("mojo")) {
- client()->OnLaunch(url_string,
- url.GetOrigin().spec(),
- navigation::ResponseDetailsPtr());
+ callback.Run(url.GetOrigin().spec(),
+ nav_details->request->url,
+ ResponseDetailsPtr());
return;
}
-
- new LaunchInstance(app_, client(), url_string);
+ new LaunchInstance(app_, callback, nav_details.Pass());
}
LaunchInstance::LaunchInstance(LauncherApp* app,
- LauncherClient* client,
- const String& url)
+ const LaunchCallback& callback,
+ NavigationDetailsPtr nav_details)
: app_(app),
destroy_scheduled_(false),
- client_(client) {
- url_loader_ = app_->CreateURLLoader();
- url_loader_.set_client(this);
-
- URLRequestPtr request(URLRequest::New());
- request->url = url;
- request->method = "GET";
+ callback_(callback) {
+ URLRequestPtr request = nav_details->request.Pass();
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());
+ url_loader_ = app_->CreateURLLoader();
+ url_loader_->Start(request.Pass(),
+ base::Bind(&LaunchInstance::OnReceivedResponse,
+ base::Unretained(this)));
}
void LaunchInstance::OnReceivedResponse(URLResponsePtr response) {
- std::string content_type = GetContentType(response->headers);
- std::string handler_url = app_->GetHandlerForContentType(content_type);
- if (!handler_url.empty()) {
- navigation::ResponseDetailsPtr nav_response(
- navigation::ResponseDetails::New());
- nav_response->response = response.Pass();
- nav_response->response_body_stream = response_body_stream_.Pass();
- client_->OnLaunch(nav_response->response->url, handler_url,
- nav_response.Pass());
+ if (!response->error) {
+ std::string content_type = GetContentType(response->headers);
+ std::string handler_url = app_->GetHandlerForContentType(content_type);
+ if (handler_url.empty()) {
+ DLOG(WARNING) << "No handler for content type: " << content_type;
+ } else {
+ ResponseDetailsPtr nav_response(ResponseDetails::New());
+ nav_response->loader = url_loader_.Pass();
+ nav_response->response = response.Pass();
+ String response_url = nav_response->response->url;
+ callback_.Run(handler_url, response_url, nav_response.Pass());
+ }
}
+ ScheduleDestroy();
}
-} // namespace launcher
-
// static
-Application* Application::Create() {
- return new launcher::LauncherApp;
+ApplicationDelegate* ApplicationDelegate::Create() {
+ return new LauncherApp;
}
} // namespace mojo