OLD | NEW |
(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/callback.h" |
| 9 #include "base/macros.h" |
| 10 #include "base/message_loop/message_loop.h" |
| 11 #include "base/task_runner.h" |
| 12 #include "base/thread_task_runner_handle.h" |
| 13 #include "base/threading/thread.h" |
| 14 #include "mojo/common/message_pump_mojo.h" |
| 15 #include "third_party/mojo/src/mojo/public/cpp/application/application_delegate.
h" |
| 16 #include "third_party/mojo/src/mojo/public/cpp/application/application_impl.h" |
| 17 #include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h" |
| 18 #include "third_party/mojo/src/mojo/public/interfaces/application/application.mo
jom.h" |
| 19 |
| 20 namespace mojo { |
| 21 |
| 22 // This is required since we depend on the |
| 23 // third_party/mojo/src/mojo/public/cpp/application target and instantiate |
| 24 // a mojo::ApplicationImpl. This exists only to support loading of static |
| 25 // applications. |
| 26 void ApplicationImpl::Terminate() { |
| 27 base::MessageLoop::current()->Quit(); |
| 28 } |
| 29 |
| 30 } // namespace mojo |
| 31 |
| 32 namespace content { |
| 33 |
| 34 namespace { |
| 35 |
| 36 // Container for a single instance of the loaded application. This lives and |
| 37 // dies on the app instance's thread and kills itself when the thread's message |
| 38 // loop is destroyed. |
| 39 class Runner : public base::MessageLoop::DestructionObserver { |
| 40 public: |
| 41 Runner(mojo::InterfaceRequest<mojo::Application> request, |
| 42 scoped_refptr<base::TaskRunner> exit_task_runner, |
| 43 const base::Closure& exit_callback, |
| 44 scoped_ptr<mojo::ApplicationDelegate> delegate) |
| 45 : exit_task_runner_(exit_task_runner), |
| 46 exit_callback_(exit_callback), |
| 47 delegate_(delegate.Pass()) { |
| 48 DCHECK(base::MessageLoop::current()); |
| 49 base::MessageLoop::current()->AddDestructionObserver(this); |
| 50 application_.reset( |
| 51 new mojo::ApplicationImpl(delegate_.get(), request.Pass())); |
| 52 } |
| 53 |
| 54 private: |
| 55 ~Runner() override { exit_task_runner_->PostTask(FROM_HERE, exit_callback_); } |
| 56 |
| 57 // base::MessageLoop::DestructionObserver: |
| 58 void WillDestroyCurrentMessageLoop() override { |
| 59 DCHECK(base::MessageLoop::current()); |
| 60 base::MessageLoop::current()->RemoveDestructionObserver(this); |
| 61 delete this; |
| 62 } |
| 63 |
| 64 scoped_refptr<base::TaskRunner> exit_task_runner_; |
| 65 base::Closure exit_callback_; |
| 66 scoped_ptr<mojo::ApplicationDelegate> delegate_; |
| 67 scoped_ptr<mojo::ApplicationImpl> application_; |
| 68 |
| 69 DISALLOW_COPY_AND_ASSIGN(Runner); |
| 70 }; |
| 71 |
| 72 void RunAppOnOwnThread( |
| 73 mojo::InterfaceRequest<mojo::Application> request, |
| 74 scoped_refptr<base::TaskRunner> exit_task_runner, |
| 75 const base::Closure& exit_callback, |
| 76 const StaticMojoApplicationLoader::ApplicationFactory& factory) { |
| 77 // This object destroys itself when the current MessageLoop is destroyed. |
| 78 new Runner(request.Pass(), exit_task_runner, exit_callback, factory.Run()); |
| 79 } |
| 80 |
| 81 } // namespace |
| 82 |
| 83 StaticMojoApplicationLoader::StaticMojoApplicationLoader( |
| 84 const std::string& name, |
| 85 const ApplicationFactory& factory) |
| 86 : name_(name), factory_(factory), weak_factory_(this) { |
| 87 } |
| 88 |
| 89 StaticMojoApplicationLoader::~StaticMojoApplicationLoader() { |
| 90 } |
| 91 |
| 92 void StaticMojoApplicationLoader::Load( |
| 93 const GURL& url, |
| 94 mojo::InterfaceRequest<mojo::Application> request) { |
| 95 threads_.insert(threads_.begin(), make_scoped_ptr(new base::Thread(name_))); |
| 96 base::Thread::Options options; |
| 97 options.message_pump_factory = |
| 98 base::Bind(&mojo::common::MessagePumpMojo::Create); |
| 99 threads_.front()->StartWithOptions(options); |
| 100 |
| 101 // If the application's thread quits on its own before this loader dies, we |
| 102 // evict the Thread object from |threads_| and destroy it. |
| 103 auto exit_callback = base::Bind(&StaticMojoApplicationLoader::ClearThread, |
| 104 weak_factory_.GetWeakPtr(), threads_.begin()); |
| 105 threads_.front()->task_runner()->PostTask( |
| 106 FROM_HERE, |
| 107 base::Bind(&RunAppOnOwnThread, base::Passed(&request), |
| 108 base::ThreadTaskRunnerHandle::Get(), exit_callback, factory_)); |
| 109 } |
| 110 |
| 111 void StaticMojoApplicationLoader::ClearThread( |
| 112 typename ThreadList::iterator iter) { |
| 113 threads_.erase(iter); |
| 114 } |
| 115 |
| 116 } // namespace content |
OLD | NEW |