Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Unified Diff: content/public/common/static_mojo_application_loader.cc

Issue 1149833007: Embed a mojo ApplicationManager in content/browser (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added some missing docs and removed some cruft Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/public/common/static_mojo_application_loader.cc
diff --git a/content/public/common/static_mojo_application_loader.cc b/content/public/common/static_mojo_application_loader.cc
new file mode 100644
index 0000000000000000000000000000000000000000..c98a49e1b833b617519a75b66ee349052530eba1
--- /dev/null
+++ b/content/public/common/static_mojo_application_loader.cc
@@ -0,0 +1,141 @@
+// Copyright 2015 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.
+
+#include "content/public/common/static_mojo_application_loader.h"
+
+#include "base/bind.h"
+#include "base/lazy_instance.h"
+#include "base/macros.h"
+#include "base/memory/ref_counted.h"
+#include "base/message_loop/message_loop.h"
+#include "base/task_runner.h"
+#include "base/thread_task_runner_handle.h"
+#include "base/threading/thread.h"
+#include "base/threading/thread_local.h"
+#include "mojo/application/public/cpp/application_delegate.h"
+#include "mojo/application/public/cpp/application_impl.h"
+#include "mojo/application/public/interfaces/application.mojom.h"
+#include "mojo/common/message_pump_mojo.h"
+#include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h"
+
+namespace content {
+
+namespace {
+
+class Runner;
+
+// Tracks each application's Runner on its main thread.
+base::LazyInstance<base::ThreadLocalPointer<Runner>> g_runner;
+
+void TerminateCurrentApp();
+
+// Container for a single instance of the loaded application. This lives and
+// dies on the app instance's own thread and kills itself either when the thread
+// message loop is destroyed or the app terminates itself.
+class Runner : public base::MessageLoop::DestructionObserver {
+ public:
+ Runner(mojo::InterfaceRequest<mojo::Application> request,
+ scoped_refptr<base::TaskRunner> exit_task_runner,
+ const base::Closure& exit_callback,
+ scoped_ptr<mojo::ApplicationDelegate> delegate)
+ : exit_task_runner_(exit_task_runner),
+ exit_callback_(exit_callback),
+ delegate_(delegate.Pass()) {
+ DCHECK(base::MessageLoop::current());
+ DCHECK(!g_runner.Get().Get());
+ g_runner.Get().Set(this);
+ base::MessageLoop::current()->AddDestructionObserver(this);
+ application_.reset(
+ new mojo::ApplicationImpl(delegate_.get(), request.Pass(),
+ base::Bind(&TerminateCurrentApp)));
+ }
+
+ private:
+ friend void TerminateCurrentApp();
+
+ ~Runner() override {
+ g_runner.Get().Set(nullptr);
+ base::MessageLoop::current()->RemoveDestructionObserver(this);
+ exit_task_runner_->PostTask(FROM_HERE, exit_callback_);
+ }
+
+ // base::MessageLoop::DestructionObserver:
+ void WillDestroyCurrentMessageLoop() override {
+ DCHECK(base::MessageLoop::current());
+ delete this;
+ }
+
+ scoped_refptr<base::TaskRunner> exit_task_runner_;
+ base::Closure exit_callback_;
+ scoped_ptr<mojo::ApplicationDelegate> delegate_;
+ scoped_ptr<mojo::ApplicationImpl> application_;
+
+ DISALLOW_COPY_AND_ASSIGN(Runner);
+};
+
+void RunAppOnOwnThread(
+ mojo::InterfaceRequest<mojo::Application> request,
+ scoped_refptr<base::TaskRunner> exit_task_runner,
+ const base::Closure& exit_callback,
+ const StaticMojoApplicationLoader::ApplicationFactory& factory) {
+ // This object either destroys itself when the current MessageLoop is
+ // destroyed, or it is destroyed by TerminateCurrentApp (see below).
+ new Runner(request.Pass(), exit_task_runner, exit_callback, factory.Run());
+}
+
+// This is run on an app's own thread when its ApplicationImpl::Terminate()
+// method is called.
+void TerminateCurrentApp() {
+ Runner* runner = g_runner.Get().Get();
+ DCHECK(runner);
+ delete runner;
+}
+
+} // namespace
+
+StaticMojoApplicationLoader::StaticMojoApplicationLoader(
+ const ApplicationFactory& factory)
+ : StaticMojoApplicationLoader(factory, base::Closure()) {
+}
+
+StaticMojoApplicationLoader::StaticMojoApplicationLoader(
+ const ApplicationFactory& factory,
+ const base::Closure& quit_callback)
+ : factory_(factory),
+ quit_callback_(quit_callback),
+ weak_factory_(this) {
+}
+
+StaticMojoApplicationLoader::~StaticMojoApplicationLoader() {
+}
+
+void StaticMojoApplicationLoader::Load(
+ const GURL& url,
+ mojo::InterfaceRequest<mojo::Application> request) {
+ threads_.insert(threads_.begin(), make_scoped_ptr(new base::Thread(
+ "Mojo Application: " + url.spec())));
+ base::Thread::Options options;
+ options.message_pump_factory =
+ base::Bind(&mojo::common::MessagePumpMojo::Create);
+ threads_.front()->StartWithOptions(options);
+
+ // If the application's thread quits on its own before this loader dies, we
+ // evict the Thread object from |threads_| and destroy it.
+ auto exit_callback = base::Bind(
+ &StaticMojoApplicationLoader::CleanUpAppThread,
+ weak_factory_.GetWeakPtr(), threads_.begin());
+ threads_.front()->task_runner()->PostTask(
+ FROM_HERE,
+ base::Bind(&RunAppOnOwnThread, base::Passed(&request),
+ base::ThreadTaskRunnerHandle::Get(), exit_callback, factory_));
+}
+
+void StaticMojoApplicationLoader::CleanUpAppThread(
+ typename ThreadList::iterator iter) {
+ threads_.erase(iter);
+ if (!quit_callback_.is_null())
+ quit_callback_.Run();
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698