summaryrefslogtreecommitdiff
path: root/chromium/components/services
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/components/services')
-rw-r--r--chromium/components/services/app_service/public/cpp/BUILD.gn11
-rw-r--r--chromium/components/services/app_service/public/cpp/intent_util.cc95
-rw-r--r--chromium/components/services/app_service/public/cpp/intent_util.h31
-rw-r--r--chromium/components/services/app_service/public/mojom/types.mojom1
-rw-r--r--chromium/components/services/font/font_service_app.cc23
-rw-r--r--chromium/components/services/font/font_service_app.h6
-rw-r--r--chromium/components/services/heap_profiling/heap_profiling_service.cc1
-rw-r--r--chromium/components/services/heap_profiling/json_exporter.cc10
-rw-r--r--chromium/components/services/heap_profiling/json_exporter_unittest.cc39
-rw-r--r--chromium/components/services/leveldb/BUILD.gn32
-rw-r--r--chromium/components/services/leveldb/DEPS3
-rw-r--r--chromium/components/services/leveldb/env_mojo.cc577
-rw-r--r--chromium/components/services/leveldb/env_mojo.h102
-rw-r--r--chromium/components/services/leveldb/leveldb.typemap16
-rw-r--r--chromium/components/services/leveldb/leveldb_database_impl.cc555
-rw-r--r--chromium/components/services/leveldb/leveldb_database_impl.h171
-rw-r--r--chromium/components/services/leveldb/leveldb_mojo_proxy.cc323
-rw-r--r--chromium/components/services/leveldb/leveldb_mojo_proxy.h159
-rw-r--r--chromium/components/services/leveldb/leveldb_mojo_unittest.cc36
-rw-r--r--chromium/components/services/leveldb/leveldb_mojom_traits.cc80
-rw-r--r--chromium/components/services/leveldb/leveldb_mojom_traits.h27
-rw-r--r--chromium/components/services/leveldb/leveldb_service_impl.cc131
-rw-r--r--chromium/components/services/leveldb/leveldb_service_impl.h66
-rw-r--r--chromium/components/services/leveldb/leveldb_service_unittest.cc833
-rw-r--r--chromium/components/services/leveldb/public/cpp/BUILD.gn2
-rw-r--r--chromium/components/services/leveldb/public/cpp/remote_iterator.cc63
-rw-r--r--chromium/components/services/leveldb/public/cpp/remote_iterator.h49
-rw-r--r--chromium/components/services/leveldb/public/cpp/util.cc57
-rw-r--r--chromium/components/services/leveldb/public/cpp/util.h16
-rw-r--r--chromium/components/services/leveldb/public/mojom/BUILD.gn10
-rw-r--r--chromium/components/services/leveldb/public/mojom/leveldb.mojom188
-rw-r--r--chromium/components/services/leveldb/remote_iterator_unittest.cc182
-rw-r--r--chromium/components/services/patch/public/cpp/patch.cc4
-rw-r--r--chromium/components/services/pdf_compositor/pdf_compositor_impl.cc13
-rw-r--r--chromium/components/services/storage/dom_storage/dom_storage_database.cc58
-rw-r--r--chromium/components/services/storage/dom_storage/dom_storage_database.h39
-rw-r--r--chromium/components/services/storage/dom_storage/dom_storage_database_unittest.cc15
-rw-r--r--chromium/components/services/storage/partition_impl_unittest.cc2
-rw-r--r--chromium/components/services/storage/storage_service_impl_unittest.cc2
-rw-r--r--chromium/components/services/unzip/public/cpp/unzip.cc26
-rw-r--r--chromium/components/services/unzip/public/mojom/unzipper.mojom9
-rw-r--r--chromium/components/services/unzip/unzipper_impl.cc71
-rw-r--r--chromium/components/services/unzip/unzipper_impl.h19
43 files changed, 637 insertions, 3516 deletions
diff --git a/chromium/components/services/app_service/public/cpp/BUILD.gn b/chromium/components/services/app_service/public/cpp/BUILD.gn
index 502f85ca84b..1e6408f3617 100644
--- a/chromium/components/services/app_service/public/cpp/BUILD.gn
+++ b/chromium/components/services/app_service/public/cpp/BUILD.gn
@@ -8,3 +8,14 @@ source_set("app_file_handling") {
"file_handler_info.h",
]
}
+
+source_set("intent_util") {
+ sources = [
+ "intent_util.cc",
+ "intent_util.h",
+ ]
+
+ deps = [
+ "//base",
+ ]
+}
diff --git a/chromium/components/services/app_service/public/cpp/intent_util.cc b/chromium/components/services/app_service/public/cpp/intent_util.cc
new file mode 100644
index 00000000000..fe37332d916
--- /dev/null
+++ b/chromium/components/services/app_service/public/cpp/intent_util.cc
@@ -0,0 +1,95 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/services/app_service/public/cpp/intent_util.h"
+
+#include "base/compiler_specific.h"
+
+namespace apps_util {
+
+// TODO(crbug.com/853604): For glob match, it is currently only for Android
+// intent filters, so we will use the ARC intent filter implementation that is
+// transcribed from Android codebase, to prevent divergence from Android code.
+bool MatchGlob(const std::string& value, const std::string& pattern) {
+#define GET_CHAR(s, i) ((UNLIKELY(i >= s.length())) ? '\0' : s[i])
+
+ const size_t NP = pattern.length();
+ const size_t NS = value.length();
+ if (NP == 0) {
+ return NS == 0;
+ }
+ size_t ip = 0, is = 0;
+ char nextChar = GET_CHAR(pattern, 0);
+ while (ip < NP && is < NS) {
+ char c = nextChar;
+ ++ip;
+ nextChar = GET_CHAR(pattern, ip);
+ const bool escaped = (c == '\\');
+ if (escaped) {
+ c = nextChar;
+ ++ip;
+ nextChar = GET_CHAR(pattern, ip);
+ }
+ if (nextChar == '*') {
+ if (!escaped && c == '.') {
+ if (ip >= (NP - 1)) {
+ // At the end with a pattern match
+ return true;
+ }
+ ++ip;
+ nextChar = GET_CHAR(pattern, ip);
+ // Consume everything until the next char in the pattern is found.
+ if (nextChar == '\\') {
+ ++ip;
+ nextChar = GET_CHAR(pattern, ip);
+ }
+ do {
+ if (GET_CHAR(value, is) == nextChar) {
+ break;
+ }
+ ++is;
+ } while (is < NS);
+ if (is == NS) {
+ // Next char in the pattern didn't exist in the match.
+ return false;
+ }
+ ++ip;
+ nextChar = GET_CHAR(pattern, ip);
+ ++is;
+ } else {
+ // Consume only characters matching the one before '*'.
+ do {
+ if (GET_CHAR(value, is) != c) {
+ break;
+ }
+ ++is;
+ } while (is < NS);
+ ++ip;
+ nextChar = GET_CHAR(pattern, ip);
+ }
+ } else {
+ if (c != '.' && GET_CHAR(value, is) != c)
+ return false;
+ ++is;
+ }
+ }
+
+ if (ip >= NP && is >= NS) {
+ // Reached the end of both strings
+ return true;
+ }
+
+ // One last check: we may have finished the match string, but still have a
+ // '.*' at the end of the pattern, which is still a match.
+ if (ip == NP - 2 && GET_CHAR(pattern, ip) == '.' &&
+ GET_CHAR(pattern, ip + 1) == '*') {
+ return true;
+ }
+
+ return false;
+
+#undef GET_CHAR
+}
+
+} // namespace apps_util
diff --git a/chromium/components/services/app_service/public/cpp/intent_util.h b/chromium/components/services/app_service/public/cpp/intent_util.h
new file mode 100644
index 00000000000..acd63593307
--- /dev/null
+++ b/chromium/components/services/app_service/public/cpp/intent_util.h
@@ -0,0 +1,31 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_INTENT_UTIL_H_
+#define COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_INTENT_UTIL_H_
+
+// Utility functions for App Service intent handling.
+// This function is needed for both components/arc and
+// chrome/services/app_service at the moment. We are planning to remove the need
+// for this in the components/arc directory and this function can be combined
+// with other intent utility functions for the App service.
+
+#include <string>
+
+namespace apps_util {
+
+// Return true if |value| matches |pattern| with simple glob syntax.
+// In this syntax, you can use the '*' character to match against zero or
+// more occurrences of the character immediately before. If the character
+// before it is '.' it will match any character. The character '\' can be
+// used as an escape. This essentially provides only the '*' wildcard part
+// of a normal regexp.
+// This function is transcribed from android's PatternMatcher#matchPattern.
+// See
+// https://android.googlesource.com/platform/frameworks/base.git/+/e93165456c3c28278f275566bd90bfbcf1a0e5f7/core/java/android/os/PatternMatcher.java#186
+bool MatchGlob(const std::string& value, const std::string& pattern);
+
+} // namespace apps_util
+
+#endif // COMPONENTS_SERVICES_APP_SERVICE_PUBLIC_CPP_INTENT_UTIL_H_ \ No newline at end of file
diff --git a/chromium/components/services/app_service/public/mojom/types.mojom b/chromium/components/services/app_service/public/mojom/types.mojom
index 5e4aaa69a4a..21eca6c2044 100644
--- a/chromium/components/services/app_service/public/mojom/types.mojom
+++ b/chromium/components/services/app_service/public/mojom/types.mojom
@@ -34,6 +34,7 @@ enum AppLaunchSource {
kSourceInstalledNotification = 20,
kSourceContextMenu = 21,
kSourceArc = 22,
+ kSourceIntentUrl = 23, // App launch triggered by a URL.
};
// Don't remove items or change the order of this enum. It's used in
diff --git a/chromium/components/services/font/font_service_app.cc b/chromium/components/services/font/font_service_app.cc
index 16c1958793e..210c2b8b387 100644
--- a/chromium/components/services/font/font_service_app.cc
+++ b/chromium/components/services/font/font_service_app.cc
@@ -10,10 +10,12 @@
#include "base/command_line.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
+#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "components/services/font/fontconfig_matching.h"
#include "mojo/public/cpp/system/platform_handle.h"
#include "ppapi/buildflags/buildflags.h"
+#include "skia/ext/skia_utils_base.h"
#include "ui/gfx/font_fallback_linux.h"
#include "ui/gfx/font_render_params.h"
@@ -115,7 +117,8 @@ void FontServiceApp::MatchFamilyName(const std::string& family_name,
// Stash away the returned path, so we can give it an ID (index)
// which will later be given to us in a request to open the file.
- int index = FindOrAddPath(result_identity.fString);
+ base::FilePath path(result_identity.fString.c_str());
+ size_t index = FindOrAddPath(path);
mojom::FontIdentityPtr identity(mojom::FontIdentity::New());
identity->id = static_cast<uint32_t>(index);
@@ -137,9 +140,8 @@ void FontServiceApp::OpenStream(uint32_t id_number,
DCHECK_LT(id_number, static_cast<uint32_t>(paths_.size()));
base::File file;
- if (id_number < static_cast<uint32_t>(paths_.size())) {
- file = GetFileForPath(base::FilePath(paths_[id_number].c_str()));
- }
+ if (id_number < static_cast<uint32_t>(paths_.size()))
+ file = GetFileForPath(paths_[id_number]);
std::move(callback).Run(std::move(file));
}
@@ -151,7 +153,7 @@ void FontServiceApp::FallbackFontForCharacter(
TRACE_EVENT0("fonts", "FontServiceApp::FallbackFontForCharacter");
auto fallback_font = gfx::GetFallbackFontForChar(character, locale);
- int index = FindOrAddPath(SkString(fallback_font.filename.data()));
+ size_t index = FindOrAddPath(base::FilePath(fallback_font.filename));
mojom::FontIdentityPtr identity(mojom::FontIdentity::New());
identity->id = static_cast<uint32_t>(index);
@@ -206,8 +208,7 @@ void FontServiceApp::MatchFontByPostscriptNameOrFullFontName(
base::Optional<FontConfigLocalMatching::FontConfigMatchResult> match_result =
FontConfigLocalMatching::FindFontByPostscriptNameOrFullFontName(family);
if (match_result) {
- uint32_t fontconfig_interface_id =
- FindOrAddPath(SkString(match_result->file_path.value().c_str()));
+ uint32_t fontconfig_interface_id = FindOrAddPath(match_result->file_path);
mojom::FontIdentityPtr font_identity =
mojom::FontIdentityPtr(mojom::FontIdentity::New(
fontconfig_interface_id, match_result->ttc_index,
@@ -240,11 +241,11 @@ void FontServiceApp::MatchFontWithFallback(
#endif
}
-int FontServiceApp::FindOrAddPath(const SkString& path) {
+size_t FontServiceApp::FindOrAddPath(const base::FilePath& path) {
TRACE_EVENT1("fonts", "FontServiceApp::FindOrAddPath", "path",
- TRACE_STR_COPY(path.c_str()));
- int count = paths_.size();
- for (int i = 0; i < count; ++i) {
+ path.AsUTF8Unsafe());
+ size_t count = paths_.size();
+ for (size_t i = 0; i < count; ++i) {
if (path == paths_[i])
return i;
}
diff --git a/chromium/components/services/font/font_service_app.h b/chromium/components/services/font/font_service_app.h
index eb920d55798..e46d79f5c6f 100644
--- a/chromium/components/services/font/font_service_app.h
+++ b/chromium/components/services/font/font_service_app.h
@@ -8,10 +8,10 @@
#include <stdint.h>
#include <vector>
+#include "base/files/file_path.h"
#include "base/macros.h"
#include "components/services/font/public/mojom/font_service.mojom.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
-#include "skia/ext/skia_utils_base.h"
namespace font_service {
@@ -48,13 +48,13 @@ class FontServiceApp : public mojom::FontService {
uint32_t charset,
uint32_t fallbackFamilyType,
MatchFontWithFallbackCallback callback) override;
- int FindOrAddPath(const SkString& path);
+ size_t FindOrAddPath(const base::FilePath& path);
mojo::ReceiverSet<mojom::FontService> receivers_;
// We don't want to leak paths to our callers; we thus enumerate the paths of
// fonts.
- std::vector<SkString> paths_;
+ std::vector<base::FilePath> paths_;
DISALLOW_COPY_AND_ASSIGN(FontServiceApp);
};
diff --git a/chromium/components/services/heap_profiling/heap_profiling_service.cc b/chromium/components/services/heap_profiling/heap_profiling_service.cc
index 5900052850d..1b66c1bfefe 100644
--- a/chromium/components/services/heap_profiling/heap_profiling_service.cc
+++ b/chromium/components/services/heap_profiling/heap_profiling_service.cc
@@ -20,7 +20,6 @@
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "mojo/public/cpp/system/platform_handle.h"
#include "services/resource_coordinator/public/mojom/memory_instrumentation/memory_instrumentation.mojom.h"
-#include "services/resource_coordinator/public/mojom/service_constants.mojom.h"
namespace heap_profiling {
diff --git a/chromium/components/services/heap_profiling/json_exporter.cc b/chromium/components/services/heap_profiling/json_exporter.cc
index e2ec70c5b42..ea9f2be67b7 100644
--- a/chromium/components/services/heap_profiling/json_exporter.cc
+++ b/chromium/components/services/heap_profiling/json_exporter.cc
@@ -234,10 +234,12 @@ base::Value BuildAllocations(const AllocationMap& allocations,
for (const auto& alloc : allocations) {
int allocator = static_cast<int>(alloc.first.allocator);
+ // We use double to store size and count, as it can precisely represent
+ // values up to 2^52 ~ 4.5 petabytes.
counts[allocator].push_back(
- base::Value(static_cast<int>(alloc.second.count)));
+ base::Value(static_cast<double>(alloc.second.count)));
sizes[allocator].push_back(
- base::Value(static_cast<int>(alloc.second.size)));
+ base::Value(static_cast<double>(alloc.second.size)));
types[allocator].push_back(base::Value(alloc.first.context_id));
nodes[allocator].push_back(base::Value(alloc_to_node_id.at(&alloc.first)));
}
@@ -300,7 +302,9 @@ std::string ExportMemoryMapsAndV2StackTraceToJSON(ExportParams* params) {
result.SetKey("heaps_v2", std::move(heaps_v2));
std::string result_json;
- bool ok = base::JSONWriter::Write(result, &result_json);
+ bool ok = base::JSONWriter::WriteWithOptions(
+ result, base::JSONWriter::OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION,
+ &result_json);
DCHECK(ok);
return result_json;
}
diff --git a/chromium/components/services/heap_profiling/json_exporter_unittest.cc b/chromium/components/services/heap_profiling/json_exporter_unittest.cc
index e9974d9af95..f9bf760435b 100644
--- a/chromium/components/services/heap_profiling/json_exporter_unittest.cc
+++ b/chromium/components/services/heap_profiling/json_exporter_unittest.cc
@@ -421,4 +421,43 @@ TEST(ProfilingJsonExporterTest, Context) {
ASSERT_TRUE(found_no_context);
}
+#if defined(ARCH_CPU_64_BITS)
+TEST(ProfilingJsonExporterTest, LargeAllocation) {
+ std::vector<Address> stack1{Address(0x5678), Address(0x1234)};
+ AllocationMap allocs;
+ InsertAllocation(&allocs, AllocatorType::kMalloc,
+ static_cast<size_t>(0x9876543210ul), stack1, 0);
+
+ ExportParams params;
+ params.allocs = std::move(allocs);
+ std::string json = ExportMemoryMapsAndV2StackTraceToJSON(&params);
+
+ // JSON should parse.
+ base::JSONReader json_reader(base::JSON_PARSE_RFC);
+ base::Optional<base::Value> result = json_reader.ReadToValue(json);
+ ASSERT_TRUE(result.has_value()) << json_reader.GetErrorMessage();
+
+ // Validate the allocators summary.
+ const base::Value* malloc_summary =
+ result.value().FindPath({"allocators", "malloc"});
+ ASSERT_TRUE(malloc_summary);
+ const base::Value* malloc_size =
+ malloc_summary->FindPath({"attrs", "size", "value"});
+ ASSERT_TRUE(malloc_size);
+ EXPECT_EQ("9876543210", malloc_size->GetString());
+ const base::Value* malloc_virtual_size =
+ malloc_summary->FindPath({"attrs", "virtual_size", "value"});
+ ASSERT_TRUE(malloc_virtual_size);
+ EXPECT_EQ("9876543210", malloc_virtual_size->GetString());
+
+ // Validate allocators details.
+ // heaps_v2.allocators.malloc.sizes.reduce((a,s)=>a+s,0).
+ const base::Value* malloc =
+ result.value().FindPath({"heaps_v2", "allocators", "malloc"});
+ const base::Value* malloc_sizes = malloc->FindKey("sizes");
+ EXPECT_EQ(1u, malloc_sizes->GetList().size());
+ EXPECT_EQ(0x9876543210ul, malloc_sizes->GetList()[0].GetDouble());
+}
+#endif
+
} // namespace heap_profiling
diff --git a/chromium/components/services/leveldb/BUILD.gn b/chromium/components/services/leveldb/BUILD.gn
index b4a651097cf..624c887c6f7 100644
--- a/chromium/components/services/leveldb/BUILD.gn
+++ b/chromium/components/services/leveldb/BUILD.gn
@@ -6,20 +6,14 @@ import("//testing/test.gni")
static_library("lib") {
sources = [
- "env_mojo.cc",
- "env_mojo.h",
"leveldb_database_impl.cc",
"leveldb_database_impl.h",
- "leveldb_mojo_proxy.cc",
- "leveldb_mojo_proxy.h",
- "leveldb_service_impl.cc",
- "leveldb_service_impl.h",
]
public_deps = [
- "//components/services/filesystem/public/mojom",
"//components/services/leveldb/public/cpp",
"//components/services/leveldb/public/mojom",
+ "//components/services/storage",
]
deps = [
@@ -27,27 +21,3 @@ static_library("lib") {
"//third_party/leveldatabase",
]
}
-
-test("leveldb_service_unittests") {
- sources = [
- "leveldb_mojo_unittest.cc",
- "leveldb_service_unittest.cc",
- "remote_iterator_unittest.cc",
- ]
-
- deps = [
- ":lib",
- "//base",
- "//base/test:test_support",
- "//components/services/filesystem:lib",
- "//components/services/filesystem:test_support",
- "//components/services/filesystem/public/mojom",
- "//components/services/leveldb/public/cpp",
- "//components/services/leveldb/public/mojom",
- "//mojo/core/test:run_all_unittests",
- "//mojo/public/cpp/bindings",
- "//mojo/public/cpp/system",
- "//testing/gtest",
- "//third_party/leveldatabase",
- ]
-}
diff --git a/chromium/components/services/leveldb/DEPS b/chromium/components/services/leveldb/DEPS
index 1debd9d34f1..995db6c575d 100644
--- a/chromium/components/services/leveldb/DEPS
+++ b/chromium/components/services/leveldb/DEPS
@@ -1,5 +1,4 @@
include_rules = [
- "+components/services/filesystem/public/mojom",
- "+mojo/public",
+ "+components/services/storage/dom_storage",
"+third_party/leveldatabase",
]
diff --git a/chromium/components/services/leveldb/env_mojo.cc b/chromium/components/services/leveldb/env_mojo.cc
deleted file mode 100644
index 01561482cee..00000000000
--- a/chromium/components/services/leveldb/env_mojo.cc
+++ /dev/null
@@ -1,577 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/services/leveldb/env_mojo.h"
-
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/bind.h"
-#include "base/metrics/histogram_functions.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/strings/string_util.h"
-#include "base/task/post_task.h"
-#include "base/trace_event/trace_event.h"
-#include "third_party/leveldatabase/chromium_logger.h"
-#include "third_party/leveldatabase/src/include/leveldb/status.h"
-
-#if defined(OS_WIN) && defined(DeleteFile)
-#undef DeleteFile
-#endif
-
-using leveldb_env::UMALogger;
-
-namespace leveldb {
-
-namespace {
-
-const base::FilePath::CharType table_extension[] = FILE_PATH_LITERAL(".ldb");
-
-Status FilesystemErrorToStatus(base::File::Error error,
- const std::string& filename,
- leveldb_env::MethodID method) {
- if (error == base::File::Error::FILE_OK)
- return Status::OK();
-
- std::string err_str = base::File::ErrorToString(error);
-
- char buf[512];
- snprintf(buf, sizeof(buf), "%s (MojoFSError: %d::%s)", err_str.c_str(),
- method, MethodIDToString(method));
-
- // TOOD(https://crbug.com/760362): Map base::File::Error::NOT_FOUND to
- // Status::NotFound, after fixing LevelDB to handle the NotFound correctly.
- return Status::IOError(filename, buf);
-}
-
-class MojoFileLock : public FileLock {
- public:
- MojoFileLock(LevelDBMojoProxy::OpaqueLock* lock, const std::string& name)
- : fname_(name), lock_(lock) {}
- ~MojoFileLock() override { DCHECK(!lock_); }
-
- const std::string& name() const { return fname_; }
-
- LevelDBMojoProxy::OpaqueLock* TakeLock() {
- LevelDBMojoProxy::OpaqueLock* to_return = lock_;
- lock_ = nullptr;
- return to_return;
- }
-
- private:
- std::string fname_;
- LevelDBMojoProxy::OpaqueLock* lock_;
-};
-
-class MojoSequentialFile : public leveldb::SequentialFile {
- public:
- MojoSequentialFile(const std::string& fname,
- base::File f,
- const UMALogger* uma_logger)
- : filename_(fname), file_(std::move(f)), uma_logger_(uma_logger) {}
- ~MojoSequentialFile() override {}
-
- Status Read(size_t n, Slice* result, char* scratch) override {
- int bytes_read =
- file_.ReadAtCurrentPosNoBestEffort(scratch, static_cast<int>(n));
- if (bytes_read == -1) {
- base::File::Error error = base::File::GetLastFileError();
- uma_logger_->RecordOSError(leveldb_env::kSequentialFileRead, error);
- return MakeIOError(filename_, base::File::ErrorToString(error),
- leveldb_env::kSequentialFileRead, error);
- }
- if (bytes_read > 0)
- uma_logger_->RecordBytesRead(bytes_read);
- *result = Slice(scratch, bytes_read);
- return Status::OK();
- }
-
- Status Skip(uint64_t n) override {
- if (file_.Seek(base::File::FROM_CURRENT, n) == -1) {
- base::File::Error error = base::File::GetLastFileError();
- uma_logger_->RecordOSError(leveldb_env::kSequentialFileSkip, error);
- return MakeIOError(filename_, base::File::ErrorToString(error),
- leveldb_env::kSequentialFileSkip, error);
- }
- return Status::OK();
- }
-
- private:
- std::string filename_;
- base::File file_;
- const UMALogger* uma_logger_;
-
- DISALLOW_COPY_AND_ASSIGN(MojoSequentialFile);
-};
-
-class MojoRandomAccessFile : public leveldb::RandomAccessFile {
- public:
- MojoRandomAccessFile(const std::string& fname,
- base::File file,
- const UMALogger* uma_logger)
- : filename_(fname), file_(std::move(file)), uma_logger_(uma_logger) {}
- ~MojoRandomAccessFile() override {}
-
- Status Read(uint64_t offset,
- size_t n,
- Slice* result,
- char* scratch) const override {
- int bytes_read = file_.Read(offset, scratch, static_cast<int>(n));
- *result = Slice(scratch, (bytes_read < 0) ? 0 : bytes_read);
- if (bytes_read < 0) {
- uma_logger_->RecordOSError(leveldb_env::kRandomAccessFileRead,
- base::File::GetLastFileError());
- return MakeIOError(filename_, "Could not perform read",
- leveldb_env::kRandomAccessFileRead);
- }
- if (bytes_read > 0)
- uma_logger_->RecordBytesRead(bytes_read);
- return Status::OK();
- }
-
- private:
- std::string filename_;
- mutable base::File file_;
- const UMALogger* uma_logger_;
-
- DISALLOW_COPY_AND_ASSIGN(MojoRandomAccessFile);
-};
-
-class MojoWritableFile : public leveldb::WritableFile {
- public:
- MojoWritableFile(LevelDBMojoProxy::OpaqueDir* dir,
- const std::string& fname,
- base::File f,
- scoped_refptr<LevelDBMojoProxy> thread,
- const UMALogger* uma_logger)
- : filename_(fname),
- file_(std::move(f)),
- file_type_(kOther),
- dir_(dir),
- thread_(thread),
- uma_logger_(uma_logger) {
- base::FilePath path = base::FilePath::FromUTF8Unsafe(fname);
- if (base::StartsWith(path.BaseName().AsUTF8Unsafe(), "MANIFEST",
- base::CompareCase::SENSITIVE)) {
- file_type_ = kManifest;
- } else if (path.MatchesExtension(table_extension)) {
- file_type_ = kTable;
- }
- parent_dir_ =
- base::FilePath::FromUTF8Unsafe(fname).DirName().AsUTF8Unsafe();
- }
-
- ~MojoWritableFile() override {}
-
- leveldb::Status Append(const leveldb::Slice& data) override {
- int bytes_written =
- file_.WriteAtCurrentPos(data.data(), static_cast<int>(data.size()));
- if (bytes_written != static_cast<int>(data.size())) {
- base::File::Error error = base::File::GetLastFileError();
- uma_logger_->RecordOSError(leveldb_env::kWritableFileAppend, error);
- return MakeIOError(filename_, base::File::ErrorToString(error),
- leveldb_env::kWritableFileAppend, error);
- }
- if (bytes_written > 0)
- uma_logger_->RecordBytesWritten(bytes_written);
- return Status::OK();
- }
-
- leveldb::Status Close() override {
- file_.Close();
- return Status::OK();
- }
-
- leveldb::Status Flush() override {
- // base::File doesn't do buffered I/O (i.e. POSIX FILE streams) so nothing
- // to flush.
- return Status::OK();
- }
-
- leveldb::Status Sync() override {
- TRACE_EVENT0("leveldb", "MojoWritableFile::Sync");
-
- if (!file_.Flush()) {
- base::File::Error error = base::File::GetLastFileError();
- uma_logger_->RecordOSError(leveldb_env::kWritableFileSync, error);
- return MakeIOError(filename_, base::File::ErrorToString(error),
- leveldb_env::kWritableFileSync, error);
- }
-
- // leveldb's implicit contract for Sync() is that if this instance is for a
- // manifest file then the directory is also sync'ed. See leveldb's
- // env_posix.cc.
- if (file_type_ == kManifest)
- return SyncParent();
-
- return Status::OK();
- }
-
- private:
- enum Type { kManifest, kTable, kOther };
-
- leveldb::Status SyncParent() {
- base::File::Error error = thread_->SyncDirectory(dir_, parent_dir_);
- if (error != base::File::Error::FILE_OK) {
- uma_logger_->RecordOSError(leveldb_env::kSyncParent,
- static_cast<base::File::Error>(error));
- }
- return error == base::File::Error::FILE_OK
- ? Status::OK()
- : Status::IOError(filename_,
- base::File::ErrorToString(base::File::Error(
- static_cast<int>(error))));
- }
-
- std::string filename_;
- base::File file_;
- Type file_type_;
- LevelDBMojoProxy::OpaqueDir* dir_;
- std::string parent_dir_;
- scoped_refptr<LevelDBMojoProxy> thread_;
- const UMALogger* uma_logger_;
-
- DISALLOW_COPY_AND_ASSIGN(MojoWritableFile);
-};
-
-class Thread : public base::PlatformThread::Delegate {
- public:
- Thread(void (*function)(void* arg), void* arg)
- : function_(function), arg_(arg) {
- base::PlatformThreadHandle handle;
- bool success = base::PlatformThread::Create(0, this, &handle);
- DCHECK(success);
- }
- ~Thread() override {}
- void ThreadMain() override {
- (*function_)(arg_);
- delete this;
- }
-
- private:
- void (*function_)(void* arg);
- void* arg_;
-
- DISALLOW_COPY_AND_ASSIGN(Thread);
-};
-
-class Retrier {
- public:
- Retrier(leveldb_env::MethodID method, MojoRetrierProvider* provider)
- : start_(base::TimeTicks::Now()),
- limit_(start_ + base::TimeDelta::FromMilliseconds(
- provider->MaxRetryTimeMillis())),
- last_(start_),
- time_to_sleep_(base::TimeDelta::FromMilliseconds(10)),
- success_(true),
- method_(method),
- last_error_(base::File::FILE_OK),
- provider_(provider) {}
-
- ~Retrier() {
- if (success_) {
- provider_->RecordRetryTime(method_, last_ - start_);
- if (last_error_ != base::File::FILE_OK) {
- DCHECK_LT(last_error_, 0);
- provider_->RecordRecoveredFromError(method_, last_error_);
- }
- }
- }
-
- bool ShouldKeepTrying(base::File::Error last_error) {
- DCHECK_NE(last_error, base::File::FILE_OK);
- last_error_ = last_error;
- if (last_ < limit_) {
- base::PlatformThread::Sleep(time_to_sleep_);
- last_ = base::TimeTicks::Now();
- return true;
- }
- success_ = false;
- return false;
- }
-
- private:
- base::TimeTicks start_;
- base::TimeTicks limit_;
- base::TimeTicks last_;
- base::TimeDelta time_to_sleep_;
- bool success_;
- leveldb_env::MethodID method_;
- base::File::Error last_error_;
- MojoRetrierProvider* provider_;
-
- DISALLOW_COPY_AND_ASSIGN(Retrier);
-};
-
-} // namespace
-
-MojoEnv::MojoEnv(scoped_refptr<LevelDBMojoProxy> file_thread,
- LevelDBMojoProxy::OpaqueDir* dir)
- : thread_(file_thread), dir_(dir) {}
-
-MojoEnv::~MojoEnv() {
- thread_->UnregisterDirectory(dir_);
-}
-
-Status MojoEnv::NewSequentialFile(const std::string& fname,
- SequentialFile** result) {
- TRACE_EVENT1("leveldb", "MojoEnv::NewSequentialFile", "fname", fname);
- base::File f = thread_->OpenFileHandle(
- dir_, fname, filesystem::mojom::kFlagOpen | filesystem::mojom::kFlagRead);
- if (!f.IsValid()) {
- *result = nullptr;
- RecordOSError(leveldb_env::kNewSequentialFile, f.error_details());
- return MakeIOError(fname, "Unable to create sequential file",
- leveldb_env::kNewSequentialFile, f.error_details());
- }
-
- *result = new MojoSequentialFile(fname, std::move(f), this);
- return Status::OK();
-}
-
-Status MojoEnv::NewRandomAccessFile(const std::string& fname,
- RandomAccessFile** result) {
- TRACE_EVENT1("leveldb", "MojoEnv::NewRandomAccessFile", "fname", fname);
- base::File f = thread_->OpenFileHandle(
- dir_, fname, filesystem::mojom::kFlagRead | filesystem::mojom::kFlagOpen);
- if (!f.IsValid()) {
- *result = nullptr;
- base::File::Error error_code = f.error_details();
- RecordOSError(leveldb_env::kNewRandomAccessFile, error_code);
- return MakeIOError(fname, base::File::ErrorToString(error_code),
- leveldb_env::kNewRandomAccessFile, error_code);
- }
-
- *result = new MojoRandomAccessFile(fname, std::move(f), this);
- return Status::OK();
-}
-
-Status MojoEnv::NewWritableFile(const std::string& fname,
- WritableFile** result) {
- TRACE_EVENT1("leveldb", "MojoEnv::NewWritableFile", "fname", fname);
- base::File f = thread_->OpenFileHandle(
- dir_, fname,
- filesystem::mojom::kCreateAlways | filesystem::mojom::kFlagWrite);
- if (!f.IsValid()) {
- *result = nullptr;
- RecordOSError(leveldb_env::kNewWritableFile, f.error_details());
- return MakeIOError(fname, "Unable to create writable file",
- leveldb_env::kNewWritableFile, f.error_details());
- }
-
- *result = new MojoWritableFile(dir_, fname, std::move(f), thread_, this);
- return Status::OK();
-}
-
-Status MojoEnv::NewAppendableFile(const std::string& fname,
- WritableFile** result) {
- TRACE_EVENT1("leveldb", "MojoEnv::NewAppendableFile", "fname", fname);
- base::File f = thread_->OpenFileHandle(
- dir_, fname,
- filesystem::mojom::kFlagOpenAlways | filesystem::mojom::kFlagAppend);
- if (!f.IsValid()) {
- *result = nullptr;
- RecordOSError(leveldb_env::kNewAppendableFile, f.error_details());
- return MakeIOError(fname, "Unable to create appendable file",
- leveldb_env::kNewAppendableFile, f.error_details());
- }
-
- *result = new MojoWritableFile(dir_, fname, std::move(f), thread_, this);
- return Status::OK();
-}
-
-bool MojoEnv::FileExists(const std::string& fname) {
- TRACE_EVENT1("leveldb", "MojoEnv::FileExists", "fname", fname);
- return thread_->FileExists(dir_, fname);
-}
-
-Status MojoEnv::GetChildren(const std::string& path,
- std::vector<std::string>* result) {
- TRACE_EVENT1("leveldb", "MojoEnv::GetChildren", "path", path);
- base::File::Error error = thread_->GetChildren(dir_, path, result);
- if (error != base::File::Error::FILE_OK)
- RecordFileError(leveldb_env::kGetChildren, error);
- return FilesystemErrorToStatus(error, path, leveldb_env::kGetChildren);
-}
-
-Status MojoEnv::DeleteFile(const std::string& fname) {
- TRACE_EVENT1("leveldb", "MojoEnv::DeleteFile", "fname", fname);
- base::File::Error error = thread_->Delete(dir_, fname, 0);
- if (error != base::File::Error::FILE_OK)
- RecordFileError(leveldb_env::kDeleteFile, error);
- return FilesystemErrorToStatus(error, fname, leveldb_env::kDeleteFile);
-}
-
-Status MojoEnv::CreateDir(const std::string& dirname) {
- TRACE_EVENT1("leveldb", "MojoEnv::CreateDir", "dirname", dirname);
- Retrier retrier(leveldb_env::kCreateDir, this);
- base::File::Error error;
- do {
- error = thread_->CreateDir(dir_, dirname);
- } while (error != base::File::Error::FILE_OK &&
- retrier.ShouldKeepTrying(error));
- if (error != base::File::Error::FILE_OK)
- RecordFileError(leveldb_env::kCreateDir, error);
- return FilesystemErrorToStatus(error, dirname, leveldb_env::kCreateDir);
-}
-
-Status MojoEnv::DeleteDir(const std::string& dirname) {
- TRACE_EVENT1("leveldb", "MojoEnv::DeleteDir", "dirname", dirname);
- base::File::Error error =
- thread_->Delete(dir_, dirname, filesystem::mojom::kDeleteFlagRecursive);
- if (error != base::File::Error::FILE_OK)
- RecordFileError(leveldb_env::kDeleteDir, error);
- return FilesystemErrorToStatus(error, dirname, leveldb_env::kDeleteDir);
-}
-
-Status MojoEnv::GetFileSize(const std::string& fname, uint64_t* file_size) {
- TRACE_EVENT1("leveldb", "MojoEnv::GetFileSize", "fname", fname);
- base::File::Error error = thread_->GetFileSize(dir_, fname, file_size);
- if (error != base::File::Error::FILE_OK)
- RecordFileError(leveldb_env::kGetFileSize, error);
- return FilesystemErrorToStatus(error, fname, leveldb_env::kGetFileSize);
-}
-
-Status MojoEnv::RenameFile(const std::string& src, const std::string& target) {
- TRACE_EVENT2("leveldb", "MojoEnv::RenameFile", "src", src, "target", target);
- if (!thread_->FileExists(dir_, src))
- return Status::OK();
- Retrier retrier(leveldb_env::kRenameFile, this);
- base::File::Error error;
- do {
- error = thread_->RenameFile(dir_, src, target);
- } while (error != base::File::Error::FILE_OK &&
- retrier.ShouldKeepTrying(error));
- if (error != base::File::Error::FILE_OK)
- RecordFileError(leveldb_env::kRenameFile, error);
- return FilesystemErrorToStatus(error, src, leveldb_env::kRenameFile);
-}
-
-Status MojoEnv::LockFile(const std::string& fname, FileLock** lock) {
- TRACE_EVENT1("leveldb", "MojoEnv::LockFile", "fname", fname);
-
- Retrier retrier(leveldb_env::kLockFile, this);
- std::pair<base::File::Error, LevelDBMojoProxy::OpaqueLock*> p;
- do {
- p = thread_->LockFile(dir_, fname);
- } while (p.first != base::File::Error::FILE_OK &&
- retrier.ShouldKeepTrying(p.first));
-
- if (p.first != base::File::Error::FILE_OK)
- RecordFileError(leveldb_env::kLockFile, p.first);
-
- if (p.second)
- *lock = new MojoFileLock(p.second, fname);
-
- return FilesystemErrorToStatus(p.first, fname, leveldb_env::kLockFile);
-}
-
-Status MojoEnv::UnlockFile(FileLock* lock) {
- MojoFileLock* my_lock = reinterpret_cast<MojoFileLock*>(lock);
-
- std::string fname = my_lock ? my_lock->name() : "(invalid)";
- TRACE_EVENT1("leveldb", "MojoEnv::UnlockFile", "fname", fname);
-
- base::File::Error error = thread_->UnlockFile(my_lock->TakeLock());
- if (error != base::File::Error::FILE_OK)
- RecordFileError(leveldb_env::kUnlockFile, error);
- delete my_lock;
- return FilesystemErrorToStatus(error, fname, leveldb_env::kUnlockFile);
-}
-
-Status MojoEnv::GetTestDirectory(std::string* path) {
- // TODO(erg): This method is actually only used from the test harness in
- // leveldb. And when we go and port that test stuff to a
- // service_manager::ServiceTest,
- // we probably won't use it since the mojo filesystem actually handles
- // temporary filesystems just fine.
- NOTREACHED();
- return Status::OK();
-}
-
-Status MojoEnv::NewLogger(const std::string& fname, Logger** result) {
- TRACE_EVENT1("leveldb", "MojoEnv::NewLogger", "fname", fname);
- base::File f(thread_->OpenFileHandle(
- dir_, fname,
- filesystem::mojom::kCreateAlways | filesystem::mojom::kFlagWrite));
- if (!f.IsValid()) {
- *result = nullptr;
- RecordOSError(leveldb_env::kNewLogger, f.error_details());
- return MakeIOError(fname, "Unable to create log file",
- leveldb_env::kNewLogger, f.error_details());
- }
- *result = new leveldb::ChromiumLogger(std::move(f));
- return Status::OK();
-}
-
-uint64_t MojoEnv::NowMicros() {
- return base::TimeTicks::Now().ToInternalValue();
-}
-
-void MojoEnv::SleepForMicroseconds(int micros) {
- // Round up to the next millisecond.
- base::PlatformThread::Sleep(base::TimeDelta::FromMicroseconds(micros));
-}
-
-void MojoEnv::Schedule(void (*function)(void* arg), void* arg) {
- base::PostTask(
- FROM_HERE,
- {base::ThreadPool(), base::MayBlock(), base::WithBaseSyncPrimitives(),
- base::TaskShutdownBehavior::BLOCK_SHUTDOWN},
- base::BindOnce(function, arg));
-}
-
-void MojoEnv::StartThread(void (*function)(void* arg), void* arg) {
- new Thread(function, arg); // Will self-delete.
-}
-
-void MojoEnv::RecordErrorAt(leveldb_env::MethodID method) const {
- UMA_HISTOGRAM_ENUMERATION("MojoLevelDBEnv.IOError", method,
- leveldb_env::kNumEntries);
-}
-
-void MojoEnv::RecordOSError(leveldb_env::MethodID method,
- base::File::Error error) const {
- RecordErrorAt(method);
- std::string uma_name =
- std::string("MojoLevelDBEnv.IOError.BFE.") + MethodIDToString(method);
- base::UmaHistogramExactLinear(uma_name, -error, -base::File::FILE_ERROR_MAX);
-}
-
-void MojoEnv::RecordBytesRead(int amount) const {
- UMA_HISTOGRAM_COUNTS_10M("Storage.BytesRead.MojoLevelDBEnv", amount);
-}
-
-void MojoEnv::RecordBytesWritten(int amount) const {
- UMA_HISTOGRAM_COUNTS_10M("Storage.BytesWritten.MojoLevelDBEnv", amount);
-}
-
-int MojoEnv::MaxRetryTimeMillis() const {
- return 1000;
-}
-
-void MojoEnv::RecordRetryTime(leveldb_env::MethodID method,
- base::TimeDelta time) const {
- std::string uma_name = std::string("MojoLevelDBEnv.TimeUntilSuccessFor") +
- MethodIDToString(method);
- UmaHistogramCustomTimes(uma_name, time, base::TimeDelta::FromMilliseconds(1),
- base::TimeDelta::FromMilliseconds(1001), 42);
-}
-
-void MojoEnv::RecordRecoveredFromError(leveldb_env::MethodID method,
- base::File::Error error) const {
- std::string uma_name =
- std::string("MojoLevelDBEnv.RetryRecoveredFromErrorIn") +
- MethodIDToString(method);
- base::UmaHistogramExactLinear(uma_name, -error, -base::File::FILE_ERROR_MAX);
-}
-
-void MojoEnv::RecordFileError(leveldb_env::MethodID method,
- base::File::Error error) const {
- RecordOSError(method, static_cast<base::File::Error>(error));
-}
-
-} // namespace leveldb
diff --git a/chromium/components/services/leveldb/env_mojo.h b/chromium/components/services/leveldb/env_mojo.h
deleted file mode 100644
index 0529d9c5836..00000000000
--- a/chromium/components/services/leveldb/env_mojo.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_SERVICES_LEVELDB_ENV_MOJO_H_
-#define COMPONENTS_SERVICES_LEVELDB_ENV_MOJO_H_
-
-#include <string>
-#include <vector>
-
-#include "build/build_config.h"
-#include "components/services/filesystem/public/mojom/directory.mojom.h"
-#include "components/services/leveldb/leveldb_mojo_proxy.h"
-#include "third_party/leveldatabase/env_chromium.h"
-#include "third_party/leveldatabase/src/include/leveldb/env.h"
-
-#if defined(OS_WIN) && defined(DeleteFile)
-// See comment in env.h.
-#undef DeleteFile
-#define ENV_MOJO_DELETEFILE_UNDEFINED
-#endif // defined(OS_WIN) && defined(DeleteFile)
-
-namespace leveldb {
-
-class MojoRetrierProvider {
- public:
- virtual int MaxRetryTimeMillis() const = 0;
- virtual void RecordRetryTime(leveldb_env::MethodID method,
- base::TimeDelta time) const = 0;
- virtual void RecordRecoveredFromError(leveldb_env::MethodID method,
- base::File::Error error) const = 0;
-};
-
-// An implementation of the leveldb operating system interaction code which
-// proxies to a specified mojo:filesystem directory. Most of these methods are
-// synchronous and block on responses from the filesystem service. That's fine
-// since, for the most part, they merely open files or check for a file's
-// existence.
-class MojoEnv : public Env,
- public leveldb_env::UMALogger,
- public MojoRetrierProvider {
- public:
- MojoEnv(scoped_refptr<LevelDBMojoProxy> file_thread,
- LevelDBMojoProxy::OpaqueDir* dir);
- ~MojoEnv() override;
-
- // Overridden from leveldb::Env:
- Status NewSequentialFile(const std::string& fname,
- SequentialFile** result) override;
- Status NewRandomAccessFile(const std::string& fname,
- RandomAccessFile** result) override;
- Status NewWritableFile(const std::string& fname,
- WritableFile** result) override;
- Status NewAppendableFile(const std::string& fname,
- WritableFile** result) override;
- bool FileExists(const std::string& fname) override;
- Status GetChildren(const std::string& dir,
- std::vector<std::string>* result) override;
- Status DeleteFile(const std::string& fname) override;
- Status CreateDir(const std::string& dirname) override;
- Status DeleteDir(const std::string& dirname) override;
- Status GetFileSize(const std::string& fname, uint64_t* file_size) override;
- Status RenameFile(const std::string& src, const std::string& target) override;
- Status LockFile(const std::string& fname, FileLock** lock) override;
- Status UnlockFile(FileLock* lock) override;
- Status GetTestDirectory(std::string* path) override;
- Status NewLogger(const std::string& fname, Logger** result) override;
-
- uint64_t NowMicros() override;
- void SleepForMicroseconds(int micros) override;
- void Schedule(void (*function)(void* arg), void* arg) override;
- void StartThread(void (*function)(void* arg), void* arg) override;
-
- private:
- void RecordErrorAt(leveldb_env::MethodID method) const override;
- void RecordOSError(leveldb_env::MethodID method,
- base::File::Error error) const override;
- void RecordBytesRead(int amount) const override;
- void RecordBytesWritten(int amount) const override;
- int MaxRetryTimeMillis() const override;
- void RecordRetryTime(leveldb_env::MethodID method,
- base::TimeDelta time) const override;
- void RecordRecoveredFromError(leveldb_env::MethodID method,
- base::File::Error error) const override;
-
- void RecordFileError(leveldb_env::MethodID method,
- base::File::Error error) const;
-
- scoped_refptr<LevelDBMojoProxy> thread_;
- LevelDBMojoProxy::OpaqueDir* dir_;
-
- DISALLOW_COPY_AND_ASSIGN(MojoEnv);
-};
-
-} // namespace leveldb
-
-// Redefine DeleteFile if necessary.
-#if defined(OS_WIN) && defined(ENV_MOJO_DELETEFILE_UNDEFINED)
-#define DeleteFile DeleteFileW
-#endif
-
-#endif // COMPONENTS_SERVICES_LEVELDB_ENV_MOJO_H_
diff --git a/chromium/components/services/leveldb/leveldb.typemap b/chromium/components/services/leveldb/leveldb.typemap
deleted file mode 100644
index 1af5cdfe363..00000000000
--- a/chromium/components/services/leveldb/leveldb.typemap
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2017 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-mojom = "//components/services/leveldb/public/mojom/leveldb.mojom"
-public_headers = [ "//third_party/leveldatabase/env_chromium.h" ]
-traits_headers = [ "//components/services/leveldb/leveldb_mojom_traits.h" ]
-sources = [
- "//components/services/leveldb/leveldb_mojom_traits.cc",
-]
-deps = []
-public_deps = [
- "//mojo/public/cpp/bindings",
- "//third_party/leveldatabase",
-]
-type_mappings = [ "leveldb.mojom.OpenOptions=::leveldb_env::Options" ]
diff --git a/chromium/components/services/leveldb/leveldb_database_impl.cc b/chromium/components/services/leveldb/leveldb_database_impl.cc
index b0970698c17..14e056aaf69 100644
--- a/chromium/components/services/leveldb/leveldb_database_impl.cc
+++ b/chromium/components/services/leveldb/leveldb_database_impl.cc
@@ -5,6 +5,7 @@
#include "components/services/leveldb/leveldb_database_impl.h"
#include <inttypes.h>
+
#include <algorithm>
#include <map>
#include <string>
@@ -14,417 +15,221 @@
#include "base/rand_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
-#include "base/trace_event/memory_dump_manager.h"
-#include "components/services/leveldb/env_mojo.h"
#include "components/services/leveldb/public/cpp/util.h"
#include "third_party/leveldatabase/env_chromium.h"
#include "third_party/leveldatabase/src/include/leveldb/db.h"
#include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
namespace leveldb {
-namespace {
-
-template <typename FunctionType>
-leveldb::Status ForEachWithPrefix(leveldb::DB* db,
- const leveldb::Slice& key_prefix,
- FunctionType function) {
- leveldb::ReadOptions read_options;
- // Disable filling the cache for bulk scans. Either this is for deletion
- // (where caching those blocks doesn't make sense) or a mass-read, which the
- // user "should" be caching / only needing once.
- read_options.fill_cache = false;
- std::unique_ptr<leveldb::Iterator> it(db->NewIterator(read_options));
- it->Seek(key_prefix);
- for (; it->Valid(); it->Next()) {
- if (!it->key().starts_with(key_prefix))
- break;
- function(it->key(), it->value());
- }
- return it->status();
-}
-
-} // namespace
-LevelDBDatabaseImpl::LevelDBDatabaseImpl(
- std::unique_ptr<Env> environment,
- std::unique_ptr<DB> db,
- std::unique_ptr<Cache> cache,
+// static
+std::unique_ptr<LevelDBDatabaseImpl> LevelDBDatabaseImpl::OpenDirectory(
const leveldb_env::Options& options,
- const std::string& name,
- base::Optional<base::trace_event::MemoryAllocatorDumpGuid> memory_dump_id)
- : environment_(std::move(environment)),
- cache_(std::move(cache)),
- db_(std::move(db)),
- options_(options),
- name_(name),
- memory_dump_id_(memory_dump_id) {
- base::trace_event::MemoryDumpManager::GetInstance()
- ->RegisterDumpProviderWithSequencedTaskRunner(
- this, "MojoLevelDB", base::SequencedTaskRunnerHandle::Get(),
- MemoryDumpProvider::Options());
-}
-
-LevelDBDatabaseImpl::~LevelDBDatabaseImpl() {
- base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
- this);
- for (auto& p : iterator_map_)
- delete p.second;
- for (auto& p : snapshot_map_)
- db_->ReleaseSnapshot(p.second);
-}
+ const base::FilePath& directory,
+ const std::string& dbname,
+ const base::Optional<base::trace_event::MemoryAllocatorDumpGuid>&
+ memory_dump_id,
+ scoped_refptr<base::SequencedTaskRunner> blocking_task_runner,
+ StatusCallback callback) {
+ std::unique_ptr<LevelDBDatabaseImpl> db(new LevelDBDatabaseImpl);
+ storage::DomStorageDatabase::OpenDirectory(
+ directory, dbname, options, memory_dump_id,
+ std::move(blocking_task_runner),
+ base::BindOnce(&LevelDBDatabaseImpl::OnDatabaseOpened,
+ db->weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+ return db;
+}
+
+// static
+std::unique_ptr<LevelDBDatabaseImpl> LevelDBDatabaseImpl::OpenInMemory(
+ const base::Optional<base::trace_event::MemoryAllocatorDumpGuid>&
+ memory_dump_id,
+ const std::string& tracking_name,
+ scoped_refptr<base::SequencedTaskRunner> blocking_task_runner,
+ StatusCallback callback) {
+ std::unique_ptr<LevelDBDatabaseImpl> db(new LevelDBDatabaseImpl);
+ storage::DomStorageDatabase::OpenInMemory(
+ tracking_name, memory_dump_id, std::move(blocking_task_runner),
+ base::BindOnce(&LevelDBDatabaseImpl::OnDatabaseOpened,
+ db->weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
+ return db;
+}
+
+LevelDBDatabaseImpl::LevelDBDatabaseImpl() = default;
+
+LevelDBDatabaseImpl::~LevelDBDatabaseImpl() = default;
void LevelDBDatabaseImpl::Put(const std::vector<uint8_t>& key,
const std::vector<uint8_t>& value,
- PutCallback callback) {
- Status status =
- db_->Put(leveldb::WriteOptions(), GetSliceFor(key), GetSliceFor(value));
- std::move(callback).Run(LeveldbStatusToError(status));
+ StatusCallback callback) {
+ RunDatabaseTask(
+ base::BindOnce(
+ [](const std::vector<uint8_t>& key, const std::vector<uint8_t>& value,
+ const storage::DomStorageDatabase& db) {
+ return db.Put(key, value);
+ },
+ key, value),
+ std::move(callback));
}
void LevelDBDatabaseImpl::Delete(const std::vector<uint8_t>& key,
- DeleteCallback callback) {
- Status status = db_->Delete(leveldb::WriteOptions(), GetSliceFor(key));
- std::move(callback).Run(LeveldbStatusToError(status));
+ StatusCallback callback) {
+ RunDatabaseTask(
+ base::BindOnce(
+ [](const std::vector<uint8_t>& key,
+ const storage::DomStorageDatabase& db) { return db.Delete(key); },
+ key),
+ std::move(callback));
}
void LevelDBDatabaseImpl::DeletePrefixed(const std::vector<uint8_t>& key_prefix,
- DeletePrefixedCallback callback) {
- WriteBatch batch;
- Status status = DeletePrefixedHelper(GetSliceFor(key_prefix), &batch);
- if (status.ok())
- status = db_->Write(leveldb::WriteOptions(), &batch);
- std::move(callback).Run(LeveldbStatusToError(status));
-}
-
-void LevelDBDatabaseImpl::RewriteDB(RewriteDBCallback callback) {
- Status status = leveldb_env::RewriteDB(options_, name_, &db_);
- std::move(callback).Run(LeveldbStatusToError(status));
- if (!db_ && close_binding_) {
- // There is no point in existence without a db_.
- std::move(close_binding_).Run();
- }
-}
-
-void LevelDBDatabaseImpl::SetCloseBindingClosure(
- base::OnceClosure close_binding) {
- close_binding_ = std::move(close_binding);
+ StatusCallback callback) {
+ RunDatabaseTask(base::BindOnce(
+ [](const std::vector<uint8_t>& prefix,
+ const storage::DomStorageDatabase& db) {
+ WriteBatch batch;
+ Status status = db.DeletePrefixed(prefix, &batch);
+ if (!status.ok())
+ return status;
+ return db.Commit(&batch);
+ },
+ key_prefix),
+ std::move(callback));
+}
+
+void LevelDBDatabaseImpl::RewriteDB(StatusCallback callback) {
+ DCHECK(database_);
+ database_.PostTaskWithThisObject(
+ FROM_HERE,
+ base::BindOnce(
+ [](StatusCallback callback,
+ scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
+ storage::DomStorageDatabase* db) {
+ callback_task_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(std::move(callback), db->RewriteDB()));
+ },
+ std::move(callback), base::SequencedTaskRunnerHandle::Get()));
}
void LevelDBDatabaseImpl::Write(
std::vector<mojom::BatchedOperationPtr> operations,
- WriteCallback callback) {
- WriteBatch batch;
-
- for (size_t i = 0; i < operations.size(); ++i) {
- switch (operations[i]->type) {
- case mojom::BatchOperationType::PUT_KEY: {
- if (operations[i]->value) {
- batch.Put(GetSliceFor(operations[i]->key),
- GetSliceFor(*(operations[i]->value)));
- } else {
- batch.Put(GetSliceFor(operations[i]->key), Slice());
- }
- break;
- }
- case mojom::BatchOperationType::DELETE_KEY: {
- batch.Delete(GetSliceFor(operations[i]->key));
- break;
- }
- case mojom::BatchOperationType::DELETE_PREFIXED_KEY: {
- DeletePrefixedHelper(GetSliceFor(operations[i]->key), &batch);
- break;
- }
- case mojom::BatchOperationType::COPY_PREFIXED_KEY: {
- if (!operations[i]->value) {
- mojo::ReportBadMessage(
- "COPY_PREFIXED_KEY operation must provide a value.");
- std::move(callback).Run(mojom::DatabaseError::INVALID_ARGUMENT);
- return;
- }
- CopyPrefixedHelper(operations[i]->key, *(operations[i]->value), &batch);
- break;
- }
- }
- }
-
- Status status = db_->Write(leveldb::WriteOptions(), &batch);
- std::move(callback).Run(LeveldbStatusToError(status));
+ StatusCallback callback) {
+ RunDatabaseTask(
+ base::BindOnce(
+ [](std::vector<mojom::BatchedOperationPtr> operations,
+ const storage::DomStorageDatabase& db) {
+ WriteBatch batch;
+ for (auto& op : operations) {
+ switch (op->type) {
+ case mojom::BatchOperationType::PUT_KEY: {
+ if (op->value) {
+ batch.Put(GetSliceFor(op->key), GetSliceFor(*(op->value)));
+ } else {
+ batch.Put(GetSliceFor(op->key), Slice());
+ }
+ break;
+ }
+ case mojom::BatchOperationType::DELETE_KEY: {
+ batch.Delete(GetSliceFor(op->key));
+ break;
+ }
+ case mojom::BatchOperationType::DELETE_PREFIXED_KEY: {
+ db.DeletePrefixed(op->key, &batch);
+ break;
+ }
+ case mojom::BatchOperationType::COPY_PREFIXED_KEY: {
+ // DCHECK is fine here since browser code is the only caller.
+ DCHECK(op->value);
+ db.CopyPrefixed(op->key, *(op->value), &batch);
+ break;
+ }
+ }
+ }
+ return db.Commit(&batch);
+ },
+ std::move(operations)),
+ std::move(callback));
}
void LevelDBDatabaseImpl::Get(const std::vector<uint8_t>& key,
GetCallback callback) {
- std::string value;
- Status status = db_->Get(leveldb::ReadOptions(), GetSliceFor(key), &value);
- std::move(callback).Run(LeveldbStatusToError(status),
- StdStringToUint8Vector(value));
-}
-
-void LevelDBDatabaseImpl::GetMany(
- std::vector<mojom::GetManyRequestPtr> keys_or_prefixes,
- GetManyCallback callback) {
- std::vector<mojom::GetManyResultPtr> data;
-
- for (const auto& request : keys_or_prefixes) {
- mojom::GetManyResultPtr result = mojom::GetManyResult::New();
+ struct GetResult {
Status status;
-
- if (request->is_key()) {
- const std::vector<uint8_t>& key = request->get_key();
- std::string value;
- status = db_->Get(leveldb::ReadOptions(), GetSliceFor(key), &value);
- if (status.ok())
- result->set_key_value(StdStringToUint8Vector(value));
- else
- result->set_status(LeveldbStatusToError(status));
- } else {
- const std::vector<uint8_t>& key_prefix = request->get_key_prefix();
- std::vector<mojom::KeyValuePtr> values;
- std::tie(status, values) = GetPrefixedHelper(key_prefix);
- if (status.ok())
- result->set_key_prefix_values(std::move(values));
- else
- result->set_status(LeveldbStatusToError(status));
- }
-
- data.push_back(std::move(result));
- }
-
- std::move(callback).Run(std::move(data));
+ storage::DomStorageDatabase::Value value;
+ };
+ RunDatabaseTask(base::BindOnce(
+ [](const std::vector<uint8_t>& key,
+ const storage::DomStorageDatabase& db) {
+ GetResult result;
+ result.status = db.Get(key, &result.value);
+ return result;
+ },
+ key),
+ base::BindOnce(
+ [](GetCallback callback, GetResult result) {
+ std::move(callback).Run(result.status, result.value);
+ },
+ std::move(callback)));
}
void LevelDBDatabaseImpl::GetPrefixed(const std::vector<uint8_t>& key_prefix,
GetPrefixedCallback callback) {
- std::vector<mojom::KeyValuePtr> data;
- Status status;
- std::tie(status, data) = GetPrefixedHelper(key_prefix);
- std::move(callback).Run(LeveldbStatusToError(status), std::move(data));
+ struct GetPrefixedResult {
+ Status status;
+ std::vector<storage::DomStorageDatabase::KeyValuePair> entries;
+ };
+
+ RunDatabaseTask(
+ base::BindOnce(
+ [](const std::vector<uint8_t>& prefix,
+ const storage::DomStorageDatabase& db) {
+ GetPrefixedResult result;
+ result.status = db.GetPrefixed(prefix, &result.entries);
+ return result;
+ },
+ key_prefix),
+ base::BindOnce(
+ [](GetPrefixedCallback callback, GetPrefixedResult result) {
+ std::vector<mojom::KeyValuePtr> entries;
+ for (auto& entry : result.entries)
+ entries.push_back(mojom::KeyValue::New(entry.key, entry.value));
+ std::move(callback).Run(result.status, std::move(entries));
+ },
+ std::move(callback)));
}
void LevelDBDatabaseImpl::CopyPrefixed(
const std::vector<uint8_t>& source_key_prefix,
const std::vector<uint8_t>& destination_key_prefix,
- CopyPrefixedCallback callback) {
- WriteBatch batch;
- Status status =
- CopyPrefixedHelper(source_key_prefix, destination_key_prefix, &batch);
- if (status.ok())
- status = db_->Write(leveldb::WriteOptions(), &batch);
- std::move(callback).Run(LeveldbStatusToError(status));
-}
-
-void LevelDBDatabaseImpl::GetSnapshot(GetSnapshotCallback callback) {
- const Snapshot* s = db_->GetSnapshot();
- base::UnguessableToken token = base::UnguessableToken::Create();
- snapshot_map_.insert(std::make_pair(token, s));
- std::move(callback).Run(token);
-}
-
-void LevelDBDatabaseImpl::ReleaseSnapshot(
- const base::UnguessableToken& snapshot) {
- auto it = snapshot_map_.find(snapshot);
- if (it != snapshot_map_.end()) {
- db_->ReleaseSnapshot(it->second);
- snapshot_map_.erase(it);
- }
-}
-
-void LevelDBDatabaseImpl::GetFromSnapshot(
- const base::UnguessableToken& snapshot,
- const std::vector<uint8_t>& key,
- GetCallback callback) {
- // If the snapshot id is invalid, send back invalid argument
- auto it = snapshot_map_.find(snapshot);
- if (it == snapshot_map_.end()) {
- std::move(callback).Run(mojom::DatabaseError::INVALID_ARGUMENT,
- std::vector<uint8_t>());
- return;
+ StatusCallback callback) {
+ RunDatabaseTask(base::BindOnce(
+ [](const std::vector<uint8_t>& prefix,
+ const std::vector<uint8_t>& new_prefix,
+ const storage::DomStorageDatabase& db) {
+ WriteBatch batch;
+ Status status =
+ db.CopyPrefixed(prefix, new_prefix, &batch);
+ if (!status.ok())
+ return status;
+ return db.Commit(&batch);
+ },
+ source_key_prefix, destination_key_prefix),
+ std::move(callback));
+}
+
+void LevelDBDatabaseImpl::OnDatabaseOpened(
+ StatusCallback callback,
+ base::SequenceBound<storage::DomStorageDatabase> database,
+ leveldb::Status status) {
+ database_ = std::move(database);
+ std::vector<DatabaseTask> tasks;
+ std::swap(tasks, tasks_to_run_on_open_);
+ if (status.ok()) {
+ for (auto& task : tasks)
+ database_.PostTaskWithThisObject(FROM_HERE, std::move(task));
}
-
- std::string value;
- leveldb::ReadOptions options;
- options.snapshot = it->second;
- Status status = db_->Get(options, GetSliceFor(key), &value);
- std::move(callback).Run(LeveldbStatusToError(status),
- StdStringToUint8Vector(value));
-}
-
-void LevelDBDatabaseImpl::NewIterator(NewIteratorCallback callback) {
- Iterator* iterator = db_->NewIterator(leveldb::ReadOptions());
- base::UnguessableToken token = base::UnguessableToken::Create();
- iterator_map_.insert(std::make_pair(token, iterator));
- std::move(callback).Run(token);
-}
-
-void LevelDBDatabaseImpl::NewIteratorFromSnapshot(
- const base::UnguessableToken& snapshot,
- NewIteratorFromSnapshotCallback callback) {
- // If the snapshot id is invalid, send back invalid argument
- auto it = snapshot_map_.find(snapshot);
- if (it == snapshot_map_.end()) {
- std::move(callback).Run(base::Optional<base::UnguessableToken>());
- return;
- }
-
- leveldb::ReadOptions options;
- options.snapshot = it->second;
-
- Iterator* iterator = db_->NewIterator(options);
- base::UnguessableToken new_token = base::UnguessableToken::Create();
- iterator_map_.insert(std::make_pair(new_token, iterator));
- std::move(callback).Run(new_token);
-}
-
-void LevelDBDatabaseImpl::ReleaseIterator(
- const base::UnguessableToken& iterator) {
- auto it = iterator_map_.find(iterator);
- if (it != iterator_map_.end()) {
- delete it->second;
- iterator_map_.erase(it);
- }
-}
-
-void LevelDBDatabaseImpl::IteratorSeekToFirst(
- const base::UnguessableToken& iterator,
- IteratorSeekToFirstCallback callback) {
- auto it = iterator_map_.find(iterator);
- if (it == iterator_map_.end()) {
- std::move(callback).Run(false, mojom::DatabaseError::INVALID_ARGUMENT,
- base::nullopt, base::nullopt);
- return;
- }
-
- it->second->SeekToFirst();
-
- ReplyToIteratorMessage(it->second, std::move(callback));
-}
-
-void LevelDBDatabaseImpl::IteratorSeekToLast(
- const base::UnguessableToken& iterator,
- IteratorSeekToLastCallback callback) {
- auto it = iterator_map_.find(iterator);
- if (it == iterator_map_.end()) {
- std::move(callback).Run(false, mojom::DatabaseError::INVALID_ARGUMENT,
- base::nullopt, base::nullopt);
- return;
- }
-
- it->second->SeekToLast();
-
- ReplyToIteratorMessage(it->second, std::move(callback));
-}
-
-void LevelDBDatabaseImpl::IteratorSeek(const base::UnguessableToken& iterator,
- const std::vector<uint8_t>& target,
- IteratorSeekToLastCallback callback) {
- auto it = iterator_map_.find(iterator);
- if (it == iterator_map_.end()) {
- std::move(callback).Run(false, mojom::DatabaseError::INVALID_ARGUMENT,
- base::nullopt, base::nullopt);
- return;
- }
-
- it->second->Seek(GetSliceFor(target));
-
- ReplyToIteratorMessage(it->second, std::move(callback));
-}
-
-void LevelDBDatabaseImpl::IteratorNext(const base::UnguessableToken& iterator,
- IteratorNextCallback callback) {
- auto it = iterator_map_.find(iterator);
- if (it == iterator_map_.end()) {
- std::move(callback).Run(false, mojom::DatabaseError::INVALID_ARGUMENT,
- base::nullopt, base::nullopt);
- return;
- }
-
- it->second->Next();
-
- ReplyToIteratorMessage(it->second, std::move(callback));
-}
-
-void LevelDBDatabaseImpl::IteratorPrev(const base::UnguessableToken& iterator,
- IteratorPrevCallback callback) {
- auto it = iterator_map_.find(iterator);
- if (it == iterator_map_.end()) {
- std::move(callback).Run(false, mojom::DatabaseError::INVALID_ARGUMENT,
- base::nullopt, base::nullopt);
- return;
- }
-
- it->second->Prev();
-
- ReplyToIteratorMessage(it->second, std::move(callback));
-}
-
-bool LevelDBDatabaseImpl::OnMemoryDump(
- const base::trace_event::MemoryDumpArgs& args,
- base::trace_event::ProcessMemoryDump* pmd) {
- auto* dump = leveldb_env::DBTracker::GetOrCreateAllocatorDump(pmd, db_.get());
- if (!dump)
- return true;
- auto* global_dump = pmd->CreateSharedGlobalAllocatorDump(*memory_dump_id_);
- pmd->AddOwnershipEdge(global_dump->guid(), dump->guid());
- // Add size to global dump to propagate the size of the database to the
- // client's dump.
- global_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize,
- base::trace_event::MemoryAllocatorDump::kUnitsBytes,
- dump->GetSizeInternal());
- return true;
-}
-
-void LevelDBDatabaseImpl::ReplyToIteratorMessage(
- leveldb::Iterator* it,
- IteratorSeekToFirstCallback callback) {
- if (!it->Valid()) {
- std::move(callback).Run(false, LeveldbStatusToError(it->status()),
- base::nullopt, base::nullopt);
- return;
- }
-
- std::move(callback).Run(true, LeveldbStatusToError(it->status()),
- GetVectorFor(it->key()), GetVectorFor(it->value()));
-}
-
-LevelDBDatabaseImpl::StatusAndKeyValues LevelDBDatabaseImpl::GetPrefixedHelper(
- const std::vector<uint8_t>& key_prefix) {
- std::vector<mojom::KeyValuePtr> data;
- Status status =
- ForEachWithPrefix(db_.get(), GetSliceFor(key_prefix),
- [&data](const Slice& key, const Slice& value) {
- mojom::KeyValuePtr kv = mojom::KeyValue::New();
- kv->key = GetVectorFor(key);
- kv->value = GetVectorFor(value);
- data.push_back(std::move(kv));
- });
- return std::make_tuple(status, std::move(data));
-}
-
-Status LevelDBDatabaseImpl::DeletePrefixedHelper(const Slice& key_prefix,
- WriteBatch* batch) {
- Status status = ForEachWithPrefix(
- db_.get(), key_prefix,
- [batch](const Slice& key, const Slice& value) { batch->Delete(key); });
- return status;
-}
-
-Status LevelDBDatabaseImpl::CopyPrefixedHelper(
- const std::vector<uint8_t>& source_key_prefix,
- const std::vector<uint8_t>& destination_key_prefix,
- leveldb::WriteBatch* batch) {
- std::vector<uint8_t> new_prefix = destination_key_prefix;
- size_t source_key_prefix_size = source_key_prefix.size();
- size_t destination_key_prefix_size = destination_key_prefix.size();
- Status status = ForEachWithPrefix(
- db_.get(), GetSliceFor(source_key_prefix),
- [&batch, &new_prefix, source_key_prefix_size,
- destination_key_prefix_size](const Slice& key, const Slice& value) {
- size_t excess_key = key.size() - source_key_prefix_size;
- new_prefix.resize(destination_key_prefix_size + excess_key);
- std::copy(key.data() + source_key_prefix_size, key.data() + key.size(),
- new_prefix.begin() + destination_key_prefix_size);
- batch->Put(GetSliceFor(new_prefix), value);
- });
- return status;
+ std::move(callback).Run(status);
}
} // namespace leveldb
diff --git a/chromium/components/services/leveldb/leveldb_database_impl.h b/chromium/components/services/leveldb/leveldb_database_impl.h
index aff55f034d3..6ddee8265dd 100644
--- a/chromium/components/services/leveldb/leveldb_database_impl.h
+++ b/chromium/components/services/leveldb/leveldb_database_impl.h
@@ -9,115 +9,120 @@
#include <tuple>
#include <vector>
-#include "base/trace_event/memory_dump_provider.h"
+#include "base/memory/scoped_refptr.h"
+#include "base/sequenced_task_runner.h"
+#include "base/threading/sequence_bound.h"
#include "base/unguessable_token.h"
#include "components/services/leveldb/public/mojom/leveldb.mojom.h"
-#include "mojo/public/cpp/bindings/interface_request.h"
+#include "components/services/storage/dom_storage/dom_storage_database.h"
#include "third_party/leveldatabase/src/include/leveldb/cache.h"
#include "third_party/leveldatabase/src/include/leveldb/db.h"
namespace leveldb {
-// The backing to a database object that we pass to our called.
-class LevelDBDatabaseImpl : public mojom::LevelDBDatabase,
- public base::trace_event::MemoryDumpProvider {
+// A temporary wrapper around the Storage Service's DomStorageDatabase class,
+// consumed by LocalStorageContextMojo, SessionStorageContextMojo, and related
+// classes.
+//
+// TODO(https://crbug.com/1000959): Delete this class.
+class LevelDBDatabaseImpl {
public:
- LevelDBDatabaseImpl(std::unique_ptr<leveldb::Env> environment,
- std::unique_ptr<leveldb::DB> db,
- std::unique_ptr<leveldb::Cache> cache,
- const leveldb_env::Options& options,
- const std::string& name,
- base::Optional<base::trace_event::MemoryAllocatorDumpGuid>
- memory_dump_id);
- ~LevelDBDatabaseImpl() override;
+ using StatusCallback = base::OnceCallback<void(Status)>;
+
+ ~LevelDBDatabaseImpl();
+
+ static std::unique_ptr<LevelDBDatabaseImpl> OpenDirectory(
+ const leveldb_env::Options& options,
+ const base::FilePath& directory,
+ const std::string& dbname,
+ const base::Optional<base::trace_event::MemoryAllocatorDumpGuid>&
+ memory_dump_id,
+ scoped_refptr<base::SequencedTaskRunner> blocking_task_runner,
+ StatusCallback callback);
+
+ static std::unique_ptr<LevelDBDatabaseImpl> OpenInMemory(
+ const base::Optional<base::trace_event::MemoryAllocatorDumpGuid>&
+ memory_dump_id,
+ const std::string& tracking_name,
+ scoped_refptr<base::SequencedTaskRunner> blocking_task_runner,
+ StatusCallback callback);
+
+ base::SequenceBound<storage::DomStorageDatabase>& database() {
+ return database_;
+ }
+ const base::SequenceBound<storage::DomStorageDatabase>& database() const {
+ return database_;
+ }
// Overridden from LevelDBDatabase:
void Put(const std::vector<uint8_t>& key,
const std::vector<uint8_t>& value,
- PutCallback callback) override;
- void Delete(const std::vector<uint8_t>& key,
- DeleteCallback callback) override;
+ StatusCallback callback);
+
+ void Delete(const std::vector<uint8_t>& key, StatusCallback callback);
+
void DeletePrefixed(const std::vector<uint8_t>& key_prefix,
- DeletePrefixedCallback callback) override;
- void RewriteDB(RewriteDBCallback callback) override;
+ StatusCallback callback);
+
+ void RewriteDB(StatusCallback callback);
+
void Write(std::vector<mojom::BatchedOperationPtr> operations,
- WriteCallback callback) override;
- void Get(const std::vector<uint8_t>& key, GetCallback callback) override;
+ StatusCallback callback);
+
+ using GetCallback =
+ base::OnceCallback<void(Status status, const std::vector<uint8_t>&)>;
+ void Get(const std::vector<uint8_t>& key, GetCallback callback);
+
+ using GetPrefixedCallback =
+ base::OnceCallback<void(Status status, std::vector<mojom::KeyValuePtr>)>;
void GetPrefixed(const std::vector<uint8_t>& key_prefix,
- GetPrefixedCallback callback) override;
- void GetMany(std::vector<mojom::GetManyRequestPtr> keys_or_prefixes,
- GetManyCallback callback) override;
+ GetPrefixedCallback callback);
+
void CopyPrefixed(const std::vector<uint8_t>& source_key_prefix,
const std::vector<uint8_t>& destination_key_prefix,
- CopyPrefixedCallback callback) override;
- void GetSnapshot(GetSnapshotCallback callback) override;
- void ReleaseSnapshot(const base::UnguessableToken& snapshot) override;
- void GetFromSnapshot(const base::UnguessableToken& snapshot,
- const std::vector<uint8_t>& key,
- GetCallback callback) override;
- void NewIterator(NewIteratorCallback callback) override;
- void NewIteratorFromSnapshot(
- const base::UnguessableToken& snapshot,
- NewIteratorFromSnapshotCallback callback) override;
- void ReleaseIterator(const base::UnguessableToken& iterator) override;
- void IteratorSeekToFirst(const base::UnguessableToken& iterator,
- IteratorSeekToFirstCallback callback) override;
- void IteratorSeekToLast(const base::UnguessableToken& iterator,
- IteratorSeekToLastCallback callback) override;
- void IteratorSeek(const base::UnguessableToken& iterator,
- const std::vector<uint8_t>& target,
- IteratorSeekToLastCallback callback) override;
- void IteratorNext(const base::UnguessableToken& iterator,
- IteratorNextCallback callback) override;
- void IteratorPrev(const base::UnguessableToken& iterator,
- IteratorPrevCallback callback) override;
-
- // base::trace_event::MemoryDumpProvider implementation.
- bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
- base::trace_event::ProcessMemoryDump* pmd) override;
-
- // Set a closure that will close the mojo connection to this object.
- // The closure will be called if this database becomes unusable e.g.
- // due to a failed rewrite attempt.
- void SetCloseBindingClosure(base::OnceClosure close_binding);
+ StatusCallback callback);
+
+ template <typename ResultType>
+ void RunDatabaseTask(
+ base::OnceCallback<ResultType(const storage::DomStorageDatabase&)> task,
+ base::OnceCallback<void(ResultType)> callback) {
+ auto wrapped_task = base::BindOnce(
+ [](base::OnceCallback<ResultType(const storage::DomStorageDatabase&)>
+ task,
+ base::OnceCallback<void(ResultType)> callback,
+ scoped_refptr<base::SequencedTaskRunner> callback_task_runner,
+ const storage::DomStorageDatabase& db) {
+ callback_task_runner->PostTask(
+ FROM_HERE,
+ base::BindOnce(std::move(callback), std::move(task).Run(db)));
+ },
+ std::move(task), std::move(callback),
+ base::SequencedTaskRunnerHandle::Get());
+ if (database_) {
+ database_.PostTaskWithThisObject(FROM_HERE, std::move(wrapped_task));
+ } else {
+ tasks_to_run_on_open_.push_back(std::move(wrapped_task));
+ }
+ }
private:
using StatusAndKeyValues =
std::tuple<Status, std::vector<mojom::KeyValuePtr>>;
- // Returns the state of |it| to a caller. Note: This assumes that all the
- // iterator movement methods have the same callback signature. We don't
- // directly reference the underlying type in case of bindings change.
- void ReplyToIteratorMessage(leveldb::Iterator* it,
- IteratorSeekToFirstCallback callback);
-
- StatusAndKeyValues GetPrefixedHelper(const std::vector<uint8_t>& key_prefix);
-
- leveldb::Status DeletePrefixedHelper(const leveldb::Slice& key_prefix,
- leveldb::WriteBatch* batch);
-
- leveldb::Status CopyPrefixedHelper(
- const std::vector<uint8_t>& source_key_prefix,
- const std::vector<uint8_t>& destination_key_prefix,
- leveldb::WriteBatch* batch);
-
- std::unique_ptr<leveldb::Env> environment_;
- std::unique_ptr<leveldb::Cache> cache_;
- std::unique_ptr<leveldb::DB> db_;
- leveldb_env::Options options_;
- std::string name_;
- base::Optional<base::trace_event::MemoryAllocatorDumpGuid> memory_dump_id_;
+ void OnDatabaseOpened(
+ StatusCallback callback,
+ base::SequenceBound<storage::DomStorageDatabase> database,
+ leveldb::Status status);
- std::map<base::UnguessableToken, const Snapshot*> snapshot_map_;
+ explicit LevelDBDatabaseImpl();
- // TODO(erg): If we have an existing iterator which depends on a snapshot,
- // and delete the snapshot from the client side, that shouldn't delete the
- // snapshot maybe? At worse it's a DDoS if there's multiple users of the
- // system, but this maybe should be fixed...
+ base::SequenceBound<storage::DomStorageDatabase> database_;
- std::map<base::UnguessableToken, Iterator*> iterator_map_;
+ using DatabaseTask =
+ base::OnceCallback<void(const storage::DomStorageDatabase&)>;
+ std::vector<DatabaseTask> tasks_to_run_on_open_;
- base::OnceClosure close_binding_;
+ base::WeakPtrFactory<LevelDBDatabaseImpl> weak_ptr_factory_{this};
DISALLOW_COPY_AND_ASSIGN(LevelDBDatabaseImpl);
};
diff --git a/chromium/components/services/leveldb/leveldb_mojo_proxy.cc b/chromium/components/services/leveldb/leveldb_mojo_proxy.cc
deleted file mode 100644
index 85f037586c4..00000000000
--- a/chromium/components/services/leveldb/leveldb_mojo_proxy.cc
+++ /dev/null
@@ -1,323 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/services/leveldb/leveldb_mojo_proxy.h"
-
-#include <set>
-
-#include "base/bind.h"
-#include "base/callback.h"
-#include "base/files/file_path.h"
-#include "base/threading/thread_restrictions.h"
-#include "mojo/public/cpp/bindings/interface_request.h"
-#include "mojo/public/cpp/bindings/sync_call_restrictions.h"
-
-namespace leveldb {
-
-struct LevelDBMojoProxy::OpaqueLock {
- filesystem::mojom::FilePtr lock_file;
-};
-
-struct LevelDBMojoProxy::OpaqueDir {
- explicit OpaqueDir(
- mojo::InterfacePtrInfo<filesystem::mojom::Directory> directory_info) {
- directory.Bind(std::move(directory_info));
- }
-
- filesystem::mojom::DirectoryPtr directory;
-};
-
-LevelDBMojoProxy::LevelDBMojoProxy(
- scoped_refptr<base::SequencedTaskRunner> task_runner)
- : task_runner_(std::move(task_runner)), outstanding_opaque_dirs_(0) {
- DCHECK(!task_runner_->RunsTasksInCurrentSequence());
-}
-
-LevelDBMojoProxy::OpaqueDir* LevelDBMojoProxy::RegisterDirectory(
- filesystem::mojom::DirectoryPtr directory) {
- OpaqueDir* out_dir = nullptr;
- RunInternal(base::Bind(&LevelDBMojoProxy::RegisterDirectoryImpl, this,
- base::Passed(directory.PassInterface()), &out_dir));
-
- return out_dir;
-}
-
-void LevelDBMojoProxy::UnregisterDirectory(OpaqueDir* dir) {
- RunInternal(
- base::Bind(&LevelDBMojoProxy::UnregisterDirectoryImpl, this, dir));
-}
-
-base::File LevelDBMojoProxy::OpenFileHandle(OpaqueDir* dir,
- const std::string& name,
- uint32_t open_flags) {
- base::File file;
- RunInternal(base::Bind(&LevelDBMojoProxy::OpenFileHandleImpl, this, dir, name,
- open_flags, &file));
- return file;
-}
-
-base::File::Error LevelDBMojoProxy::SyncDirectory(OpaqueDir* dir,
- const std::string& name) {
- base::File::Error error = base::File::Error::FILE_ERROR_FAILED;
- RunInternal(base::Bind(&LevelDBMojoProxy::SyncDirectoryImpl, this, dir, name,
- &error));
- return error;
-}
-
-bool LevelDBMojoProxy::FileExists(OpaqueDir* dir, const std::string& name) {
- bool exists = false;
- RunInternal(
- base::Bind(&LevelDBMojoProxy::FileExistsImpl, this, dir, name, &exists));
- return exists;
-}
-
-base::File::Error LevelDBMojoProxy::GetChildren(
- OpaqueDir* dir,
- const std::string& path,
- std::vector<std::string>* result) {
- base::File::Error error = base::File::Error::FILE_ERROR_FAILED;
- RunInternal(base::Bind(&LevelDBMojoProxy::GetChildrenImpl, this, dir, path,
- result, &error));
- return error;
-}
-
-base::File::Error LevelDBMojoProxy::Delete(OpaqueDir* dir,
- const std::string& path,
- uint32_t delete_flags) {
- base::File::Error error = base::File::Error::FILE_ERROR_FAILED;
- RunInternal(base::Bind(&LevelDBMojoProxy::DeleteImpl, this, dir, path,
- delete_flags, &error));
- return error;
-}
-
-base::File::Error LevelDBMojoProxy::CreateDir(OpaqueDir* dir,
- const std::string& path) {
- base::File::Error error = base::File::Error::FILE_ERROR_FAILED;
- RunInternal(
- base::Bind(&LevelDBMojoProxy::CreateDirImpl, this, dir, path, &error));
- return error;
-}
-
-base::File::Error LevelDBMojoProxy::GetFileSize(OpaqueDir* dir,
- const std::string& path,
- uint64_t* file_size) {
- base::File::Error error = base::File::Error::FILE_ERROR_FAILED;
- RunInternal(base::Bind(&LevelDBMojoProxy::GetFileSizeImpl, this, dir, path,
- file_size, &error));
- return error;
-}
-
-base::File::Error LevelDBMojoProxy::RenameFile(OpaqueDir* dir,
- const std::string& old_path,
- const std::string& new_path) {
- base::File::Error error = base::File::Error::FILE_ERROR_FAILED;
- RunInternal(base::Bind(&LevelDBMojoProxy::RenameFileImpl, this, dir, old_path,
- new_path, &error));
- return error;
-}
-
-std::pair<base::File::Error, LevelDBMojoProxy::OpaqueLock*>
-LevelDBMojoProxy::LockFile(OpaqueDir* dir, const std::string& path) {
- base::File::Error error = base::File::Error::FILE_ERROR_FAILED;
- OpaqueLock* out_lock = nullptr;
- RunInternal(base::Bind(&LevelDBMojoProxy::LockFileImpl, this, dir, path,
- &error, &out_lock));
- return std::make_pair(error, out_lock);
-}
-
-base::File::Error LevelDBMojoProxy::UnlockFile(OpaqueLock* lock) {
- // Take ownership of the incoming lock so it gets destroyed whatever happens.
- std::unique_ptr<OpaqueLock> scoped_lock(lock);
- base::File::Error error = base::File::Error::FILE_ERROR_FAILED;
- RunInternal(base::Bind(&LevelDBMojoProxy::UnlockFileImpl, this,
- base::Passed(&scoped_lock), &error));
- return error;
-}
-
-LevelDBMojoProxy::~LevelDBMojoProxy() {
- DCHECK_EQ(0, outstanding_opaque_dirs_);
-}
-
-void LevelDBMojoProxy::RunInternal(const base::Closure& task) {
- if (task_runner_->RunsTasksInCurrentSequence()) {
- task.Run();
- } else {
- base::WaitableEvent done_event(
- base::WaitableEvent::ResetPolicy::AUTOMATIC,
- base::WaitableEvent::InitialState::NOT_SIGNALED);
- task_runner_->PostTask(
- FROM_HERE, base::BindOnce(&LevelDBMojoProxy::DoOnOtherThread, this,
- task, base::Unretained(&done_event)));
- base::ScopedAllowBaseSyncPrimitives allow_base_sync_primitives;
- done_event.Wait();
- }
-}
-
-void LevelDBMojoProxy::DoOnOtherThread(const base::Closure& c,
- base::WaitableEvent* event) {
- c.Run();
- event->Signal();
-}
-
-void LevelDBMojoProxy::RegisterDirectoryImpl(
- mojo::InterfacePtrInfo<filesystem::mojom::Directory> directory_info,
- OpaqueDir** out_dir) {
- // Take the Directory pipe and bind it on this thread.
- *out_dir = new OpaqueDir(std::move(directory_info));
- outstanding_opaque_dirs_++;
-}
-
-void LevelDBMojoProxy::UnregisterDirectoryImpl(OpaqueDir* dir) {
- // Only delete the directories on the thread that owns them.
- delete dir;
- outstanding_opaque_dirs_--;
-}
-
-void LevelDBMojoProxy::OpenFileHandleImpl(OpaqueDir* dir,
- std::string name,
- uint32_t open_flags,
- base::File* output_file) {
- mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync;
- base::File file;
- base::File::Error error = base::File::Error::FILE_ERROR_FAILED;
- bool completed =
- dir->directory->OpenFileHandle(name, open_flags, &error, &file);
- DCHECK(completed);
-
- if (error != base::File::Error::FILE_OK) {
- *output_file = base::File(error);
- } else {
- *output_file = std::move(file);
- }
-}
-
-void LevelDBMojoProxy::SyncDirectoryImpl(OpaqueDir* dir,
- std::string name,
- base::File::Error* out_error) {
- mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync;
- filesystem::mojom::DirectoryPtr target;
- bool completed = dir->directory->OpenDirectory(
- name, MakeRequest(&target),
- filesystem::mojom::kFlagRead | filesystem::mojom::kFlagWrite, out_error);
- DCHECK(completed);
-
- if (*out_error != base::File::Error::FILE_OK)
- return;
-
- completed = target->Flush(out_error);
- DCHECK(completed);
-}
-
-void LevelDBMojoProxy::FileExistsImpl(OpaqueDir* dir,
- std::string name,
- bool* exists) {
- mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync;
- base::File::Error error = base::File::Error::FILE_ERROR_FAILED;
- bool completed = dir->directory->Exists(name, &error, exists);
- DCHECK(completed);
-}
-
-void LevelDBMojoProxy::GetChildrenImpl(OpaqueDir* dir,
- std::string name,
- std::vector<std::string>* out_contents,
- base::File::Error* out_error) {
- mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync;
- filesystem::mojom::DirectoryPtr target;
- bool completed = dir->directory->OpenDirectory(
- name, mojo::MakeRequest(&target),
- filesystem::mojom::kFlagRead | filesystem::mojom::kFlagWrite, out_error);
- DCHECK(completed);
-
- if (*out_error != base::File::Error::FILE_OK)
- return;
-
- base::Optional<std::vector<filesystem::mojom::DirectoryEntryPtr>>
- directory_contents;
- completed = target->Read(out_error, &directory_contents);
- DCHECK(completed);
-
- if (directory_contents.has_value()) {
- for (size_t i = 0; i < directory_contents->size(); ++i)
- out_contents->push_back(
- directory_contents.value()[i]->name.AsUTF8Unsafe());
- }
-}
-
-void LevelDBMojoProxy::DeleteImpl(OpaqueDir* dir,
- std::string name,
- uint32_t delete_flags,
- base::File::Error* out_error) {
- mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync;
- bool completed = dir->directory->Delete(name, delete_flags, out_error);
- DCHECK(completed);
-}
-
-void LevelDBMojoProxy::CreateDirImpl(OpaqueDir* dir,
- std::string name,
- base::File::Error* out_error) {
- mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync;
- bool completed = dir->directory->OpenDirectory(
- name, mojo::NullReceiver(),
- filesystem::mojom::kFlagRead | filesystem::mojom::kFlagWrite |
- filesystem::mojom::kFlagCreate,
- out_error);
- DCHECK(completed);
-}
-
-void LevelDBMojoProxy::GetFileSizeImpl(OpaqueDir* dir,
- const std::string& path,
- uint64_t* file_size,
- base::File::Error* out_error) {
- mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync;
- filesystem::mojom::FileInformationPtr info;
- bool completed = dir->directory->StatFile(path, out_error, &info);
- DCHECK(completed);
- if (info)
- *file_size = info->size;
-}
-
-void LevelDBMojoProxy::RenameFileImpl(OpaqueDir* dir,
- const std::string& old_path,
- const std::string& new_path,
- base::File::Error* out_error) {
- mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync;
- bool completed = dir->directory->Replace(old_path, new_path, out_error);
- DCHECK(completed);
-}
-
-void LevelDBMojoProxy::LockFileImpl(OpaqueDir* dir,
- const std::string& path,
- base::File::Error* out_error,
- OpaqueLock** out_lock) {
- mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync;
- // Since a lock is associated with a file descriptor, we need to open and
- // have a persistent file on the other side of the connection.
- filesystem::mojom::FilePtr target;
- bool completed = dir->directory->OpenFile(path, mojo::MakeRequest(&target),
- filesystem::mojom::kFlagOpenAlways |
- filesystem::mojom::kFlagRead |
- filesystem::mojom::kFlagWrite,
- out_error);
- DCHECK(completed);
-
- if (*out_error != base::File::Error::FILE_OK)
- return;
-
- completed = target->Lock(out_error);
- DCHECK(completed);
-
- if (*out_error == base::File::Error::FILE_OK) {
- OpaqueLock* l = new OpaqueLock;
- l->lock_file = std::move(target);
- *out_lock = l;
- }
-}
-
-void LevelDBMojoProxy::UnlockFileImpl(std::unique_ptr<OpaqueLock> lock,
- base::File::Error* out_error) {
- mojo::SyncCallRestrictions::ScopedAllowSyncCall allow_sync;
- lock->lock_file->Unlock(out_error);
-}
-
-} // namespace leveldb
diff --git a/chromium/components/services/leveldb/leveldb_mojo_proxy.h b/chromium/components/services/leveldb/leveldb_mojo_proxy.h
deleted file mode 100644
index 3c9309e979d..00000000000
--- a/chromium/components/services/leveldb/leveldb_mojo_proxy.h
+++ /dev/null
@@ -1,159 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_SERVICES_LEVELDB_LEVELDB_MOJO_PROXY_H_
-#define COMPONENTS_SERVICES_LEVELDB_LEVELDB_MOJO_PROXY_H_
-
-#include <map>
-#include <memory>
-#include <string>
-#include <utility>
-#include <vector>
-
-#include "base/callback_forward.h"
-#include "base/files/file.h"
-#include "base/memory/ref_counted.h"
-#include "base/sequenced_task_runner.h"
-
-#include "base/synchronization/waitable_event.h"
-#include "components/services/filesystem/public/mojom/directory.mojom.h"
-
-namespace leveldb {
-
-// A proxy for thread safe access to Mojo objects from multiple threads.
-//
-// MojoEnv is an object passed to the LevelDB implementation which can be
-// called from multiple threads. Mojo pipes are bound to a single
-// thread. Because of this mismatch, we create a proxy object which will
-// redirect calls to the thread which owns the Mojo pipe, sends and receives
-// messages.
-//
-// All public methods can be accessed from any thread.
-class LevelDBMojoProxy : public base::RefCountedThreadSafe<LevelDBMojoProxy> {
- public:
- explicit LevelDBMojoProxy(
- scoped_refptr<base::SequencedTaskRunner> task_runner);
-
- // A private struct to hide the underlying file that holds the lock from our
- // callers, forcing them to go through our LockFile()/UnlockFile() interface
- // so that they don't try to use the underlying pointer from an unsafe thread.
- struct OpaqueLock;
-
- // A private struct to hide the underlying root directory that we're
- // operating in. LevelDBMojoProxy will want to own all the directory
- // pointers, so while opening a database, we pass the directory to the thread
- // it will be operated on.
- struct OpaqueDir;
-
- // Passes ownership of a |directory| to the other thread, giving a reference
- // handle back to the caller.
- OpaqueDir* RegisterDirectory(filesystem::mojom::DirectoryPtr directory);
- void UnregisterDirectory(OpaqueDir* dir);
-
- // Synchronously calls Directory.OpenFileHandle().
- base::File OpenFileHandle(OpaqueDir* dir,
- const std::string& name,
- uint32_t open_flags);
-
- // Synchronously syncs |directory_|.
- base::File::Error SyncDirectory(OpaqueDir* dir, const std::string& name);
-
- // Synchronously checks whether |name| exists.
- bool FileExists(OpaqueDir* dir, const std::string& name);
-
- // Synchronously returns the filenames of all files in |path|.
- base::File::Error GetChildren(OpaqueDir* dir,
- const std::string& path,
- std::vector<std::string>* result);
-
- // Synchronously deletes |path|.
- base::File::Error Delete(OpaqueDir* dir,
- const std::string& path,
- uint32_t delete_flags);
-
- // Synchronously creates |path|.
- base::File::Error CreateDir(OpaqueDir* dir, const std::string& path);
-
- // Synchronously gets the size of a file.
- base::File::Error GetFileSize(OpaqueDir* dir,
- const std::string& path,
- uint64_t* file_size);
-
- // Synchronously renames a file.
- base::File::Error RenameFile(OpaqueDir* dir,
- const std::string& old_path,
- const std::string& new_path);
-
- // Synchronously locks a file. Returns both the file return code, and if OK,
- // an opaque object to the lock to enforce going through this interface to
- // unlock the file so that unlocking happens on the correct thread.
- std::pair<base::File::Error, OpaqueLock*> LockFile(OpaqueDir* dir,
- const std::string& path);
-
- // Unlocks a file. LevelDBMojoProxy takes ownership of lock. (We don't make
- // this a scoped_ptr because exporting the ctor/dtor for this struct publicly
- // defeats the purpose of the struct.)
- base::File::Error UnlockFile(OpaqueLock* lock);
-
- private:
- friend class base::RefCountedThreadSafe<LevelDBMojoProxy>;
- ~LevelDBMojoProxy();
-
- void RunInternal(const base::Closure& task);
-
- void DoOnOtherThread(const base::Closure& c, base::WaitableEvent* event);
-
- // Implementation methods of the public interface. Depending on whether they
- // were called from the thread that |task_runner_| is, these might be run
- // on the current thread or through PostTask().
- void RegisterDirectoryImpl(
- mojo::InterfacePtrInfo<filesystem::mojom::Directory> directory_info,
- OpaqueDir** out_dir);
- void UnregisterDirectoryImpl(OpaqueDir* dir);
- void OpenFileHandleImpl(OpaqueDir* dir,
- std::string name,
- uint32_t open_flags,
- base::File* out_file);
- void SyncDirectoryImpl(OpaqueDir* dir,
- std::string name,
- base::File::Error* out_error);
- void FileExistsImpl(OpaqueDir* dir, std::string name, bool* exists);
- void GetChildrenImpl(OpaqueDir* dir,
- std::string name,
- std::vector<std::string>* contents,
- base::File::Error* out_error);
- void DeleteImpl(OpaqueDir* dir,
- std::string name,
- uint32_t delete_flags,
- base::File::Error* out_error);
- void CreateDirImpl(OpaqueDir* dir,
- std::string name,
- base::File::Error* out_error);
- void GetFileSizeImpl(OpaqueDir* dir,
- const std::string& path,
- uint64_t* file_size,
- base::File::Error* out_error);
- void RenameFileImpl(OpaqueDir* dir,
- const std::string& old_path,
- const std::string& new_path,
- base::File::Error* out_error);
- void LockFileImpl(OpaqueDir* dir,
- const std::string& path,
- base::File::Error* out_error,
- OpaqueLock** out_lock);
- void UnlockFileImpl(std::unique_ptr<OpaqueLock> lock,
- base::File::Error* out_error);
-
- // The task runner which represents the sequence that all mojo objects are
- // bound to.
- scoped_refptr<base::SequencedTaskRunner> task_runner_;
-
- int outstanding_opaque_dirs_;
-
- DISALLOW_COPY_AND_ASSIGN(LevelDBMojoProxy);
-};
-
-} // namespace leveldb
-
-#endif // COMPONENTS_SERVICES_LEVELDB_LEVELDB_MOJO_PROXY_H_
diff --git a/chromium/components/services/leveldb/leveldb_mojo_unittest.cc b/chromium/components/services/leveldb/leveldb_mojo_unittest.cc
deleted file mode 100644
index 8a1efefcc6f..00000000000
--- a/chromium/components/services/leveldb/leveldb_mojo_unittest.cc
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-//
-#include "components/services/leveldb/leveldb_mojom_traits.h"
-
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/leveldatabase/leveldb_chrome.h"
-
-namespace {
-
-class LevelDBServiceMojoTest : public testing::Test {};
-
-} // namespace
-
-TEST(LevelDBServiceMojoTest, TestSerialization) {
- leveldb_env::Options input;
- // Tweak all input values to have a non-default value.
- input.create_if_missing = !input.create_if_missing;
- input.error_if_exists = !input.error_if_exists;
- input.paranoid_checks = !input.paranoid_checks;
- input.write_buffer_size += 1;
- input.max_open_files += 1;
- input.block_cache = leveldb_chrome::GetSharedWebBlockCache();
-
- leveldb_env::Options output;
- ASSERT_TRUE(leveldb::mojom::OpenOptions::Deserialize(
- leveldb::mojom::OpenOptions::Serialize(&input), &output));
-
- EXPECT_EQ(output.create_if_missing, output.create_if_missing);
- EXPECT_EQ(output.error_if_exists, output.error_if_exists);
- EXPECT_EQ(output.paranoid_checks, output.paranoid_checks);
- EXPECT_EQ(output.write_buffer_size, output.write_buffer_size);
- EXPECT_EQ(output.max_open_files, output.max_open_files);
- EXPECT_EQ(leveldb_chrome::GetSharedWebBlockCache(), output.block_cache);
-}
diff --git a/chromium/components/services/leveldb/leveldb_mojom_traits.cc b/chromium/components/services/leveldb/leveldb_mojom_traits.cc
deleted file mode 100644
index 0403c350907..00000000000
--- a/chromium/components/services/leveldb/leveldb_mojom_traits.cc
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/services/leveldb/leveldb_mojom_traits.h"
-
-#include "third_party/leveldatabase/env_chromium.h"
-#include "third_party/leveldatabase/leveldb_chrome.h"
-
-namespace mojo {
-
-bool StructTraits<leveldb::mojom::OpenOptionsDataView, leveldb_env::Options>::
- create_if_missing(const leveldb_env::Options& options) {
- return options.create_if_missing;
-}
-
-bool StructTraits<leveldb::mojom::OpenOptionsDataView, leveldb_env::Options>::
- error_if_exists(const leveldb_env::Options& options) {
- return options.error_if_exists;
-}
-
-bool StructTraits<leveldb::mojom::OpenOptionsDataView, leveldb_env::Options>::
- paranoid_checks(const leveldb_env::Options& options) {
- return options.paranoid_checks;
-}
-
-uint64_t
-StructTraits<leveldb::mojom::OpenOptionsDataView, leveldb_env::Options>::
- write_buffer_size(const leveldb_env::Options& options) {
- return options.write_buffer_size;
-}
-
-int32_t StructTraits<
- leveldb::mojom::OpenOptionsDataView,
- leveldb_env::Options>::max_open_files(const leveldb_env::Options& options) {
- return options.max_open_files;
-}
-
-leveldb::mojom::SharedReadCache
-StructTraits<leveldb::mojom::OpenOptionsDataView, leveldb_env::Options>::
- shared_block_read_cache(const leveldb_env::Options& options) {
- // The Mojo wrapper for leveldb only supports using one of two different
- // shared caches. Chrome's Mojo wrapper does not currently support custom
- // caches, nor nullptr to have leveldb create the block read cache.
- if (!options.block_cache) {
- // Specify either Default or Web.
- NOTREACHED();
- return leveldb::mojom::SharedReadCache::Default;
- }
- if (options.block_cache == leveldb_chrome::GetSharedWebBlockCache())
- return leveldb::mojom::SharedReadCache::Web;
-
- leveldb_env::Options default_options;
- // If failing see comment above.
- DCHECK_EQ(default_options.block_cache, options.block_cache);
-
- return leveldb::mojom::SharedReadCache::Default;
-}
-
-bool StructTraits<leveldb::mojom::OpenOptionsDataView, leveldb_env::Options>::
- Read(leveldb::mojom::OpenOptionsDataView data, leveldb_env::Options* out) {
- out->create_if_missing = data.create_if_missing();
- out->error_if_exists = data.error_if_exists();
- out->paranoid_checks = data.paranoid_checks();
- out->write_buffer_size = data.write_buffer_size();
- out->max_open_files = data.max_open_files();
- switch (data.shared_block_read_cache()) {
- case leveldb::mojom::SharedReadCache::Default: {
- leveldb_env::Options options;
- out->block_cache = options.block_cache;
- } break;
- case leveldb::mojom::SharedReadCache::Web:
- out->block_cache = leveldb_chrome::GetSharedWebBlockCache();
- break;
- }
-
- return true;
-}
-
-} // namespace mojo
diff --git a/chromium/components/services/leveldb/leveldb_mojom_traits.h b/chromium/components/services/leveldb/leveldb_mojom_traits.h
deleted file mode 100644
index 2bbfafd503e..00000000000
--- a/chromium/components/services/leveldb/leveldb_mojom_traits.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2017 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_SERVICES_LEVELDB_LEVELDB_MOJOM_TRAITS_H_
-#define COMPONENTS_SERVICES_LEVELDB_LEVELDB_MOJOM_TRAITS_H_
-
-#include "components/services/leveldb/public/mojom/leveldb.mojom.h"
-
-namespace mojo {
-
-template <>
-struct StructTraits<leveldb::mojom::OpenOptionsDataView, leveldb_env::Options> {
- static bool create_if_missing(const leveldb_env::Options& options);
- static bool error_if_exists(const leveldb_env::Options& options);
- static bool paranoid_checks(const leveldb_env::Options& options);
- static uint64_t write_buffer_size(const leveldb_env::Options& options);
- static int32_t max_open_files(const leveldb_env::Options& options);
- static ::leveldb::mojom::SharedReadCache shared_block_read_cache(
- const leveldb_env::Options& options);
- static bool Read(::leveldb::mojom::OpenOptionsDataView data,
- leveldb_env::Options* out);
-};
-
-} // namespace mojo
-
-#endif // COMPONENTS_SERVICES_LEVELDB_LEVELDB_MOJOM_TRAITS_H_
diff --git a/chromium/components/services/leveldb/leveldb_service_impl.cc b/chromium/components/services/leveldb/leveldb_service_impl.cc
deleted file mode 100644
index ca312231e1e..00000000000
--- a/chromium/components/services/leveldb/leveldb_service_impl.cc
+++ /dev/null
@@ -1,131 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/services/leveldb/leveldb_service_impl.h"
-
-#include <memory>
-#include <utility>
-
-#include "base/bind.h"
-#include "base/sequenced_task_runner.h"
-#include "components/services/leveldb/env_mojo.h"
-#include "components/services/leveldb/leveldb_database_impl.h"
-#include "components/services/leveldb/public/cpp/util.h"
-#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
-#include "mojo/public/cpp/bindings/self_owned_associated_receiver.h"
-#include "third_party/leveldatabase/leveldb_chrome.h"
-#include "third_party/leveldatabase/src/include/leveldb/db.h"
-#include "third_party/leveldatabase/src/include/leveldb/filter_policy.h"
-#include "third_party/leveldatabase/src/include/leveldb/slice.h"
-
-namespace leveldb {
-
-namespace {
-void CreateReceiver(
- std::unique_ptr<LevelDBDatabaseImpl> db,
- mojo::PendingAssociatedReceiver<leveldb::mojom::LevelDBDatabase> receiver) {
- // The database should be able to close the binding if it gets into an
- // error condition that can't be recovered.
- LevelDBDatabaseImpl* impl = db.get();
- impl->SetCloseBindingClosure(base::BindOnce(
- &mojo::StrongAssociatedBinding<mojom::LevelDBDatabase>::Close,
- mojo::MakeSelfOwnedAssociatedReceiver(std::move(db),
- std::move(receiver))));
-}
-
-} // namespace
-
-LevelDBServiceImpl::LevelDBServiceImpl(
- scoped_refptr<base::SequencedTaskRunner> file_task_runner)
- : thread_(new LevelDBMojoProxy(std::move(file_task_runner))) {}
-
-LevelDBServiceImpl::~LevelDBServiceImpl() {}
-
-void LevelDBServiceImpl::Open(
- filesystem::mojom::DirectoryPtr directory,
- const std::string& dbname,
- const base::Optional<base::trace_event::MemoryAllocatorDumpGuid>&
- memory_dump_id,
- mojo::PendingAssociatedReceiver<leveldb::mojom::LevelDBDatabase> database,
- OpenCallback callback) {
- leveldb_env::Options options;
- // the default here to 80 instead of leveldb's default 1000 because we don't
- // want to consume all file descriptors. See
- // https://code.google.com/p/chromium/issues/detail?id=227313#c11 for
- // details.)
- options.max_open_files = 80;
-
- OpenWithOptions(options, std::move(directory), dbname, memory_dump_id,
- std::move(database), std::move(callback));
-}
-
-void LevelDBServiceImpl::OpenWithOptions(
- const leveldb_env::Options& options,
- filesystem::mojom::DirectoryPtr directory,
- const std::string& dbname,
- const base::Optional<base::trace_event::MemoryAllocatorDumpGuid>&
- memory_dump_id,
- mojo::PendingAssociatedReceiver<leveldb::mojom::LevelDBDatabase> database,
- OpenCallback callback) {
- // Register our directory with the file thread.
- LevelDBMojoProxy::OpaqueDir* dir =
- thread_->RegisterDirectory(std::move(directory));
-
- std::unique_ptr<MojoEnv> env_mojo(new MojoEnv(thread_, dir));
- leveldb_env::Options open_options = options;
- open_options.env = env_mojo.get();
-
- std::unique_ptr<leveldb::DB> db;
- leveldb::Status s = leveldb_env::OpenDB(open_options, dbname, &db);
-
- if (s.ok()) {
- CreateReceiver(std::make_unique<LevelDBDatabaseImpl>(
- std::move(env_mojo), std::move(db), nullptr,
- open_options, dbname, memory_dump_id),
- std::move(database));
- }
-
- std::move(callback).Run(LeveldbStatusToError(s));
-}
-
-void LevelDBServiceImpl::OpenInMemory(
- const base::Optional<base::trace_event::MemoryAllocatorDumpGuid>&
- memory_dump_id,
- const std::string& tracking_name,
- mojo::PendingAssociatedReceiver<leveldb::mojom::LevelDBDatabase> database,
- OpenCallback callback) {
- leveldb_env::Options options;
- options.create_if_missing = true;
- options.max_open_files = 0; // Use minimum.
-
- auto env = leveldb_chrome::NewMemEnv(tracking_name);
- options.env = env.get();
-
- std::unique_ptr<leveldb::DB> db;
- leveldb::Status s = leveldb_env::OpenDB(options, "", &db);
-
- if (s.ok()) {
- CreateReceiver(std::make_unique<LevelDBDatabaseImpl>(
- std::move(env), std::move(db), nullptr, options,
- tracking_name, memory_dump_id),
- std::move(database));
- }
-
- std::move(callback).Run(LeveldbStatusToError(s));
-}
-
-void LevelDBServiceImpl::Destroy(filesystem::mojom::DirectoryPtr directory,
- const std::string& dbname,
- DestroyCallback callback) {
- leveldb_env::Options options;
- // Register our directory with the file thread.
- LevelDBMojoProxy::OpaqueDir* dir =
- thread_->RegisterDirectory(std::move(directory));
- std::unique_ptr<MojoEnv> env_mojo(new MojoEnv(thread_, dir));
- options.env = env_mojo.get();
- std::move(callback).Run(
- LeveldbStatusToError(leveldb::DestroyDB(dbname, options)));
-}
-
-} // namespace leveldb
diff --git a/chromium/components/services/leveldb/leveldb_service_impl.h b/chromium/components/services/leveldb/leveldb_service_impl.h
deleted file mode 100644
index 0665d5abbf5..00000000000
--- a/chromium/components/services/leveldb/leveldb_service_impl.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_SERVICES_LEVELDB_LEVELDB_SERVICE_IMPL_H_
-#define COMPONENTS_SERVICES_LEVELDB_LEVELDB_SERVICE_IMPL_H_
-
-#include "base/memory/ref_counted.h"
-#include "components/services/leveldb/leveldb_mojo_proxy.h"
-#include "components/services/leveldb/public/mojom/leveldb.mojom.h"
-#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
-
-namespace base {
-class SequencedTaskRunner;
-}
-
-namespace leveldb {
-
-// Creates LevelDBDatabases based scoped to a |directory|/|dbname|.
-class LevelDBServiceImpl : public mojom::LevelDBService {
- public:
- // The |file_task_runner| is used to run tasks to interact with the
- // file_service. Specifically this task runner must NOT be the same as the
- // task runner this implementation runs on, or deadlock might occur.
- explicit LevelDBServiceImpl(
- scoped_refptr<base::SequencedTaskRunner> file_task_runner);
- ~LevelDBServiceImpl() override;
-
- // Overridden from LevelDBService:
- void Open(
- filesystem::mojom::DirectoryPtr directory,
- const std::string& dbname,
- const base::Optional<base::trace_event::MemoryAllocatorDumpGuid>&
- memory_dump_id,
- mojo::PendingAssociatedReceiver<leveldb::mojom::LevelDBDatabase> database,
- OpenCallback callback) override;
- void OpenWithOptions(
- const leveldb_env::Options& open_options,
- filesystem::mojom::DirectoryPtr directory,
- const std::string& dbname,
- const base::Optional<base::trace_event::MemoryAllocatorDumpGuid>&
- memory_dump_id,
- mojo::PendingAssociatedReceiver<leveldb::mojom::LevelDBDatabase> database,
- OpenCallback callback) override;
- void OpenInMemory(
- const base::Optional<base::trace_event::MemoryAllocatorDumpGuid>&
- memory_dump_id,
- const std::string& tracking_name,
- mojo::PendingAssociatedReceiver<leveldb::mojom::LevelDBDatabase> database,
- OpenInMemoryCallback callback) override;
- void Destroy(filesystem::mojom::DirectoryPtr directory,
- const std::string& dbname,
- DestroyCallback callback) override;
-
- private:
- // Thread to own the mojo message pipe. Because leveldb spawns multiple
- // threads that want to call file stuff, we create a dedicated thread to send
- // and receive mojo message calls.
- scoped_refptr<LevelDBMojoProxy> thread_;
-
- DISALLOW_COPY_AND_ASSIGN(LevelDBServiceImpl);
-};
-
-} // namespace leveldb
-
-#endif // COMPONENTS_SERVICES_LEVELDB_LEVELDB_SERVICE_IMPL_H_
diff --git a/chromium/components/services/leveldb/leveldb_service_unittest.cc b/chromium/components/services/leveldb/leveldb_service_unittest.cc
deleted file mode 100644
index 0dc185c481e..00000000000
--- a/chromium/components/services/leveldb/leveldb_service_unittest.cc
+++ /dev/null
@@ -1,833 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "base/bind.h"
-#include "base/files/file_path.h"
-#include "base/files/scoped_temp_dir.h"
-#include "base/macros.h"
-#include "base/run_loop.h"
-#include "base/task/post_task.h"
-#include "base/test/scoped_feature_list.h"
-#include "base/test/task_environment.h"
-#include "components/services/filesystem/directory_test_helper.h"
-#include "components/services/filesystem/public/mojom/directory.mojom.h"
-#include "components/services/filesystem/public/mojom/types.mojom.h"
-#include "components/services/leveldb/leveldb_service_impl.h"
-#include "components/services/leveldb/public/cpp/util.h"
-#include "components/services/leveldb/public/mojom/leveldb.mojom.h"
-#include "mojo/public/cpp/bindings/associated_remote.h"
-#include "mojo/public/cpp/bindings/pending_associated_receiver.h"
-#include "mojo/public/cpp/bindings/remote.h"
-#include "mojo/public/cpp/bindings/self_owned_receiver.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/leveldatabase/leveldb_features.h"
-
-namespace leveldb {
-namespace {
-
-template <typename... Args>
-void IgnoreAllArgs(Args&&...) {}
-
-template <typename... Args>
-void DoCaptures(typename std::decay<Args>::type*... out_args,
- const base::Closure& quit_closure,
- Args... in_args) {
- IgnoreAllArgs((*out_args = std::move(in_args))...);
- quit_closure.Run();
-}
-
-template <typename T1>
-base::Callback<void(T1)> Capture(T1* t1, const base::Closure& quit_closure) {
- return base::Bind(&DoCaptures<T1>, t1, quit_closure);
-}
-
-template <typename T1, typename T2>
-base::Callback<void(T1, T2)> Capture(T1* t1,
- T2* t2,
- const base::Closure& quit_closure) {
- return base::Bind(&DoCaptures<T1, T2>, t1, t2, quit_closure);
-}
-
-template <typename T1>
-base::Callback<void(const T1&)> CaptureConstRef(
- T1* t1,
- const base::Closure& quit_closure) {
- return base::Bind(&DoCaptures<const T1&>, t1, quit_closure);
-}
-
-template <typename T1, typename T2>
-base::Callback<void(T1, const T2&)>
-CaptureConstRef(T1* t1, T2* t2, const base::Closure& quit_closure) {
- return base::Bind(&DoCaptures<T1, const T2&>, t1, t2, quit_closure);
-}
-
-void DatabaseSyncPut(mojom::LevelDBDatabase* database,
- const std::string& key,
- const std::string& value,
- mojom::DatabaseError* out_error) {
- base::RunLoop run_loop;
- database->Put(StdStringToUint8Vector(key), StdStringToUint8Vector(value),
- Capture(out_error, run_loop.QuitClosure()));
- run_loop.Run();
-}
-
-void DatabaseSyncGet(mojom::LevelDBDatabase* database,
- const std::string& key,
- mojom::DatabaseError* out_error,
- std::vector<uint8_t>* out_value) {
- base::RunLoop run_loop;
- database->Get(StdStringToUint8Vector(key),
- CaptureConstRef(out_error, out_value, run_loop.QuitClosure()));
- run_loop.Run();
-}
-
-void DatabaseSyncGetPrefixed(mojom::LevelDBDatabase* database,
- const std::string& key_prefix,
- mojom::DatabaseError* out_error,
- std::vector<mojom::KeyValuePtr>* out_key_values) {
- base::RunLoop run_loop;
- database->GetPrefixed(
- StdStringToUint8Vector(key_prefix),
- Capture(out_error, out_key_values, run_loop.QuitClosure()));
- run_loop.Run();
-}
-
-void DatabaseSyncGetMany(
- mojom::LevelDBDatabase* database,
- std::vector<mojom::GetManyRequestPtr>& keys_or_prefixes,
- std::vector<mojom::GetManyResultPtr>* out_values) {
- base::RunLoop run_loop;
- database->GetMany(std::move(keys_or_prefixes),
- Capture(out_values, run_loop.QuitClosure()));
- run_loop.Run();
-}
-
-void DatabaseSyncCopyPrefixed(mojom::LevelDBDatabase* database,
- const std::string& source_key_prefix,
- const std::string& destination_key_prefix,
- mojom::DatabaseError* out_error) {
- base::RunLoop run_loop;
- database->CopyPrefixed(StdStringToUint8Vector(source_key_prefix),
- StdStringToUint8Vector(destination_key_prefix),
- Capture(out_error, run_loop.QuitClosure()));
- run_loop.Run();
-}
-
-void DatabaseSyncDelete(mojom::LevelDBDatabase* database,
- const std::string& key,
- mojom::DatabaseError* out_error) {
- base::RunLoop run_loop;
- database->Delete(StdStringToUint8Vector(key),
- Capture(out_error, run_loop.QuitClosure()));
- run_loop.Run();
-}
-
-void DatabaseSyncDeletePrefixed(mojom::LevelDBDatabase* database,
- const std::string& key_prefix,
- mojom::DatabaseError* out_error) {
- base::RunLoop run_loop;
- database->DeletePrefixed(StdStringToUint8Vector(key_prefix),
- Capture(out_error, run_loop.QuitClosure()));
- run_loop.Run();
-}
-
-void DatabaseSyncRewrite(mojom::LevelDBDatabase* database,
- mojom::DatabaseError* out_error) {
- base::RunLoop run_loop;
- database->RewriteDB(Capture(out_error, run_loop.QuitClosure()));
- run_loop.Run();
-}
-
-void LevelDBSyncOpenInMemory(
- mojom::LevelDBService* leveldb,
- mojo::PendingAssociatedReceiver<leveldb::mojom::LevelDBDatabase> database,
- mojom::DatabaseError* out_error) {
- base::RunLoop run_loop;
- leveldb->OpenInMemory(base::nullopt, "LevelDBSync", std::move(database),
- Capture(out_error, run_loop.QuitClosure()));
- run_loop.Run();
-}
-
-void AddKeyToGetManyRequest(const std::string& key,
- std::vector<mojom::GetManyRequestPtr>* list) {
- std::vector<uint8_t> in_arg = StdStringToUint8Vector(key);
- list->emplace_back(mojom::GetManyRequest::NewKey(in_arg));
-}
-
-void AddKeyPrefixToGetManyRequest(const std::string& key_prefix,
- std::vector<mojom::GetManyRequestPtr>* list) {
- std::vector<uint8_t> in_arg = StdStringToUint8Vector(key_prefix);
- list->emplace_back(mojom::GetManyRequest::NewKeyPrefix(in_arg));
-}
-
-class LevelDBServiceTest : public testing::Test {
- public:
- LevelDBServiceTest()
- : leveldb_service_(base::CreateSequencedTaskRunner(
- {base::ThreadPool(), base::MayBlock(),
- base::TaskShutdownBehavior::BLOCK_SHUTDOWN})),
- leveldb_receiver_(&leveldb_service_,
- leveldb_remote_.BindNewPipeAndPassReceiver()) {}
- ~LevelDBServiceTest() override = default;
-
- protected:
- void SetUp() override {
- // TODO(dullweber): This doesn't seem to work. The reason is probably that
- // the LevelDB service is a separate executable here. How should we set
- // features that affect a service?
- feature_list_.InitAndEnableFeature(leveldb::kLevelDBRewriteFeature);
- }
-
- mojo::Remote<filesystem::mojom::Directory> CreateTempDir() {
- return directory_helper_.CreateTempDir();
- }
-
- mojo::Remote<mojom::LevelDBService>& leveldb() { return leveldb_remote_; }
-
- private:
- base::test::TaskEnvironment task_environment_;
- base::test::ScopedFeatureList feature_list_;
- filesystem::DirectoryTestHelper directory_helper_;
- LevelDBServiceImpl leveldb_service_;
- mojo::Remote<mojom::LevelDBService> leveldb_remote_;
- mojo::Receiver<mojom::LevelDBService> leveldb_receiver_;
-
- DISALLOW_COPY_AND_ASSIGN(LevelDBServiceTest);
-};
-
-TEST_F(LevelDBServiceTest, Basic) {
- mojom::DatabaseError error;
- mojo::AssociatedRemote<mojom::LevelDBDatabase> database;
- LevelDBSyncOpenInMemory(leveldb().get(),
- database.BindNewEndpointAndPassReceiver(), &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- // Write a key to the database.
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- DatabaseSyncPut(database.get(), "key", "value", &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- // Read the key back from the database.
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- std::vector<uint8_t> value;
- DatabaseSyncGet(database.get(), "key", &error, &value);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- EXPECT_EQ("value", Uint8VectorToStdString(value));
-
- // Delete the key from the database.
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- DatabaseSyncDelete(database.get(), "key", &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- // Read the key back from the database.
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- value.clear();
- DatabaseSyncGet(database.get(), "key", &error, &value);
- EXPECT_EQ(mojom::DatabaseError::NOT_FOUND, error);
- EXPECT_EQ("", Uint8VectorToStdString(value));
-}
-
-TEST_F(LevelDBServiceTest, WriteBatch) {
- mojom::DatabaseError error;
- mojo::AssociatedRemote<mojom::LevelDBDatabase> database;
- LevelDBSyncOpenInMemory(leveldb().get(),
- database.BindNewEndpointAndPassReceiver(), &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- // Write a key to the database.
- DatabaseSyncPut(database.get(), "key", "value", &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- // Create a batched operation which both deletes "key" and adds another write.
- std::vector<mojom::BatchedOperationPtr> operations;
- mojom::BatchedOperationPtr item = mojom::BatchedOperation::New();
- item->type = mojom::BatchOperationType::DELETE_KEY;
- item->key = StdStringToUint8Vector("key");
- operations.push_back(std::move(item));
-
- item = mojom::BatchedOperation::New();
- item->type = mojom::BatchOperationType::PUT_KEY;
- item->key = StdStringToUint8Vector("other");
- item->value = StdStringToUint8Vector("more");
- operations.push_back(std::move(item));
-
- base::RunLoop run_loop;
- database->Write(std::move(operations),
- Capture(&error, run_loop.QuitClosure()));
- run_loop.Run();
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- // Reading "key" should be invalid now.
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- std::vector<uint8_t> value;
- DatabaseSyncGet(database.get(), "key", &error, &value);
- EXPECT_EQ(mojom::DatabaseError::NOT_FOUND, error);
- EXPECT_EQ("", Uint8VectorToStdString(value));
-
- // Reading "other" should return "more"
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- DatabaseSyncGet(database.get(), "other", &error, &value);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- EXPECT_EQ("more", Uint8VectorToStdString(value));
-
- // Write a some prefixed keys to the database.
- DatabaseSyncPut(database.get(), "prefix-key1", "value", &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- DatabaseSyncPut(database.get(), "prefix-key2", "value", &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- // Create batched operations to copy and then delete the 'prefix' data.
- operations.clear();
- item = mojom::BatchedOperation::New();
- item->type = mojom::BatchOperationType::COPY_PREFIXED_KEY;
- item->key = StdStringToUint8Vector("prefix");
- item->value = StdStringToUint8Vector("copy-prefix");
- operations.push_back(std::move(item));
- item = mojom::BatchedOperation::New();
- item->type = mojom::BatchOperationType::DELETE_PREFIXED_KEY;
- item->key = StdStringToUint8Vector("prefix");
- operations.push_back(std::move(item));
- base::RunLoop run_loop2;
- database->Write(std::move(operations),
- Capture(&error, run_loop2.QuitClosure()));
- run_loop2.Run();
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- // Reading all "prefix" keys should be invalid now.
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- value.clear();
- DatabaseSyncGet(database.get(), "prefix-key1", &error, &value);
- EXPECT_EQ(mojom::DatabaseError::NOT_FOUND, error);
- EXPECT_EQ("", Uint8VectorToStdString(value));
- // Reading "key" should be invalid now.
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- value.clear();
- DatabaseSyncGet(database.get(), "prefix-key2", &error, &value);
- EXPECT_EQ(mojom::DatabaseError::NOT_FOUND, error);
- EXPECT_EQ("", Uint8VectorToStdString(value));
-
- // Prefix keys should have been copied to 'copy-prefix' before deletion.
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- DatabaseSyncGet(database.get(), "copy-prefix-key1", &error, &value);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- EXPECT_EQ("value", Uint8VectorToStdString(value));
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- DatabaseSyncGet(database.get(), "copy-prefix-key2", &error, &value);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- EXPECT_EQ("value", Uint8VectorToStdString(value));
-}
-
-TEST_F(LevelDBServiceTest, WriteBatchPrefixesAndDeletes) {
- // This test makes sure that prefixes & deletes happen before all other batch
- // operations.
- mojom::DatabaseError error;
- mojo::AssociatedRemote<mojom::LevelDBDatabase> database;
- LevelDBSyncOpenInMemory(leveldb().get(),
- database.BindNewEndpointAndPassReceiver(), &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- // Write a key to the database.
- DatabaseSyncPut(database.get(), "key", "value", &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- // The copy applies as if it happens before this write batch.
- // The delete applies to all keys that existed before these changes.
- std::vector<mojom::BatchedOperationPtr> operations;
- mojom::BatchedOperationPtr item = mojom::BatchedOperation::New();
- item->type = mojom::BatchOperationType::PUT_KEY;
- item->key = StdStringToUint8Vector("key");
- item->value = StdStringToUint8Vector("new_value");
- operations.push_back(std::move(item));
-
- item = mojom::BatchedOperation::New();
- item->type = mojom::BatchOperationType::PUT_KEY;
- item->key = StdStringToUint8Vector("key2");
- item->value = StdStringToUint8Vector("value2");
- operations.push_back(std::move(item));
-
- item = mojom::BatchedOperation::New();
- item->type = mojom::BatchOperationType::DELETE_PREFIXED_KEY;
- item->key = StdStringToUint8Vector("k");
- operations.push_back(std::move(item));
-
- item = mojom::BatchedOperation::New();
- item->type = mojom::BatchOperationType::COPY_PREFIXED_KEY;
- item->key = StdStringToUint8Vector("k");
- item->value = StdStringToUint8Vector("f");
- operations.push_back(std::move(item));
- base::RunLoop run_loop;
- database->Write(std::move(operations),
- Capture(&error, run_loop.QuitClosure()));
- run_loop.Run();
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- std::vector<uint8_t> value;
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- DatabaseSyncGet(database.get(), "key", &error, &value);
- EXPECT_EQ(mojom::DatabaseError::NOT_FOUND, error);
- DatabaseSyncGet(database.get(), "key2", &error, &value);
- EXPECT_EQ("value2", Uint8VectorToStdString(value));
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- DatabaseSyncGet(database.get(), "fey", &error, &value);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- EXPECT_EQ("value", Uint8VectorToStdString(value));
-}
-
-TEST_F(LevelDBServiceTest, Reconnect) {
- mojom::DatabaseError error;
-
- mojo::Remote<filesystem::mojom::Directory> temp_directory = CreateTempDir();
-
- {
- filesystem::mojom::DirectoryPtr directory;
- temp_directory->Clone(MakeRequest(&directory));
-
- mojo::AssociatedRemote<mojom::LevelDBDatabase> database;
- leveldb_env::Options options;
- options.error_if_exists = true;
- options.create_if_missing = true;
- base::RunLoop run_loop;
- leveldb()->OpenWithOptions(std::move(options), std::move(directory), "test",
- base::nullopt,
- database.BindNewEndpointAndPassReceiver(),
- Capture(&error, run_loop.QuitClosure()));
- run_loop.Run();
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- // Write a key to the database.
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- DatabaseSyncPut(database.get(), "key", "value", &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- // The database should go out of scope here.
- }
-
- {
- filesystem::mojom::DirectoryPtr directory;
- temp_directory->Clone(MakeRequest(&directory));
-
- // Reconnect to the database.
- mojo::AssociatedRemote<mojom::LevelDBDatabase> database;
- base::RunLoop run_loop;
- leveldb()->Open(std::move(directory), "test", base::nullopt,
- database.BindNewEndpointAndPassReceiver(),
- Capture(&error, run_loop.QuitClosure()));
- run_loop.Run();
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- // We should still be able to read the key back from the database.
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- std::vector<uint8_t> value;
- DatabaseSyncGet(database.get(), "key", &error, &value);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- EXPECT_EQ("value", Uint8VectorToStdString(value));
- }
-}
-
-TEST_F(LevelDBServiceTest, Destroy) {
- mojom::DatabaseError error;
-
- mojo::Remote<filesystem::mojom::Directory> temp_directory = CreateTempDir();
-
- {
- filesystem::mojom::DirectoryPtr directory;
- temp_directory->Clone(MakeRequest(&directory));
-
- mojo::AssociatedRemote<mojom::LevelDBDatabase> database;
- leveldb_env::Options options;
- options.error_if_exists = true;
- options.create_if_missing = true;
- base::RunLoop run_loop;
- leveldb()->OpenWithOptions(std::move(options), std::move(directory), "test",
- base::nullopt,
- database.BindNewEndpointAndPassReceiver(),
- Capture(&error, run_loop.QuitClosure()));
- run_loop.Run();
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- // Write a key to the database.
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- DatabaseSyncPut(database.get(), "key", "value", &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- // The database should go out of scope here.
- }
-
- {
- filesystem::mojom::DirectoryPtr directory;
- temp_directory->Clone(MakeRequest(&directory));
-
- // Destroy the database.
- base::RunLoop run_loop;
- leveldb()->Destroy(std::move(directory), "test",
- Capture(&error, run_loop.QuitClosure()));
- run_loop.Run();
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- }
-
- {
- filesystem::mojom::DirectoryPtr directory;
- temp_directory->Clone(MakeRequest(&directory));
-
- // Reconnect to the database should fail.
- mojo::AssociatedRemote<mojom::LevelDBDatabase> database;
- base::RunLoop run_loop;
- leveldb()->Open(std::move(directory), "test", base::nullopt,
- database.BindNewEndpointAndPassReceiver(),
- Capture(&error, run_loop.QuitClosure()));
- run_loop.Run();
- EXPECT_EQ(mojom::DatabaseError::INVALID_ARGUMENT, error);
- }
-
- {
- filesystem::mojom::DirectoryPtr directory;
- temp_directory->Clone(MakeRequest(&directory));
-
- // Destroying a non-existant database should still succeed.
- base::RunLoop run_loop;
- leveldb()->Destroy(std::move(directory), "test",
- Capture(&error, run_loop.QuitClosure()));
- run_loop.Run();
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- }
-}
-
-TEST_F(LevelDBServiceTest, GetSnapshotSimple) {
- mojom::DatabaseError error;
- mojo::AssociatedRemote<mojom::LevelDBDatabase> database;
- LevelDBSyncOpenInMemory(leveldb().get(),
- database.BindNewEndpointAndPassReceiver(), &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- base::UnguessableToken snapshot;
- base::RunLoop run_loop;
- database->GetSnapshot(CaptureConstRef(&snapshot, run_loop.QuitClosure()));
- run_loop.Run();
- EXPECT_FALSE(snapshot.is_empty());
-}
-
-TEST_F(LevelDBServiceTest, GetFromSnapshots) {
- mojom::DatabaseError error;
- mojo::AssociatedRemote<mojom::LevelDBDatabase> database;
- LevelDBSyncOpenInMemory(leveldb().get(),
- database.BindNewEndpointAndPassReceiver(), &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- // Write a key to the database.
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- DatabaseSyncPut(database.get(), "key", "value", &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- // Take a snapshot where key=value.
- base::UnguessableToken key_value_snapshot;
- base::RunLoop run_loop;
- database->GetSnapshot(
- CaptureConstRef(&key_value_snapshot, run_loop.QuitClosure()));
- run_loop.Run();
-
- // Change key to "yek".
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- DatabaseSyncPut(database.get(), "key", "yek", &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- // (Ensure this change is live on the database.)
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- std::vector<uint8_t> value;
- DatabaseSyncGet(database.get(), "key", &error, &value);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- EXPECT_EQ("yek", Uint8VectorToStdString(value));
-
- // But if we were to read from the snapshot, we'd still get value.
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- value.clear();
- base::RunLoop run_loop2;
- database->GetFromSnapshot(
- key_value_snapshot, StdStringToUint8Vector("key"),
- CaptureConstRef(&error, &value, run_loop2.QuitClosure()));
- run_loop2.Run();
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- EXPECT_EQ("value", Uint8VectorToStdString(value));
-}
-
-TEST_F(LevelDBServiceTest, InvalidArgumentOnInvalidSnapshot) {
- mojo::AssociatedRemote<mojom::LevelDBDatabase> database;
- mojom::DatabaseError error = mojom::DatabaseError::INVALID_ARGUMENT;
- LevelDBSyncOpenInMemory(leveldb().get(),
- database.BindNewEndpointAndPassReceiver(), &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- base::UnguessableToken invalid_snapshot = base::UnguessableToken::Create();
-
- error = mojom::DatabaseError::OK;
- std::vector<uint8_t> value;
- base::RunLoop run_loop;
- database->GetFromSnapshot(
- invalid_snapshot, StdStringToUint8Vector("key"),
- CaptureConstRef(&error, &value, run_loop.QuitClosure()));
- run_loop.Run();
- EXPECT_EQ(mojom::DatabaseError::INVALID_ARGUMENT, error);
-}
-
-TEST_F(LevelDBServiceTest, MemoryDBReadWrite) {
- mojo::AssociatedRemote<mojom::LevelDBDatabase> database;
- mojom::DatabaseError error = mojom::DatabaseError::INVALID_ARGUMENT;
- LevelDBSyncOpenInMemory(leveldb().get(),
- database.BindNewEndpointAndPassReceiver(), &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- // Write a key to the database.
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- DatabaseSyncPut(database.get(), "key", "value", &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- // Read the key back from the database.
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- std::vector<uint8_t> value;
- DatabaseSyncGet(database.get(), "key", &error, &value);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- EXPECT_EQ("value", Uint8VectorToStdString(value));
-
- // Delete the key from the database.
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- DatabaseSyncDelete(database.get(), "key", &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- // Read the key back from the database.
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- value.clear();
- DatabaseSyncGet(database.get(), "key", &error, &value);
- EXPECT_EQ(mojom::DatabaseError::NOT_FOUND, error);
- EXPECT_EQ("", Uint8VectorToStdString(value));
-}
-
-TEST_F(LevelDBServiceTest, Prefixed) {
- // Open an in memory database for speed.
- mojom::DatabaseError error = mojom::DatabaseError::INVALID_ARGUMENT;
- mojo::AssociatedRemote<mojom::LevelDBDatabase> database;
- LevelDBSyncOpenInMemory(leveldb().get(),
- database.BindNewEndpointAndPassReceiver(), &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- const std::string prefix("prefix");
- const std::string copy_prefix("foo");
- std::vector<mojom::KeyValuePtr> key_values;
-
- // Completely empty database.
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- DatabaseSyncGetPrefixed(database.get(), prefix, &error, &key_values);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- EXPECT_TRUE(key_values.empty());
-
- // No values with our prefix, but values before and after.
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- DatabaseSyncPut(database.get(), "a-before-prefix", "value", &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- DatabaseSyncPut(database.get(), "z-after-prefix", "value", &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- key_values.clear();
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- DatabaseSyncGetPrefixed(database.get(), prefix, &error, &key_values);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- EXPECT_TRUE(key_values.empty());
-
- // One value with the exact prefix.
- DatabaseSyncPut(database.get(), prefix, "value", &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- key_values.clear();
- DatabaseSyncGetPrefixed(database.get(), prefix, &error, &key_values);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- EXPECT_EQ(1u, key_values.size());
- EXPECT_EQ("prefix", Uint8VectorToStdString(key_values[0]->key));
- EXPECT_EQ("value", Uint8VectorToStdString(key_values[0]->value));
-
- // Multiple values with starting with the prefix.
- DatabaseSyncPut(database.get(), (prefix + "2"), "value2", &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- key_values.clear();
- DatabaseSyncGetPrefixed(database.get(), prefix, &error, &key_values);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- EXPECT_EQ(2u, key_values.size());
- EXPECT_EQ("prefix", Uint8VectorToStdString(key_values[0]->key));
- EXPECT_EQ("value", Uint8VectorToStdString(key_values[0]->value));
- EXPECT_EQ("prefix2", Uint8VectorToStdString(key_values[1]->key));
- EXPECT_EQ("value2", Uint8VectorToStdString(key_values[1]->value));
-
- // Copy to a different prefix
- DatabaseSyncCopyPrefixed(database.get(), prefix, copy_prefix, &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- DatabaseSyncGetPrefixed(database.get(), copy_prefix, &error, &key_values);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- ASSERT_EQ(2u, key_values.size());
- EXPECT_EQ("foo", Uint8VectorToStdString(key_values[0]->key));
- EXPECT_EQ("value", Uint8VectorToStdString(key_values[0]->value));
- EXPECT_EQ("foo2", Uint8VectorToStdString(key_values[1]->key));
- EXPECT_EQ("value2", Uint8VectorToStdString(key_values[1]->value));
-
- // Delete the prefixed values.
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- DatabaseSyncDeletePrefixed(database.get(), prefix, &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- key_values.clear();
- DatabaseSyncGetPrefixed(database.get(), prefix, &error, &key_values);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- EXPECT_TRUE(key_values.empty());
-
- // Make sure the others are not deleted.
- std::vector<uint8_t> value;
- DatabaseSyncGet(database.get(), "a-before-prefix", &error, &value);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- EXPECT_EQ("value", Uint8VectorToStdString(value));
- value.clear();
- DatabaseSyncGet(database.get(), "z-after-prefix", &error, &value);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- EXPECT_EQ("value", Uint8VectorToStdString(value));
- DatabaseSyncGetPrefixed(database.get(), copy_prefix, &error, &key_values);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- EXPECT_EQ(2u, key_values.size());
-
- // A key having our prefix, but no key matching it exactly.
- // Even thought there is no exact matching key, GetPrefixed
- // and DeletePrefixed still operate on the values.
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- DatabaseSyncPut(database.get(), (prefix + "2"), "value2", &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- key_values.clear();
- DatabaseSyncGetPrefixed(database.get(), prefix, &error, &key_values);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- EXPECT_EQ(1u, key_values.size());
- EXPECT_EQ("prefix2", Uint8VectorToStdString(key_values[0]->key));
- EXPECT_EQ("value2", Uint8VectorToStdString(key_values[0]->value));
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- DatabaseSyncDeletePrefixed(database.get(), prefix, &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- key_values.clear();
- DatabaseSyncGetPrefixed(database.get(), prefix, &error, &key_values);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- EXPECT_TRUE(key_values.empty());
-}
-
-TEST_F(LevelDBServiceTest, RewriteDB) {
- mojom::DatabaseError error;
- filesystem::mojom::DirectoryPtr directory(CreateTempDir().Unbind());
-
- mojo::AssociatedRemote<mojom::LevelDBDatabase> database;
- leveldb_env::Options options;
- options.create_if_missing = true;
- base::RunLoop run_loop;
- leveldb()->OpenWithOptions(std::move(options), std::move(directory), "test",
- base::nullopt,
- database.BindNewEndpointAndPassReceiver(),
- Capture(&error, run_loop.QuitClosure()));
- run_loop.Run();
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- // Write entries to the database.
- DatabaseSyncPut(database.get(), "key1", "value1", &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- DatabaseSyncPut(database.get(), "key2", "value2", &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- // Delete key 1.
- DatabaseSyncDelete(database.get(), "key1", &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- // Perform a rewrite.
- DatabaseSyncRewrite(database.get(), &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- // Read the keys back from the database.
- std::vector<uint8_t> value;
- DatabaseSyncGet(database.get(), "key1", &error, &value);
- EXPECT_EQ(mojom::DatabaseError::NOT_FOUND, error);
- DatabaseSyncGet(database.get(), "key2", &error, &value);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- EXPECT_EQ("value2", Uint8VectorToStdString(value));
-}
-
-TEST_F(LevelDBServiceTest, GetMany) {
- mojom::DatabaseError error;
- mojo::AssociatedRemote<mojom::LevelDBDatabase> database;
- LevelDBSyncOpenInMemory(leveldb().get(),
- database.BindNewEndpointAndPassReceiver(), &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- // Write two keys to the database.
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- DatabaseSyncPut(database.get(), "key", "value", &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- DatabaseSyncPut(database.get(), "key1", "value1", &error);
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- std::vector<mojom::GetManyRequestPtr> requests;
- std::vector<mojom::GetManyResultPtr> results;
-
- // Test: Read keys back from the database
- AddKeyToGetManyRequest("key", &requests);
- AddKeyToGetManyRequest("key1", &requests);
- AddKeyPrefixToGetManyRequest("key", &requests);
- DatabaseSyncGetMany(database.get(), requests, &results);
-
- ASSERT_EQ(results.size(), 3UL);
- EXPECT_TRUE(results[0]->is_key_value());
- EXPECT_TRUE(results[1]->is_key_value());
- EXPECT_EQ(Uint8VectorToStdString(results[0]->get_key_value()), "value");
- EXPECT_EQ(Uint8VectorToStdString(results[1]->get_key_value()), "value1");
-
- // Test: the last key-prefix read should correctly return a list of KeyValue
- EXPECT_TRUE(results[2]->is_key_prefix_values());
- const std::vector<mojom::KeyValuePtr>& kv =
- results[2]->get_key_prefix_values();
- ASSERT_EQ(2UL, kv.size());
- EXPECT_EQ("key", Uint8VectorToStdString(kv[0]->key));
- EXPECT_EQ("value", Uint8VectorToStdString(kv[0]->value));
- EXPECT_EQ("key1", Uint8VectorToStdString(kv[1]->key));
- EXPECT_EQ("value1", Uint8VectorToStdString(kv[1]->value));
-
- // Test: Read a sequence of (existing key, non-existing key,
- // existing key), GetMany should return NOT_FOUND for the non-existing key
- requests.clear();
- results.clear();
-
- AddKeyToGetManyRequest("key", &requests);
- AddKeyToGetManyRequest("key-not-found", &requests);
- AddKeyToGetManyRequest("key", &requests);
- DatabaseSyncGetMany(database.get(), requests, &results);
-
- ASSERT_EQ(results.size(), 3UL);
- EXPECT_EQ(Uint8VectorToStdString(results[0]->get_key_value()), "value");
- EXPECT_TRUE(results[1]->is_status());
- EXPECT_TRUE(results[1]->get_status() == mojom::DatabaseError::NOT_FOUND);
- EXPECT_EQ(Uint8VectorToStdString(results[2]->get_key_value()), "value");
-
- // Test: Read a sequence of (existing key, non-existing key prefix,
- // existing key), GetMany should return empty data for the non-existing
- // key prefix
- requests.clear();
- results.clear();
-
- AddKeyToGetManyRequest("key", &requests);
- AddKeyPrefixToGetManyRequest("key-prefix-not-found", &requests);
- AddKeyToGetManyRequest("key", &requests);
- DatabaseSyncGetMany(database.get(), requests, &results);
-
- ASSERT_EQ(results.size(), 3UL);
- EXPECT_EQ(Uint8VectorToStdString(results[0]->get_key_value()), "value");
- EXPECT_TRUE(results[1]->get_key_prefix_values().empty());
- EXPECT_EQ(Uint8VectorToStdString(results[2]->get_key_value()), "value");
-
- // Test: Read empty data
- requests.clear();
- results.clear();
- DatabaseSyncGetMany(database.get(), requests, &results);
- EXPECT_TRUE(results.empty());
-}
-
-} // namespace
-} // namespace leveldb
diff --git a/chromium/components/services/leveldb/public/cpp/BUILD.gn b/chromium/components/services/leveldb/public/cpp/BUILD.gn
index 033466eb05a..24e3edb522f 100644
--- a/chromium/components/services/leveldb/public/cpp/BUILD.gn
+++ b/chromium/components/services/leveldb/public/cpp/BUILD.gn
@@ -4,8 +4,6 @@
static_library("cpp") {
sources = [
- "remote_iterator.cc",
- "remote_iterator.h",
"util.cc",
"util.h",
]
diff --git a/chromium/components/services/leveldb/public/cpp/remote_iterator.cc b/chromium/components/services/leveldb/public/cpp/remote_iterator.cc
deleted file mode 100644
index 0f9b5996100..00000000000
--- a/chromium/components/services/leveldb/public/cpp/remote_iterator.cc
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/services/leveldb/public/cpp/remote_iterator.h"
-
-#include "components/services/leveldb/public/cpp/util.h"
-
-namespace leveldb {
-
-RemoteIterator::RemoteIterator(mojom::LevelDBDatabase* database,
- const base::UnguessableToken& iterator)
- : database_(database),
- iterator_(iterator),
- valid_(false),
- status_(mojom::DatabaseError::OK) {}
-
-RemoteIterator::~RemoteIterator() {
- database_->ReleaseIterator(iterator_);
-}
-
-bool RemoteIterator::Valid() const {
- return valid_;
-}
-
-void RemoteIterator::SeekToFirst() {
- database_->IteratorSeekToFirst(iterator_, &valid_, &status_, &key_, &value_);
-}
-
-void RemoteIterator::SeekToLast() {
- database_->IteratorSeekToLast(iterator_, &valid_, &status_, &key_, &value_);
-}
-
-void RemoteIterator::Seek(const Slice& target) {
- database_->IteratorSeek(iterator_, GetVectorFor(target), &valid_, &status_,
- &key_, &value_);
-}
-
-void RemoteIterator::Next() {
- database_->IteratorNext(iterator_, &valid_, &status_, &key_, &value_);
-}
-
-void RemoteIterator::Prev() {
- database_->IteratorPrev(iterator_, &valid_, &status_, &key_, &value_);
-}
-
-Slice RemoteIterator::key() const {
- if (!key_)
- return leveldb::Slice();
- return GetSliceFor(*key_);
-}
-
-Slice RemoteIterator::value() const {
- if (!value_)
- return leveldb::Slice();
- return GetSliceFor(*value_);
-}
-
-Status RemoteIterator::status() const {
- return DatabaseErrorToStatus(status_, key(), value());
-}
-
-} // namespace leveldb
diff --git a/chromium/components/services/leveldb/public/cpp/remote_iterator.h b/chromium/components/services/leveldb/public/cpp/remote_iterator.h
deleted file mode 100644
index cad8da8b839..00000000000
--- a/chromium/components/services/leveldb/public/cpp/remote_iterator.h
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_SERVICES_LEVELDB_PUBLIC_CPP_REMOTE_ITERATOR_H_
-#define COMPONENTS_SERVICES_LEVELDB_PUBLIC_CPP_REMOTE_ITERATOR_H_
-
-#include "base/unguessable_token.h"
-#include "components/services/leveldb/public/mojom/leveldb.mojom.h"
-#include "third_party/leveldatabase/src/include/leveldb/iterator.h"
-
-namespace leveldb {
-
-// A wrapper around the raw iterator movement methods on the mojo leveldb
-// interface to allow drop in replacement to current leveldb usage.
-//
-// Note: Next(), Prev() and all the Seek*() calls cause mojo sync calls.
-class RemoteIterator : public Iterator {
- public:
- RemoteIterator(mojom::LevelDBDatabase* database,
- const base::UnguessableToken& iterator);
- ~RemoteIterator() override;
-
- // Overridden from leveldb::Iterator:
- bool Valid() const override;
- void SeekToFirst() override;
- void SeekToLast() override;
- void Seek(const Slice& target) override;
- void Next() override;
- void Prev() override;
- Slice key() const override;
- Slice value() const override;
- Status status() const override;
-
- private:
- mojom::LevelDBDatabase* database_;
- base::UnguessableToken iterator_;
-
- bool valid_;
- mojom::DatabaseError status_;
- base::Optional<std::vector<uint8_t>> key_;
- base::Optional<std::vector<uint8_t>> value_;
-
- DISALLOW_COPY_AND_ASSIGN(RemoteIterator);
-};
-
-} // namespace leveldb
-
-#endif // COMPONENTS_SERVICES_LEVELDB_PUBLIC_CPP_REMOTE_ITERATOR_H_
diff --git a/chromium/components/services/leveldb/public/cpp/util.cc b/chromium/components/services/leveldb/public/cpp/util.cc
index 0bcdcfe4309..0b61b11bd54 100644
--- a/chromium/components/services/leveldb/public/cpp/util.cc
+++ b/chromium/components/services/leveldb/public/cpp/util.cc
@@ -10,63 +10,6 @@
namespace leveldb {
-mojom::DatabaseError LeveldbStatusToError(const leveldb::Status& s) {
- if (s.ok())
- return mojom::DatabaseError::OK;
- if (s.IsNotFound())
- return mojom::DatabaseError::NOT_FOUND;
- if (s.IsCorruption())
- return mojom::DatabaseError::CORRUPTION;
- if (s.IsNotSupportedError())
- return mojom::DatabaseError::NOT_SUPPORTED;
- if (s.IsIOError())
- return mojom::DatabaseError::IO_ERROR;
- return mojom::DatabaseError::INVALID_ARGUMENT;
-}
-
-leveldb::Status DatabaseErrorToStatus(mojom::DatabaseError e,
- const Slice& msg,
- const Slice& msg2) {
- switch (e) {
- case mojom::DatabaseError::OK:
- return leveldb::Status::OK();
- case mojom::DatabaseError::NOT_FOUND:
- return leveldb::Status::NotFound(msg, msg2);
- case mojom::DatabaseError::CORRUPTION:
- return leveldb::Status::Corruption(msg, msg2);
- case mojom::DatabaseError::NOT_SUPPORTED:
- return leveldb::Status::NotSupported(msg, msg2);
- case mojom::DatabaseError::INVALID_ARGUMENT:
- return leveldb::Status::InvalidArgument(msg, msg2);
- case mojom::DatabaseError::IO_ERROR:
- return leveldb::Status::IOError(msg, msg2);
- }
-
- // This will never be reached, but we still have configurations which don't
- // do switch enum checking.
- return leveldb::Status::InvalidArgument(msg, msg2);
-}
-
-leveldb_env::LevelDBStatusValue GetLevelDBStatusUMAValue(
- mojom::DatabaseError status) {
- switch (status) {
- case mojom::DatabaseError::OK:
- return leveldb_env::LEVELDB_STATUS_OK;
- case mojom::DatabaseError::NOT_FOUND:
- return leveldb_env::LEVELDB_STATUS_NOT_FOUND;
- case mojom::DatabaseError::CORRUPTION:
- return leveldb_env::LEVELDB_STATUS_CORRUPTION;
- case mojom::DatabaseError::NOT_SUPPORTED:
- return leveldb_env::LEVELDB_STATUS_NOT_SUPPORTED;
- case mojom::DatabaseError::INVALID_ARGUMENT:
- return leveldb_env::LEVELDB_STATUS_INVALID_ARGUMENT;
- case mojom::DatabaseError::IO_ERROR:
- return leveldb_env::LEVELDB_STATUS_IO_ERROR;
- }
- NOTREACHED();
- return leveldb_env::LEVELDB_STATUS_OK;
-}
-
leveldb::Slice GetSliceFor(const std::vector<uint8_t>& key) {
if (key.size() == 0)
return leveldb::Slice();
diff --git a/chromium/components/services/leveldb/public/cpp/util.h b/chromium/components/services/leveldb/public/cpp/util.h
index b45b2fa9596..a3044e74f4e 100644
--- a/chromium/components/services/leveldb/public/cpp/util.h
+++ b/chromium/components/services/leveldb/public/cpp/util.h
@@ -9,27 +9,11 @@
#include <vector>
#include "base/strings/string16.h"
-#include "components/services/leveldb/public/mojom/leveldb.mojom.h"
#include "third_party/leveldatabase/env_chromium.h"
namespace leveldb {
class Slice;
-class Status;
-
-// Builds a mojo mojom::DatabaseError from a leveldb::Status object.
-mojom::DatabaseError LeveldbStatusToError(const leveldb::Status& s);
-
-// Creates a leveldb Status object form a database error and two optional
-// messages. A mojoification of the various static leveldb::Status
-// constructors.
-leveldb::Status DatabaseErrorToStatus(mojom::DatabaseError e,
- const Slice& msg,
- const Slice& msg2);
-
-// Returns an UMA value for a mojom::DatabaseError.
-leveldb_env::LevelDBStatusValue GetLevelDBStatusUMAValue(
- mojom::DatabaseError status);
// Builds a Slice pointing to the data inside |a|. This is not a type-converter
// as it is not a copy operation; the returned Slice points into |a| and must
diff --git a/chromium/components/services/leveldb/public/mojom/BUILD.gn b/chromium/components/services/leveldb/public/mojom/BUILD.gn
index 79572d0f510..6434221598f 100644
--- a/chromium/components/services/leveldb/public/mojom/BUILD.gn
+++ b/chromium/components/services/leveldb/public/mojom/BUILD.gn
@@ -5,17 +5,7 @@
import("//mojo/public/tools/bindings/mojom.gni")
mojom("mojom") {
- support_lazy_serialization = true
-
sources = [
"leveldb.mojom",
]
-
- deps = [
- "//components/services/filesystem/public/mojom",
- ]
-
- public_deps = [
- "//mojo/public/mojom/base",
- ]
}
diff --git a/chromium/components/services/leveldb/public/mojom/leveldb.mojom b/chromium/components/services/leveldb/public/mojom/leveldb.mojom
index 3de269f8cf5..4bc70cf1f83 100644
--- a/chromium/components/services/leveldb/public/mojom/leveldb.mojom
+++ b/chromium/components/services/leveldb/public/mojom/leveldb.mojom
@@ -4,19 +4,6 @@
module leveldb.mojom;
-import "components/services/filesystem/public/mojom/directory.mojom";
-import "mojo/public/mojom/base/memory_allocator_dump_cross_process_uid.mojom";
-import "mojo/public/mojom/base/unguessable_token.mojom";
-
-enum DatabaseError {
- OK,
- NOT_FOUND,
- CORRUPTION,
- NOT_SUPPORTED,
- INVALID_ARGUMENT,
- IO_ERROR
-};
-
enum BatchOperationType {
PUT_KEY,
DELETE_KEY,
@@ -37,178 +24,3 @@ struct KeyValue {
array<uint8> key;
array<uint8> value;
};
-
-union GetManyRequest {
- array<uint8> key_prefix;
- array<uint8> key;
-};
-
-union GetManyResult {
- DatabaseError status;
- array<KeyValue> key_prefix_values;
- array<uint8> key_value;
-};
-
-enum SharedReadCache {
- Default,
- Web,
-};
-
-// Options which control the behavior of a database. (This struct corresponds
-// with the struct in leveldb's options.h.)
-//
-// Note: This struct does not have default values. The values are set by a
-// struct trait which copies values to/from a leveldb_env::Options instance.
-struct OpenOptions {
- // TODO(erg): Find all comparators and copy them into the service.
-
- // If true, the database will be created if it is missing.
- bool create_if_missing;
-
- // If true, an error is raised if the database already exists.
- bool error_if_exists;
-
- // If true, the implementation will do aggressive checking of the
- // data it is processing and will stop early if it detects any
- // errors.
- bool paranoid_checks;
-
- // Amount of data to build up in memory (backed by an unsorted log
- // on disk) before converting to a sorted on-disk file.
- uint64 write_buffer_size;
-
- // Number of open files that can be used by the DB.
- int32 max_open_files;
-
- // The shared read cache to use.
- SharedReadCache shared_block_read_cache = SharedReadCache.Default;
-};
-
-// Service which hands out databases.
-interface LevelDBService {
- // Open the database with the specified "name" in the specified "directory".
- // Fails if the database doesn't already exist.
- Open(filesystem.mojom.Directory directory,
- string dbname,
- mojo_base.mojom.MemoryAllocatorDumpCrossProcessUid? memory_dump_id,
- pending_associated_receiver<LevelDBDatabase> database)
- => (DatabaseError status);
-
- // Open the database with the specified "name" in the specified "directory".
- OpenWithOptions(OpenOptions options,
- filesystem.mojom.Directory directory,
- string dbname,
- mojo_base.mojom.MemoryAllocatorDumpCrossProcessUid?
- memory_dump_id,
- pending_associated_receiver<LevelDBDatabase> database)
- => (DatabaseError status);
-
- // Opens a database stored purely in memory.
- // "tracking_name" will be used for memory-infra reporting to associate memory
- // use with its origin.
- OpenInMemory(mojo_base.mojom.MemoryAllocatorDumpCrossProcessUid?
- memory_dump_id, string tracking_name,
- pending_associated_receiver<LevelDBDatabase> database)
- => (DatabaseError status);
-
- // Destroys the contents of the specified database. Returns OK if the database
- // already didn't exist.
- Destroy(filesystem.mojom.Directory directory,
- string dbname) => (DatabaseError status);
-};
-
-// A leveldb database.
-interface LevelDBDatabase {
- // Basic Interface -------------------------------------------------------
-
- // Sets the database entry for "key" to "value". Returns OK on success.
- Put(array<uint8> key, array<uint8> value) => (DatabaseError status);
-
- // Remove the database entry (if any) for "key". Returns OK on
- // success, and a non-OK status on error. It is not an error if "key"
- // did not exist in the database.
- Delete(array<uint8> key) => (DatabaseError status);
-
- DeletePrefixed(array<uint8> key_prefix) => (DatabaseError status);
-
- // Rewrites the database to remove traces of deleted entries from disk.
- // Returns OK on success. A non-OK error means that the rewrite failed.
- // If the status is not OK, the database can become unusable which will close
- // the mojo connection.
- RewriteDB() => (DatabaseError status);
-
- // Atomically performs all |operations|.
- // The DELETE_PREFIXED_KEY applies to all keys that exist before these
- // operations execute. If a 'put' operation precedes a delete prefix, then it
- // will only be deleted if it was a previously-populated key in the database.
- // The COPY_PREFIXED_KEY operations will always ignore all other changes in
- // the operations batch. It will not copy records that were inserted earlier
- // in the operations list.
- Write(array<BatchedOperation> operations) => (DatabaseError status);
-
- Get(array<uint8> key) => (DatabaseError status, array<uint8> value);
-
- GetPrefixed(array<uint8> key_prefix)
- => (DatabaseError status, array<KeyValue> data);
-
- // Get multiple keys and key prefixes and return corresponding values or
- // non-OK error in the same order. Each request has a corresponding result
- // in the same array position. A result can only be either a non-OK
- // db status or a value for the key or key prefix.
- GetMany(array<GetManyRequest> keys_or_prefixes)
- => (array<GetManyResult> data);
-
- // Copies all data from the source prefix to the destination prefix. Useful
- // for deep copies.
- CopyPrefixed(array<uint8> source_key_prefix,
- array<uint8> destination_key_prefix)
- => (DatabaseError status);
-
- // Snapshots -------------------------------------------------------------
-
- // Returns a handle to the current database state.
- GetSnapshot() => (mojo_base.mojom.UnguessableToken snapshot);
-
- // Releases a previously acquired snapshot.
- ReleaseSnapshot(mojo_base.mojom.UnguessableToken snapshot);
-
- // If |key| exists at the time |snapshot_id| was taken, return OK and the
- // value. Otherwise return NOT_FOUND.
- GetFromSnapshot(mojo_base.mojom.UnguessableToken snapshot,
- array<uint8> key)
- => (DatabaseError status, array<uint8> value);
-
- // Iteartors -------------------------------------------------------------
-
- // Creates an iterator, either from the current view or from a snapshot.
- NewIterator() => (mojo_base.mojom.UnguessableToken iterator);
- NewIteratorFromSnapshot(mojo_base.mojom.UnguessableToken snapshot)
- => (mojo_base.mojom.UnguessableToken? iterator);
-
- ReleaseIterator(mojo_base.mojom.UnguessableToken iterator);
-
- // Positions the iterator at the first key, last key, or the first key after
- // |target|.
- [Sync]
- IteratorSeekToFirst(mojo_base.mojom.UnguessableToken iterator)
- => (bool valid, DatabaseError status, array<uint8>? key,
- array<uint8>? value);
- [Sync]
- IteratorSeekToLast(mojo_base.mojom.UnguessableToken iterator)
- => (bool valid, DatabaseError status, array<uint8>? key,
- array<uint8>? value);
- [Sync]
- IteratorSeek(mojo_base.mojom.UnguessableToken iterator, array<uint8> target)
- => (bool valid, DatabaseError status, array<uint8>? key,
- array<uint8>? value);
-
- // Moves forward or backwards in iterator space.
- [Sync]
- IteratorNext(mojo_base.mojom.UnguessableToken iterator)
- => (bool valid, DatabaseError status, array<uint8>? key,
- array<uint8>? value);
- [Sync]
- IteratorPrev(mojo_base.mojom.UnguessableToken iterator)
- => (bool valid, DatabaseError status, array<uint8>? key,
- array<uint8>? value);
-};
diff --git a/chromium/components/services/leveldb/remote_iterator_unittest.cc b/chromium/components/services/leveldb/remote_iterator_unittest.cc
deleted file mode 100644
index a53273331de..00000000000
--- a/chromium/components/services/leveldb/remote_iterator_unittest.cc
+++ /dev/null
@@ -1,182 +0,0 @@
-// Copyright 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <map>
-
-#include "base/bind.h"
-#include "base/macros.h"
-#include "base/run_loop.h"
-#include "base/task/post_task.h"
-#include "base/test/task_environment.h"
-#include "components/services/leveldb/leveldb_service_impl.h"
-#include "components/services/leveldb/public/cpp/remote_iterator.h"
-#include "components/services/leveldb/public/cpp/util.h"
-#include "components/services/leveldb/public/mojom/leveldb.mojom.h"
-#include "mojo/public/cpp/bindings/associated_remote.h"
-#include "mojo/public/cpp/bindings/receiver.h"
-#include "mojo/public/cpp/bindings/remote.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace leveldb {
-namespace {
-
-template <typename... Args>
-void IgnoreAllArgs(Args&&...) {}
-
-template <typename... Args>
-void DoCaptures(typename std::decay<Args>::type*... out_args,
- const base::Closure& quit_closure,
- Args... in_args) {
- IgnoreAllArgs((*out_args = std::move(in_args))...);
- quit_closure.Run();
-}
-
-template <typename T1>
-base::Callback<void(T1)> Capture(T1* t1, const base::Closure& quit_closure) {
- return base::Bind(&DoCaptures<T1>, t1, quit_closure);
-}
-
-base::Callback<void(const base::UnguessableToken&)> CaptureToken(
- base::UnguessableToken* t1,
- const base::Closure& quit_closure) {
- return base::Bind(&DoCaptures<const base::UnguessableToken&>, t1,
- quit_closure);
-}
-
-class RemoteIteratorTest : public testing::Test {
- public:
- RemoteIteratorTest()
- : leveldb_service_(base::CreateSequencedTaskRunner(
- {base::ThreadPool(), base::MayBlock(),
- base::TaskShutdownBehavior::BLOCK_SHUTDOWN})),
- leveldb_receiver_(&leveldb_service_,
- leveldb_remote_.BindNewPipeAndPassReceiver()) {}
- ~RemoteIteratorTest() override = default;
-
- protected:
- void SetUp() override {
- mojom::DatabaseError error;
- base::RunLoop run_loop;
- leveldb()->OpenInMemory(base::nullopt, "RemoteIteratorTest",
- database_.BindNewEndpointAndPassReceiver(),
- Capture(&error, run_loop.QuitClosure()));
- run_loop.Run();
- EXPECT_EQ(mojom::DatabaseError::OK, error);
-
- std::map<std::string, std::string> data{
- {"a", "first"}, {"b:suffix", "second"}, {"c", "third"}};
-
- for (auto p : data) {
- // Write a key to the database.
- error = mojom::DatabaseError::INVALID_ARGUMENT;
- base::RunLoop run_loop;
- database_->Put(StdStringToUint8Vector(p.first),
- StdStringToUint8Vector(p.second),
- Capture(&error, run_loop.QuitClosure()));
- run_loop.Run();
- EXPECT_EQ(mojom::DatabaseError::OK, error);
- }
- }
-
- mojo::Remote<mojom::LevelDBService>& leveldb() { return leveldb_remote_; }
- mojo::AssociatedRemote<mojom::LevelDBDatabase>& database() {
- return database_;
- }
-
- private:
- base::test::TaskEnvironment task_environment_;
- LevelDBServiceImpl leveldb_service_;
- mojo::Remote<mojom::LevelDBService> leveldb_remote_;
- mojo::Receiver<mojom::LevelDBService> leveldb_receiver_;
- mojo::AssociatedRemote<mojom::LevelDBDatabase> database_;
-
- DISALLOW_COPY_AND_ASSIGN(RemoteIteratorTest);
-};
-
-TEST_F(RemoteIteratorTest, Seeking) {
- base::UnguessableToken iterator;
- base::RunLoop run_loop;
- database()->NewIterator(CaptureToken(&iterator, run_loop.QuitClosure()));
- run_loop.Run();
- EXPECT_FALSE(iterator.is_empty());
-
- RemoteIterator it(database().get(), iterator);
- EXPECT_FALSE(it.Valid());
-
- it.SeekToFirst();
- EXPECT_TRUE(it.Valid());
- EXPECT_EQ("a", it.key());
- EXPECT_EQ("first", it.value());
-
- it.SeekToLast();
- EXPECT_TRUE(it.Valid());
- EXPECT_EQ("c", it.key());
- EXPECT_EQ("third", it.value());
-
- it.Seek("b");
- EXPECT_TRUE(it.Valid());
- EXPECT_EQ("b:suffix", it.key());
- EXPECT_EQ("second", it.value());
-}
-
-TEST_F(RemoteIteratorTest, Next) {
- base::UnguessableToken iterator;
- base::RunLoop run_loop;
- database()->NewIterator(CaptureToken(&iterator, run_loop.QuitClosure()));
- run_loop.Run();
- EXPECT_FALSE(iterator.is_empty());
-
- RemoteIterator it(database().get(), iterator);
- EXPECT_FALSE(it.Valid());
-
- it.SeekToFirst();
- EXPECT_TRUE(it.Valid());
- EXPECT_EQ("a", it.key());
- EXPECT_EQ("first", it.value());
-
- it.Next();
- EXPECT_TRUE(it.Valid());
- EXPECT_EQ("b:suffix", it.key());
- EXPECT_EQ("second", it.value());
-
- it.Next();
- EXPECT_TRUE(it.Valid());
- EXPECT_EQ("c", it.key());
- EXPECT_EQ("third", it.value());
-
- it.Next();
- EXPECT_FALSE(it.Valid());
-}
-
-TEST_F(RemoteIteratorTest, Prev) {
- base::UnguessableToken iterator;
- base::RunLoop run_loop;
- database()->NewIterator(CaptureToken(&iterator, run_loop.QuitClosure()));
- run_loop.Run();
- EXPECT_FALSE(iterator.is_empty());
-
- RemoteIterator it(database().get(), iterator);
- EXPECT_FALSE(it.Valid());
-
- it.SeekToLast();
- EXPECT_TRUE(it.Valid());
- EXPECT_EQ("c", it.key());
- EXPECT_EQ("third", it.value());
-
- it.Prev();
- EXPECT_TRUE(it.Valid());
- EXPECT_EQ("b:suffix", it.key());
- EXPECT_EQ("second", it.value());
-
- it.Prev();
- EXPECT_TRUE(it.Valid());
- EXPECT_EQ("a", it.key());
- EXPECT_EQ("first", it.value());
-
- it.Prev();
- EXPECT_FALSE(it.Valid());
-}
-
-} // namespace
-} // namespace leveldb
diff --git a/chromium/components/services/patch/public/cpp/patch.cc b/chromium/components/services/patch/public/cpp/patch.cc
index 60c3a2f2774..83fcbc62adf 100644
--- a/chromium/components/services/patch/public/cpp/patch.cc
+++ b/chromium/components/services/patch/public/cpp/patch.cc
@@ -38,8 +38,8 @@ class PatchParams : public base::RefCounted<PatchParams> {
~PatchParams() = default;
- // The FilePatcherPtr is stored so it does not get deleted before the callback
- // runs.
+ // The mojo::Remote<FilePatcher> is stored so it does not get deleted before
+ // the callback runs.
mojo::Remote<mojom::FilePatcher> file_patcher_;
PatchCallback callback_;
diff --git a/chromium/components/services/pdf_compositor/pdf_compositor_impl.cc b/chromium/components/services/pdf_compositor/pdf_compositor_impl.cc
index b4fd83e3e2c..a1d3264e413 100644
--- a/chromium/components/services/pdf_compositor/pdf_compositor_impl.cc
+++ b/chromium/components/services/pdf_compositor/pdf_compositor_impl.cc
@@ -18,6 +18,7 @@
#include "components/services/pdf_compositor/public/cpp/pdf_service_mojo_types.h"
#include "content/public/utility/utility_thread.h"
#include "mojo/public/cpp/base/shared_memory_utils.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/system/platform_handle.h"
#include "printing/common/metafile_utils.h"
#include "third_party/blink/public/platform/web_image_generator.h"
@@ -46,6 +47,9 @@ PdfCompositorImpl::PdfCompositorImpl(
if (receiver)
receiver_.Bind(std::move(receiver));
+ if (!initialize_environment)
+ return;
+
#if defined(OS_WIN)
// Initialize direct write font proxy so skia can use it.
content::InitializeDWriteFontProxy();
@@ -55,9 +59,6 @@ PdfCompositorImpl::PdfCompositorImpl(
SkGraphics::SetImageGeneratorFromEncodedDataFactory(
blink::WebImageGenerator::CreateAsSkImageGenerator);
- if (!initialize_environment)
- return;
-
#if defined(OS_POSIX) && !defined(OS_ANDROID)
content::UtilityThread::Get()->EnsureBlinkInitializedWithSandboxSupport();
// Check that we have sandbox support on this platform.
@@ -85,11 +86,11 @@ void PdfCompositorImpl::SetDiscardableSharedMemoryManager(
mojo::PendingRemote<
discardable_memory::mojom::DiscardableSharedMemoryManager> manager) {
// Set up discardable memory manager.
- discardable_memory::mojom::DiscardableSharedMemoryManagerPtr manager_ptr(
- std::move(manager));
+ mojo::PendingRemote<discardable_memory::mojom::DiscardableSharedMemoryManager>
+ manager_remote(std::move(manager));
discardable_shared_memory_manager_ = std::make_unique<
discardable_memory::ClientDiscardableSharedMemoryManager>(
- std::move(manager_ptr), io_task_runner_);
+ std::move(manager_remote), io_task_runner_);
base::DiscardableMemoryAllocator::SetInstance(
discardable_shared_memory_manager_.get());
}
diff --git a/chromium/components/services/storage/dom_storage/dom_storage_database.cc b/chromium/components/services/storage/dom_storage/dom_storage_database.cc
index 184a55008e1..43ee71d3cc1 100644
--- a/chromium/components/services/storage/dom_storage/dom_storage_database.cc
+++ b/chromium/components/services/storage/dom_storage/dom_storage_database.cc
@@ -21,6 +21,10 @@ namespace storage {
namespace {
+// IOError message returned whenever a call is made on a DomStorageDatabase
+// which has been invalidated (e.g. by a failed |RewriteDB()| operation).
+const char kInvalidDatabaseMessage[] = "DomStorageDatabase no longer valid.";
+
class DomStorageDatabaseEnv : public leveldb_env::ChromiumEnv {
public:
DomStorageDatabaseEnv() : ChromiumEnv("ChromiumEnv.StorageService") {}
@@ -167,11 +171,11 @@ DomStorageDatabase::DomStorageDatabase(
env_(std::move(env)),
options_(AddEnvToOptions(options,
env_ ? env_.get() : GetDomStorageDatabaseEnv())),
+ memory_dump_id_(memory_dump_id),
db_(TryOpenDB(options_,
name,
std::move(callback_task_runner),
- std::move(callback))),
- memory_dump_id_(memory_dump_id) {
+ std::move(callback))) {
base::trace_event::MemoryDumpManager::GetInstance()
->RegisterDumpProviderWithSequencedTaskRunner(
this, "MojoLevelDB", base::SequencedTaskRunnerHandle::Get(),
@@ -181,6 +185,8 @@ DomStorageDatabase::DomStorageDatabase(
DomStorageDatabase::~DomStorageDatabase() {
base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
this);
+ if (destruction_callback_)
+ std::move(destruction_callback_).Run();
}
// static
@@ -258,6 +264,8 @@ void DomStorageDatabase::Destroy(
DomStorageDatabase::Status DomStorageDatabase::Get(KeyView key,
Value* out_value) const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!db_)
+ return Status::IOError(kInvalidDatabaseMessage);
std::string value;
Status status = db_->Get(leveldb::ReadOptions(), MakeSlice(key), &value);
*out_value = Value(value.begin(), value.end());
@@ -267,11 +275,15 @@ DomStorageDatabase::Status DomStorageDatabase::Get(KeyView key,
DomStorageDatabase::Status DomStorageDatabase::Put(KeyView key,
ValueView value) const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!db_)
+ return Status::IOError(kInvalidDatabaseMessage);
return db_->Put(leveldb::WriteOptions(), MakeSlice(key), MakeSlice(value));
}
DomStorageDatabase::Status DomStorageDatabase::Delete(KeyView key) const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!db_)
+ return Status::IOError(kInvalidDatabaseMessage);
return db_->Delete(leveldb::WriteOptions(), MakeSlice(key));
}
@@ -279,6 +291,8 @@ DomStorageDatabase::Status DomStorageDatabase::GetPrefixed(
KeyView prefix,
std::vector<KeyValuePair>* entries) const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
+ if (!db_)
+ return Status::IOError(kInvalidDatabaseMessage);
return ForEachWithPrefix(
db_.get(), prefix,
[&](const leveldb::Slice& key, const leveldb::Slice& value) {
@@ -287,24 +301,26 @@ DomStorageDatabase::Status DomStorageDatabase::GetPrefixed(
}
DomStorageDatabase::Status DomStorageDatabase::DeletePrefixed(
- KeyView prefix) const {
+ KeyView prefix,
+ leveldb::WriteBatch* batch) const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- leveldb::WriteBatch batch;
+ if (!db_)
+ return Status::IOError(kInvalidDatabaseMessage);
Status status = ForEachWithPrefix(
db_.get(), prefix,
[&](const leveldb::Slice& key, const leveldb::Slice& value) {
- batch.Delete(key);
+ batch->Delete(key);
});
- if (!status.ok())
- return status;
- return db_->Write(leveldb::WriteOptions(), &batch);
+ return status;
}
DomStorageDatabase::Status DomStorageDatabase::CopyPrefixed(
KeyView prefix,
- KeyView new_prefix) const {
+ KeyView new_prefix,
+ leveldb::WriteBatch* batch) const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
- leveldb::WriteBatch batch;
+ if (!db_)
+ return Status::IOError(kInvalidDatabaseMessage);
Key new_key(new_prefix.begin(), new_prefix.end());
Status status = ForEachWithPrefix(
db_.get(), prefix,
@@ -314,11 +330,27 @@ DomStorageDatabase::Status DomStorageDatabase::CopyPrefixed(
new_key.resize(new_prefix.size() + suffix_length);
std::copy(key.data() + prefix.size(), key.data() + key.size(),
new_key.begin() + new_prefix.size());
- batch.Put(MakeSlice(new_key), value);
+ batch->Put(MakeSlice(new_key), value);
});
+ return status;
+}
+
+DomStorageDatabase::Status DomStorageDatabase::Commit(
+ leveldb::WriteBatch* batch) const {
+ if (!db_)
+ return Status::IOError(kInvalidDatabaseMessage);
+ if (fail_commits_for_testing_)
+ return Status::IOError("Simulated I/O Error");
+ return db_->Write(leveldb::WriteOptions(), batch);
+}
+
+DomStorageDatabase::Status DomStorageDatabase::RewriteDB() {
+ if (!db_)
+ return Status::IOError(kInvalidDatabaseMessage);
+ Status status = leveldb_env::RewriteDB(options_, name_, &db_);
if (!status.ok())
- return status;
- return db_->Write(leveldb::WriteOptions(), &batch);
+ db_.reset();
+ return status;
}
bool DomStorageDatabase::OnMemoryDump(
diff --git a/chromium/components/services/storage/dom_storage/dom_storage_database.h b/chromium/components/services/storage/dom_storage/dom_storage_database.h
index aac805a0c6b..ffe142c3c6e 100644
--- a/chromium/components/services/storage/dom_storage/dom_storage_database.h
+++ b/chromium/components/services/storage/dom_storage/dom_storage_database.h
@@ -25,6 +25,7 @@
#include "third_party/leveldatabase/env_chromium.h"
#include "third_party/leveldatabase/src/include/leveldb/db.h"
#include "third_party/leveldatabase/src/include/leveldb/env.h"
+#include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
namespace storage {
@@ -125,12 +126,31 @@ class DomStorageDatabase : private base::trace_event::MemoryDumpProvider {
// Gets all database entries whose key starts with |prefix|.
Status GetPrefixed(KeyView prefix, std::vector<KeyValuePair>* entries) const;
- // Deletes all database entries whose key starts with |prefix|.
- Status DeletePrefixed(KeyView prefix) const;
+ // Adds operations to |batch| which will delete all database entries whose key
+ // starts with |prefix| when committed.
+ Status DeletePrefixed(KeyView prefix, leveldb::WriteBatch* batch) const;
- // Copies all database entries whose key starts with |prefix| over to new
- // entries with |prefix| replaced by |new_prefix| in each new key.
- Status CopyPrefixed(KeyView prefix, KeyView new_prefix) const;
+ // Adds operations to |batch| which when committed will copy all database
+ // entries whose key starts with |prefix| over to new entries with |prefix|
+ // replaced by |new_prefix| in each new key.
+ Status CopyPrefixed(KeyView prefix,
+ KeyView new_prefix,
+ leveldb::WriteBatch* batch) const;
+
+ // Commits operations in |batch| to the database.
+ Status Commit(leveldb::WriteBatch* batch) const;
+
+ // Rewrites the database on disk to clean up traces of deleted entries.
+ //
+ // NOTE: If |RewriteDB()| fails, this DomStorageDatabase may no longer be
+ // usable; in such cases, all future operations will return an IOError status.
+ Status RewriteDB();
+
+ void SetDestructionCallbackForTesting(base::OnceClosure callback) {
+ destruction_callback_ = std::move(callback);
+ }
+
+ void MakeAllCommitsFailForTesting() { fail_commits_for_testing_ = true; }
private:
friend class base::SequenceBound<DomStorageDatabase>;
@@ -176,9 +196,16 @@ class DomStorageDatabase : private base::trace_event::MemoryDumpProvider {
const std::string name_;
const std::unique_ptr<leveldb::Env> env_;
const leveldb_env::Options options_;
- const std::unique_ptr<leveldb::DB> db_;
const base::Optional<base::trace_event::MemoryAllocatorDumpGuid>
memory_dump_id_;
+ std::unique_ptr<leveldb::DB> db_;
+
+ // Causes all calls to |Commit()| to fail with an IOError for simulated
+ // disk failures in testing.
+ bool fail_commits_for_testing_ = false;
+
+ // Callback to run on destruction in tests.
+ base::OnceClosure destruction_callback_;
SEQUENCE_CHECKER(sequence_checker_);
diff --git a/chromium/components/services/storage/dom_storage/dom_storage_database_unittest.cc b/chromium/components/services/storage/dom_storage/dom_storage_database_unittest.cc
index e3982fc23dd..70fd9a9a222 100644
--- a/chromium/components/services/storage/dom_storage/dom_storage_database_unittest.cc
+++ b/chromium/components/services/storage/dom_storage/dom_storage_database_unittest.cc
@@ -19,6 +19,7 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/leveldatabase/env_chromium.h"
+#include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
using ::testing::UnorderedElementsAreArray;
@@ -362,7 +363,9 @@ TEST_F(StorageServiceDomStorageDatabaseTest, DeletePrefixed) {
// Wipe out the first prefix. We should still see the second prefix.
std::vector<DomStorageDatabase::KeyValuePair> entries;
- EXPECT_STATUS_OK(db.DeletePrefixed(MakeBytes(kTestPrefix1)));
+ leveldb::WriteBatch batch;
+ EXPECT_STATUS_OK(db.DeletePrefixed(MakeBytes(kTestPrefix1), &batch));
+ EXPECT_STATUS_OK(db.Commit(&batch));
EXPECT_STATUS_OK(db.GetPrefixed(MakeBytes(kTestPrefix1), &entries));
EXPECT_TRUE(entries.empty());
EXPECT_STATUS_OK(db.GetPrefixed(MakeBytes(kTestPrefix2), &entries));
@@ -372,7 +375,9 @@ TEST_F(StorageServiceDomStorageDatabaseTest, DeletePrefixed) {
MakeKeyValuePair(kTestPrefix2Key2, kTestValue3)}));
// Wipe out the second prefix.
- EXPECT_STATUS_OK(db.DeletePrefixed(MakeBytes(kTestPrefix2)));
+ batch.Clear();
+ EXPECT_STATUS_OK(db.DeletePrefixed(MakeBytes(kTestPrefix2), &batch));
+ EXPECT_STATUS_OK(db.Commit(&batch));
EXPECT_STATUS_OK(db.GetPrefixed(MakeBytes(kTestPrefix2), &entries));
// The lone unprefixed value should still exist.
@@ -414,8 +419,10 @@ TEST_F(StorageServiceDomStorageDatabaseTest, CopyPrefixed) {
// Copy the prefixed entries to |kTestPrefix2| and verify that we have the
// expected entries.
- EXPECT_STATUS_OK(
- db.CopyPrefixed(MakeBytes(kTestPrefix1), MakeBytes(kTestPrefix2)));
+ leveldb::WriteBatch batch;
+ EXPECT_STATUS_OK(db.CopyPrefixed(MakeBytes(kTestPrefix1),
+ MakeBytes(kTestPrefix2), &batch));
+ EXPECT_STATUS_OK(db.Commit(&batch));
std::vector<DomStorageDatabase::KeyValuePair> entries;
EXPECT_STATUS_OK(db.GetPrefixed(MakeBytes(kTestPrefix2), &entries));
diff --git a/chromium/components/services/storage/partition_impl_unittest.cc b/chromium/components/services/storage/partition_impl_unittest.cc
index baa6f45f106..1cd6ad7ac78 100644
--- a/chromium/components/services/storage/partition_impl_unittest.cc
+++ b/chromium/components/services/storage/partition_impl_unittest.cc
@@ -38,7 +38,7 @@ class StorageServicePartitionImplTest : public testing::Test {
PartitionImpl* test_partition_impl() { return test_partition_impl_; }
private:
- base::test::ScopedTaskEnvironment task_environment_;
+ base::test::TaskEnvironment task_environment_;
mojo::Remote<mojom::StorageService> remote_service_;
StorageServiceImpl service_{remote_service_.BindNewPipeAndPassReceiver()};
mojo::Remote<mojom::Partition> remote_test_partition_;
diff --git a/chromium/components/services/storage/storage_service_impl_unittest.cc b/chromium/components/services/storage/storage_service_impl_unittest.cc
index b852bbccf6c..0533bf31aa7 100644
--- a/chromium/components/services/storage/storage_service_impl_unittest.cc
+++ b/chromium/components/services/storage/storage_service_impl_unittest.cc
@@ -26,7 +26,7 @@ class StorageServiceImplTest : public testing::Test {
StorageServiceImpl& service_impl() { return service_; }
private:
- base::test::ScopedTaskEnvironment task_environment_;
+ base::test::TaskEnvironment task_environment_;
mojo::Remote<mojom::StorageService> remote_service_;
StorageServiceImpl service_{remote_service_.BindNewPipeAndPassReceiver()};
diff --git a/chromium/components/services/unzip/public/cpp/unzip.cc b/chromium/components/services/unzip/public/cpp/unzip.cc
index 5e8ffb3b497..d254d6e7f3b 100644
--- a/chromium/components/services/unzip/public/cpp/unzip.cc
+++ b/chromium/components/services/unzip/public/cpp/unzip.cc
@@ -19,8 +19,9 @@
#include "components/services/filesystem/directory_impl.h"
#include "components/services/filesystem/lock_table.h"
#include "components/services/unzip/public/mojom/unzipper.mojom.h"
+#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
-#include "mojo/public/cpp/bindings/strong_binding.h"
+#include "mojo/public/cpp/bindings/self_owned_receiver.h"
namespace unzip {
@@ -28,9 +29,10 @@ namespace {
class UnzipFilter : public unzip::mojom::UnzipFilter {
public:
- UnzipFilter(unzip::mojom::UnzipFilterRequest request,
+ UnzipFilter(mojo::PendingReceiver<unzip::mojom::UnzipFilter> receiver,
UnzipFilterCallback filter_callback)
- : binding_(this, std::move(request)), filter_callback_(filter_callback) {}
+ : receiver_(this, std::move(receiver)),
+ filter_callback_(filter_callback) {}
private:
// unzip::mojom::UnzipFilter implementation:
@@ -39,7 +41,7 @@ class UnzipFilter : public unzip::mojom::UnzipFilter {
std::move(callback).Run(filter_callback_.Run(path));
}
- mojo::Binding<unzip::mojom::UnzipFilter> binding_;
+ mojo::Receiver<unzip::mojom::UnzipFilter> receiver_;
UnzipFilterCallback filter_callback_;
DISALLOW_COPY_AND_ASSIGN(UnzipFilter);
@@ -111,10 +113,10 @@ void DoUnzipWithFilter(
return;
}
- filesystem::mojom::DirectoryPtr directory_ptr;
- mojo::MakeStrongBinding(
+ mojo::PendingRemote<filesystem::mojom::Directory> directory_remote;
+ mojo::MakeSelfOwnedReceiver(
std::make_unique<filesystem::DirectoryImpl>(output_dir, nullptr, nullptr),
- mojo::MakeRequest(&directory_ptr));
+ directory_remote.InitWithNewPipeAndPassReceiver());
// |result_callback| is shared between the connection error handler and the
// Unzip call using a refcounted UnzipParams object that owns
@@ -128,18 +130,18 @@ void DoUnzipWithFilter(
if (filter_callback.is_null()) {
unzip_params->unzipper()->Unzip(std::move(zip_file),
- std::move(directory_ptr),
+ std::move(directory_remote),
base::BindOnce(&UnzipDone, unzip_params));
return;
}
- unzip::mojom::UnzipFilterPtr unzip_filter_ptr;
+ mojo::PendingRemote<unzip::mojom::UnzipFilter> unzip_filter_remote;
unzip_params->set_unzip_filter(std::make_unique<UnzipFilter>(
- mojo::MakeRequest(&unzip_filter_ptr), filter_callback));
+ unzip_filter_remote.InitWithNewPipeAndPassReceiver(), filter_callback));
unzip_params->unzipper()->UnzipWithFilter(
- std::move(zip_file), std::move(directory_ptr),
- std::move(unzip_filter_ptr), base::BindOnce(&UnzipDone, unzip_params));
+ std::move(zip_file), std::move(directory_remote),
+ std::move(unzip_filter_remote), base::BindOnce(&UnzipDone, unzip_params));
}
} // namespace
diff --git a/chromium/components/services/unzip/public/mojom/unzipper.mojom b/chromium/components/services/unzip/public/mojom/unzipper.mojom
index ece5f106949..8fd46f5a943 100644
--- a/chromium/components/services/unzip/public/mojom/unzipper.mojom
+++ b/chromium/components/services/unzip/public/mojom/unzipper.mojom
@@ -16,13 +16,14 @@ interface UnzipFilter {
interface Unzipper {
// Unzip |zip_file| into |output_dir|.
// Returns true on success, false otherwise.
- Unzip(mojo_base.mojom.File zip_file, filesystem.mojom.Directory output_dir)
- => (bool result);
+ Unzip(mojo_base.mojom.File zip_file,
+ pending_remote<filesystem.mojom.Directory> output_dir)
+ => (bool result);
// Same as |unzip| but only includes the files for which |filter| returns
// true. Note that this incurs one IPC for each file of the archive.
UnzipWithFilter(
mojo_base.mojom.File zip_file,
- filesystem.mojom.Directory output_dir,
- UnzipFilter filter) => (bool result);
+ pending_remote<filesystem.mojom.Directory> output_dir,
+ pending_remote<UnzipFilter> filter) => (bool result);
};
diff --git a/chromium/components/services/unzip/unzipper_impl.cc b/chromium/components/services/unzip/unzipper_impl.cc
index 76b8a50810d..04602bbf402 100644
--- a/chromium/components/services/unzip/unzipper_impl.cc
+++ b/chromium/components/services/unzip/unzipper_impl.cc
@@ -12,6 +12,7 @@
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "components/services/filesystem/public/mojom/directory.mojom.h"
+#include "mojo/public/cpp/bindings/remote.h"
#include "third_party/zlib/google/zip.h"
#include "third_party/zlib/google/zip_reader.h"
@@ -43,26 +44,24 @@ std::string PathToMojoString(const base::FilePath& path) {
}
// Modifies output_dir to point to the final directory.
-bool CreateDirectory(filesystem::mojom::DirectoryPtr* output_dir,
+bool CreateDirectory(filesystem::mojom::Directory* output_dir,
const base::FilePath& path) {
base::File::Error err = base::File::Error::FILE_OK;
- return (*output_dir)
- ->OpenDirectory(PathToMojoString(path), mojo::NullReceiver(),
- filesystem::mojom::kFlagOpenAlways, &err) &&
+ return output_dir->OpenDirectory(PathToMojoString(path), mojo::NullReceiver(),
+ filesystem::mojom::kFlagOpenAlways, &err) &&
err == base::File::Error::FILE_OK;
}
std::unique_ptr<zip::WriterDelegate> MakeFileWriterDelegateNoParent(
- filesystem::mojom::DirectoryPtr* output_dir,
+ filesystem::mojom::Directory* output_dir,
const base::FilePath& path) {
auto file = std::make_unique<base::File>();
base::File::Error err;
- if (!(*output_dir)
- ->OpenFileHandle(PathToMojoString(path),
- filesystem::mojom::kFlagCreate |
- filesystem::mojom::kFlagWrite |
- filesystem::mojom::kFlagWriteAttributes,
- &err, file.get()) ||
+ if (!output_dir->OpenFileHandle(PathToMojoString(path),
+ filesystem::mojom::kFlagCreate |
+ filesystem::mojom::kFlagWrite |
+ filesystem::mojom::kFlagWriteAttributes,
+ &err, file.get()) ||
err != base::File::Error::FILE_OK) {
return std::make_unique<DudWriterDelegate>();
}
@@ -70,30 +69,29 @@ std::unique_ptr<zip::WriterDelegate> MakeFileWriterDelegateNoParent(
}
std::unique_ptr<zip::WriterDelegate> MakeFileWriterDelegate(
- filesystem::mojom::DirectoryPtr* output_dir,
+ filesystem::mojom::Directory* output_dir,
const base::FilePath& path) {
if (path == path.BaseName())
return MakeFileWriterDelegateNoParent(output_dir, path);
- filesystem::mojom::DirectoryPtr parent;
+ mojo::Remote<filesystem::mojom::Directory> parent;
base::File::Error err;
- if (!(*output_dir)
- ->OpenDirectory(PathToMojoString(path.DirName()),
- mojo::MakeRequest(&parent),
- filesystem::mojom::kFlagOpenAlways, &err) ||
+ if (!output_dir->OpenDirectory(PathToMojoString(path.DirName()),
+ parent.BindNewPipeAndPassReceiver(),
+ filesystem::mojom::kFlagOpenAlways, &err) ||
err != base::File::Error::FILE_OK) {
return std::make_unique<DudWriterDelegate>();
}
- return MakeFileWriterDelegateNoParent(&parent, path.BaseName());
+ return MakeFileWriterDelegateNoParent(parent.get(), path.BaseName());
}
bool FilterNoFiles(const base::FilePath& unused) {
return true;
}
-bool FilterWithFilterPtr(mojom::UnzipFilterPtr* filter,
- const base::FilePath& path) {
+bool FilterWithFilterRemote(mojom::UnzipFilter* filter,
+ const base::FilePath& path) {
bool result = false;
- (*filter)->ShouldUnzipFile(path, &result);
+ filter->ShouldUnzipFile(path, &result);
return result;
}
@@ -106,22 +104,29 @@ UnzipperImpl::UnzipperImpl(mojo::PendingReceiver<mojom::Unzipper> receiver)
UnzipperImpl::~UnzipperImpl() = default;
-void UnzipperImpl::Unzip(base::File zip_file,
- filesystem::mojom::DirectoryPtr output_dir,
- UnzipCallback callback) {
+void UnzipperImpl::Unzip(
+ base::File zip_file,
+ mojo::PendingRemote<filesystem::mojom::Directory> output_dir_remote,
+ UnzipCallback callback) {
DCHECK(zip_file.IsValid());
+ mojo::Remote<filesystem::mojom::Directory> output_dir(
+ std::move(output_dir_remote));
std::move(callback).Run(zip::UnzipWithFilterAndWriters(
zip_file.GetPlatformFile(),
- base::BindRepeating(&MakeFileWriterDelegate, &output_dir),
- base::BindRepeating(&CreateDirectory, &output_dir),
+ base::BindRepeating(&MakeFileWriterDelegate, output_dir.get()),
+ base::BindRepeating(&CreateDirectory, output_dir.get()),
base::BindRepeating(&FilterNoFiles), /*log_skipped_files=*/false));
}
-void UnzipperImpl::UnzipWithFilter(base::File zip_file,
- filesystem::mojom::DirectoryPtr output_dir,
- mojom::UnzipFilterPtr filter,
- UnzipCallback callback) {
+void UnzipperImpl::UnzipWithFilter(
+ base::File zip_file,
+ mojo::PendingRemote<filesystem::mojom::Directory> output_dir_remote,
+ mojo::PendingRemote<mojom::UnzipFilter> filter_remote,
+ UnzipCallback callback) {
DCHECK(zip_file.IsValid());
+ mojo::Remote<filesystem::mojom::Directory> output_dir(
+ std::move(output_dir_remote));
+ mojo::Remote<mojom::UnzipFilter> filter(std::move(filter_remote));
// Note that we pass a pointer to |filter| below, as it is a repeating
// callback and transferring its value would cause the callback to fail when
@@ -130,9 +135,9 @@ void UnzipperImpl::UnzipWithFilter(base::File zip_file,
// the method returns.
std::move(callback).Run(zip::UnzipWithFilterAndWriters(
zip_file.GetPlatformFile(),
- base::BindRepeating(&MakeFileWriterDelegate, &output_dir),
- base::BindRepeating(&CreateDirectory, &output_dir),
- base::BindRepeating(&FilterWithFilterPtr, &filter),
+ base::BindRepeating(&MakeFileWriterDelegate, output_dir.get()),
+ base::BindRepeating(&CreateDirectory, output_dir.get()),
+ base::BindRepeating(&FilterWithFilterRemote, filter.get()),
/*log_skipped_files=*/false));
}
diff --git a/chromium/components/services/unzip/unzipper_impl.h b/chromium/components/services/unzip/unzipper_impl.h
index d5cc821e78c..9de2a096f96 100644
--- a/chromium/components/services/unzip/unzipper_impl.h
+++ b/chromium/components/services/unzip/unzipper_impl.h
@@ -11,6 +11,7 @@
#include "base/macros.h"
#include "components/services/unzip/public/mojom/unzipper.mojom.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
namespace unzip {
@@ -28,14 +29,16 @@ class UnzipperImpl : public mojom::Unzipper {
private:
// unzip::mojom::Unzipper:
- void Unzip(base::File zip_file,
- filesystem::mojom::DirectoryPtr output_dir,
- UnzipCallback callback) override;
-
- void UnzipWithFilter(base::File zip_file,
- filesystem::mojom::DirectoryPtr output_dir,
- mojom::UnzipFilterPtr filter,
- UnzipWithFilterCallback callback) override;
+ void Unzip(
+ base::File zip_file,
+ mojo::PendingRemote<filesystem::mojom::Directory> output_dir_remote,
+ UnzipCallback callback) override;
+
+ void UnzipWithFilter(
+ base::File zip_file,
+ mojo::PendingRemote<filesystem::mojom::Directory> output_dir_remote,
+ mojo::PendingRemote<mojom::UnzipFilter> filter_remote,
+ UnzipWithFilterCallback callback) override;
mojo::Receiver<mojom::Unzipper> receiver_{this};