Home | History | Annotate | Download | only in browser
      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/common/pref_names.h"
     17 #include "content/public/browser/browser_thread.h"
     18 #include "content/public/browser/navigation_details.h"
     19 #include "content/public/browser/web_contents.h"
     20 #include "grit/generated_resources.h"
     21 #include "grit/locale_settings.h"
     22 #include "net/base/net_util.h"
     23 #include "ui/base/l10n/l10n_util.h"
     24 #include "url/gurl.h"
     25 #include "webkit/common/quota/quota_types.h"
     26 
     27 
     28 
     29 // RequestQuotaInfoBarDelegate ------------------------------------------------
     30 
     31 namespace {
     32 
     33 class RequestQuotaInfoBarDelegate : public ConfirmInfoBarDelegate {
     34  public:
     35   // Creates a request quota infobar delegate and adds it to |infobar_service|.
     36   static void Create(
     37       InfoBarService* infobar_service,
     38       ChromeQuotaPermissionContext* context,
     39       const GURL& origin_url,
     40       int64 requested_quota,
     41       const std::string& display_languages,
     42       const content::QuotaPermissionContext::PermissionCallback& callback);
     43 
     44  private:
     45   RequestQuotaInfoBarDelegate(
     46       InfoBarService* infobar_service,
     47       ChromeQuotaPermissionContext* context,
     48       const GURL& origin_url,
     49       int64 requested_quota,
     50       const std::string& display_languages,
     51       const content::QuotaPermissionContext::PermissionCallback& callback);
     52   virtual ~RequestQuotaInfoBarDelegate();
     53 
     54   // ConfirmInfoBarDelegate:
     55   virtual bool ShouldExpireInternal(
     56       const content::LoadCommittedDetails& details) const OVERRIDE;
     57   virtual string16 GetMessageText() const OVERRIDE;
     58   virtual bool Accept() OVERRIDE;
     59   virtual bool Cancel() OVERRIDE;
     60 
     61   scoped_refptr<ChromeQuotaPermissionContext> context_;
     62   GURL origin_url_;
     63   std::string display_languages_;
     64   int64 requested_quota_;
     65   content::QuotaPermissionContext::PermissionCallback callback_;
     66 
     67   DISALLOW_COPY_AND_ASSIGN(RequestQuotaInfoBarDelegate);
     68 };
     69 
     70 // static
     71 void RequestQuotaInfoBarDelegate::Create(
     72     InfoBarService* infobar_service,
     73     ChromeQuotaPermissionContext* context,
     74     const GURL& origin_url,
     75     int64 requested_quota,
     76     const std::string& display_languages,
     77     const content::QuotaPermissionContext::PermissionCallback& callback) {
     78   infobar_service->AddInfoBar(scoped_ptr<InfoBarDelegate>(
     79       new RequestQuotaInfoBarDelegate(infobar_service, context, origin_url,
     80                                       requested_quota, display_languages,
     81                                       callback)));
     82 }
     83 
     84 RequestQuotaInfoBarDelegate::RequestQuotaInfoBarDelegate(
     85     InfoBarService* infobar_service,
     86     ChromeQuotaPermissionContext* context,
     87     const GURL& origin_url,
     88     int64 requested_quota,
     89     const std::string& display_languages,
     90     const content::QuotaPermissionContext::PermissionCallback& callback)
     91     : ConfirmInfoBarDelegate(infobar_service),
     92       context_(context),
     93       origin_url_(origin_url),
     94       display_languages_(display_languages),
     95       requested_quota_(requested_quota),
     96       callback_(callback) {
     97 }
     98 
     99 RequestQuotaInfoBarDelegate::~RequestQuotaInfoBarDelegate() {
    100   if (!callback_.is_null()) {
    101     context_->DispatchCallbackOnIOThread(
    102         callback_,
    103         content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
    104   }
    105 }
    106 
    107 bool RequestQuotaInfoBarDelegate::ShouldExpireInternal(
    108     const content::LoadCommittedDetails& details) const {
    109   return false;
    110 }
    111 
    112 string16 RequestQuotaInfoBarDelegate::GetMessageText() const {
    113   // If the site requested larger quota than this threshold, show a different
    114   // message to the user.
    115   const int64 kRequestLargeQuotaThreshold = 5 * 1024 * 1024;
    116   return l10n_util::GetStringFUTF16(
    117       (requested_quota_ > kRequestLargeQuotaThreshold ?
    118           IDS_REQUEST_LARGE_QUOTA_INFOBAR_QUESTION :
    119           IDS_REQUEST_QUOTA_INFOBAR_QUESTION),
    120       net::FormatUrl(origin_url_, display_languages_));
    121 }
    122 
    123 bool RequestQuotaInfoBarDelegate::Accept() {
    124   context_->DispatchCallbackOnIOThread(
    125       callback_,
    126       content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW);
    127   return true;
    128 }
    129 
    130 bool RequestQuotaInfoBarDelegate::Cancel() {
    131   context_->DispatchCallbackOnIOThread(
    132       callback_,
    133       content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
    134   return true;
    135 }
    136 
    137 }  // namespace
    138 
    139 
    140 // ChromeQuotaPermissionContext -----------------------------------------------
    141 
    142 ChromeQuotaPermissionContext::ChromeQuotaPermissionContext() {
    143 }
    144 
    145 void ChromeQuotaPermissionContext::RequestQuotaPermission(
    146     const GURL& origin_url,
    147     quota::StorageType type,
    148     int64 requested_quota,
    149     int render_process_id,
    150     int render_view_id,
    151     const PermissionCallback& callback) {
    152   if (type != quota::kStorageTypePersistent) {
    153     // For now we only support requesting quota with this interface
    154     // for Persistent storage type.
    155     callback.Run(QUOTA_PERMISSION_RESPONSE_DISALLOW);
    156     return;
    157   }
    158 
    159   if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
    160     content::BrowserThread::PostTask(
    161         content::BrowserThread::UI, FROM_HERE,
    162         base::Bind(&ChromeQuotaPermissionContext::RequestQuotaPermission, this,
    163                    origin_url, type, requested_quota, render_process_id,
    164                    render_view_id, callback));
    165     return;
    166   }
    167 
    168   content::WebContents* web_contents =
    169       tab_util::GetWebContentsByID(render_process_id, render_view_id);
    170   if (!web_contents) {
    171     // The tab may have gone away or the request may not be from a tab.
    172     LOG(WARNING) << "Attempt to request quota tabless renderer: "
    173                  << render_process_id << "," << render_view_id;
    174     DispatchCallbackOnIOThread(callback, QUOTA_PERMISSION_RESPONSE_CANCELLED);
    175     return;
    176   }
    177 
    178   InfoBarService* infobar_service =
    179       InfoBarService::FromWebContents(web_contents);
    180   if (!infobar_service) {
    181     // The tab has no infobar service.
    182     LOG(WARNING) << "Attempt to request quota from a background page: "
    183                  << render_process_id << "," << render_view_id;
    184     DispatchCallbackOnIOThread(callback, QUOTA_PERMISSION_RESPONSE_CANCELLED);
    185     return;
    186   }
    187   RequestQuotaInfoBarDelegate::Create(
    188       infobar_service, this, origin_url, requested_quota,
    189       Profile::FromBrowserContext(web_contents->GetBrowserContext())->
    190           GetPrefs()->GetString(prefs::kAcceptLanguages),
    191       callback);
    192 }
    193 
    194 void ChromeQuotaPermissionContext::DispatchCallbackOnIOThread(
    195     const PermissionCallback& callback,
    196     QuotaPermissionResponse response) {
    197   DCHECK_EQ(false, callback.is_null());
    198 
    199   if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
    200     content::BrowserThread::PostTask(
    201         content::BrowserThread::IO, FROM_HERE,
    202         base::Bind(&ChromeQuotaPermissionContext::DispatchCallbackOnIOThread,
    203                    this, callback, response));
    204     return;
    205   }
    206 
    207   callback.Run(response);
    208 }
    209 
    210 ChromeQuotaPermissionContext::~ChromeQuotaPermissionContext() {}
    211