Popular sites on the NTP: re-download popular suggestions once per Chrome run
[chromium-blink-merge.git] / chrome / browser / chrome_quota_permission_context.cc
blobb31fff823a5afa90ff152ecdaa4e46f71f9d4acf
1 // Copyright (c) 2012 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.
5 #include "chrome/browser/chrome_quota_permission_context.h"
7 #include <string>
9 #include "base/bind.h"
10 #include "base/prefs/pref_service.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/infobars/infobar_service.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/tab_contents/tab_util.h"
15 #include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
16 #include "chrome/browser/ui/website_settings/permission_bubble_request.h"
17 #include "chrome/common/pref_names.h"
18 #include "chrome/grit/generated_resources.h"
19 #include "chrome/grit/locale_settings.h"
20 #include "components/infobars/core/confirm_infobar_delegate.h"
21 #include "components/infobars/core/infobar.h"
22 #include "components/url_formatter/url_formatter.h"
23 #include "content/public/browser/browser_thread.h"
24 #include "content/public/browser/navigation_details.h"
25 #include "content/public/browser/web_contents.h"
26 #include "grit/theme_resources.h"
27 #include "storage/common/quota/quota_types.h"
28 #include "ui/base/l10n/l10n_util.h"
29 #include "url/gurl.h"
31 namespace {
33 // If the site requested larger quota than this threshold, show a different
34 // message to the user.
35 const int64 kRequestLargeQuotaThreshold = 5 * 1024 * 1024;
37 // QuotaPermissionRequest ---------------------------------------------
39 class QuotaPermissionRequest : public PermissionBubbleRequest {
40 public:
41 QuotaPermissionRequest(
42 ChromeQuotaPermissionContext* context,
43 const GURL& origin_url,
44 int64 requested_quota,
45 bool user_gesture,
46 const std::string& display_languages,
47 const content::QuotaPermissionContext::PermissionCallback& callback);
49 ~QuotaPermissionRequest() override;
51 // PermissionBubbleRequest:
52 int GetIconId() const override;
53 base::string16 GetMessageText() const override;
54 base::string16 GetMessageTextFragment() const override;
55 bool HasUserGesture() const override;
56 GURL GetRequestingHostname() const override;
57 void PermissionGranted() override;
58 void PermissionDenied() override;
59 void Cancelled() override;
60 void RequestFinished() override;
62 private:
63 scoped_refptr<ChromeQuotaPermissionContext> context_;
64 GURL origin_url_;
65 std::string display_languages_;
66 int64 requested_quota_;
67 bool user_gesture_;
68 content::QuotaPermissionContext::PermissionCallback callback_;
70 DISALLOW_COPY_AND_ASSIGN(QuotaPermissionRequest);
73 QuotaPermissionRequest::QuotaPermissionRequest(
74 ChromeQuotaPermissionContext* context,
75 const GURL& origin_url,
76 int64 requested_quota,
77 bool user_gesture,
78 const std::string& display_languages,
79 const content::QuotaPermissionContext::PermissionCallback& callback)
80 : context_(context),
81 origin_url_(origin_url),
82 display_languages_(display_languages),
83 requested_quota_(requested_quota),
84 user_gesture_(user_gesture),
85 callback_(callback) {}
87 QuotaPermissionRequest::~QuotaPermissionRequest() {}
89 int QuotaPermissionRequest::GetIconId() const {
90 // TODO(gbillock): get the proper image here
91 return IDR_INFOBAR_WARNING;
94 base::string16 QuotaPermissionRequest::GetMessageText() const {
95 return l10n_util::GetStringFUTF16(
96 (requested_quota_ > kRequestLargeQuotaThreshold
97 ? IDS_REQUEST_LARGE_QUOTA_INFOBAR_QUESTION
98 : IDS_REQUEST_QUOTA_INFOBAR_QUESTION),
99 url_formatter::FormatUrl(
100 origin_url_, display_languages_,
101 url_formatter::kFormatUrlOmitUsernamePassword |
102 url_formatter::kFormatUrlOmitTrailingSlashOnBareHostname,
103 net::UnescapeRule::SPACES, nullptr, nullptr, nullptr));
106 base::string16 QuotaPermissionRequest::GetMessageTextFragment() const {
107 return l10n_util::GetStringUTF16(IDS_REQUEST_QUOTA_PERMISSION_FRAGMENT);
110 bool QuotaPermissionRequest::HasUserGesture() const {
111 return user_gesture_;
114 GURL QuotaPermissionRequest::GetRequestingHostname() const {
115 return origin_url_;
118 void QuotaPermissionRequest::PermissionGranted() {
119 context_->DispatchCallbackOnIOThread(
120 callback_,
121 content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW);
122 callback_ = content::QuotaPermissionContext::PermissionCallback();
125 void QuotaPermissionRequest::PermissionDenied() {
126 context_->DispatchCallbackOnIOThread(
127 callback_,
128 content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_DISALLOW);
129 callback_ = content::QuotaPermissionContext::PermissionCallback();
132 void QuotaPermissionRequest::Cancelled() {
135 void QuotaPermissionRequest::RequestFinished() {
136 if (!callback_.is_null()) {
137 context_->DispatchCallbackOnIOThread(
138 callback_,
139 content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
142 delete this;
146 // RequestQuotaInfoBarDelegate ------------------------------------------------
148 class RequestQuotaInfoBarDelegate : public ConfirmInfoBarDelegate {
149 public:
150 // Creates a request quota infobar and delegate and adds the infobar to
151 // |infobar_service|.
152 static void Create(
153 InfoBarService* infobar_service,
154 ChromeQuotaPermissionContext* context,
155 const GURL& origin_url,
156 int64 requested_quota,
157 const std::string& display_languages,
158 const content::QuotaPermissionContext::PermissionCallback& callback);
160 private:
161 RequestQuotaInfoBarDelegate(
162 ChromeQuotaPermissionContext* context,
163 const GURL& origin_url,
164 int64 requested_quota,
165 const std::string& display_languages,
166 const content::QuotaPermissionContext::PermissionCallback& callback);
167 ~RequestQuotaInfoBarDelegate() override;
169 // ConfirmInfoBarDelegate:
170 base::string16 GetMessageText() const override;
171 bool Accept() override;
172 bool Cancel() override;
174 scoped_refptr<ChromeQuotaPermissionContext> context_;
175 GURL origin_url_;
176 std::string display_languages_;
177 int64 requested_quota_;
178 content::QuotaPermissionContext::PermissionCallback callback_;
180 DISALLOW_COPY_AND_ASSIGN(RequestQuotaInfoBarDelegate);
183 // static
184 void RequestQuotaInfoBarDelegate::Create(
185 InfoBarService* infobar_service,
186 ChromeQuotaPermissionContext* context,
187 const GURL& origin_url,
188 int64 requested_quota,
189 const std::string& display_languages,
190 const content::QuotaPermissionContext::PermissionCallback& callback) {
191 infobar_service->AddInfoBar(infobar_service->CreateConfirmInfoBar(
192 scoped_ptr<ConfirmInfoBarDelegate>(new RequestQuotaInfoBarDelegate(
193 context, origin_url, requested_quota, display_languages, callback))));
196 RequestQuotaInfoBarDelegate::RequestQuotaInfoBarDelegate(
197 ChromeQuotaPermissionContext* context,
198 const GURL& origin_url,
199 int64 requested_quota,
200 const std::string& display_languages,
201 const content::QuotaPermissionContext::PermissionCallback& callback)
202 : ConfirmInfoBarDelegate(),
203 context_(context),
204 origin_url_(origin_url),
205 display_languages_(display_languages),
206 requested_quota_(requested_quota),
207 callback_(callback) {
210 RequestQuotaInfoBarDelegate::~RequestQuotaInfoBarDelegate() {
211 if (!callback_.is_null()) {
212 context_->DispatchCallbackOnIOThread(
213 callback_,
214 content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
218 base::string16 RequestQuotaInfoBarDelegate::GetMessageText() const {
219 // If the site requested larger quota than this threshold, show a different
220 // message to the user.
221 return l10n_util::GetStringFUTF16(
222 (requested_quota_ > kRequestLargeQuotaThreshold
223 ? IDS_REQUEST_LARGE_QUOTA_INFOBAR_QUESTION
224 : IDS_REQUEST_QUOTA_INFOBAR_QUESTION),
225 url_formatter::FormatUrl(
226 origin_url_, display_languages_,
227 url_formatter::kFormatUrlOmitUsernamePassword |
228 url_formatter::kFormatUrlOmitTrailingSlashOnBareHostname,
229 net::UnescapeRule::SPACES, nullptr, nullptr, nullptr));
232 bool RequestQuotaInfoBarDelegate::Accept() {
233 context_->DispatchCallbackOnIOThread(
234 callback_,
235 content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW);
236 return true;
239 bool RequestQuotaInfoBarDelegate::Cancel() {
240 context_->DispatchCallbackOnIOThread(
241 callback_,
242 content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
243 return true;
246 } // namespace
249 // ChromeQuotaPermissionContext -----------------------------------------------
251 ChromeQuotaPermissionContext::ChromeQuotaPermissionContext() {
254 void ChromeQuotaPermissionContext::RequestQuotaPermission(
255 const content::StorageQuotaParams& params,
256 int render_process_id,
257 const PermissionCallback& callback) {
258 if (params.storage_type != storage::kStorageTypePersistent) {
259 // For now we only support requesting quota with this interface
260 // for Persistent storage type.
261 callback.Run(QUOTA_PERMISSION_RESPONSE_DISALLOW);
262 return;
265 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
266 content::BrowserThread::PostTask(
267 content::BrowserThread::UI, FROM_HERE,
268 base::Bind(&ChromeQuotaPermissionContext::RequestQuotaPermission, this,
269 params, render_process_id, callback));
270 return;
273 content::WebContents* web_contents =
274 tab_util::GetWebContentsByID(render_process_id,
275 params.render_view_id);
276 if (!web_contents) {
277 // The tab may have gone away or the request may not be from a tab.
278 LOG(WARNING) << "Attempt to request quota tabless renderer: "
279 << render_process_id << "," << params.render_view_id;
280 DispatchCallbackOnIOThread(callback, QUOTA_PERMISSION_RESPONSE_CANCELLED);
281 return;
284 InfoBarService* infobar_service =
285 InfoBarService::FromWebContents(web_contents);
286 if (!infobar_service) {
287 // The tab has no infobar service.
288 LOG(WARNING) << "Attempt to request quota from a background page: "
289 << render_process_id << "," << params.render_view_id;
290 DispatchCallbackOnIOThread(callback, QUOTA_PERMISSION_RESPONSE_CANCELLED);
291 return;
294 if (PermissionBubbleManager::Enabled()) {
295 PermissionBubbleManager* bubble_manager =
296 PermissionBubbleManager::FromWebContents(web_contents);
297 if (bubble_manager) {
298 bubble_manager->AddRequest(new QuotaPermissionRequest(this,
299 params.origin_url, params.requested_size, params.user_gesture,
300 Profile::FromBrowserContext(web_contents->GetBrowserContext())->
301 GetPrefs()->GetString(prefs::kAcceptLanguages),
302 callback));
304 return;
307 RequestQuotaInfoBarDelegate::Create(
308 infobar_service, this, params.origin_url, params.requested_size,
309 Profile::FromBrowserContext(web_contents->GetBrowserContext())->
310 GetPrefs()->GetString(prefs::kAcceptLanguages),
311 callback);
314 void ChromeQuotaPermissionContext::DispatchCallbackOnIOThread(
315 const PermissionCallback& callback,
316 QuotaPermissionResponse response) {
317 DCHECK_EQ(false, callback.is_null());
319 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
320 content::BrowserThread::PostTask(
321 content::BrowserThread::IO, FROM_HERE,
322 base::Bind(&ChromeQuotaPermissionContext::DispatchCallbackOnIOThread,
323 this, callback, response));
324 return;
327 callback.Run(response);
330 ChromeQuotaPermissionContext::~ChromeQuotaPermissionContext() {}