Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chrome_quota_permission_context.cc
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.
4
5 #include "chrome/browser/chrome_quota_permission_context.h"
6
7 #include <string>
8
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"
30
31 namespace {
32
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;
36
37 // QuotaPermissionRequest ---------------------------------------------
38
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);
48
49   virtual ~QuotaPermissionRequest();
50
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;
61
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_;
69
70   DISALLOW_COPY_AND_ASSIGN(QuotaPermissionRequest);
71 };
72
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) {}
86
87 QuotaPermissionRequest::~QuotaPermissionRequest() {}
88
89 int QuotaPermissionRequest::GetIconID() const {
90   // TODO(gbillock): get the proper image here
91   return IDR_INFOBAR_WARNING;
92 }
93
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_));
100 }
101
102 base::string16 QuotaPermissionRequest::GetMessageTextFragment() const {
103   return l10n_util::GetStringUTF16(IDS_REQUEST_QUOTA_PERMISSION_FRAGMENT);
104 }
105
106 bool QuotaPermissionRequest::HasUserGesture() const {
107   return user_gesture_;
108 }
109
110 GURL QuotaPermissionRequest::GetRequestingHostname() const {
111   return origin_url_;
112 }
113
114 void QuotaPermissionRequest::PermissionGranted() {
115   context_->DispatchCallbackOnIOThread(
116       callback_,
117       content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW);
118   callback_ = content::QuotaPermissionContext::PermissionCallback();
119 }
120
121 void QuotaPermissionRequest::PermissionDenied() {
122   context_->DispatchCallbackOnIOThread(
123       callback_,
124       content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_DISALLOW);
125   callback_ = content::QuotaPermissionContext::PermissionCallback();
126 }
127
128 void QuotaPermissionRequest::Cancelled() {
129 }
130
131 void QuotaPermissionRequest::RequestFinished() {
132   if (!callback_.is_null()) {
133     context_->DispatchCallbackOnIOThread(
134         callback_,
135         content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
136   }
137
138   delete this;
139 }
140
141
142 // RequestQuotaInfoBarDelegate ------------------------------------------------
143
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);
155
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();
164
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;
171
172   scoped_refptr<ChromeQuotaPermissionContext> context_;
173   GURL origin_url_;
174   std::string display_languages_;
175   int64 requested_quota_;
176   content::QuotaPermissionContext::PermissionCallback callback_;
177
178   DISALLOW_COPY_AND_ASSIGN(RequestQuotaInfoBarDelegate);
179 };
180
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))));
192 }
193
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) {
206 }
207
208 RequestQuotaInfoBarDelegate::~RequestQuotaInfoBarDelegate() {
209   if (!callback_.is_null()) {
210     context_->DispatchCallbackOnIOThread(
211         callback_,
212         content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
213   }
214 }
215
216 bool RequestQuotaInfoBarDelegate::ShouldExpireInternal(
217     const NavigationDetails& details) const {
218   return false;
219 }
220
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_));
229 }
230
231 bool RequestQuotaInfoBarDelegate::Accept() {
232   context_->DispatchCallbackOnIOThread(
233       callback_,
234       content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW);
235   return true;
236 }
237
238 bool RequestQuotaInfoBarDelegate::Cancel() {
239   context_->DispatchCallbackOnIOThread(
240       callback_,
241       content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
242   return true;
243 }
244
245 }  // namespace
246
247
248 // ChromeQuotaPermissionContext -----------------------------------------------
249
250 ChromeQuotaPermissionContext::ChromeQuotaPermissionContext() {
251 }
252
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;
262   }
263
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;
270   }
271
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;
281   }
282
283   if (PermissionBubbleManager::Enabled()) {
284     PermissionBubbleManager* bubble_manager =
285         PermissionBubbleManager::FromWebContents(web_contents);
286     bubble_manager->AddRequest(new QuotaPermissionRequest(this,
287             params.origin_url, params.requested_size, params.user_gesture,
288             Profile::FromBrowserContext(web_contents->GetBrowserContext())->
289                 GetPrefs()->GetString(prefs::kAcceptLanguages),
290             callback));
291     return;
292   }
293
294   InfoBarService* infobar_service =
295       InfoBarService::FromWebContents(web_contents);
296   if (!infobar_service) {
297     // The tab has no infobar service.
298     LOG(WARNING) << "Attempt to request quota from a background page: "
299                  << render_process_id << "," << params.render_view_id;
300     DispatchCallbackOnIOThread(callback, QUOTA_PERMISSION_RESPONSE_CANCELLED);
301     return;
302   }
303   RequestQuotaInfoBarDelegate::Create(
304       infobar_service, this, params.origin_url, params.requested_size,
305       Profile::FromBrowserContext(web_contents->GetBrowserContext())->
306           GetPrefs()->GetString(prefs::kAcceptLanguages),
307       callback);
308 }
309
310 void ChromeQuotaPermissionContext::DispatchCallbackOnIOThread(
311     const PermissionCallback& callback,
312     QuotaPermissionResponse response) {
313   DCHECK_EQ(false, callback.is_null());
314
315   if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
316     content::BrowserThread::PostTask(
317         content::BrowserThread::IO, FROM_HERE,
318         base::Bind(&ChromeQuotaPermissionContext::DispatchCallbackOnIOThread,
319                    this, callback, response));
320     return;
321   }
322
323   callback.Run(response);
324 }
325
326 ChromeQuotaPermissionContext::~ChromeQuotaPermissionContext() {}