#include "mojo/shell/context.h"
-#include "build/build_config.h"
+#include <vector>
+
#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "base/memory/scoped_vector.h"
+#include "base/strings/string_split.h"
+#include "build/build_config.h"
+#include "mojo/application_manager/application_loader.h"
+#include "mojo/application_manager/application_manager.h"
+#include "mojo/application_manager/background_shell_application_loader.h"
#include "mojo/embedder/embedder.h"
-#include "mojo/gles2/gles2_support_impl.h"
-#include "mojo/public/cpp/application/application.h"
-#include "mojo/service_manager/background_service_loader.h"
-#include "mojo/service_manager/service_loader.h"
-#include "mojo/service_manager/service_manager.h"
-#include "mojo/services/native_viewport/native_viewport_service.h"
-#include "mojo/shell/dynamic_service_loader.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/services/native_viewport/native_viewport_impl.h"
+#include "mojo/shell/dynamic_application_loader.h"
#include "mojo/shell/in_process_dynamic_service_runner.h"
#include "mojo/shell/out_of_process_dynamic_service_runner.h"
#include "mojo/shell/switches.h"
+#include "mojo/shell/ui_application_loader_android.h"
#include "mojo/spy/spy.h"
#if defined(OS_LINUX)
-#include "mojo/shell/dbus_service_loader_linux.h"
+#include "mojo/shell/dbus_application_loader_linux.h"
#endif // defined(OS_LINUX)
+#if defined(OS_ANDROID)
+#include "mojo/shell/network_application_loader.h"
+#endif // defined(OS_ANDROID)
+
#if defined(USE_AURA)
#include "mojo/shell/view_manager_loader.h"
#endif
public:
Setup() {
embedder::Init();
- gles2::GLES2SupportImpl::Init();
}
~Setup() {
static base::LazyInstance<Setup>::Leaky setup = LAZY_INSTANCE_INITIALIZER;
+void InitContentHandlers(DynamicApplicationLoader* loader,
+ base::CommandLine* command_line) {
+ std::string handlers_spec = command_line->GetSwitchValueASCII(
+ switches::kContentHandlers);
+ if (handlers_spec.empty())
+ return;
+
+ std::vector<std::string> parts;
+ base::SplitString(handlers_spec, ',', &parts);
+ if (parts.size() % 2 != 0) {
+ LOG(ERROR) << "Invalid value for switch " << switches::kContentHandlers
+ << ": must be a comma-separated list of mimetype/url pairs.";
+ return;
+ }
+
+ for (size_t i = 0; i < parts.size(); i += 2) {
+ GURL url(parts[i + 1]);
+ if (!url.is_valid()) {
+ LOG(ERROR) << "Invalid value for switch " << switches::kContentHandlers
+ << ": '" << parts[i + 1] << "' is not a valid URL.";
+ return;
+ }
+ loader->RegisterContentHandler(parts[i], url);
+ }
+}
+
} // namespace
-class Context::NativeViewportServiceLoader : public ServiceLoader {
+class Context::NativeViewportApplicationLoader
+ : public ApplicationLoader,
+ public ApplicationDelegate,
+ public InterfaceFactory<NativeViewport> {
public:
- explicit NativeViewportServiceLoader(Context* context) : context_(context) {}
- virtual ~NativeViewportServiceLoader() {}
+ NativeViewportApplicationLoader() {}
+ virtual ~NativeViewportApplicationLoader() {}
private:
- virtual void LoadService(ServiceManager* manager,
- const GURL& url,
- ScopedMessagePipeHandle service_handle) OVERRIDE {
- app_.reset(::CreateNativeViewportService(context_, service_handle.Pass()));
+ // ApplicationLoader implementation.
+ virtual void Load(ApplicationManager* manager,
+ const GURL& url,
+ scoped_refptr<LoadCallbacks> callbacks) OVERRIDE {
+ ScopedMessagePipeHandle shell_handle = callbacks->RegisterApplication();
+ if (shell_handle.is_valid())
+ app_.reset(new ApplicationImpl(this, shell_handle.Pass()));
+ }
+
+ virtual void OnServiceError(ApplicationManager* manager,
+ const GURL& url) OVERRIDE {}
+
+ // ApplicationDelegate implementation.
+ virtual bool ConfigureIncomingConnection(
+ mojo::ApplicationConnection* connection) OVERRIDE {
+ connection->AddService(this);
+ return true;
}
- virtual void OnServiceError(ServiceManager* manager,
- const GURL& url) OVERRIDE {
+ // InterfaceFactory<NativeViewport> implementation.
+ virtual void Create(ApplicationConnection* connection,
+ InterfaceRequest<NativeViewport> request) OVERRIDE {
+ BindToRequest(new NativeViewportImpl, &request);
}
- Context* context_;
- scoped_ptr<Application> app_;
- DISALLOW_COPY_AND_ASSIGN(NativeViewportServiceLoader);
+ scoped_ptr<ApplicationImpl> app_;
+ DISALLOW_COPY_AND_ASSIGN(NativeViewportApplicationLoader);
};
-Context::Context()
- : task_runners_(base::MessageLoop::current()->message_loop_proxy()) {
+Context::Context() {
+ DCHECK(!base::MessageLoop::current());
+}
+
+void Context::Init() {
setup.Get();
+ task_runners_.reset(
+ new TaskRunners(base::MessageLoop::current()->message_loop_proxy()));
for (size_t i = 0; i < arraysize(kLocalMojoURLs); ++i)
mojo_url_resolver_.AddLocalFileMapping(GURL(kLocalMojoURLs[i]));
- base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
scoped_ptr<DynamicServiceRunnerFactory> runner_factory;
- if (cmdline->HasSwitch(switches::kEnableMultiprocess))
+ if (command_line->HasSwitch(switches::kEnableMultiprocess))
runner_factory.reset(new OutOfProcessDynamicServiceRunnerFactory());
else
runner_factory.reset(new InProcessDynamicServiceRunnerFactory());
- service_manager_.set_default_loader(
- scoped_ptr<ServiceLoader>(
- new DynamicServiceLoader(this, runner_factory.Pass())));
+ DynamicApplicationLoader* dynamic_application_loader =
+ new DynamicApplicationLoader(this, runner_factory.Pass());
+ InitContentHandlers(dynamic_application_loader, command_line);
+ application_manager_.set_default_loader(
+ scoped_ptr<ApplicationLoader>(dynamic_application_loader));
+
// The native viewport service synchronously waits for certain messages. If we
// don't run it on its own thread we can easily deadlock. Long term native
// viewport should run its own process so that this isn't an issue.
- service_manager_.SetLoaderForURL(
- scoped_ptr<ServiceLoader>(
- new BackgroundServiceLoader(
- scoped_ptr<ServiceLoader>(new NativeViewportServiceLoader(this)),
- "native_viewport",
- base::MessageLoop::TYPE_UI)),
+#if defined(OS_ANDROID)
+ application_manager_.SetLoaderForURL(
+ scoped_ptr<ApplicationLoader>(new UIApplicationLoader(
+ scoped_ptr<ApplicationLoader>(new NativeViewportApplicationLoader()),
+ this)),
GURL("mojo:mojo_native_viewport_service"));
+#else
+ {
+ scoped_ptr<BackgroundShellApplicationLoader> loader(
+ new BackgroundShellApplicationLoader(
+ scoped_ptr<ApplicationLoader>(
+ new NativeViewportApplicationLoader()),
+ "native_viewport",
+ base::MessageLoop::TYPE_UI));
+ application_manager_.SetLoaderForURL(
+ loader.PassAs<ApplicationLoader>(),
+ GURL("mojo:mojo_native_viewport_service"));
+ }
+#endif
#if defined(USE_AURA)
// TODO(sky): need a better way to find this. It shouldn't be linked in.
- service_manager_.SetLoaderForURL(
- scoped_ptr<ServiceLoader>(new ViewManagerLoader()),
+ application_manager_.SetLoaderForURL(
+ scoped_ptr<ApplicationLoader>(new ViewManagerLoader()),
GURL("mojo:mojo_view_manager"));
#endif
#if defined(OS_LINUX)
- service_manager_.SetLoaderForScheme(
- scoped_ptr<ServiceLoader>(new DBusServiceLoader(this)),
- "dbus");
+ application_manager_.SetLoaderForScheme(
+ scoped_ptr<ApplicationLoader>(new DBusApplicationLoader(this)), "dbus");
#endif // defined(OS_LINUX)
- if (cmdline->HasSwitch(switches::kSpy)) {
- spy_.reset(new mojo::Spy(&service_manager_,
- cmdline->GetSwitchValueASCII(switches::kSpy)));
+ if (command_line->HasSwitch(switches::kSpy)) {
+ spy_.reset(
+ new mojo::Spy(&application_manager_,
+ command_line->GetSwitchValueASCII(switches::kSpy)));
}
+
+#if defined(OS_ANDROID)
+ // On android, the network service is bundled with the shell because the
+ // network stack depends on the android runtime.
+ {
+ scoped_ptr<BackgroundShellApplicationLoader> loader(
+ new BackgroundShellApplicationLoader(
+ scoped_ptr<ApplicationLoader>(new NetworkApplicationLoader()),
+ "network_service",
+ base::MessageLoop::TYPE_IO));
+ application_manager_.SetLoaderForURL(loader.PassAs<ApplicationLoader>(),
+ GURL("mojo:mojo_network_service"));
+ }
+#endif
}
Context::~Context() {
- // mojo_view_manager uses native_viewport. Destroy mojo_view_manager first so
- // that there aren't shutdown ordering issues. Once native viewport service is
- // moved into its own process this can likely be nuked.
-#if defined(USE_AURA)
- service_manager_.SetLoaderForURL(
- scoped_ptr<ServiceLoader>(),
- GURL("mojo:mojo_view_manager"));
-#endif
- service_manager_.set_default_loader(scoped_ptr<ServiceLoader>());
+ DCHECK(!base::MessageLoop::current());
}
} // namespace shell