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..e43b849547c352578460887fe3a4e8be8ac08898 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,15 +71,18 @@ void GetSessionStorageUsageHelper( |
} // namespace |
DOMStorageContextWrapper::DOMStorageContextWrapper( |
- const base::FilePath& data_path, |
- storage::SpecialStoragePolicy* special_storage_policy) { |
+ BrowserContext* context, |
+ const base::FilePath& data_path) |
+ : 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 |
: data_path.AppendASCII(kLocalStorageDirectory), |
data_path.empty() ? data_path |
: data_path.AppendASCII(kSessionStorageDirectory), |
- special_storage_policy, |
+ context->GetSpecialStoragePolicy(), |
new DOMStorageWorkerPoolTaskRunner( |
worker_pool, |
worker_pool->GetNamedSequenceToken("dom_storage_primary"), |
@@ -84,8 +91,7 @@ DOMStorageContextWrapper::DOMStorageContextWrapper( |
.get())); |
} |
-DOMStorageContextWrapper::~DOMStorageContextWrapper() { |
-} |
+DOMStorageContextWrapper::~DOMStorageContextWrapper() {} |
void DOMStorageContextWrapper::GetLocalStorageUsage( |
const GetLocalStorageUsageCallback& callback) { |
@@ -170,25 +176,81 @@ 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_ = MojoAppConnection::Create( |
+ browser_context_, "mojo:profile", kBrowserMojoAppUrl); |
+ profile_connection_->GetInterface(&profile_service_); |
+ |
+ profile_service_->GetDirectory( |
michaeln
2016/03/05 01:38:54
What do we do about incognito profiles? How is tha
Elliot Glaysher
2016/03/10 21:00:35
I was under the impression that incognito stuff ne
|
+ 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) { |
+ DCHECK(level_db_wrappers_.find(origin) != level_db_wrappers_.end()); |
+ level_db_wrappers_.erase(origin); |
+} |
+ |
+void DOMStorageContextWrapper::OnDirectoryOpened(filesystem::FileError err) { |
+ if (err != filesystem::FileError::OK) { |
+ NOTREACHED(); |
michaeln
2016/03/05 01:38:54
What makes this not reachable? If the native file
Elliot Glaysher
2016/03/10 21:00:35
Changed all of this so that it should work even wh
|
+ return; |
+ } |
+ |
+ // Now that we have a directory, connect to the LevelDB service and get our |
+ // database. |
+ leveldb_connection_ = MojoAppConnection::Create( |
michaeln
2016/03/05 01:38:54
naming nit: I understand this was chosen from a mo
Elliot Glaysher
2016/03/10 21:00:35
To match the mojo convention, I renamed |leveldb_|
|
+ browser_context_, "mojo:leveldb", kBrowserMojoAppUrl); |
+ leveldb_connection_->GetInterface(&leveldb_); |
+ |
+ leveldb_->Open(std::move(directory_), "local_storage", GetProxy(&database_), |
michaeln
2016/03/05 01:38:54
I think directory_ corresponds to a particular pro
Elliot Glaysher
2016/03/10 21:00:35
Done, but not like this. |directory_| now points t
|
+ base::Bind(&DOMStorageContextWrapper::OnDatabaseOpened, |
+ weak_ptr_factory_.GetWeakPtr())); |
michaeln
2016/03/05 01:38:54
We currently keep individual local storage sqlite
Elliot Glaysher
2016/03/10 21:00:35
Done.
|
+} |
+ |
+void DOMStorageContextWrapper::OnDatabaseOpened(leveldb::DatabaseError status) { |
+ if (status != leveldb::DatabaseError::OK) { |
+ NOTREACHED(); |
michaeln
2016/03/05 01:38:54
This is certainly reachable, per the show must go
|
+ return; |
+ } |
+ |
+ // |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(); |
+} |
+ |
+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 |