1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/offline_pages/core/prefetch/tasks/mark_operation_done_task.h"
6
7 #include <memory>
8 #include <utility>
9
10 #include "base/bind.h"
11 #include "base/callback.h"
12 #include "components/offline_pages/core/offline_clock.h"
13 #include "components/offline_pages/core/offline_store_utils.h"
14 #include "components/offline_pages/core/prefetch/prefetch_dispatcher.h"
15 #include "components/offline_pages/core/prefetch/prefetch_network_request_factory.h"
16 #include "components/offline_pages/core/prefetch/store/prefetch_store.h"
17 #include "sql/database.h"
18 #include "sql/statement.h"
19 #include "sql/transaction.h"
20
21 namespace offline_pages {
22
23 namespace {
24
UpdatePrefetchItemsSync(sql::Database * db,const std::string & operation_name)25 bool UpdatePrefetchItemsSync(sql::Database* db,
26 const std::string& operation_name) {
27 static const char kSql[] =
28 "UPDATE prefetch_items SET state = ?, freshness_time = ?"
29 " WHERE state = ? AND operation_name = ?";
30
31 sql::Statement statement(db->GetCachedStatement(SQL_FROM_HERE, kSql));
32 statement.BindInt(0, static_cast<int>(PrefetchItemState::RECEIVED_GCM));
33 statement.BindInt64(1, store_utils::ToDatabaseTime(OfflineTimeNow()));
34 statement.BindInt(2, static_cast<int>(PrefetchItemState::AWAITING_GCM));
35 statement.BindString(3, operation_name);
36
37 return statement.Run();
38 }
39
MakeStoreError()40 MarkOperationDoneTask::TaskResult MakeStoreError() {
41 return std::make_pair(MarkOperationDoneTask::StoreResult::STORE_ERROR, -1);
42 }
43
44 // Will hold the actual SQL implementation for marking a MarkOperationDone
45 // attempt in the database.
MarkOperationCompletedOnServerSync(const std::string & operation_name,sql::Database * db)46 MarkOperationDoneTask::TaskResult MarkOperationCompletedOnServerSync(
47 const std::string& operation_name,
48 sql::Database* db) {
49 sql::Transaction transaction(db);
50 if (transaction.Begin() && UpdatePrefetchItemsSync(db, operation_name) &&
51 transaction.Commit()) {
52 return std::make_pair(MarkOperationDoneTask::StoreResult::UPDATED,
53 db->GetLastChangeCount());
54 }
55 return MakeStoreError();
56 }
57
58 } // namespace
59
MarkOperationDoneTask(PrefetchDispatcher * prefetch_dispatcher,PrefetchStore * prefetch_store,const std::string & operation_name)60 MarkOperationDoneTask::MarkOperationDoneTask(
61 PrefetchDispatcher* prefetch_dispatcher,
62 PrefetchStore* prefetch_store,
63 const std::string& operation_name)
64 : prefetch_dispatcher_(prefetch_dispatcher),
65 prefetch_store_(prefetch_store),
66 operation_name_(operation_name) {}
67
~MarkOperationDoneTask()68 MarkOperationDoneTask::~MarkOperationDoneTask() {}
69
Run()70 void MarkOperationDoneTask::Run() {
71 prefetch_store_->Execute(
72 base::BindOnce(&MarkOperationCompletedOnServerSync, operation_name_),
73 base::BindOnce(&MarkOperationDoneTask::Done, weak_factory_.GetWeakPtr()),
74 MakeStoreError());
75 }
76
Done(TaskResult result)77 void MarkOperationDoneTask::Done(TaskResult result) {
78 result_ = result;
79
80 // We need to make sure we can process any work that was created by this event
81 // so we will ensure the task is scheudled.
82 if (change_count() > 0)
83 prefetch_dispatcher_->EnsureTaskScheduled();
84
85 TaskComplete();
86 }
87
88 } // namespace offline_pages
89