mesa gn build: suppress -Wstring-conversion warnings
[chromium-blink-merge.git] / storage / browser / fileapi / sandbox_prioritized_origin_database.cc
blobc55ad42bd710c736856946e24c44762c175e2c9a
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
3 // found in the LICENSE file.
5 #include "storage/browser/fileapi/sandbox_prioritized_origin_database.h"
7 #include "base/files/file.h"
8 #include "base/files/file_util.h"
9 #include "base/logging.h"
10 #include "base/pickle.h"
11 #include "storage/browser/fileapi/sandbox_isolated_origin_database.h"
12 #include "storage/browser/fileapi/sandbox_origin_database.h"
14 namespace storage {
16 const base::FilePath::CharType*
17 SandboxPrioritizedOriginDatabase::kPrimaryDirectory =
18 FILE_PATH_LITERAL("primary");
20 const base::FilePath::CharType*
21 SandboxPrioritizedOriginDatabase::kPrimaryOriginFile =
22 FILE_PATH_LITERAL("primary.origin");
24 namespace {
26 bool WritePrimaryOriginFile(const base::FilePath& path,
27 const std::string& origin) {
28 base::File file(path, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_WRITE);
29 if (!file.IsValid())
30 return false;
31 if (!file.created())
32 file.SetLength(0);
33 Pickle pickle;
34 pickle.WriteString(origin);
35 file.Write(0, static_cast<const char*>(pickle.data()), pickle.size());
36 file.Flush();
37 return true;
40 bool ReadPrimaryOriginFile(const base::FilePath& path,
41 std::string* origin) {
42 std::string buffer;
43 if (!base::ReadFileToString(path, &buffer))
44 return false;
45 Pickle pickle(buffer.data(), buffer.size());
46 PickleIterator iter(pickle);
47 return pickle.ReadString(&iter, origin) && !origin->empty();
50 } // namespace
52 SandboxPrioritizedOriginDatabase::SandboxPrioritizedOriginDatabase(
53 const base::FilePath& file_system_directory,
54 leveldb::Env* env_override)
55 : file_system_directory_(file_system_directory),
56 env_override_(env_override),
57 primary_origin_file_(
58 file_system_directory_.Append(kPrimaryOriginFile)) {
61 SandboxPrioritizedOriginDatabase::~SandboxPrioritizedOriginDatabase() {
64 bool SandboxPrioritizedOriginDatabase::InitializePrimaryOrigin(
65 const std::string& origin) {
66 if (!primary_origin_database_) {
67 if (!MaybeLoadPrimaryOrigin() && ResetPrimaryOrigin(origin)) {
68 MaybeMigrateDatabase(origin);
69 primary_origin_database_.reset(
70 new SandboxIsolatedOriginDatabase(
71 origin,
72 file_system_directory_,
73 base::FilePath(kPrimaryDirectory)));
74 return true;
78 if (primary_origin_database_)
79 return primary_origin_database_->HasOriginPath(origin);
81 return false;
84 std::string SandboxPrioritizedOriginDatabase::GetPrimaryOrigin() {
85 MaybeLoadPrimaryOrigin();
86 if (primary_origin_database_)
87 return primary_origin_database_->origin();
88 return std::string();
91 bool SandboxPrioritizedOriginDatabase::HasOriginPath(
92 const std::string& origin) {
93 MaybeInitializeDatabases(false);
94 if (primary_origin_database_ &&
95 primary_origin_database_->HasOriginPath(origin))
96 return true;
97 if (origin_database_)
98 return origin_database_->HasOriginPath(origin);
99 return false;
102 bool SandboxPrioritizedOriginDatabase::GetPathForOrigin(
103 const std::string& origin, base::FilePath* directory) {
104 MaybeInitializeDatabases(true);
105 if (primary_origin_database_ &&
106 primary_origin_database_->GetPathForOrigin(origin, directory))
107 return true;
108 DCHECK(origin_database_);
109 return origin_database_->GetPathForOrigin(origin, directory);
112 bool SandboxPrioritizedOriginDatabase::RemovePathForOrigin(
113 const std::string& origin) {
114 MaybeInitializeDatabases(false);
115 if (primary_origin_database_ &&
116 primary_origin_database_->HasOriginPath(origin)) {
117 primary_origin_database_.reset();
118 base::DeleteFile(file_system_directory_.Append(kPrimaryOriginFile),
119 true /* recursive */);
120 return true;
122 if (origin_database_)
123 return origin_database_->RemovePathForOrigin(origin);
124 return true;
127 bool SandboxPrioritizedOriginDatabase::ListAllOrigins(
128 std::vector<OriginRecord>* origins) {
129 // SandboxOriginDatabase may clear the |origins|, so call this before
130 // primary_origin_database_.
131 MaybeInitializeDatabases(false);
132 if (origin_database_ && !origin_database_->ListAllOrigins(origins))
133 return false;
134 if (primary_origin_database_)
135 return primary_origin_database_->ListAllOrigins(origins);
136 return true;
139 void SandboxPrioritizedOriginDatabase::DropDatabase() {
140 primary_origin_database_.reset();
141 origin_database_.reset();
144 bool SandboxPrioritizedOriginDatabase::MaybeLoadPrimaryOrigin() {
145 if (primary_origin_database_)
146 return true;
147 std::string saved_origin;
148 if (!ReadPrimaryOriginFile(primary_origin_file_, &saved_origin))
149 return false;
150 primary_origin_database_.reset(
151 new SandboxIsolatedOriginDatabase(
152 saved_origin,
153 file_system_directory_,
154 base::FilePath(kPrimaryDirectory)));
155 return true;
158 bool SandboxPrioritizedOriginDatabase::ResetPrimaryOrigin(
159 const std::string& origin) {
160 DCHECK(!primary_origin_database_);
161 if (!WritePrimaryOriginFile(primary_origin_file_, origin))
162 return false;
163 // We reset the primary origin directory too.
164 // (This means the origin file corruption causes data loss
165 // We could keep the directory there as the same origin will likely
166 // become the primary origin, but let's play conservatively.)
167 base::DeleteFile(file_system_directory_.Append(kPrimaryDirectory),
168 true /* recursive */);
169 return true;
172 void SandboxPrioritizedOriginDatabase::MaybeMigrateDatabase(
173 const std::string& origin) {
174 MaybeInitializeNonPrimaryDatabase(false);
175 if (!origin_database_)
176 return;
177 if (origin_database_->HasOriginPath(origin)) {
178 base::FilePath directory_name;
179 if (origin_database_->GetPathForOrigin(origin, &directory_name) &&
180 directory_name != base::FilePath(kPrimaryOriginFile)) {
181 base::FilePath from_path = file_system_directory_.Append(directory_name);
182 base::FilePath to_path = file_system_directory_.Append(kPrimaryDirectory);
184 if (base::PathExists(to_path))
185 base::DeleteFile(to_path, true /* recursive */);
186 base::Move(from_path, to_path);
189 origin_database_->RemovePathForOrigin(origin);
192 std::vector<OriginRecord> origins;
193 origin_database_->ListAllOrigins(&origins);
194 if (origins.empty()) {
195 origin_database_->RemoveDatabase();
196 origin_database_.reset();
200 void SandboxPrioritizedOriginDatabase::MaybeInitializeDatabases(
201 bool create) {
202 MaybeLoadPrimaryOrigin();
203 MaybeInitializeNonPrimaryDatabase(create);
206 void SandboxPrioritizedOriginDatabase::MaybeInitializeNonPrimaryDatabase(
207 bool create) {
208 if (origin_database_)
209 return;
211 origin_database_.reset(new SandboxOriginDatabase(file_system_directory_,
212 env_override_));
213 if (!create && !base::DirectoryExists(origin_database_->GetDatabasePath())) {
214 origin_database_.reset();
215 return;
219 SandboxOriginDatabase*
220 SandboxPrioritizedOriginDatabase::GetSandboxOriginDatabase() {
221 MaybeInitializeNonPrimaryDatabase(true);
222 return origin_database_.get();
225 } // namespace storage