Commit fdae685f authored by Yafei Duan's avatar Yafei Duan Committed by Commit Bot

[Offline Pages] Implementing MarkPageAccessedTask.

Implementing the MarkPageAccessedTask which is responsible for updating
the database entry when a page is loaded.
Also added a utility method to get all pages for testing.

Bug: 753595
Change-Id: I0f0ba0f150928b7e245eb357893067c6863d420f
Reviewed-on: https://chromium-review.googlesource.com/677026
Commit-Queue: Yafei Duan <romax@chromium.org>
Reviewed-by: default avatarFilip Gorski <fgorski@chromium.org>
Cr-Commit-Position: refs/heads/master@{#504278}
parent 81f3a6b9
...@@ -26,6 +26,8 @@ static_library("core") { ...@@ -26,6 +26,8 @@ static_library("core") {
"model/delete_page_task.h", "model/delete_page_task.h",
"model/get_pages_task.cc", "model/get_pages_task.cc",
"model/get_pages_task.h", "model/get_pages_task.h",
"model/mark_page_accessed_task.cc",
"model/mark_page_accessed_task.h",
"model/offline_store_utils.cc", "model/offline_store_utils.cc",
"model/offline_store_utils.h", "model/offline_store_utils.h",
"offline_event_logger.cc", "offline_event_logger.cc",
...@@ -127,6 +129,7 @@ source_set("unit_tests") { ...@@ -127,6 +129,7 @@ source_set("unit_tests") {
"model/create_archive_task_unittest.cc", "model/create_archive_task_unittest.cc",
"model/delete_page_task_unittest.cc", "model/delete_page_task_unittest.cc",
"model/get_pages_task_unittest.cc", "model/get_pages_task_unittest.cc",
"model/mark_page_accessed_task_unittest.cc",
"offline_event_logger_unittest.cc", "offline_event_logger_unittest.cc",
"offline_page_metadata_store_unittest.cc", "offline_page_metadata_store_unittest.cc",
"offline_page_model_event_logger_unittest.cc", "offline_page_model_event_logger_unittest.cc",
......
// 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/offline_pages/core/model/mark_page_accessed_task.h"
#include "base/bind.h"
#include "base/time/clock.h"
#include "base/time/default_clock.h"
#include "components/offline_pages/core/offline_page_metadata_store_sql.h"
#include "components/offline_pages/core/offline_time_utils.h"
#include "sql/connection.h"
#include "sql/statement.h"
namespace offline_pages {
namespace {
bool MarkPageAccessedSync(const base::Time& last_access_time,
int64_t offline_id,
sql::Connection* db) {
const char kSql[] =
"UPDATE OR IGNORE offlinepages_v1"
" SET last_access_time = ?, access_count = access_count + 1"
" WHERE offline_id = ?";
sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql));
statement.BindInt64(0, ToDatabaseTime(last_access_time));
statement.BindInt64(1, offline_id);
return statement.Run();
}
} // namespace
MarkPageAccessedTask::MarkPageAccessedTask(OfflinePageMetadataStoreSQL* store,
int64_t offline_id,
const base::Time& access_time)
: store_(store), offline_id_(offline_id), access_time_(access_time) {}
MarkPageAccessedTask::~MarkPageAccessedTask(){};
void MarkPageAccessedTask::Run() {
store_->Execute(
base::BindOnce(&MarkPageAccessedSync, access_time_, offline_id_),
base::BindOnce([](bool success) {}));
}
} // namespace offline_pages
// 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_OFFLINE_PAGES_CORE_TASKS_MARK_PAGE_ACCESSED_TASK_H_
#define COMPONENTS_OFFLINE_PAGES_CORE_TASKS_MARK_PAGE_ACCESSED_TASK_H_
#include "base/macros.h"
#include "components/offline_pages/core/task.h"
namespace base {
class Time;
} // namespace base
namespace offline_pages {
class OfflinePageMetadataStoreSQL;
// Task that mark a page accessed in the metadata store. It takes the offline ID
// of the page accessed, and the time when it was accessed.
// There is no callback needed for this task.
class MarkPageAccessedTask : public Task {
public:
MarkPageAccessedTask(OfflinePageMetadataStoreSQL* store,
int64_t offline_id,
const base::Time& access_time);
~MarkPageAccessedTask() override;
// Task implementation.
void Run() override;
private:
// The metadata store used to update the page. Not owned.
OfflinePageMetadataStoreSQL* store_;
int64_t offline_id_;
base::Time access_time_;
DISALLOW_COPY_AND_ASSIGN(MarkPageAccessedTask);
};
} // namespace offline_pages
#endif // COMPONENTS_OFFLINE_PAGES_CORE_TASKS_MARK_PAGE_ACCESSED_TASK_H_
// 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/offline_pages/core/model/mark_page_accessed_task.h"
#include <vector>
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/test/test_simple_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "components/offline_pages/core/offline_page_metadata_store_test_util.h"
#include "components/offline_pages/core/test_task_runner.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace offline_pages {
namespace {
const GURL kTestUrl("http://example.com");
const int64_t kTestOfflineId = 1234LL;
const char kTestClientNamespace[] = "default";
const ClientId kTestClientId(kTestClientNamespace, "1234");
const base::FilePath kTestFilePath(FILE_PATH_LITERAL("/test/path/file"));
const int64_t kTestFileSize = 876543LL;
} // namespace
class MarkPageAccessedTaskTest : public testing::Test {
public:
MarkPageAccessedTaskTest();
~MarkPageAccessedTaskTest() override;
void SetUp() override;
void TearDown() override;
OfflinePageMetadataStoreSQL* store() { return store_test_util_.store(); }
OfflinePageMetadataStoreTestUtil* store_test_util() {
return &store_test_util_;
}
private:
scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
base::ThreadTaskRunnerHandle task_runner_handle_;
OfflinePageMetadataStoreTestUtil store_test_util_;
};
MarkPageAccessedTaskTest::MarkPageAccessedTaskTest()
: task_runner_(new base::TestSimpleTaskRunner()),
task_runner_handle_(task_runner_),
store_test_util_(task_runner_) {}
MarkPageAccessedTaskTest::~MarkPageAccessedTaskTest() {}
void MarkPageAccessedTaskTest::SetUp() {
store_test_util_.BuildStoreInMemory();
}
void MarkPageAccessedTaskTest::TearDown() {
store_test_util_.DeleteStore();
}
TEST_F(MarkPageAccessedTaskTest, MarkPageAccessed) {
OfflinePageItem page(kTestUrl, kTestOfflineId, kTestClientId, kTestFilePath,
kTestFileSize);
store_test_util()->InsertItem(page);
base::Time current_time = base::Time::Now();
auto task = base::MakeUnique<MarkPageAccessedTask>(store(), kTestOfflineId,
current_time);
std::move(task)->Run();
OfflinePageItem offline_page =
store_test_util()->GetPageByOfflineId(kTestOfflineId);
EXPECT_EQ(kTestUrl, offline_page.url);
EXPECT_EQ(kTestClientId, offline_page.client_id);
EXPECT_EQ(kTestFileSize, offline_page.file_size);
EXPECT_EQ(1, offline_page.access_count);
EXPECT_EQ(current_time, offline_page.last_access_time);
}
TEST_F(MarkPageAccessedTaskTest, MarkPageAccessedTwice) {
OfflinePageItem page(kTestUrl, kTestOfflineId, kTestClientId, kTestFilePath,
kTestFileSize);
store_test_util()->InsertItem(page);
base::Time current_time = base::Time::Now();
auto task = base::MakeUnique<MarkPageAccessedTask>(store(), kTestOfflineId,
current_time);
std::move(task)->Run();
OfflinePageItem offline_page =
store_test_util()->GetPageByOfflineId(kTestOfflineId);
EXPECT_EQ(kTestOfflineId, offline_page.offline_id);
EXPECT_EQ(kTestUrl, offline_page.url);
EXPECT_EQ(kTestClientId, offline_page.client_id);
EXPECT_EQ(kTestFileSize, offline_page.file_size);
EXPECT_EQ(1, offline_page.access_count);
EXPECT_EQ(current_time, offline_page.last_access_time);
task = base::MakeUnique<MarkPageAccessedTask>(store(), kTestOfflineId,
base::Time::Now());
std::move(task)->Run();
offline_page = store_test_util()->GetPageByOfflineId(kTestOfflineId);
EXPECT_EQ(kTestOfflineId, offline_page.offline_id);
EXPECT_EQ(2, offline_page.access_count);
EXPECT_LT(current_time, offline_page.last_access_time);
}
} // namespace offline_pages
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/callback_forward.h" #include "base/callback_forward.h"
#include "components/offline_pages/core/model/get_pages_task.h"
#include "components/offline_pages/core/offline_page_types.h" #include "components/offline_pages/core/offline_page_types.h"
#include "sql/connection.h" #include "sql/connection.h"
#include "sql/statement.h" #include "sql/statement.h"
...@@ -76,4 +77,21 @@ int64_t OfflinePageMetadataStoreTestUtil::GetPageCount() { ...@@ -76,4 +77,21 @@ int64_t OfflinePageMetadataStoreTestUtil::GetPageCount() {
return page_count; return page_count;
} }
OfflinePageItem OfflinePageMetadataStoreTestUtil::GetPageByOfflineId(
int64_t offline_id) {
OfflinePageItem out_page;
auto task = GetPagesTask::CreateTaskMatchingOfflineId(
store(),
base::Bind(
[](OfflinePageItem* out_page, const OfflinePageItem* page) {
if (page)
*out_page = *page;
},
&out_page),
offline_id);
task->Run();
task_runner_->RunUntilIdle();
return out_page;
}
} // namespace offline_pages } // namespace offline_pages
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define COMPONENTS_OFFLINE_PAGES_CORE_OFFLINE_PAGE_METADATA_STORE_TEST_UTIL_H_ #define COMPONENTS_OFFLINE_PAGES_CORE_OFFLINE_PAGE_METADATA_STORE_TEST_UTIL_H_
#include <memory> #include <memory>
#include <vector>
#include "base/files/scoped_temp_dir.h" #include "base/files/scoped_temp_dir.h"
#include "base/macros.h" #include "base/macros.h"
...@@ -43,6 +44,9 @@ class OfflinePageMetadataStoreTestUtil { ...@@ -43,6 +44,9 @@ class OfflinePageMetadataStoreTestUtil {
// Gets the total number of pages in the store. // Gets the total number of pages in the store.
int64_t GetPageCount(); int64_t GetPageCount();
// Gets offline page by offline_id.
OfflinePageItem GetPageByOfflineId(int64_t offline_id);
OfflinePageMetadataStoreSQL* store() { return store_.get(); } OfflinePageMetadataStoreSQL* store() { return store_.get(); }
base::SimpleTestClock* clock() { return &clock_; } base::SimpleTestClock* clock() { return &clock_; }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment