Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(393)

Side by Side Diff: content/browser/dom_storage/dom_storage_context_wrapper.cc

Issue 1737933002: mojo leveldb: Get profile and leveldb connected to DOMStorageContext. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove stray mark. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/dom_storage/dom_storage_context_wrapper.h" 5 #include "content/browser/dom_storage/dom_storage_context_wrapper.h"
6 6
7 #include <string> 7 #include <string>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/bind_helpers.h" 11 #include "base/bind_helpers.h"
12 #include "base/files/file_path.h" 12 #include "base/files/file_path.h"
13 #include "base/location.h" 13 #include "base/location.h"
14 #include "base/memory/weak_ptr.h"
14 #include "base/single_thread_task_runner.h" 15 #include "base/single_thread_task_runner.h"
16 #include "base/strings/utf_string_conversions.h"
15 #include "base/thread_task_runner_handle.h" 17 #include "base/thread_task_runner_handle.h"
18 #include "components/filesystem/public/interfaces/directory.mojom.h"
19 #include "components/leveldb/public/interfaces/leveldb.mojom.h"
20 #include "components/profile_service/public/interfaces/profile.mojom.h"
16 #include "content/browser/dom_storage/dom_storage_area.h" 21 #include "content/browser/dom_storage/dom_storage_area.h"
17 #include "content/browser/dom_storage/dom_storage_context_impl.h" 22 #include "content/browser/dom_storage/dom_storage_context_impl.h"
18 #include "content/browser/dom_storage/dom_storage_task_runner.h" 23 #include "content/browser/dom_storage/dom_storage_task_runner.h"
19 #include "content/browser/dom_storage/session_storage_namespace_impl.h" 24 #include "content/browser/dom_storage/session_storage_namespace_impl.h"
20 #include "content/browser/leveldb_wrapper_impl.h" 25 #include "content/browser/leveldb_wrapper_impl.h"
21 #include "content/public/browser/browser_thread.h" 26 #include "content/public/browser/browser_thread.h"
22 #include "content/public/browser/local_storage_usage_info.h" 27 #include "content/public/browser/local_storage_usage_info.h"
28 #include "content/public/browser/mojo_app_connection.h"
23 #include "content/public/browser/session_storage_usage_info.h" 29 #include "content/public/browser/session_storage_usage_info.h"
30 #include "mojo/common/common_type_converters.h"
24 31
25 namespace content { 32 namespace content {
26 namespace { 33 namespace {
27 34
28 const char kLocalStorageDirectory[] = "Local Storage"; 35 const char kLocalStorageDirectory[] = "Local Storage";
29 const char kSessionStorageDirectory[] = "Session Storage"; 36 const char kSessionStorageDirectory[] = "Session Storage";
30 37
31 void InvokeLocalStorageUsageCallbackHelper( 38 void InvokeLocalStorageUsageCallbackHelper(
32 const DOMStorageContext::GetLocalStorageUsageCallback& callback, 39 const DOMStorageContext::GetLocalStorageUsageCallback& callback,
33 const std::vector<LocalStorageUsageInfo>* infos) { 40 const std::vector<LocalStorageUsageInfo>* infos) {
(...skipping 25 matching lines...) Expand all
59 std::vector<SessionStorageUsageInfo>* infos = 66 std::vector<SessionStorageUsageInfo>* infos =
60 new std::vector<SessionStorageUsageInfo>; 67 new std::vector<SessionStorageUsageInfo>;
61 context->GetSessionStorageUsage(infos); 68 context->GetSessionStorageUsage(infos);
62 reply_task_runner->PostTask( 69 reply_task_runner->PostTask(
63 FROM_HERE, base::Bind(&InvokeSessionStorageUsageCallbackHelper, callback, 70 FROM_HERE, base::Bind(&InvokeSessionStorageUsageCallbackHelper, callback,
64 base::Owned(infos))); 71 base::Owned(infos)));
65 } 72 }
66 73
67 } // namespace 74 } // namespace
68 75
76 // Used for mojo-based LocalStorage implementation (behind --mojo-local-storage
77 // for now).
78 class DOMStorageContextWrapper::MojoState {
79 public:
80 MojoState(const std::string& mojo_user_id, const base::FilePath& subdirectory)
81 : mojo_user_id_(mojo_user_id),
82 subdirectory_(subdirectory),
83 connection_state_(NO_CONNECTION),
84 weak_ptr_factory_(this) {}
85
86 void OpenLocalStorage(const url::Origin& origin,
87 LevelDBWrapperRequest request);
88
89 private:
90 void LevelDBWrapperImplHasNoBindings(const url::Origin& origin) {
91 DCHECK(level_db_wrappers_.find(origin) != level_db_wrappers_.end());
92 level_db_wrappers_.erase(origin);
michaeln 2016/03/17 22:35:42 given the current strategy of no leveldb backing f
93 }
94
95 // Part of our asynchronous directory opening called from OpenLocalStorage().
96 void OnDirectoryOpened(filesystem::FileError err);
97 void OnDatabaseOpened(leveldb::DatabaseError status);
98
99 // The (possibly delayed) implementation of OpenLocalStorage(). Can be called
100 // directly from that function, or through |on_database_open_callbacks_|.
101 void BindLocalStorage(const url::Origin& origin,
102 LevelDBWrapperRequest request);
103
104 // Maps between an origin and its prefixed LevelDB view.
105 std::map<url::Origin, scoped_ptr<LevelDBWrapperImpl>> level_db_wrappers_;
106
107 std::string mojo_user_id_;
108 base::FilePath subdirectory_;
109
110 enum ConnectionState {
111 NO_CONNECTION,
112 CONNECTION_IN_PROGRESS,
113 CONNECTION_FINISHED
114 } connection_state_;
115
116 scoped_ptr<MojoAppConnection> profile_app_connection_;
117 profile::ProfileServicePtr profile_service_;
118 filesystem::DirectoryPtr directory_;
119
120 leveldb::LevelDBServicePtr leveldb_service_;
121 leveldb::LevelDBDatabasePtr database_;
122
123 std::vector<base::Closure> on_database_opened_callbacks_;
124
125 base::WeakPtrFactory<MojoState> weak_ptr_factory_;
126 };
127
128 void DOMStorageContextWrapper::MojoState::OpenLocalStorage(
129 const url::Origin& origin,
130 LevelDBWrapperRequest request) {
131 // If we don't have a specific subdirectory where we want to put our data
132 // (ie, we're in incognito mode), just bind the storage with a null leveldb_
133 // database.
134 if (subdirectory_.empty()) {
135 BindLocalStorage(origin, std::move(request));
136 return;
137 }
138
139 // If we don't have a filesystem_connection_, we'll need to establish one.
140 if (connection_state_ == NO_CONNECTION) {
141 profile_app_connection_ = MojoAppConnection::Create(
142 mojo_user_id_, "mojo:profile", kBrowserMojoAppUrl);
143 profile_app_connection_->GetInterface(&profile_service_);
144
145 profile_service_->GetSubDirectory(
146 mojo::String::From(subdirectory_.AsUTF8Unsafe()),
michaeln 2016/03/17 22:35:41 yup, utf8 is really safe since this is just the re
147 GetProxy(&directory_),
148 base::Bind(&MojoState::OnDirectoryOpened,
149 weak_ptr_factory_.GetWeakPtr()));
150 connection_state_ = CONNECTION_IN_PROGRESS;
151 }
152
153 if (connection_state_ == CONNECTION_IN_PROGRESS) {
154 // Queue this OpenLocalStorage call for when we have a level db pointer.
155 on_database_opened_callbacks_.push_back(
156 base::Bind(&MojoState::BindLocalStorage, weak_ptr_factory_.GetWeakPtr(),
157 origin, base::Passed(&request)));
158 return;
159 }
160
161 BindLocalStorage(origin, std::move(request));
162 }
163
164 void DOMStorageContextWrapper::MojoState::OnDirectoryOpened(
165 filesystem::FileError err) {
166 if (err != filesystem::FileError::OK) {
167 // We failed to open the directory; continue with startup so that we create
168 // the |level_db_wrappers_|.
169 OnDatabaseOpened(leveldb::DatabaseError::IO_ERROR);
170 return;
171 }
172
173 // Now that we have a directory, connect to the LevelDB service and get our
174 // database.
175 profile_app_connection_->GetInterface(&leveldb_service_);
176
177 leveldb_service_->Open(
178 std::move(directory_), "leveldb", GetProxy(&database_),
179 base::Bind(&MojoState::OnDatabaseOpened, weak_ptr_factory_.GetWeakPtr()));
180 }
181
182 void DOMStorageContextWrapper::MojoState::OnDatabaseOpened(
183 leveldb::DatabaseError status) {
184 if (status != leveldb::DatabaseError::OK) {
185 // If we failed to open the database, reset the service object so we pass
186 // null pointers to our wrappers.
187 database_.reset();
188 leveldb_service_.reset();
189 }
190
191 // We no longer need the profile service; we've either transferred
192 // |directory_| to the leveldb service, or we got a file error and no more is
193 // possible.
194 directory_.reset();
195 profile_service_.reset();
196
197 // |leveldb_| should be know to either be valid or invalid by now. Run our
michaeln 2016/03/17 22:35:41 typo: known
198 // delayed bindings.
199 connection_state_ = CONNECTION_FINISHED;
200 for (size_t i = 0; i < on_database_opened_callbacks_.size(); ++i)
201 on_database_opened_callbacks_[i].Run();
202 on_database_opened_callbacks_.clear();
203 }
204
205 void DOMStorageContextWrapper::MojoState::BindLocalStorage(
206 const url::Origin& origin,
207 LevelDBWrapperRequest request) {
208 if (level_db_wrappers_.find(origin) == level_db_wrappers_.end()) {
209 level_db_wrappers_[origin] = make_scoped_ptr(new LevelDBWrapperImpl(
210 database_.get(),
211 origin.Serialize(),
212 base::Bind(&MojoState::LevelDBWrapperImplHasNoBindings,
213 base::Unretained(this),
214 origin)));
215 }
216
217 level_db_wrappers_[origin]->Bind(std::move(request));
218 }
219
69 DOMStorageContextWrapper::DOMStorageContextWrapper( 220 DOMStorageContextWrapper::DOMStorageContextWrapper(
70 const base::FilePath& data_path, 221 const std::string& mojo_user_id,
222 const base::FilePath& profile_path,
223 const base::FilePath& local_partition_path,
71 storage::SpecialStoragePolicy* special_storage_policy) { 224 storage::SpecialStoragePolicy* special_storage_policy) {
225 base::FilePath storage_dir;
226 if (!profile_path.empty())
227 storage_dir = local_partition_path.AppendASCII(kLocalStorageDirectory);
228 mojo_state_.reset(new MojoState(mojo_user_id, storage_dir));
229
230 base::FilePath data_path;
231 if (!profile_path.empty())
232 data_path = profile_path.Append(local_partition_path);
72 base::SequencedWorkerPool* worker_pool = BrowserThread::GetBlockingPool(); 233 base::SequencedWorkerPool* worker_pool = BrowserThread::GetBlockingPool();
73 context_ = new DOMStorageContextImpl( 234 context_ = new DOMStorageContextImpl(
74 data_path.empty() ? data_path 235 data_path.empty() ? data_path
75 : data_path.AppendASCII(kLocalStorageDirectory), 236 : data_path.AppendASCII(kLocalStorageDirectory),
76 data_path.empty() ? data_path 237 data_path.empty() ? data_path
77 : data_path.AppendASCII(kSessionStorageDirectory), 238 : data_path.AppendASCII(kSessionStorageDirectory),
78 special_storage_policy, 239 special_storage_policy,
79 new DOMStorageWorkerPoolTaskRunner( 240 new DOMStorageWorkerPoolTaskRunner(
80 worker_pool, 241 worker_pool,
81 worker_pool->GetNamedSequenceToken("dom_storage_primary"), 242 worker_pool->GetNamedSequenceToken("dom_storage_primary"),
82 worker_pool->GetNamedSequenceToken("dom_storage_commit"), 243 worker_pool->GetNamedSequenceToken("dom_storage_commit"),
83 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO) 244 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)
84 .get())); 245 .get()));
85 } 246 }
86 247
87 DOMStorageContextWrapper::~DOMStorageContextWrapper() { 248 DOMStorageContextWrapper::~DOMStorageContextWrapper() {}
88 }
89 249
90 void DOMStorageContextWrapper::GetLocalStorageUsage( 250 void DOMStorageContextWrapper::GetLocalStorageUsage(
91 const GetLocalStorageUsageCallback& callback) { 251 const GetLocalStorageUsageCallback& callback) {
92 DCHECK(context_.get()); 252 DCHECK(context_.get());
93 context_->task_runner()->PostShutdownBlockingTask( 253 context_->task_runner()->PostShutdownBlockingTask(
94 FROM_HERE, DOMStorageTaskRunner::PRIMARY_SEQUENCE, 254 FROM_HERE, DOMStorageTaskRunner::PRIMARY_SEQUENCE,
95 base::Bind(&GetLocalStorageUsageHelper, 255 base::Bind(&GetLocalStorageUsageHelper,
96 base::ThreadTaskRunnerHandle::Get(), context_, callback)); 256 base::ThreadTaskRunnerHandle::Get(), context_, callback));
97 } 257 }
98 258
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
147 void DOMStorageContextWrapper::SetForceKeepSessionState() { 307 void DOMStorageContextWrapper::SetForceKeepSessionState() {
148 DCHECK(context_.get()); 308 DCHECK(context_.get());
149 context_->task_runner()->PostShutdownBlockingTask( 309 context_->task_runner()->PostShutdownBlockingTask(
150 FROM_HERE, 310 FROM_HERE,
151 DOMStorageTaskRunner::PRIMARY_SEQUENCE, 311 DOMStorageTaskRunner::PRIMARY_SEQUENCE,
152 base::Bind(&DOMStorageContextImpl::SetForceKeepSessionState, context_)); 312 base::Bind(&DOMStorageContextImpl::SetForceKeepSessionState, context_));
153 } 313 }
154 314
155 void DOMStorageContextWrapper::Shutdown() { 315 void DOMStorageContextWrapper::Shutdown() {
156 DCHECK(context_.get()); 316 DCHECK(context_.get());
317 mojo_state_.reset();
157 context_->task_runner()->PostShutdownBlockingTask( 318 context_->task_runner()->PostShutdownBlockingTask(
158 FROM_HERE, 319 FROM_HERE,
159 DOMStorageTaskRunner::PRIMARY_SEQUENCE, 320 DOMStorageTaskRunner::PRIMARY_SEQUENCE,
160 base::Bind(&DOMStorageContextImpl::Shutdown, context_)); 321 base::Bind(&DOMStorageContextImpl::Shutdown, context_));
161 } 322 }
162 323
163 void DOMStorageContextWrapper::Flush() { 324 void DOMStorageContextWrapper::Flush() {
164 DCHECK(context_.get()); 325 DCHECK(context_.get());
165 context_->task_runner()->PostShutdownBlockingTask( 326 context_->task_runner()->PostShutdownBlockingTask(
166 FROM_HERE, DOMStorageTaskRunner::PRIMARY_SEQUENCE, 327 FROM_HERE, DOMStorageTaskRunner::PRIMARY_SEQUENCE,
167 base::Bind(&DOMStorageContextImpl::Flush, context_)); 328 base::Bind(&DOMStorageContextImpl::Flush, context_));
168 } 329 }
169 330
170 void DOMStorageContextWrapper::OpenLocalStorage( 331 void DOMStorageContextWrapper::OpenLocalStorage(const url::Origin& origin,
171 const url::Origin& origin, 332 LevelDBWrapperRequest request) {
172 mojo::InterfaceRequest<LevelDBWrapper> request) { 333 mojo_state_->OpenLocalStorage(origin, std::move(request));
173 if (level_db_wrappers_.find(origin) == level_db_wrappers_.end()) {
174 level_db_wrappers_[origin] = make_scoped_ptr(new LevelDBWrapperImpl(
175 origin.Serialize(),
176 base::Bind(&DOMStorageContextWrapper::LevelDBWrapperImplHasNoBindings,
177 base::Unretained(this),
178 origin)));
179 }
180 // TODO(jam): call LevelDB service (once per this object) to open the database
181 // for LocalStorage and keep a pointer to it in this class. Then keep a map
182 // from origins to LevelDBWrapper object. Each call here for the same origin
183 // should use the same LevelDBWrapper object.
184
185 level_db_wrappers_[origin]->Bind(std::move(request));
186 }
187
188 void DOMStorageContextWrapper::LevelDBWrapperImplHasNoBindings(
189 const url::Origin& origin) {
190 DCHECK(level_db_wrappers_.find(origin) != level_db_wrappers_.end());
191 level_db_wrappers_.erase(origin);
192 } 334 }
193 335
194 } // namespace content 336 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698