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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/public/common/static_mojo_application_loader.h"
6
7 #include "base/bind.h"
8 #include "base/lazy_instance.h"
9 #include "base/macros.h"
10 #include "base/memory/ref_counted.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/task_runner.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "base/threading/thread.h"
15 #include "base/threading/thread_local.h"
16 #include "mojo/application/public/cpp/application_delegate.h"
17 #include "mojo/application/public/cpp/application_impl.h"
18 #include "mojo/application/public/interfaces/application.mojom.h"
19 #include "mojo/common/message_pump_mojo.h"
20 #include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h"
21
22 namespace content {
23
24 namespace {
25
26 class Runner;
27
28 // Tracks each application's Runner on its main thread.
29 base::LazyInstance<base::ThreadLocalPointer<Runner>> g_runner;
30
31 void TerminateCurrentApp();
32
33 // Container for a single instance of the loaded application. This lives and
34 // dies on the app instance's own thread and kills itself either when the thread
35 // message loop is destroyed or the app terminates itself.
36 class Runner : public base::MessageLoop::DestructionObserver {
37 public:
38 Runner(mojo::InterfaceRequest<mojo::Application> request,
39 scoped_refptr<base::TaskRunner> exit_task_runner,
40 const base::Closure& exit_callback,
41 scoped_ptr<mojo::ApplicationDelegate> delegate)
42 : exit_task_runner_(exit_task_runner),
43 exit_callback_(exit_callback),
44 delegate_(delegate.Pass()) {
45 DCHECK(base::MessageLoop::current());
46 DCHECK(!g_runner.Get().Get());
47 g_runner.Get().Set(this);
48 base::MessageLoop::current()->AddDestructionObserver(this);
49 application_.reset(
50 new mojo::ApplicationImpl(delegate_.get(), request.Pass(),
51 base::Bind(&TerminateCurrentApp)));
52 }
53
54 private:
55 friend void TerminateCurrentApp();
56
57 ~Runner() override {
58 g_runner.Get().Set(nullptr);
59 base::MessageLoop::current()->RemoveDestructionObserver(this);
60 exit_task_runner_->PostTask(FROM_HERE, exit_callback_);
61 }
62
63 // base::MessageLoop::DestructionObserver:
64 void WillDestroyCurrentMessageLoop() override {
65 DCHECK(base::MessageLoop::current());
66 delete this;
67 }
68
69 scoped_refptr<base::TaskRunner> exit_task_runner_;
70 base::Closure exit_callback_;
71 scoped_ptr<mojo::ApplicationDelegate> delegate_;
72 scoped_ptr<mojo::ApplicationImpl> application_;
73
74 DISALLOW_COPY_AND_ASSIGN(Runner);
75 };
76
77 void RunAppOnOwnThread(
78 mojo::InterfaceRequest<mojo::Application> request,
79 scoped_refptr<base::TaskRunner> exit_task_runner,
80 const base::Closure& exit_callback,
81 const StaticMojoApplicationLoader::ApplicationFactory& factory) {
82 // This object either destroys itself when the current MessageLoop is
83 // destroyed, or it is destroyed by TerminateCurrentApp (see below).
84 new Runner(request.Pass(), exit_task_runner, exit_callback, factory.Run());
85 }
86
87 // This is run on an app's own thread when its ApplicationImpl::Terminate()
88 // method is called.
89 void TerminateCurrentApp() {
90 Runner* runner = g_runner.Get().Get();
91 DCHECK(runner);
92 delete runner;
93 }
94
95 } // namespace
96
97 StaticMojoApplicationLoader::StaticMojoApplicationLoader(
98 const ApplicationFactory& factory)
99 : StaticMojoApplicationLoader(factory, base::Closure()) {
100 }
101
102 StaticMojoApplicationLoader::StaticMojoApplicationLoader(
103 const ApplicationFactory& factory,
104 const base::Closure& quit_callback)
105 : factory_(factory),
106 quit_callback_(quit_callback),
107 weak_factory_(this) {
108 }
109
110 StaticMojoApplicationLoader::~StaticMojoApplicationLoader() {
111 }
112
113 void StaticMojoApplicationLoader::Load(
114 const GURL& url,
115 mojo::InterfaceRequest<mojo::Application> request) {
116 threads_.insert(threads_.begin(), make_scoped_ptr(new base::Thread(
117 "Mojo Application: " + url.spec())));
118 base::Thread::Options options;
119 options.message_pump_factory =
120 base::Bind(&mojo::common::MessagePumpMojo::Create);
121 threads_.front()->StartWithOptions(options);
122
123 // If the application's thread quits on its own before this loader dies, we
124 // evict the Thread object from |threads_| and destroy it.
125 auto exit_callback = base::Bind(
126 &StaticMojoApplicationLoader::CleanUpAppThread,
127 weak_factory_.GetWeakPtr(), threads_.begin());
128 threads_.front()->task_runner()->PostTask(
129 FROM_HERE,
130 base::Bind(&RunAppOnOwnThread, base::Passed(&request),
131 base::ThreadTaskRunnerHandle::Get(), exit_callback, factory_));
132 }
133
134 void StaticMojoApplicationLoader::CleanUpAppThread(
135 typename ThreadList::iterator iter) {
136 threads_.erase(iter);
137 if (!quit_callback_.is_null())
138 quit_callback_.Run();
139 }
140
141 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698