diff options
Diffstat (limited to 'mojo/shell/android/background_application_loader.cc')
-rw-r--r-- | mojo/shell/android/background_application_loader.cc | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/mojo/shell/android/background_application_loader.cc b/mojo/shell/android/background_application_loader.cc new file mode 100644 index 0000000..cdb175e --- /dev/null +++ b/mojo/shell/android/background_application_loader.cc @@ -0,0 +1,73 @@ +// Copyright 2014 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 "mojo/shell/android/background_application_loader.h" + +#include "base/bind.h" +#include "base/run_loop.h" +#include "mojo/shell/application_manager/application_manager.h" + +namespace mojo { +namespace shell { + +BackgroundApplicationLoader::BackgroundApplicationLoader( + scoped_ptr<ApplicationLoader> real_loader, + const std::string& thread_name, + base::MessageLoop::Type message_loop_type) + : loader_(real_loader.Pass()), + message_loop_type_(message_loop_type), + thread_name_(thread_name), + message_loop_created_(true, false) { +} + +BackgroundApplicationLoader::~BackgroundApplicationLoader() { + if (thread_) + thread_->Join(); +} + +void BackgroundApplicationLoader::Load( + const GURL& url, + InterfaceRequest<Application> application_request) { + DCHECK(application_request.is_pending()); + if (!thread_) { + // TODO(tim): It'd be nice if we could just have each Load call + // result in a new thread like DynamicService{Loader, Runner}. But some + // loaders are creating multiple ApplicationImpls (NetworkApplicationLoader) + // sharing a delegate (etc). So we have to keep it single threaded, wait + // for the thread to initialize, and post to the TaskRunner for subsequent + // Load calls for now. + thread_.reset(new base::DelegateSimpleThread(this, thread_name_)); + thread_->Start(); + message_loop_created_.Wait(); + DCHECK(task_runner_.get()); + } + + task_runner_->PostTask( + FROM_HERE, + base::Bind(&BackgroundApplicationLoader::LoadOnBackgroundThread, + base::Unretained(this), url, + base::Passed(&application_request))); +} + +void BackgroundApplicationLoader::Run() { + base::MessageLoop message_loop(message_loop_type_); + base::RunLoop loop; + task_runner_ = message_loop.task_runner(); + quit_closure_ = loop.QuitClosure(); + message_loop_created_.Signal(); + loop.Run(); + + // Destroy |loader_| on the thread it's actually used on. + loader_.reset(); +} + +void BackgroundApplicationLoader::LoadOnBackgroundThread( + const GURL& url, + InterfaceRequest<Application> application_request) { + DCHECK(task_runner_->RunsTasksOnCurrentThread()); + loader_->Load(url, application_request.Pass()); +} + +} // namespace shell +} // namespace mojo |