Update To 11.40.268.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/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 "content/public/browser/browser_thread.h"
23 #include "content/public/browser/navigation_details.h"
24 #include "content/public/browser/web_contents.h"
25 #include "grit/theme_resources.h"
26 #include "net/base/net_util.h"
27 #include "storage/common/quota/quota_types.h"
28 #include "ui/base/l10n/l10n_util.h"
29 #include "url/gurl.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   ~QuotaPermissionRequest() override;
50
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;
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                      net::kFormatUrlOmitUsernamePassword |
101                      net::kFormatUrlOmitTrailingSlashOnBareHostname,
102                      net::UnescapeRule::SPACES, NULL, NULL, NULL)
103   );
104 }
105
106 base::string16 QuotaPermissionRequest::GetMessageTextFragment() const {
107   return l10n_util::GetStringUTF16(IDS_REQUEST_QUOTA_PERMISSION_FRAGMENT);
108 }
109
110 bool QuotaPermissionRequest::HasUserGesture() const {
111   return user_gesture_;
112 }
113
114 GURL QuotaPermissionRequest::GetRequestingHostname() const {
115   return origin_url_;
116 }
117
118 void QuotaPermissionRequest::PermissionGranted() {
119   context_->DispatchCallbackOnIOThread(
120       callback_,
121       content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW);
122   callback_ = content::QuotaPermissionContext::PermissionCallback();
123 }
124
125 void QuotaPermissionRequest::PermissionDenied() {
126   context_->DispatchCallbackOnIOThread(
127       callback_,
128       content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_DISALLOW);
129   callback_ = content::QuotaPermissionContext::PermissionCallback();
130 }
131
132 void QuotaPermissionRequest::Cancelled() {
133 }
134
135 void 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 }
144
145
146 // RequestQuotaInfoBarDelegate ------------------------------------------------
147
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);
159
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;
168
169   // ConfirmInfoBarDelegate:
170   base::string16 GetMessageText() const override;
171   bool Accept() override;
172   bool Cancel() override;
173
174   scoped_refptr<ChromeQuotaPermissionContext> context_;
175   GURL origin_url_;
176   std::string display_languages_;
177   int64 requested_quota_;
178   content::QuotaPermissionContext::PermissionCallback callback_;
179
180   DISALLOW_COPY_AND_ASSIGN(RequestQuotaInfoBarDelegate);
181 };
182
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(ConfirmInfoBarDelegate::CreateInfoBar(
192       scoped_ptr<ConfirmInfoBarDelegate>(new RequestQuotaInfoBarDelegate(
193           context, origin_url, requested_quota, display_languages, callback))));
194 }
195
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) {
208 }
209
210 RequestQuotaInfoBarDelegate::~RequestQuotaInfoBarDelegate() {
211   if (!callback_.is_null()) {
212     context_->DispatchCallbackOnIOThread(
213         callback_,
214         content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
215   }
216 }
217
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       net::FormatUrl(origin_url_, display_languages_,
226                      net::kFormatUrlOmitUsernamePassword |
227                      net::kFormatUrlOmitTrailingSlashOnBareHostname,
228                      net::UnescapeRule::SPACES, NULL, NULL, NULL)
229       );
230 }
231
232 bool RequestQuotaInfoBarDelegate::Accept() {
233   context_->DispatchCallbackOnIOThread(
234       callback_,
235       content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW);
236   return true;
237 }
238
239 bool RequestQuotaInfoBarDelegate::Cancel() {
240   context_->DispatchCallbackOnIOThread(
241       callback_,
242       content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
243   return true;
244 }
245
246 }  // namespace
247
248
249 // ChromeQuotaPermissionContext -----------------------------------------------
250
251 ChromeQuotaPermissionContext::ChromeQuotaPermissionContext() {
252 }
253
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;
263   }
264
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;
271   }
272
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;
282   }
283
284   if (PermissionBubbleManager::Enabled()) {
285     PermissionBubbleManager* bubble_manager =
286         PermissionBubbleManager::FromWebContents(web_contents);
287     if (bubble_manager) {
288       bubble_manager->AddRequest(new QuotaPermissionRequest(this,
289               params.origin_url, params.requested_size, params.user_gesture,
290               Profile::FromBrowserContext(web_contents->GetBrowserContext())->
291                   GetPrefs()->GetString(prefs::kAcceptLanguages),
292               callback));
293     }
294     return;
295   }
296
297   InfoBarService* infobar_service =
298       InfoBarService::FromWebContents(web_contents);
299   if (!infobar_service) {
300     // The tab has no infobar service.
301     LOG(WARNING) << "Attempt to request quota from a background page: "
302                  << render_process_id << "," << params.render_view_id;
303     DispatchCallbackOnIOThread(callback, QUOTA_PERMISSION_RESPONSE_CANCELLED);
304     return;
305   }
306   RequestQuotaInfoBarDelegate::Create(
307       infobar_service, this, params.origin_url, params.requested_size,
308       Profile::FromBrowserContext(web_contents->GetBrowserContext())->
309           GetPrefs()->GetString(prefs::kAcceptLanguages),
310       callback);
311 }
312
313 void ChromeQuotaPermissionContext::DispatchCallbackOnIOThread(
314     const PermissionCallback& callback,
315     QuotaPermissionResponse response) {
316   DCHECK_EQ(false, callback.is_null());
317
318   if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
319     content::BrowserThread::PostTask(
320         content::BrowserThread::IO, FROM_HERE,
321         base::Bind(&ChromeQuotaPermissionContext::DispatchCallbackOnIOThread,
322                    this, callback, response));
323     return;
324   }
325
326   callback.Run(response);
327 }
328
329 ChromeQuotaPermissionContext::~ChromeQuotaPermissionContext() {}