Chromium Code Reviews| Index: mojo/services/network/network_service_delegate.cc |
| diff --git a/mojo/services/network/network_service_delegate.cc b/mojo/services/network/network_service_delegate.cc |
| index b3b1c8e8a4bf546bfa4e8ccdc22ddcebc2330811..7edb2de9db511c82d6859faca399e0229859dbbe 100644 |
| --- a/mojo/services/network/network_service_delegate.cc |
| +++ b/mojo/services/network/network_service_delegate.cc |
| @@ -6,23 +6,127 @@ |
| #include "base/at_exit.h" |
| #include "base/base_paths.h" |
| +#include "base/bind.h" |
| +#include "base/command_line.h" |
| #include "base/files/file_path.h" |
| #include "base/message_loop/message_loop.h" |
| #include "base/path_service.h" |
| #include "mojo/application/public/cpp/application_connection.h" |
| +#include "mojo/common/message_pump_mojo.h" |
| +#include "mojo/services/network/network_service_delegate_observer.h" |
| #include "mojo/services/network/network_service_impl.h" |
| #include "mojo/services/network/url_loader_factory_impl.h" |
| +#include "mojo/util/capture_util.h" |
| +#include "sql/mojo/mojo_vfs.h" |
| -NetworkServiceDelegate::NetworkServiceDelegate() : app_(nullptr) {} |
| +namespace { |
| -NetworkServiceDelegate::~NetworkServiceDelegate() {} |
| +const char kSQLThreadName[] = "SQL_IO_Thread"; |
| +const char kUserDataDir[] = "user-data-dir"; |
| + |
| +// SQL blocks on the filesystem service, so perform all SQL functions on a |
| +// separate thread. |
| +class SQLThread : public base::Thread { |
| + public: |
| + SQLThread(filesystem::DirectoryPtr directory) |
| + : base::Thread(kSQLThreadName), |
| + directory_info_(directory.PassInterface().Pass()) { |
| + base::Thread::Options options; |
| + options.message_pump_factory = |
| + base::Bind(&mojo::common::MessagePumpMojo::Create); |
| + StartWithOptions(options); |
| + } |
| + ~SQLThread() override { Stop(); } |
| + |
| + void Init() override { |
| + filesystem::DirectoryPtr directory; |
| + directory.Bind(directory_info_.Pass()); |
| + vfs_.reset(new sql::ScopedMojoFilesystemVFS(directory.Pass())); |
| + } |
| + |
| + void CleanUp() override { |
| + vfs_.reset(); |
| + } |
| + |
| + private: |
| + // Our VFS which wraps sqlite so that we can reuse the current sqlite code. |
| + scoped_ptr<sql::ScopedMojoFilesystemVFS> vfs_; |
| + |
| + // This member is used to safely pass data from one thread to another. It is |
| + // set in the constructor and is consumed in Init(). |
| + mojo::InterfacePtrInfo<filesystem::Directory> directory_info_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(SQLThread); |
| +}; |
| + |
| +} // namespace |
| + |
| +namespace mojo { |
| + |
| +NetworkServiceDelegate::NetworkServiceDelegate() |
| + : app_(nullptr), |
| + binding_(this) { |
| +} |
| + |
| +NetworkServiceDelegate::~NetworkServiceDelegate() { |
| +} |
| + |
| +void NetworkServiceDelegate::AddObserver( |
| + NetworkServiceDelegateObserver* observer) { |
| + observers_.AddObserver(observer); |
| +} |
| + |
| +void NetworkServiceDelegate::RemoveObserver( |
| + NetworkServiceDelegateObserver* observer) { |
| + observers_.RemoveObserver(observer); |
| +} |
| void NetworkServiceDelegate::Initialize(mojo::ApplicationImpl* app) { |
| app_ = app; |
| + |
| +#if !defined(OS_ANDROID) |
| + // TODO(erg): The following doesn't work when running the android |
| + // apptests. It works in the mandoline shell (on desktop and on android), and |
| + // in the apptests on desktop. However, on android, whenever we make the call |
| + // to OpenFileSystem, the entire mojo system hangs to the point where writes |
| + // to stderr that previously would have printed to our console aren't. The |
| + // apptests are also fairly resistant to being run under gdb on android. |
| + mojo::URLRequestPtr request(mojo::URLRequest::New()); |
| + request->url = mojo::String::From("mojo:filesystem"); |
| + app_->ConnectToService(request.Pass(), &files_); |
| + |
| + filesystem::FileSystemClientPtr client; |
| + binding_.Bind(GetProxy(&client)); |
| + |
| + filesystem::FileError error = filesystem::FILE_ERROR_FAILED; |
| + filesystem::DirectoryPtr directory; |
| + files_->OpenFileSystem("origin", GetProxy(&directory), client.Pass(), |
| + mojo::Capture(&error)); |
| + files_.WaitForIncomingResponse(); |
| + |
| + io_worker_thread_.reset(new SQLThread(directory.Pass())); |
| +#endif |
| + |
| + // TODO(erg): Find everything else that writes to the filesystem and |
| + // transition it to proxying mojo:filesystem. We shouldn't have any path |
| + // calculation code here, but sadly need it until the transition is done. In |
| + // the mean time, manually handle the user-data-dir switch (which gets set in |
| + // tests) so that tests are writing to a temp dir. |
| base::FilePath base_path; |
| - CHECK(PathService::Get(base::DIR_TEMP, &base_path)); |
| - base_path = base_path.Append(FILE_PATH_LITERAL("network_service")); |
| - context_.reset(new mojo::NetworkContext(base_path)); |
| + const base::CommandLine* command_line = |
| + base::CommandLine::ForCurrentProcess(); |
| + if (command_line->HasSwitch(kUserDataDir)) { |
| + base_path = command_line->GetSwitchValuePath(kUserDataDir); |
| + } else { |
| + CHECK(PathService::Get(base::DIR_TEMP, &base_path)); |
| + base_path = base_path.Append(FILE_PATH_LITERAL("network_service")); |
| + } |
| + |
| + scoped_refptr<base::SequencedTaskRunner> worker_thread; |
| +#if !defined(OS_ANDROID) |
| + worker_thread = io_worker_thread_->task_runner(); |
| +#endif |
| + context_.reset(new mojo::NetworkContext(base_path, worker_thread, this)); |
| } |
| bool NetworkServiceDelegate::ConfigureIncomingConnection( |
| @@ -33,7 +137,14 @@ bool NetworkServiceDelegate::ConfigureIncomingConnection( |
| return true; |
| } |
| +bool NetworkServiceDelegate::OnShellConnectionError() { |
| + EnsureIOThreadShutdown(); |
| + return true; |
| +} |
| + |
| void NetworkServiceDelegate::Quit() { |
| + EnsureIOThreadShutdown(); |
| + |
| // Destroy the NetworkContext now as it requires MessageLoop::current() upon |
| // destruction and it is the last moment we know for sure that it is |
| // running. |
| @@ -59,3 +170,23 @@ void NetworkServiceDelegate::Create( |
| app_->app_lifetime_helper()->CreateAppRefCount(), |
| request.Pass()); |
| } |
| + |
| +void NetworkServiceDelegate::OnFileSystemShutdown() { |
| + EnsureIOThreadShutdown(); |
| +} |
| + |
| +void NetworkServiceDelegate::EnsureIOThreadShutdown() { |
| + if (io_worker_thread_) { |
| + // Broadcast to the entire system that we have to shut down anything |
| + // depending on the connection an |
|
jam
2015/07/13 15:48:33
nit: comment cut off
|
| + FOR_EACH_OBSERVER(NetworkServiceDelegateObserver, observers_, |
| + OnIOWorkerThreadShutdown()); |
| + |
| + // Destroy the io worker thread here so that we can commit any pending |
| + // cookies here. |
| + io_worker_thread_.reset(); |
| + } |
| +} |
| + |
| + |
| +} // namespace mojo |