blob: fc03747607115e30039b97e0df95e51b550c452a [file] [log] [blame]
[email protected]9f9749a2012-03-02 19:37:001// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]317f96c92011-05-31 06:53:412// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/chrome_quota_permission_context.h"
6
7#include <string>
8
[email protected]c8d98dd2011-10-18 23:12:089#include "base/bind.h"
[email protected]3853a4c2013-02-11 17:15:5710#include "base/prefs/pref_service.h"
[email protected]135cb802013-06-09 16:44:2011#include "base/strings/utf_string_conversions.h"
[email protected]4a8adfa02013-03-19 22:37:4612#include "chrome/browser/infobars/confirm_infobar_delegate.h"
[email protected]39308cb2013-12-06 03:01:4813#include "chrome/browser/infobars/infobar.h"
[email protected]4a8adfa02013-03-19 22:37:4614#include "chrome/browser/infobars/infobar_service.h"
[email protected]317f96c92011-05-31 06:53:4115#include "chrome/browser/profiles/profile.h"
[email protected]317f96c92011-05-31 06:53:4116#include "chrome/browser/tab_contents/tab_util.h"
[email protected]c032489d2014-02-11 19:07:2417#include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
18#include "chrome/browser/ui/website_settings/permission_bubble_request.h"
[email protected]317f96c92011-05-31 06:53:4119#include "chrome/common/pref_names.h"
[email protected]c38831a12011-10-28 12:44:4920#include "content/public/browser/browser_thread.h"
[email protected]5b96836f2011-12-22 07:39:0021#include "content/public/browser/navigation_details.h"
[email protected]4f822f022012-12-20 19:11:4222#include "content/public/browser/web_contents.h"
[email protected]317f96c92011-05-31 06:53:4123#include "grit/generated_resources.h"
24#include "grit/locale_settings.h"
25#include "net/base/net_util.h"
26#include "ui/base/l10n/l10n_util.h"
[email protected]761fa4702013-07-02 15:25:1527#include "url/gurl.h"
[email protected]7660ec92013-05-30 05:12:3928#include "webkit/common/quota/quota_types.h"
[email protected]317f96c92011-05-31 06:53:4129
[email protected]c032489d2014-02-11 19:07:2430namespace {
31
32// If the site requested larger quota than this threshold, show a different
33// message to the user.
34const int64 kRequestLargeQuotaThreshold = 5 * 1024 * 1024;
35
36// QuotaPermissionRequest ---------------------------------------------
37
38class QuotaPermissionRequest : public PermissionBubbleRequest {
39 public:
40 QuotaPermissionRequest(
41 ChromeQuotaPermissionContext* context,
42 const GURL& origin_url,
43 int64 requested_quota,
44 const std::string& display_languages,
45 const content::QuotaPermissionContext::PermissionCallback& callback);
46
47 virtual ~QuotaPermissionRequest();
48
49 // PermissionBubbleRequest:
50 virtual base::string16 GetMessageText() const OVERRIDE;
51 virtual base::string16 GetMessageTextFragment() const OVERRIDE;
52 virtual base::string16 GetAlternateAcceptButtonText() const OVERRIDE;
53 virtual base::string16 GetAlternateDenyButtonText() const OVERRIDE;
54 virtual void PermissionGranted() OVERRIDE;
55 virtual void PermissionDenied() OVERRIDE;
56 virtual void Cancelled() OVERRIDE;
57 virtual void RequestFinished() OVERRIDE;
58
59 private:
60 scoped_refptr<ChromeQuotaPermissionContext> context_;
61 GURL origin_url_;
62 std::string display_languages_;
63 int64 requested_quota_;
64 content::QuotaPermissionContext::PermissionCallback callback_;
65
66 DISALLOW_COPY_AND_ASSIGN(QuotaPermissionRequest);
67};
68
69QuotaPermissionRequest::QuotaPermissionRequest(
70 ChromeQuotaPermissionContext* context,
71 const GURL& origin_url,
72 int64 requested_quota,
73 const std::string& display_languages,
74 const content::QuotaPermissionContext::PermissionCallback& callback)
75 : context_(context),
76 origin_url_(origin_url),
77 display_languages_(display_languages),
78 requested_quota_(requested_quota),
79 callback_(callback) {}
80
81QuotaPermissionRequest::~QuotaPermissionRequest() {}
82
83base::string16 QuotaPermissionRequest::GetMessageText() const {
84 return l10n_util::GetStringFUTF16(
85 (requested_quota_ > kRequestLargeQuotaThreshold ?
86 IDS_REQUEST_LARGE_QUOTA_INFOBAR_QUESTION :
87 IDS_REQUEST_QUOTA_INFOBAR_QUESTION),
88 net::FormatUrl(origin_url_, display_languages_));
89}
90
91base::string16 QuotaPermissionRequest::GetMessageTextFragment() const {
92 return l10n_util::GetStringUTF16(IDS_REQUEST_QUOTA_PERMISSION_FRAGMENT);
93}
94
95base::string16 QuotaPermissionRequest::GetAlternateAcceptButtonText() const {
96 return base::string16();
97}
98
99base::string16 QuotaPermissionRequest::GetAlternateDenyButtonText() const {
100 return base::string16();
101}
102
103void QuotaPermissionRequest::PermissionGranted() {
104 context_->DispatchCallbackOnIOThread(
105 callback_,
106 content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW);
107 callback_ = content::QuotaPermissionContext::PermissionCallback();
108}
109
110void QuotaPermissionRequest::PermissionDenied() {
111 context_->DispatchCallbackOnIOThread(
112 callback_,
113 content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_DISALLOW);
114 callback_ = content::QuotaPermissionContext::PermissionCallback();
115}
116
117void QuotaPermissionRequest::Cancelled() {
118}
119
120void QuotaPermissionRequest::RequestFinished() {
121 if (!callback_.is_null()) {
122 context_->DispatchCallbackOnIOThread(
123 callback_,
124 content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
125 }
126
127 delete this;
128}
[email protected]631bb742011-11-02 11:29:39129
[email protected]49c71ac2013-05-03 01:36:22130
131// RequestQuotaInfoBarDelegate ------------------------------------------------
132
[email protected]317f96c92011-05-31 06:53:41133class RequestQuotaInfoBarDelegate : public ConfirmInfoBarDelegate {
134 public:
[email protected]39308cb2013-12-06 03:01:48135 // Creates a request quota infobar and delegate and adds the infobar to
136 // |infobar_service|.
[email protected]0be09932013-01-08 02:03:50137 static void Create(
138 InfoBarService* infobar_service,
139 ChromeQuotaPermissionContext* context,
140 const GURL& origin_url,
141 int64 requested_quota,
142 const std::string& display_languages,
[email protected]9a88ea992013-07-10 21:21:57143 const content::QuotaPermissionContext::PermissionCallback& callback);
[email protected]0be09932013-01-08 02:03:50144
145 private:
[email protected]317f96c92011-05-31 06:53:41146 RequestQuotaInfoBarDelegate(
[email protected]317f96c92011-05-31 06:53:41147 ChromeQuotaPermissionContext* context,
148 const GURL& origin_url,
149 int64 requested_quota,
150 const std::string& display_languages,
[email protected]9a88ea992013-07-10 21:21:57151 const content::QuotaPermissionContext::PermissionCallback& callback);
[email protected]49c71ac2013-05-03 01:36:22152 virtual ~RequestQuotaInfoBarDelegate();
[email protected]317f96c92011-05-31 06:53:41153
[email protected]49c71ac2013-05-03 01:36:22154 // ConfirmInfoBarDelegate:
[email protected]38eb4972013-01-07 18:35:05155 virtual bool ShouldExpireInternal(
[email protected]49c71ac2013-05-03 01:36:22156 const content::LoadCommittedDetails& details) const OVERRIDE;
[email protected]96920152013-12-04 21:00:16157 virtual base::string16 GetMessageText() const OVERRIDE;
[email protected]317f96c92011-05-31 06:53:41158 virtual bool Accept() OVERRIDE;
159 virtual bool Cancel() OVERRIDE;
160
161 scoped_refptr<ChromeQuotaPermissionContext> context_;
162 GURL origin_url_;
163 std::string display_languages_;
164 int64 requested_quota_;
[email protected]9a88ea992013-07-10 21:21:57165 content::QuotaPermissionContext::PermissionCallback callback_;
[email protected]49c71ac2013-05-03 01:36:22166
[email protected]317f96c92011-05-31 06:53:41167 DISALLOW_COPY_AND_ASSIGN(RequestQuotaInfoBarDelegate);
168};
169
[email protected]0be09932013-01-08 02:03:50170// static
171void RequestQuotaInfoBarDelegate::Create(
172 InfoBarService* infobar_service,
173 ChromeQuotaPermissionContext* context,
174 const GURL& origin_url,
175 int64 requested_quota,
176 const std::string& display_languages,
[email protected]9a88ea992013-07-10 21:21:57177 const content::QuotaPermissionContext::PermissionCallback& callback) {
[email protected]39308cb2013-12-06 03:01:48178 infobar_service->AddInfoBar(ConfirmInfoBarDelegate::CreateInfoBar(
179 scoped_ptr<ConfirmInfoBarDelegate>(new RequestQuotaInfoBarDelegate(
180 context, origin_url, requested_quota, display_languages, callback))));
[email protected]0be09932013-01-08 02:03:50181}
182
[email protected]49c71ac2013-05-03 01:36:22183RequestQuotaInfoBarDelegate::RequestQuotaInfoBarDelegate(
[email protected]49c71ac2013-05-03 01:36:22184 ChromeQuotaPermissionContext* context,
185 const GURL& origin_url,
186 int64 requested_quota,
187 const std::string& display_languages,
[email protected]9a88ea992013-07-10 21:21:57188 const content::QuotaPermissionContext::PermissionCallback& callback)
[email protected]39308cb2013-12-06 03:01:48189 : ConfirmInfoBarDelegate(),
[email protected]49c71ac2013-05-03 01:36:22190 context_(context),
191 origin_url_(origin_url),
192 display_languages_(display_languages),
193 requested_quota_(requested_quota),
194 callback_(callback) {
195}
196
197RequestQuotaInfoBarDelegate::~RequestQuotaInfoBarDelegate() {
198 if (!callback_.is_null()) {
199 context_->DispatchCallbackOnIOThread(
200 callback_,
[email protected]9a88ea992013-07-10 21:21:57201 content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
[email protected]49c71ac2013-05-03 01:36:22202 }
203}
204
205bool RequestQuotaInfoBarDelegate::ShouldExpireInternal(
206 const content::LoadCommittedDetails& details) const {
207 return false;
208}
209
[email protected]6a72a632013-12-12 22:22:00210base::string16 RequestQuotaInfoBarDelegate::GetMessageText() const {
[email protected]9a88ea992013-07-10 21:21:57211 // If the site requested larger quota than this threshold, show a different
212 // message to the user.
[email protected]317f96c92011-05-31 06:53:41213 return l10n_util::GetStringFUTF16(
214 (requested_quota_ > kRequestLargeQuotaThreshold ?
215 IDS_REQUEST_LARGE_QUOTA_INFOBAR_QUESTION :
216 IDS_REQUEST_QUOTA_INFOBAR_QUESTION),
217 net::FormatUrl(origin_url_, display_languages_));
218}
219
220bool RequestQuotaInfoBarDelegate::Accept() {
221 context_->DispatchCallbackOnIOThread(
[email protected]9f9749a2012-03-02 19:37:00222 callback_,
[email protected]9a88ea992013-07-10 21:21:57223 content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW);
[email protected]317f96c92011-05-31 06:53:41224 return true;
225}
226
227bool RequestQuotaInfoBarDelegate::Cancel() {
228 context_->DispatchCallbackOnIOThread(
[email protected]9f9749a2012-03-02 19:37:00229 callback_,
[email protected]9a88ea992013-07-10 21:21:57230 content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
[email protected]317f96c92011-05-31 06:53:41231 return true;
232}
233
[email protected]49c71ac2013-05-03 01:36:22234} // namespace
235
236
237// ChromeQuotaPermissionContext -----------------------------------------------
[email protected]317f96c92011-05-31 06:53:41238
[email protected]9a88ea992013-07-10 21:21:57239ChromeQuotaPermissionContext::ChromeQuotaPermissionContext() {
240}
[email protected]317f96c92011-05-31 06:53:41241
242void ChromeQuotaPermissionContext::RequestQuotaPermission(
243 const GURL& origin_url,
244 quota::StorageType type,
245 int64 requested_quota,
246 int render_process_id,
247 int render_view_id,
[email protected]c8d98dd2011-10-18 23:12:08248 const PermissionCallback& callback) {
[email protected]317f96c92011-05-31 06:53:41249 if (type != quota::kStorageTypePersistent) {
250 // For now we only support requesting quota with this interface
251 // for Persistent storage type.
[email protected]9f9749a2012-03-02 19:37:00252 callback.Run(QUOTA_PERMISSION_RESPONSE_DISALLOW);
[email protected]317f96c92011-05-31 06:53:41253 return;
254 }
255
[email protected]9a88ea992013-07-10 21:21:57256 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
257 content::BrowserThread::PostTask(
258 content::BrowserThread::UI, FROM_HERE,
[email protected]1c6bfbb2011-11-30 04:36:14259 base::Bind(&ChromeQuotaPermissionContext::RequestQuotaPermission, this,
260 origin_url, type, requested_quota, render_process_id,
261 render_view_id, callback));
[email protected]317f96c92011-05-31 06:53:41262 return;
263 }
264
[email protected]9a88ea992013-07-10 21:21:57265 content::WebContents* web_contents =
[email protected]83ff91c2012-01-05 20:54:13266 tab_util::GetWebContentsByID(render_process_id, render_view_id);
267 if (!web_contents) {
[email protected]317f96c92011-05-31 06:53:41268 // The tab may have gone away or the request may not be from a tab.
269 LOG(WARNING) << "Attempt to request quota tabless renderer: "
270 << render_process_id << "," << render_view_id;
[email protected]9f9749a2012-03-02 19:37:00271 DispatchCallbackOnIOThread(callback, QUOTA_PERMISSION_RESPONSE_CANCELLED);
[email protected]317f96c92011-05-31 06:53:41272 return;
273 }
274
[email protected]c032489d2014-02-11 19:07:24275 if (PermissionBubbleManager::Enabled()) {
276 PermissionBubbleManager* bubble_manager =
277 PermissionBubbleManager::FromWebContents(web_contents);
278 bubble_manager->AddRequest(new QuotaPermissionRequest(this,
279 origin_url, requested_quota,
280 Profile::FromBrowserContext(web_contents->GetBrowserContext())->
281 GetPrefs()->GetString(prefs::kAcceptLanguages),
282 callback));
283 return;
284 }
285
[email protected]4f822f022012-12-20 19:11:42286 InfoBarService* infobar_service =
287 InfoBarService::FromWebContents(web_contents);
288 if (!infobar_service) {
289 // The tab has no infobar service.
[email protected]17f2adb2012-07-22 15:43:40290 LOG(WARNING) << "Attempt to request quota from a background page: "
291 << render_process_id << "," << render_view_id;
292 DispatchCallbackOnIOThread(callback, QUOTA_PERMISSION_RESPONSE_CANCELLED);
293 return;
294 }
[email protected]0be09932013-01-08 02:03:50295 RequestQuotaInfoBarDelegate::Create(
[email protected]4f822f022012-12-20 19:11:42296 infobar_service, this, origin_url, requested_quota,
[email protected]9a88ea992013-07-10 21:21:57297 Profile::FromBrowserContext(web_contents->GetBrowserContext())->
298 GetPrefs()->GetString(prefs::kAcceptLanguages),
[email protected]0be09932013-01-08 02:03:50299 callback);
[email protected]317f96c92011-05-31 06:53:41300}
301
302void ChromeQuotaPermissionContext::DispatchCallbackOnIOThread(
[email protected]c8d98dd2011-10-18 23:12:08303 const PermissionCallback& callback,
[email protected]9f9749a2012-03-02 19:37:00304 QuotaPermissionResponse response) {
[email protected]c8d98dd2011-10-18 23:12:08305 DCHECK_EQ(false, callback.is_null());
306
[email protected]9a88ea992013-07-10 21:21:57307 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
308 content::BrowserThread::PostTask(
309 content::BrowserThread::IO, FROM_HERE,
[email protected]c8d98dd2011-10-18 23:12:08310 base::Bind(&ChromeQuotaPermissionContext::DispatchCallbackOnIOThread,
311 this, callback, response));
[email protected]317f96c92011-05-31 06:53:41312 return;
313 }
[email protected]c8d98dd2011-10-18 23:12:08314
315 callback.Run(response);
[email protected]317f96c92011-05-31 06:53:41316}
[email protected]649d1c02012-04-27 02:56:21317
318ChromeQuotaPermissionContext::~ChromeQuotaPermissionContext() {}