Chromium Code Reviews| Index: content/browser/dom_storage/dom_storage_context_wrapper.cc |
| diff --git a/content/browser/dom_storage/dom_storage_context_wrapper.cc b/content/browser/dom_storage/dom_storage_context_wrapper.cc |
| index d028d6faab5145e18d5ecc6bef40bfcd4c819801..2900501f8d11c9d00199b805ce6c72c01f6a9776 100644 |
| --- a/content/browser/dom_storage/dom_storage_context_wrapper.cc |
| +++ b/content/browser/dom_storage/dom_storage_context_wrapper.cc |
| @@ -13,14 +13,18 @@ |
| #include "base/location.h" |
| #include "base/single_thread_task_runner.h" |
| #include "base/thread_task_runner_handle.h" |
| +#include "components/filesystem/public/interfaces/file_system.mojom.h" |
| #include "content/browser/dom_storage/dom_storage_area.h" |
| #include "content/browser/dom_storage/dom_storage_context_impl.h" |
| #include "content/browser/dom_storage/dom_storage_task_runner.h" |
| #include "content/browser/dom_storage/session_storage_namespace_impl.h" |
| #include "content/browser/leveldb_wrapper_impl.h" |
| +#include "content/public/browser/browser_context.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/local_storage_usage_info.h" |
| +#include "content/public/browser/mojo_app_connection.h" |
| #include "content/public/browser/session_storage_usage_info.h" |
| +#include "mojo/common/common_type_converters.h" |
| namespace content { |
| namespace { |
| @@ -67,8 +71,12 @@ void GetSessionStorageUsageHelper( |
| } // namespace |
| DOMStorageContextWrapper::DOMStorageContextWrapper( |
| + BrowserContext* context, |
| const base::FilePath& data_path, |
| - storage::SpecialStoragePolicy* special_storage_policy) { |
| + storage::SpecialStoragePolicy* special_storage_policy) |
| + : browser_context_(context), |
| + connection_state_(NO_CONNECTION), |
| + weak_ptr_factory_(this) { |
| base::SequencedWorkerPool* worker_pool = BrowserThread::GetBlockingPool(); |
| context_ = new DOMStorageContextImpl( |
| data_path.empty() ? data_path |
| @@ -85,6 +93,7 @@ DOMStorageContextWrapper::DOMStorageContextWrapper( |
| } |
| DOMStorageContextWrapper::~DOMStorageContextWrapper() { |
| + LOG(ERROR) << "Size of level_db_wrappers_: " << level_db_wrappers_.size(); |
| } |
| void DOMStorageContextWrapper::GetLocalStorageUsage( |
| @@ -170,25 +179,95 @@ void DOMStorageContextWrapper::Flush() { |
| void DOMStorageContextWrapper::OpenLocalStorage( |
| const mojo::String& origin, |
| mojo::InterfaceRequest<LevelDBWrapper> request) { |
| + // If we don't have a filesystem_connection_, we'll need to establish one. |
| + if (connection_state_ == NO_CONNECTION) { |
| + profile_connection_ = content::MojoAppConnection::Create( |
| + browser_context_, "mojo:profile", content::kBrowserMojoAppUrl); |
| + profile_connection_->GetInterface(&profile_service_); |
| + |
| + profile_service_->GetDirectory( |
| + GetProxy(&directory_), |
| + base::Bind(&DOMStorageContextWrapper::OnDirectoryOpened, |
| + weak_ptr_factory_.GetWeakPtr())); |
| + connection_state_ = CONNECITON_IN_PROGRESS; |
| + } |
| + |
| + if (connection_state_ == CONNECITON_IN_PROGRESS) { |
| + // Queue this OpenLocalStorage call for when we have a level db pointer. |
| + on_database_opened_callbacks_.push_back( |
| + base::Bind(&DOMStorageContextWrapper::BindLocalStorage, |
| + weak_ptr_factory_.GetWeakPtr(), |
| + origin, |
| + base::Passed(&request))); |
| + return; |
| + } |
| + |
| + BindLocalStorage(origin, std::move(request)); |
| +} |
| + |
| +void DOMStorageContextWrapper::LevelDBWrapperImplHasNoBindings( |
| + const std::string& origin) { |
| + // The DCHECK here broke on chrome-extensions. |
| + level_db_wrappers_.erase(origin); |
| +} |
| + |
| +void DOMStorageContextWrapper::OnDirectoryOpened(filesystem::FileError err) { |
| + if (err != filesystem::FileError::OK) { |
| + NOTREACHED(); |
| + return; |
| + } |
| + |
| + // Now that we have a directory, connect to the LevelDB service and get our |
| + // database. |
| + leveldb_connection_ = content::MojoAppConnection::Create( |
| + browser_context_, "mojo:leveldb", content::kBrowserMojoAppUrl); |
| + leveldb_connection_->GetInterface(&leveldb_); |
| + |
| + leveldb_->Open(std::move(directory_), "dom_storage", GetProxy(&database_), |
| + base::Bind(&DOMStorageContextWrapper::OnDatabaseOpened, |
| + weak_ptr_factory_.GetWeakPtr())); |
| +} |
| + |
| +void DOMStorageContextWrapper::OnDatabaseOpened(leveldb::DatabaseError status) { |
| + if (status != leveldb::DatabaseError::OK) { |
| + NOTREACHED(); |
| + return; |
| + } |
| + |
| + // Tear down the profile connection now; we no longer need it. |
| + directory_.reset(); |
| + profile_service_.reset(); |
| + profile_connection_.reset(); |
| + |
| + // |database_| should be valid now. Run our delayed bindings. |
| + connection_state_ = CONNECTED; |
| + for (size_t i = 0; i < on_database_opened_callbacks_.size(); ++i) |
| + on_database_opened_callbacks_[i].Run(); |
| + on_database_opened_callbacks_.clear(); |
| + |
| + database_->Put(mojo::Array<uint8_t>::From(std::string("key")), |
| + mojo::Array<uint8_t>::From(std::string("value")), |
| + base::Bind(&DOMStorageContextWrapper::OnCrudWritten, |
| + weak_ptr_factory_.GetWeakPtr())); |
| +} |
| + |
| +void DOMStorageContextWrapper::OnCrudWritten(leveldb::DatabaseError status) { |
| + LOG(ERROR) << "Writing some crud to dom storage: " << status; |
|
Elliot Glaysher
2016/03/02 23:06:20
[xxx: Obviously not commitable as is, this is just
|
| +} |
| + |
| +void DOMStorageContextWrapper::BindLocalStorage( |
| + const mojo::String& origin, |
| + mojo::InterfaceRequest<LevelDBWrapper> request) { |
| if (level_db_wrappers_.find(origin) == level_db_wrappers_.end()) { |
| level_db_wrappers_[origin] = make_scoped_ptr(new LevelDBWrapperImpl( |
| + database_.get(), |
| origin, |
| base::Bind(&DOMStorageContextWrapper::LevelDBWrapperImplHasNoBindings, |
| base::Unretained(this), |
| origin.get()))); |
| } |
| - // TODO(jam): call LevelDB service (once per this object) to open the database |
| - // for LocalStorage and keep a pointer to it in this class. Then keep a map |
| - // from origins to LevelDBWrapper object. Each call here for the same origin |
| - // should use the same LevelDBWrapper object. |
| level_db_wrappers_[origin]->Bind(std::move(request)); |
| } |
| -void DOMStorageContextWrapper::LevelDBWrapperImplHasNoBindings( |
| - const std::string& origin) { |
| - DCHECK(level_db_wrappers_.find(origin) != level_db_wrappers_.end()); |
| - level_db_wrappers_.erase(origin); |
| -} |
| - |
| } // namespace content |