Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / components / precache / content / precache_manager.cc
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/precache/content/precache_manager.h"
6
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/files/file_path.h"
10 #include "base/logging.h"
11 #include "base/metrics/field_trial.h"
12 #include "base/time/time.h"
13 #include "components/precache/core/precache_database.h"
14 #include "components/precache/core/precache_switches.h"
15 #include "components/precache/core/url_list_provider.h"
16 #include "content/public/browser/browser_context.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "net/base/network_change_notifier.h"
19
20 using content::BrowserThread;
21
22 namespace {
23
24 const char kPrecacheFieldTrialName[] = "Precache";
25 const char kPrecacheFieldTrialEnabledGroup[] = "Enabled";
26
27 }  // namespace
28
29 namespace precache {
30
31 PrecacheManager::PrecacheManager(content::BrowserContext* browser_context)
32     : browser_context_(browser_context),
33       precache_database_(new PrecacheDatabase()),
34       is_precaching_(false) {
35   base::FilePath db_path(browser_context_->GetPath().Append(
36       base::FilePath(FILE_PATH_LITERAL("PrecacheDatabase"))));
37
38   BrowserThread::PostTask(
39       BrowserThread::DB, FROM_HERE,
40       base::Bind(base::IgnoreResult(&PrecacheDatabase::Init),
41                  precache_database_, db_path));
42 }
43
44 PrecacheManager::~PrecacheManager() {}
45
46 // static
47 bool PrecacheManager::IsPrecachingEnabled() {
48   return base::FieldTrialList::FindFullName(kPrecacheFieldTrialName) ==
49              kPrecacheFieldTrialEnabledGroup ||
50          CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnablePrecache);
51 }
52
53 void PrecacheManager::StartPrecaching(
54     const PrecacheCompletionCallback& precache_completion_callback,
55     URLListProvider* url_list_provider) {
56   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
57
58   if (is_precaching_) {
59     DLOG(WARNING) << "Cannot start precaching because precaching is already "
60                      "in progress.";
61     return;
62   }
63   is_precaching_ = true;
64
65   BrowserThread::PostTask(
66       BrowserThread::DB, FROM_HERE,
67       base::Bind(&PrecacheDatabase::DeleteExpiredPrecacheHistory,
68                  precache_database_, base::Time::Now()));
69
70   precache_completion_callback_ = precache_completion_callback;
71
72   url_list_provider->GetURLs(
73       base::Bind(&PrecacheManager::OnURLsReceived, AsWeakPtr()));
74 }
75
76 void PrecacheManager::CancelPrecaching() {
77   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
78
79   if (!is_precaching_) {
80     // Do nothing if precaching is not in progress.
81     return;
82   }
83   is_precaching_ = false;
84
85   // Destroying the |precache_fetcher_| will cancel any fetch in progress.
86   precache_fetcher_.reset();
87
88   // Uninitialize the callback so that any scoped_refptrs in it are released.
89   precache_completion_callback_.Reset();
90 }
91
92 bool PrecacheManager::IsPrecaching() const {
93   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
94   return is_precaching_;
95 }
96
97 void PrecacheManager::RecordStatsForFetch(const GURL& url,
98                                           const base::Time& fetch_time,
99                                           int64 size,
100                                           bool was_cached) {
101   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
102
103   if (size == 0 || url.is_empty() || !url.SchemeIsHTTPOrHTTPS()) {
104     // Ignore empty responses, empty URLs, or URLs that aren't HTTP or HTTPS.
105     return;
106   }
107
108   if (is_precaching_) {
109     // Assume that precache is responsible for all requests made while
110     // precaching is currently in progress.
111     // TODO(sclittle): Make PrecacheFetcher explicitly mark precache-motivated
112     // fetches, and use that to determine whether or not a fetch was motivated
113     // by precaching.
114     BrowserThread::PostTask(
115         BrowserThread::DB, FROM_HERE,
116         base::Bind(&PrecacheDatabase::RecordURLPrecached, precache_database_,
117                    url, fetch_time, size, was_cached));
118   } else {
119     bool is_connection_cellular =
120         net::NetworkChangeNotifier::IsConnectionCellular(
121             net::NetworkChangeNotifier::GetConnectionType());
122
123     BrowserThread::PostTask(
124         BrowserThread::DB, FROM_HERE,
125         base::Bind(&PrecacheDatabase::RecordURLFetched, precache_database_, url,
126                    fetch_time, size, was_cached, is_connection_cellular));
127   }
128 }
129
130 void PrecacheManager::Shutdown() {
131   CancelPrecaching();
132 }
133
134 void PrecacheManager::OnDone() {
135   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
136
137   // If OnDone has been called, then we should just be finishing precaching.
138   DCHECK(is_precaching_);
139   is_precaching_ = false;
140
141   precache_fetcher_.reset();
142
143   precache_completion_callback_.Run();
144   // Uninitialize the callback so that any scoped_refptrs in it are released.
145   precache_completion_callback_.Reset();
146 }
147
148 void PrecacheManager::OnURLsReceived(const std::list<GURL>& urls) {
149   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
150
151   if (!is_precaching_) {
152     // Don't start precaching if it was canceled while waiting for the list of
153     // URLs.
154     return;
155   }
156
157   // Start precaching.
158   precache_fetcher_.reset(
159       new PrecacheFetcher(urls, browser_context_->GetRequestContext(), this));
160   precache_fetcher_->Start();
161 }
162
163 }  // namespace precache