[Metrics] Make MetricsStateManager take a callback param to check if UMA is enabled.
[chromium-blink-merge.git] / chrome / browser / chrome_quota_permission_context.cc
blobfac03db67ca3acf6657597354ab191d5cfb1356d
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/confirm_infobar_delegate.h"
13 #include "chrome/browser/infobars/infobar_service.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/tab_contents/tab_util.h"
16 #include "chrome/browser/ui/website_settings/permission_bubble_manager.h"
17 #include "chrome/browser/ui/website_settings/permission_bubble_request.h"
18 #include "chrome/common/pref_names.h"
19 #include "components/infobars/core/infobar.h"
20 #include "content/public/browser/browser_thread.h"
21 #include "content/public/browser/navigation_details.h"
22 #include "content/public/browser/web_contents.h"
23 #include "grit/generated_resources.h"
24 #include "grit/locale_settings.h"
25 #include "grit/theme_resources.h"
26 #include "net/base/net_util.h"
27 #include "ui/base/l10n/l10n_util.h"
28 #include "url/gurl.h"
29 #include "webkit/common/quota/quota_types.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 virtual ~QuotaPermissionRequest();
51 // PermissionBubbleRequest:
52 virtual int GetIconID() const OVERRIDE;
53 virtual base::string16 GetMessageText() const OVERRIDE;
54 virtual base::string16 GetMessageTextFragment() const OVERRIDE;
55 virtual bool HasUserGesture() const OVERRIDE;
56 virtual GURL GetRequestingHostname() const OVERRIDE;
57 virtual void PermissionGranted() OVERRIDE;
58 virtual void PermissionDenied() OVERRIDE;
59 virtual void Cancelled() OVERRIDE;
60 virtual 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 net::FormatUrl(origin_url_, display_languages_));
102 base::string16 QuotaPermissionRequest::GetMessageTextFragment() const {
103 return l10n_util::GetStringUTF16(IDS_REQUEST_QUOTA_PERMISSION_FRAGMENT);
106 bool QuotaPermissionRequest::HasUserGesture() const {
107 return user_gesture_;
110 GURL QuotaPermissionRequest::GetRequestingHostname() const {
111 return origin_url_;
114 void QuotaPermissionRequest::PermissionGranted() {
115 context_->DispatchCallbackOnIOThread(
116 callback_,
117 content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW);
118 callback_ = content::QuotaPermissionContext::PermissionCallback();
121 void QuotaPermissionRequest::PermissionDenied() {
122 context_->DispatchCallbackOnIOThread(
123 callback_,
124 content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_DISALLOW);
125 callback_ = content::QuotaPermissionContext::PermissionCallback();
128 void QuotaPermissionRequest::Cancelled() {
131 void QuotaPermissionRequest::RequestFinished() {
132 if (!callback_.is_null()) {
133 context_->DispatchCallbackOnIOThread(
134 callback_,
135 content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
138 delete this;
142 // RequestQuotaInfoBarDelegate ------------------------------------------------
144 class RequestQuotaInfoBarDelegate : public ConfirmInfoBarDelegate {
145 public:
146 // Creates a request quota infobar and delegate and adds the infobar to
147 // |infobar_service|.
148 static void Create(
149 InfoBarService* infobar_service,
150 ChromeQuotaPermissionContext* context,
151 const GURL& origin_url,
152 int64 requested_quota,
153 const std::string& display_languages,
154 const content::QuotaPermissionContext::PermissionCallback& callback);
156 private:
157 RequestQuotaInfoBarDelegate(
158 ChromeQuotaPermissionContext* context,
159 const GURL& origin_url,
160 int64 requested_quota,
161 const std::string& display_languages,
162 const content::QuotaPermissionContext::PermissionCallback& callback);
163 virtual ~RequestQuotaInfoBarDelegate();
165 // ConfirmInfoBarDelegate:
166 virtual bool ShouldExpireInternal(
167 const NavigationDetails& details) const OVERRIDE;
168 virtual base::string16 GetMessageText() const OVERRIDE;
169 virtual bool Accept() OVERRIDE;
170 virtual bool Cancel() OVERRIDE;
172 scoped_refptr<ChromeQuotaPermissionContext> context_;
173 GURL origin_url_;
174 std::string display_languages_;
175 int64 requested_quota_;
176 content::QuotaPermissionContext::PermissionCallback callback_;
178 DISALLOW_COPY_AND_ASSIGN(RequestQuotaInfoBarDelegate);
181 // static
182 void RequestQuotaInfoBarDelegate::Create(
183 InfoBarService* infobar_service,
184 ChromeQuotaPermissionContext* context,
185 const GURL& origin_url,
186 int64 requested_quota,
187 const std::string& display_languages,
188 const content::QuotaPermissionContext::PermissionCallback& callback) {
189 infobar_service->AddInfoBar(ConfirmInfoBarDelegate::CreateInfoBar(
190 scoped_ptr<ConfirmInfoBarDelegate>(new RequestQuotaInfoBarDelegate(
191 context, origin_url, requested_quota, display_languages, callback))));
194 RequestQuotaInfoBarDelegate::RequestQuotaInfoBarDelegate(
195 ChromeQuotaPermissionContext* context,
196 const GURL& origin_url,
197 int64 requested_quota,
198 const std::string& display_languages,
199 const content::QuotaPermissionContext::PermissionCallback& callback)
200 : ConfirmInfoBarDelegate(),
201 context_(context),
202 origin_url_(origin_url),
203 display_languages_(display_languages),
204 requested_quota_(requested_quota),
205 callback_(callback) {
208 RequestQuotaInfoBarDelegate::~RequestQuotaInfoBarDelegate() {
209 if (!callback_.is_null()) {
210 context_->DispatchCallbackOnIOThread(
211 callback_,
212 content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
216 bool RequestQuotaInfoBarDelegate::ShouldExpireInternal(
217 const NavigationDetails& details) const {
218 return false;
221 base::string16 RequestQuotaInfoBarDelegate::GetMessageText() const {
222 // If the site requested larger quota than this threshold, show a different
223 // message to the user.
224 return l10n_util::GetStringFUTF16(
225 (requested_quota_ > kRequestLargeQuotaThreshold ?
226 IDS_REQUEST_LARGE_QUOTA_INFOBAR_QUESTION :
227 IDS_REQUEST_QUOTA_INFOBAR_QUESTION),
228 net::FormatUrl(origin_url_, display_languages_));
231 bool RequestQuotaInfoBarDelegate::Accept() {
232 context_->DispatchCallbackOnIOThread(
233 callback_,
234 content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW);
235 return true;
238 bool RequestQuotaInfoBarDelegate::Cancel() {
239 context_->DispatchCallbackOnIOThread(
240 callback_,
241 content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
242 return true;
245 } // namespace
248 // ChromeQuotaPermissionContext -----------------------------------------------
250 ChromeQuotaPermissionContext::ChromeQuotaPermissionContext() {
253 void ChromeQuotaPermissionContext::RequestQuotaPermission(
254 const content::StorageQuotaParams& params,
255 int render_process_id,
256 const PermissionCallback& callback) {
257 if (params.storage_type != quota::kStorageTypePersistent) {
258 // For now we only support requesting quota with this interface
259 // for Persistent storage type.
260 callback.Run(QUOTA_PERMISSION_RESPONSE_DISALLOW);
261 return;
264 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
265 content::BrowserThread::PostTask(
266 content::BrowserThread::UI, FROM_HERE,
267 base::Bind(&ChromeQuotaPermissionContext::RequestQuotaPermission, this,
268 params, render_process_id, callback));
269 return;
272 content::WebContents* web_contents =
273 tab_util::GetWebContentsByID(render_process_id,
274 params.render_view_id);
275 if (!web_contents) {
276 // The tab may have gone away or the request may not be from a tab.
277 LOG(WARNING) << "Attempt to request quota tabless renderer: "
278 << render_process_id << "," << params.render_view_id;
279 DispatchCallbackOnIOThread(callback, QUOTA_PERMISSION_RESPONSE_CANCELLED);
280 return;
283 if (PermissionBubbleManager::Enabled()) {
284 PermissionBubbleManager* bubble_manager =
285 PermissionBubbleManager::FromWebContents(web_contents);
286 if (bubble_manager) {
287 bubble_manager->AddRequest(new QuotaPermissionRequest(this,
288 params.origin_url, params.requested_size, params.user_gesture,
289 Profile::FromBrowserContext(web_contents->GetBrowserContext())->
290 GetPrefs()->GetString(prefs::kAcceptLanguages),
291 callback));
293 return;
296 InfoBarService* infobar_service =
297 InfoBarService::FromWebContents(web_contents);
298 if (!infobar_service) {
299 // The tab has no infobar service.
300 LOG(WARNING) << "Attempt to request quota from a background page: "
301 << render_process_id << "," << params.render_view_id;
302 DispatchCallbackOnIOThread(callback, QUOTA_PERMISSION_RESPONSE_CANCELLED);
303 return;
305 RequestQuotaInfoBarDelegate::Create(
306 infobar_service, this, params.origin_url, params.requested_size,
307 Profile::FromBrowserContext(web_contents->GetBrowserContext())->
308 GetPrefs()->GetString(prefs::kAcceptLanguages),
309 callback);
312 void ChromeQuotaPermissionContext::DispatchCallbackOnIOThread(
313 const PermissionCallback& callback,
314 QuotaPermissionResponse response) {
315 DCHECK_EQ(false, callback.is_null());
317 if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
318 content::BrowserThread::PostTask(
319 content::BrowserThread::IO, FROM_HERE,
320 base::Bind(&ChromeQuotaPermissionContext::DispatchCallbackOnIOThread,
321 this, callback, response));
322 return;
325 callback.Run(response);
328 ChromeQuotaPermissionContext::~ChromeQuotaPermissionContext() {}