summaryrefslogtreecommitdiffstats
path: root/content/browser/indexed_db
diff options
context:
space:
mode:
authorcmumford <cmumford@chromium.org>2015-03-13 19:39:27 -0700
committerCommit bot <commit-bot@chromium.org>2015-03-14 02:39:58 +0000
commit3a61739491730a1acd96c09a6ae7b79825eb445f (patch)
tree1afa956d9d8c9f922cff38e997b06a06b22a9e7e /content/browser/indexed_db
parente3b16f181ab489621ca9866f472e012e33b6e9c0 (diff)
downloadchromium_src-3a61739491730a1acd96c09a6ae7b79825eb445f.zip
chromium_src-3a61739491730a1acd96c09a6ae7b79825eb445f.tar.gz
chromium_src-3a61739491730a1acd96c09a6ae7b79825eb445f.tar.bz2
IndexedDB: Fixed support for empty blobs.
This solution allows empty blobs (and files) to be created. Most tests for this change are Blink layout tests, so will land in a separate CL. BUG=399323 Review URL: https://codereview.chromium.org/942633004 Cr-Commit-Position: refs/heads/master@{#320636}
Diffstat (limited to 'content/browser/indexed_db')
-rw-r--r--content/browser/indexed_db/indexed_db_backing_store.cc22
-rw-r--r--content/browser/indexed_db/indexed_db_browsertest.cc38
-rw-r--r--content/browser/indexed_db/indexed_db_context_impl.cc13
-rw-r--r--content/browser/indexed_db/indexed_db_context_impl.h1
4 files changed, 72 insertions, 2 deletions
diff --git a/content/browser/indexed_db/indexed_db_backing_store.cc b/content/browser/indexed_db/indexed_db_backing_store.cc
index 4ae9ed4..22bd411 100644
--- a/content/browser/indexed_db/indexed_db_backing_store.cc
+++ b/content/browser/indexed_db/indexed_db_backing_store.cc
@@ -2339,8 +2339,12 @@ class LocalWriteClosure : public FileWriterDelegate::DelegateWriteCallback,
}
bool success = write_status == FileWriterDelegate::SUCCESS_COMPLETED;
-
- if (success && !last_modified_.is_null()) {
+ if (success && !bytes_written_) {
+ // LocalFileStreamWriter only creates a file if data is actually written.
+ // If none was then create one now.
+ task_runner_->PostTask(
+ FROM_HERE, base::Bind(&LocalWriteClosure::CreateEmptyFile, this));
+ } else if (success && !last_modified_.is_null()) {
task_runner_->PostTask(
FROM_HERE, base::Bind(&LocalWriteClosure::UpdateTimeStamp, this));
} else {
@@ -2403,6 +2407,20 @@ class LocalWriteClosure : public FileWriterDelegate::DelegateWriteCallback,
chained_blob_writer_->ReportWriteCompletion(true, bytes_written_);
}
+ // Create an empty file.
+ void CreateEmptyFile() {
+ DCHECK(task_runner_->RunsTasksOnCurrentThread());
+ base::File file(file_path_,
+ base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
+ bool success = file.created();
+ if (success && !last_modified_.is_null() &&
+ !file.SetTimes(last_modified_, last_modified_)) {
+ // TODO(cmumford): Complain quietly; timestamp's probably not vital.
+ }
+ file.Close();
+ chained_blob_writer_->ReportWriteCompletion(success, bytes_written_);
+ }
+
scoped_refptr<IndexedDBBackingStore::Transaction::ChainedBlobWriter>
chained_blob_writer_;
scoped_refptr<base::SequencedTaskRunner> task_runner_;
diff --git a/content/browser/indexed_db/indexed_db_browsertest.cc b/content/browser/indexed_db/indexed_db_browsertest.cc
index fbe35bf..9bfad25 100644
--- a/content/browser/indexed_db/indexed_db_browsertest.cc
+++ b/content/browser/indexed_db/indexed_db_browsertest.cc
@@ -150,6 +150,22 @@ class IndexedDBBrowserTest : public ContentBrowserTest {
return disk_usage_;
}
+ virtual int RequestBlobFileCount() {
+ PostTaskAndReplyWithResult(
+ GetContext()->TaskRunner(), FROM_HERE,
+ base::Bind(&IndexedDBContextImpl::GetOriginBlobFileCount, GetContext(),
+ GURL("file:///")),
+ base::Bind(&IndexedDBBrowserTest::DidGetBlobFileCount, this));
+ scoped_refptr<base::ThreadTestHelper> helper(
+ new base::ThreadTestHelper(BrowserMainLoop::GetInstance()
+ ->indexed_db_thread()
+ ->message_loop_proxy()));
+ EXPECT_TRUE(helper->Run());
+ // Wait for DidGetBlobFileCount to be called.
+ base::MessageLoop::current()->RunUntilIdle();
+ return blob_file_count_;
+ }
+
private:
static MockBrowserTestIndexedDBClassFactory* GetTestClassFactory() {
static ::base::LazyInstance<MockBrowserTestIndexedDBClassFactory>::Leaky
@@ -165,7 +181,10 @@ class IndexedDBBrowserTest : public ContentBrowserTest {
disk_usage_ = bytes;
}
+ virtual void DidGetBlobFileCount(int count) { blob_file_count_ = count; }
+
int64 disk_usage_;
+ int blob_file_count_ = 0;
DISALLOW_COPY_AND_ASSIGN(IndexedDBBrowserTest);
};
@@ -405,6 +424,25 @@ IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, CanDeleteWhenOverQuotaTest) {
SimpleTest(GetTestUrl("indexeddb", "delete_over_quota.html"));
}
+IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTest, EmptyBlob) {
+ // First delete all IDB's for the test origin
+ GetContext()->TaskRunner()->PostTask(
+ FROM_HERE, base::Bind(&IndexedDBContextImpl::DeleteForOrigin,
+ GetContext(), GURL("file:///")));
+ EXPECT_EQ(0, RequestBlobFileCount()); // Start with no blob files.
+ const GURL test_url = GetTestUrl("indexeddb", "empty_blob.html");
+ // For some reason Android's futimes fails (EPERM) in this test. Do not assert
+ // file times on Android, but do so on other platforms. crbug.com/467247
+ // TODO(cmumford): Figure out why this is the case and fix if possible.
+#if defined(OS_ANDROID)
+ SimpleTest(GURL(test_url.spec() + "#ignoreTimes"));
+#else
+ SimpleTest(GURL(test_url.spec()));
+#endif
+ // Test stores one blob and one file to disk, so expect two files.
+ EXPECT_EQ(2, RequestBlobFileCount());
+}
+
IN_PROC_BROWSER_TEST_F(IndexedDBBrowserTestWithGCExposed, BlobDidAck) {
SimpleTest(GetTestUrl("indexeddb", "blob_did_ack.html"));
// Wait for idle so that the blob ack has time to be received/processed by
diff --git a/content/browser/indexed_db/indexed_db_context_impl.cc b/content/browser/indexed_db/indexed_db_context_impl.cc
index f1357fd..2a6a4b4 100644
--- a/content/browser/indexed_db/indexed_db_context_impl.cc
+++ b/content/browser/indexed_db/indexed_db_context_impl.cc
@@ -273,6 +273,19 @@ base::ListValue* IndexedDBContextImpl::GetAllOriginsDetails() {
return list.release();
}
+int IndexedDBContextImpl::GetOriginBlobFileCount(const GURL& origin_url) {
+ DCHECK(TaskRunner()->RunsTasksOnCurrentThread());
+ int count = 0;
+ base::FileEnumerator file_enumerator(
+ GetBlobPath(storage::GetIdentifierFromOrigin(origin_url)), true,
+ base::FileEnumerator::FILES);
+ for (base::FilePath file_path = file_enumerator.Next(); !file_path.empty();
+ file_path = file_enumerator.Next()) {
+ count++;
+ }
+ return count;
+}
+
int64 IndexedDBContextImpl::GetOriginDiskUsage(const GURL& origin_url) {
DCHECK(TaskRunner()->RunsTasksOnCurrentThread());
if (data_path_.empty() || !IsInOriginSet(origin_url))
diff --git a/content/browser/indexed_db/indexed_db_context_impl.h b/content/browser/indexed_db/indexed_db_context_impl.h
index da2878b..2955a3a 100644
--- a/content/browser/indexed_db/indexed_db_context_impl.h
+++ b/content/browser/indexed_db/indexed_db_context_impl.h
@@ -101,6 +101,7 @@ class CONTENT_EXPORT IndexedDBContextImpl
return set->find(origin_url) != set->end();
}
size_t GetConnectionCount(const GURL& origin_url);
+ int GetOriginBlobFileCount(const GURL& origin_url);
// For unit tests allow to override the |data_path_|.
void set_data_path_for_testing(const base::FilePath& data_path) {