blob: 332afb64605e47137f41c040688e9fecfa8c2e2a [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/infobar_service.h"
[email protected]317f96c92011-05-31 06:53:4113#include "chrome/browser/profiles/profile.h"
[email protected]317f96c92011-05-31 06:53:4114#include "chrome/browser/tab_contents/tab_util.h"
[email protected]c032489d2014-02-11 19:07:2415#include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
16#include "chrome/browser/ui/website_settings/permission_bubble_request.h"
[email protected]317f96c92011-05-31 06:53:4117#include "chrome/common/pref_names.h"
[email protected]af39f002014-08-22 10:18:1818#include "chrome/grit/generated_resources.h"
thestigaeddd322014-08-27 06:58:3919#include "chrome/grit/locale_settings.h"
[email protected]f9b21602014-05-22 00:53:1220#include "components/infobars/core/confirm_infobar_delegate.h"
[email protected]051655ad2014-04-18 15:09:4121#include "components/infobars/core/infobar.h"
rsleevi24f64dc22015-08-07 21:39:2122#include "components/url_formatter/url_formatter.h"
[email protected]c38831a12011-10-28 12:44:4923#include "content/public/browser/browser_thread.h"
[email protected]5b96836f2011-12-22 07:39:0024#include "content/public/browser/navigation_details.h"
[email protected]4f822f022012-12-20 19:11:4225#include "content/public/browser/web_contents.h"
[email protected]d23cdeee2014-03-10 06:39:5326#include "grit/theme_resources.h"
pilgrim16330552014-09-10 01:32:2227#include "storage/common/quota/quota_types.h"
[email protected]317f96c92011-05-31 06:53:4128#include "ui/base/l10n/l10n_util.h"
[email protected]761fa4702013-07-02 15:25:1529#include "url/gurl.h"
[email protected]317f96c92011-05-31 06:53:4130
[email protected]c032489d2014-02-11 19:07:2431namespace {
32
33// If the site requested larger quota than this threshold, show a different
34// message to the user.
35const int64 kRequestLargeQuotaThreshold = 5 * 1024 * 1024;
36
37// QuotaPermissionRequest ---------------------------------------------
38
39class QuotaPermissionRequest : public PermissionBubbleRequest {
40 public:
41 QuotaPermissionRequest(
42 ChromeQuotaPermissionContext* context,
43 const GURL& origin_url,
44 int64 requested_quota,
[email protected]f78aa7722014-04-04 00:04:2545 bool user_gesture,
[email protected]c032489d2014-02-11 19:07:2446 const std::string& display_languages,
47 const content::QuotaPermissionContext::PermissionCallback& callback);
48
Daniel Chenga542fca2014-10-21 09:51:2949 ~QuotaPermissionRequest() override;
[email protected]c032489d2014-02-11 19:07:2450
51 // PermissionBubbleRequest:
Daniel Chenga542fca2014-10-21 09:51:2952 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;
[email protected]c032489d2014-02-11 19:07:2461
62 private:
63 scoped_refptr<ChromeQuotaPermissionContext> context_;
64 GURL origin_url_;
65 std::string display_languages_;
66 int64 requested_quota_;
[email protected]f78aa7722014-04-04 00:04:2567 bool user_gesture_;
[email protected]c032489d2014-02-11 19:07:2468 content::QuotaPermissionContext::PermissionCallback callback_;
69
70 DISALLOW_COPY_AND_ASSIGN(QuotaPermissionRequest);
71};
72
73QuotaPermissionRequest::QuotaPermissionRequest(
74 ChromeQuotaPermissionContext* context,
75 const GURL& origin_url,
76 int64 requested_quota,
[email protected]f78aa7722014-04-04 00:04:2577 bool user_gesture,
[email protected]c032489d2014-02-11 19:07:2478 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),
[email protected]f78aa7722014-04-04 00:04:2584 user_gesture_(user_gesture),
[email protected]c032489d2014-02-11 19:07:2485 callback_(callback) {}
86
87QuotaPermissionRequest::~QuotaPermissionRequest() {}
88
[email protected]d23cdeee2014-03-10 06:39:5389int QuotaPermissionRequest::GetIconID() const {
90 // TODO(gbillock): get the proper image here
91 return IDR_INFOBAR_WARNING;
92}
93
[email protected]c032489d2014-02-11 19:07:2494base::string16 QuotaPermissionRequest::GetMessageText() const {
95 return l10n_util::GetStringFUTF16(
rsleevi24f64dc22015-08-07 21:39:2196 (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));
[email protected]c032489d2014-02-11 19:07:24104}
105
106base::string16 QuotaPermissionRequest::GetMessageTextFragment() const {
107 return l10n_util::GetStringUTF16(IDS_REQUEST_QUOTA_PERMISSION_FRAGMENT);
108}
109
[email protected]d23cdeee2014-03-10 06:39:53110bool QuotaPermissionRequest::HasUserGesture() const {
[email protected]f78aa7722014-04-04 00:04:25111 return user_gesture_;
[email protected]c032489d2014-02-11 19:07:24112}
113
[email protected]d23cdeee2014-03-10 06:39:53114GURL QuotaPermissionRequest::GetRequestingHostname() const {
115 return origin_url_;
[email protected]c032489d2014-02-11 19:07:24116}
117
118void QuotaPermissionRequest::PermissionGranted() {
119 context_->DispatchCallbackOnIOThread(
120 callback_,
121 content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW);
122 callback_ = content::QuotaPermissionContext::PermissionCallback();
123}
124
125void QuotaPermissionRequest::PermissionDenied() {
126 context_->DispatchCallbackOnIOThread(
127 callback_,
128 content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_DISALLOW);
129 callback_ = content::QuotaPermissionContext::PermissionCallback();
130}
131
132void QuotaPermissionRequest::Cancelled() {
133}
134
135void QuotaPermissionRequest::RequestFinished() {
136 if (!callback_.is_null()) {
137 context_->DispatchCallbackOnIOThread(
138 callback_,
139 content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
140 }
141
142 delete this;
143}
[email protected]631bb742011-11-02 11:29:39144
[email protected]49c71ac2013-05-03 01:36:22145
146// RequestQuotaInfoBarDelegate ------------------------------------------------
147
[email protected]317f96c92011-05-31 06:53:41148class RequestQuotaInfoBarDelegate : public ConfirmInfoBarDelegate {
149 public:
[email protected]39308cb2013-12-06 03:01:48150 // Creates a request quota infobar and delegate and adds the infobar to
151 // |infobar_service|.
[email protected]0be09932013-01-08 02:03:50152 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,
[email protected]9a88ea992013-07-10 21:21:57158 const content::QuotaPermissionContext::PermissionCallback& callback);
[email protected]0be09932013-01-08 02:03:50159
160 private:
[email protected]317f96c92011-05-31 06:53:41161 RequestQuotaInfoBarDelegate(
[email protected]317f96c92011-05-31 06:53:41162 ChromeQuotaPermissionContext* context,
163 const GURL& origin_url,
164 int64 requested_quota,
165 const std::string& display_languages,
[email protected]9a88ea992013-07-10 21:21:57166 const content::QuotaPermissionContext::PermissionCallback& callback);
Daniel Chenga542fca2014-10-21 09:51:29167 ~RequestQuotaInfoBarDelegate() override;
[email protected]317f96c92011-05-31 06:53:41168
[email protected]49c71ac2013-05-03 01:36:22169 // ConfirmInfoBarDelegate:
Daniel Chenga542fca2014-10-21 09:51:29170 base::string16 GetMessageText() const override;
171 bool Accept() override;
172 bool Cancel() override;
[email protected]317f96c92011-05-31 06:53:41173
174 scoped_refptr<ChromeQuotaPermissionContext> context_;
175 GURL origin_url_;
176 std::string display_languages_;
177 int64 requested_quota_;
[email protected]9a88ea992013-07-10 21:21:57178 content::QuotaPermissionContext::PermissionCallback callback_;
[email protected]49c71ac2013-05-03 01:36:22179
[email protected]317f96c92011-05-31 06:53:41180 DISALLOW_COPY_AND_ASSIGN(RequestQuotaInfoBarDelegate);
181};
182
[email protected]0be09932013-01-08 02:03:50183// static
184void RequestQuotaInfoBarDelegate::Create(
185 InfoBarService* infobar_service,
186 ChromeQuotaPermissionContext* context,
187 const GURL& origin_url,
188 int64 requested_quota,
189 const std::string& display_languages,
[email protected]9a88ea992013-07-10 21:21:57190 const content::QuotaPermissionContext::PermissionCallback& callback) {
sdefresne316da452014-12-22 17:30:59191 infobar_service->AddInfoBar(infobar_service->CreateConfirmInfoBar(
[email protected]39308cb2013-12-06 03:01:48192 scoped_ptr<ConfirmInfoBarDelegate>(new RequestQuotaInfoBarDelegate(
193 context, origin_url, requested_quota, display_languages, callback))));
[email protected]0be09932013-01-08 02:03:50194}
195
[email protected]49c71ac2013-05-03 01:36:22196RequestQuotaInfoBarDelegate::RequestQuotaInfoBarDelegate(
[email protected]49c71ac2013-05-03 01:36:22197 ChromeQuotaPermissionContext* context,
198 const GURL& origin_url,
199 int64 requested_quota,
200 const std::string& display_languages,
[email protected]9a88ea992013-07-10 21:21:57201 const content::QuotaPermissionContext::PermissionCallback& callback)
[email protected]39308cb2013-12-06 03:01:48202 : ConfirmInfoBarDelegate(),
[email protected]49c71ac2013-05-03 01:36:22203 context_(context),
204 origin_url_(origin_url),
205 display_languages_(display_languages),
206 requested_quota_(requested_quota),
207 callback_(callback) {
208}
209
210RequestQuotaInfoBarDelegate::~RequestQuotaInfoBarDelegate() {
211 if (!callback_.is_null()) {
212 context_->DispatchCallbackOnIOThread(
213 callback_,
[email protected]9a88ea992013-07-10 21:21:57214 content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
[email protected]49c71ac2013-05-03 01:36:22215 }
216}
217
[email protected]6a72a632013-12-12 22:22:00218base::string16 RequestQuotaInfoBarDelegate::GetMessageText() const {
[email protected]9a88ea992013-07-10 21:21:57219 // If the site requested larger quota than this threshold, show a different
220 // message to the user.
[email protected]317f96c92011-05-31 06:53:41221 return l10n_util::GetStringFUTF16(
rsleevi24f64dc22015-08-07 21:39:21222 (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));
[email protected]317f96c92011-05-31 06:53:41230}
231
232bool RequestQuotaInfoBarDelegate::Accept() {
233 context_->DispatchCallbackOnIOThread(
[email protected]9f9749a2012-03-02 19:37:00234 callback_,
[email protected]9a88ea992013-07-10 21:21:57235 content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW);
[email protected]317f96c92011-05-31 06:53:41236 return true;
237}
238
239bool RequestQuotaInfoBarDelegate::Cancel() {
240 context_->DispatchCallbackOnIOThread(
[email protected]9f9749a2012-03-02 19:37:00241 callback_,
[email protected]9a88ea992013-07-10 21:21:57242 content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
[email protected]317f96c92011-05-31 06:53:41243 return true;
244}
245
[email protected]49c71ac2013-05-03 01:36:22246} // namespace
247
248
249// ChromeQuotaPermissionContext -----------------------------------------------
[email protected]317f96c92011-05-31 06:53:41250
[email protected]9a88ea992013-07-10 21:21:57251ChromeQuotaPermissionContext::ChromeQuotaPermissionContext() {
252}
[email protected]317f96c92011-05-31 06:53:41253
254void ChromeQuotaPermissionContext::RequestQuotaPermission(
[email protected]f78aa7722014-04-04 00:04:25255 const content::StorageQuotaParams& params,
[email protected]317f96c92011-05-31 06:53:41256 int render_process_id,
[email protected]c8d98dd2011-10-18 23:12:08257 const PermissionCallback& callback) {
[email protected]cd501a72014-08-22 19:58:31258 if (params.storage_type != storage::kStorageTypePersistent) {
[email protected]317f96c92011-05-31 06:53:41259 // For now we only support requesting quota with this interface
260 // for Persistent storage type.
[email protected]9f9749a2012-03-02 19:37:00261 callback.Run(QUOTA_PERMISSION_RESPONSE_DISALLOW);
[email protected]317f96c92011-05-31 06:53:41262 return;
263 }
264
[email protected]9a88ea992013-07-10 21:21:57265 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
266 content::BrowserThread::PostTask(
267 content::BrowserThread::UI, FROM_HERE,
[email protected]1c6bfbb2011-11-30 04:36:14268 base::Bind(&ChromeQuotaPermissionContext::RequestQuotaPermission, this,
[email protected]f78aa7722014-04-04 00:04:25269 params, render_process_id, callback));
[email protected]317f96c92011-05-31 06:53:41270 return;
271 }
272
[email protected]9a88ea992013-07-10 21:21:57273 content::WebContents* web_contents =
[email protected]f78aa7722014-04-04 00:04:25274 tab_util::GetWebContentsByID(render_process_id,
275 params.render_view_id);
[email protected]83ff91c2012-01-05 20:54:13276 if (!web_contents) {
[email protected]317f96c92011-05-31 06:53:41277 // The tab may have gone away or the request may not be from a tab.
278 LOG(WARNING) << "Attempt to request quota tabless renderer: "
[email protected]f78aa7722014-04-04 00:04:25279 << render_process_id << "," << params.render_view_id;
[email protected]9f9749a2012-03-02 19:37:00280 DispatchCallbackOnIOThread(callback, QUOTA_PERMISSION_RESPONSE_CANCELLED);
[email protected]317f96c92011-05-31 06:53:41281 return;
282 }
283
felt51f26d1f2015-03-10 04:09:37284 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;
292 }
293
[email protected]c032489d2014-02-11 19:07:24294 if (PermissionBubbleManager::Enabled()) {
295 PermissionBubbleManager* bubble_manager =
296 PermissionBubbleManager::FromWebContents(web_contents);
[email protected]f2d770862014-05-13 03:26:14297 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));
303 }
[email protected]c032489d2014-02-11 19:07:24304 return;
305 }
306
[email protected]0be09932013-01-08 02:03:50307 RequestQuotaInfoBarDelegate::Create(
[email protected]f78aa7722014-04-04 00:04:25308 infobar_service, this, params.origin_url, params.requested_size,
[email protected]9a88ea992013-07-10 21:21:57309 Profile::FromBrowserContext(web_contents->GetBrowserContext())->
310 GetPrefs()->GetString(prefs::kAcceptLanguages),
[email protected]0be09932013-01-08 02:03:50311 callback);
[email protected]317f96c92011-05-31 06:53:41312}
313
314void ChromeQuotaPermissionContext::DispatchCallbackOnIOThread(
[email protected]c8d98dd2011-10-18 23:12:08315 const PermissionCallback& callback,
[email protected]9f9749a2012-03-02 19:37:00316 QuotaPermissionResponse response) {
[email protected]c8d98dd2011-10-18 23:12:08317 DCHECK_EQ(false, callback.is_null());
318
[email protected]9a88ea992013-07-10 21:21:57319 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
320 content::BrowserThread::PostTask(
321 content::BrowserThread::IO, FROM_HERE,
[email protected]c8d98dd2011-10-18 23:12:08322 base::Bind(&ChromeQuotaPermissionContext::DispatchCallbackOnIOThread,
323 this, callback, response));
[email protected]317f96c92011-05-31 06:53:41324 return;
325 }
[email protected]c8d98dd2011-10-18 23:12:08326
327 callback.Run(response);
[email protected]317f96c92011-05-31 06:53:41328}
[email protected]649d1c02012-04-27 02:56:21329
330ChromeQuotaPermissionContext::~ChromeQuotaPermissionContext() {}