[email protected] | 9f9749a | 2012-03-02 19:37:00 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | 317f96c9 | 2011-05-31 06:53:41 | [diff] [blame] | 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 | |
avi | e4d7b6f | 2015-12-26 00:59:18 | [diff] [blame] | 7 | #include <stdint.h> |
| 8 | |
[email protected] | 317f96c9 | 2011-05-31 06:53:41 | [diff] [blame] | 9 | #include <string> |
| 10 | |
[email protected] | c8d98dd | 2011-10-18 23:12:08 | [diff] [blame] | 11 | #include "base/bind.h" |
avi | e4d7b6f | 2015-12-26 00:59:18 | [diff] [blame] | 12 | #include "base/macros.h" |
[email protected] | 135cb80 | 2013-06-09 16:44:20 | [diff] [blame] | 13 | #include "base/strings/utf_string_conversions.h" |
Eric Seckler | 8652dcd5 | 2018-09-20 10:42:28 | [diff] [blame] | 14 | #include "base/task/post_task.h" |
avi | e4d7b6f | 2015-12-26 00:59:18 | [diff] [blame] | 15 | #include "build/build_config.h" |
tsergeant | 58defcfb | 2016-07-19 23:47:28 | [diff] [blame] | 16 | #include "chrome/browser/permissions/permission_request.h" |
timloh | 5b34b67 | 2017-03-08 01:49:34 | [diff] [blame] | 17 | #include "chrome/browser/permissions/permission_request_manager.h" |
[email protected] | 317f96c9 | 2011-05-31 06:53:41 | [diff] [blame] | 18 | #include "chrome/browser/profiles/profile.h" |
[email protected] | 317f96c9 | 2011-05-31 06:53:41 | [diff] [blame] | 19 | #include "chrome/browser/tab_contents/tab_util.h" |
[email protected] | af39f00 | 2014-08-22 10:18:18 | [diff] [blame] | 20 | #include "chrome/grit/generated_resources.h" |
palmer | a6615c59 | 2015-09-24 00:49:09 | [diff] [blame] | 21 | #include "components/url_formatter/elide_url.h" |
Eric Seckler | 8652dcd5 | 2018-09-20 10:42:28 | [diff] [blame] | 22 | #include "content/public/browser/browser_task_traits.h" |
[email protected] | c38831a1 | 2011-10-28 12:44:49 | [diff] [blame] | 23 | #include "content/public/browser/browser_thread.h" |
[email protected] | 5b96836f | 2011-12-22 07:39:00 | [diff] [blame] | 24 | #include "content/public/browser/navigation_details.h" |
[email protected] | 4f822f02 | 2012-12-20 19:11:42 | [diff] [blame] | 25 | #include "content/public/browser/web_contents.h" |
Blink Reformat | a30d423 | 2018-04-07 15:31:06 | [diff] [blame] | 26 | #include "third_party/blink/public/mojom/quota/quota_types.mojom.h" |
[email protected] | 317f96c9 | 2011-05-31 06:53:41 | [diff] [blame] | 27 | #include "ui/base/l10n/l10n_util.h" |
[email protected] | 761fa470 | 2013-07-02 15:25:15 | [diff] [blame] | 28 | #include "url/gurl.h" |
[email protected] | 317f96c9 | 2011-05-31 06:53:41 | [diff] [blame] | 29 | |
estade | 6d95d1d | 2015-10-02 18:55:23 | [diff] [blame] | 30 | #if defined(OS_ANDROID) |
estade | 20c051a9 | 2016-10-15 22:53:22 | [diff] [blame] | 31 | #include "chrome/browser/android/android_theme_resources.h" |
estade | 6d95d1d | 2015-10-02 18:55:23 | [diff] [blame] | 32 | #else |
Joshua Bell | 82b9c71d | 2017-10-14 00:23:52 | [diff] [blame] | 33 | #include "chrome/app/vector_icons/vector_icons.h" |
Evan Stade | 619a89be | 2017-07-17 20:24:26 | [diff] [blame] | 34 | #include "components/vector_icons/vector_icons.h" |
estade | 6d95d1d | 2015-10-02 18:55:23 | [diff] [blame] | 35 | #endif |
| 36 | |
[email protected] | c032489d | 2014-02-11 19:07:24 | [diff] [blame] | 37 | namespace { |
| 38 | |
timloh | aa3ce26 | 2017-06-01 05:29:40 | [diff] [blame] | 39 | // On Android, if the site requested larger quota than this threshold, show a |
| 40 | // different message to the user. |
avi | e4d7b6f | 2015-12-26 00:59:18 | [diff] [blame] | 41 | const int64_t kRequestLargeQuotaThreshold = 5 * 1024 * 1024; |
[email protected] | c032489d | 2014-02-11 19:07:24 | [diff] [blame] | 42 | |
| 43 | // QuotaPermissionRequest --------------------------------------------- |
| 44 | |
tsergeant | 58defcfb | 2016-07-19 23:47:28 | [diff] [blame] | 45 | class QuotaPermissionRequest : public PermissionRequest { |
[email protected] | c032489d | 2014-02-11 19:07:24 | [diff] [blame] | 46 | public: |
| 47 | QuotaPermissionRequest( |
| 48 | ChromeQuotaPermissionContext* context, |
| 49 | const GURL& origin_url, |
timloh | aa3ce26 | 2017-06-01 05:29:40 | [diff] [blame] | 50 | bool is_large_quota_request_, |
[email protected] | c032489d | 2014-02-11 19:07:24 | [diff] [blame] | 51 | const content::QuotaPermissionContext::PermissionCallback& callback); |
| 52 | |
Daniel Cheng | a542fca | 2014-10-21 09:51:29 | [diff] [blame] | 53 | ~QuotaPermissionRequest() override; |
[email protected] | c032489d | 2014-02-11 19:07:24 | [diff] [blame] | 54 | |
benwells | 46b02fa | 2016-04-20 02:37:02 | [diff] [blame] | 55 | private: |
tsergeant | 58defcfb | 2016-07-19 23:47:28 | [diff] [blame] | 56 | // PermissionRequest: |
estade | 20c051a9 | 2016-10-15 22:53:22 | [diff] [blame] | 57 | IconId GetIconId() const override; |
timloh | aa3ce26 | 2017-06-01 05:29:40 | [diff] [blame] | 58 | #if defined(OS_ANDROID) |
| 59 | base::string16 GetMessageText() const override; |
| 60 | #endif |
Daniel Cheng | a542fca | 2014-10-21 09:51:29 | [diff] [blame] | 61 | base::string16 GetMessageTextFragment() const override; |
johnme | fe4e96d | 2016-01-27 16:14:41 | [diff] [blame] | 62 | GURL GetOrigin() const override; |
Daniel Cheng | a542fca | 2014-10-21 09:51:29 | [diff] [blame] | 63 | void PermissionGranted() override; |
| 64 | void PermissionDenied() override; |
| 65 | void Cancelled() override; |
| 66 | void RequestFinished() override; |
tsergeant | 58defcfb | 2016-07-19 23:47:28 | [diff] [blame] | 67 | PermissionRequestType GetPermissionRequestType() const override; |
[email protected] | c032489d | 2014-02-11 19:07:24 | [diff] [blame] | 68 | |
timloh | aa3ce26 | 2017-06-01 05:29:40 | [diff] [blame] | 69 | const scoped_refptr<ChromeQuotaPermissionContext> context_; |
| 70 | const GURL origin_url_; |
| 71 | const bool is_large_quota_request_; |
[email protected] | c032489d | 2014-02-11 19:07:24 | [diff] [blame] | 72 | content::QuotaPermissionContext::PermissionCallback callback_; |
| 73 | |
| 74 | DISALLOW_COPY_AND_ASSIGN(QuotaPermissionRequest); |
| 75 | }; |
| 76 | |
| 77 | QuotaPermissionRequest::QuotaPermissionRequest( |
| 78 | ChromeQuotaPermissionContext* context, |
| 79 | const GURL& origin_url, |
timloh | aa3ce26 | 2017-06-01 05:29:40 | [diff] [blame] | 80 | bool is_large_quota_request, |
[email protected] | c032489d | 2014-02-11 19:07:24 | [diff] [blame] | 81 | const content::QuotaPermissionContext::PermissionCallback& callback) |
| 82 | : context_(context), |
| 83 | origin_url_(origin_url), |
timloh | aa3ce26 | 2017-06-01 05:29:40 | [diff] [blame] | 84 | is_large_quota_request_(is_large_quota_request), |
| 85 | callback_(callback) { |
| 86 | // Suppress unused private field warning on desktop |
| 87 | (void)is_large_quota_request_; |
| 88 | } |
[email protected] | c032489d | 2014-02-11 19:07:24 | [diff] [blame] | 89 | |
| 90 | QuotaPermissionRequest::~QuotaPermissionRequest() {} |
| 91 | |
estade | 20c051a9 | 2016-10-15 22:53:22 | [diff] [blame] | 92 | PermissionRequest::IconId QuotaPermissionRequest::GetIconId() const { |
estade | 20c051a9 | 2016-10-15 22:53:22 | [diff] [blame] | 93 | #if defined(OS_ANDROID) |
Joshua Bell | 82b9c71d | 2017-10-14 00:23:52 | [diff] [blame] | 94 | return IDR_ANDROID_INFOBAR_FOLDER; |
estade | 20c051a9 | 2016-10-15 22:53:22 | [diff] [blame] | 95 | #else |
Joshua Bell | 82b9c71d | 2017-10-14 00:23:52 | [diff] [blame] | 96 | return kFolderIcon; |
estade | 20c051a9 | 2016-10-15 22:53:22 | [diff] [blame] | 97 | #endif |
[email protected] | d23cdeee | 2014-03-10 06:39:53 | [diff] [blame] | 98 | } |
| 99 | |
timloh | aa3ce26 | 2017-06-01 05:29:40 | [diff] [blame] | 100 | #if defined(OS_ANDROID) |
| 101 | base::string16 QuotaPermissionRequest::GetMessageText() const { |
| 102 | // If the site requested larger quota than this threshold, show a different |
| 103 | // message to the user. |
| 104 | return l10n_util::GetStringFUTF16( |
Peter Kasting | 16ac39a | 2018-01-04 00:48:43 | [diff] [blame] | 105 | (is_large_quota_request_ ? IDS_REQUEST_LARGE_QUOTA_INFOBAR_TEXT |
| 106 | : IDS_REQUEST_QUOTA_INFOBAR_TEXT), |
timloh | aa3ce26 | 2017-06-01 05:29:40 | [diff] [blame] | 107 | url_formatter::FormatUrlForSecurityDisplay(origin_url_)); |
| 108 | } |
| 109 | #endif |
| 110 | |
[email protected] | c032489d | 2014-02-11 19:07:24 | [diff] [blame] | 111 | base::string16 QuotaPermissionRequest::GetMessageTextFragment() const { |
| 112 | return l10n_util::GetStringUTF16(IDS_REQUEST_QUOTA_PERMISSION_FRAGMENT); |
| 113 | } |
| 114 | |
johnme | fe4e96d | 2016-01-27 16:14:41 | [diff] [blame] | 115 | GURL QuotaPermissionRequest::GetOrigin() const { |
[email protected] | d23cdeee | 2014-03-10 06:39:53 | [diff] [blame] | 116 | return origin_url_; |
[email protected] | c032489d | 2014-02-11 19:07:24 | [diff] [blame] | 117 | } |
| 118 | |
| 119 | void QuotaPermissionRequest::PermissionGranted() { |
| 120 | context_->DispatchCallbackOnIOThread( |
| 121 | callback_, |
| 122 | content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW); |
| 123 | callback_ = content::QuotaPermissionContext::PermissionCallback(); |
| 124 | } |
| 125 | |
| 126 | void QuotaPermissionRequest::PermissionDenied() { |
| 127 | context_->DispatchCallbackOnIOThread( |
| 128 | callback_, |
| 129 | content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_DISALLOW); |
| 130 | callback_ = content::QuotaPermissionContext::PermissionCallback(); |
| 131 | } |
| 132 | |
| 133 | void QuotaPermissionRequest::Cancelled() { |
| 134 | } |
| 135 | |
| 136 | void QuotaPermissionRequest::RequestFinished() { |
| 137 | if (!callback_.is_null()) { |
| 138 | context_->DispatchCallbackOnIOThread( |
| 139 | callback_, |
| 140 | content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED); |
| 141 | } |
| 142 | |
| 143 | delete this; |
| 144 | } |
[email protected] | 631bb74 | 2011-11-02 11:29:39 | [diff] [blame] | 145 | |
tsergeant | 58defcfb | 2016-07-19 23:47:28 | [diff] [blame] | 146 | PermissionRequestType QuotaPermissionRequest::GetPermissionRequestType() const { |
| 147 | return PermissionRequestType::QUOTA; |
benwells | 46b02fa | 2016-04-20 02:37:02 | [diff] [blame] | 148 | } |
| 149 | |
[email protected] | 49c71ac | 2013-05-03 01:36:22 | [diff] [blame] | 150 | } // namespace |
| 151 | |
| 152 | |
| 153 | // ChromeQuotaPermissionContext ----------------------------------------------- |
[email protected] | 317f96c9 | 2011-05-31 06:53:41 | [diff] [blame] | 154 | |
[email protected] | 9a88ea99 | 2013-07-10 21:21:57 | [diff] [blame] | 155 | ChromeQuotaPermissionContext::ChromeQuotaPermissionContext() { |
| 156 | } |
[email protected] | 317f96c9 | 2011-05-31 06:53:41 | [diff] [blame] | 157 | |
| 158 | void ChromeQuotaPermissionContext::RequestQuotaPermission( |
[email protected] | f78aa772 | 2014-04-04 00:04:25 | [diff] [blame] | 159 | const content::StorageQuotaParams& params, |
[email protected] | 317f96c9 | 2011-05-31 06:53:41 | [diff] [blame] | 160 | int render_process_id, |
[email protected] | c8d98dd | 2011-10-18 23:12:08 | [diff] [blame] | 161 | const PermissionCallback& callback) { |
Sasha Bermeister | b8957f8 | 2018-01-04 04:17:40 | [diff] [blame] | 162 | if (params.storage_type != blink::mojom::StorageType::kPersistent) { |
[email protected] | 317f96c9 | 2011-05-31 06:53:41 | [diff] [blame] | 163 | // For now we only support requesting quota with this interface |
| 164 | // for Persistent storage type. |
[email protected] | 9f9749a | 2012-03-02 19:37:00 | [diff] [blame] | 165 | callback.Run(QUOTA_PERMISSION_RESPONSE_DISALLOW); |
[email protected] | 317f96c9 | 2011-05-31 06:53:41 | [diff] [blame] | 166 | return; |
| 167 | } |
| 168 | |
[email protected] | 9a88ea99 | 2013-07-10 21:21:57 | [diff] [blame] | 169 | if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) { |
Eric Seckler | 8652dcd5 | 2018-09-20 10:42:28 | [diff] [blame] | 170 | base::PostTaskWithTraits( |
| 171 | FROM_HERE, {content::BrowserThread::UI}, |
tzik | 29ea5c7 | 2017-04-20 02:16:51 | [diff] [blame] | 172 | base::BindOnce(&ChromeQuotaPermissionContext::RequestQuotaPermission, |
| 173 | this, params, render_process_id, callback)); |
[email protected] | 317f96c9 | 2011-05-31 06:53:41 | [diff] [blame] | 174 | return; |
| 175 | } |
| 176 | |
nick | 6206d82 | 2016-12-09 20:05:03 | [diff] [blame] | 177 | content::WebContents* web_contents = tab_util::GetWebContentsByFrameID( |
| 178 | render_process_id, params.render_frame_id); |
[email protected] | 83ff91c | 2012-01-05 20:54:13 | [diff] [blame] | 179 | if (!web_contents) { |
[email protected] | 317f96c9 | 2011-05-31 06:53:41 | [diff] [blame] | 180 | // The tab may have gone away or the request may not be from a tab. |
| 181 | LOG(WARNING) << "Attempt to request quota tabless renderer: " |
nick | 6206d82 | 2016-12-09 20:05:03 | [diff] [blame] | 182 | << render_process_id << "," << params.render_frame_id; |
[email protected] | 9f9749a | 2012-03-02 19:37:00 | [diff] [blame] | 183 | DispatchCallbackOnIOThread(callback, QUOTA_PERMISSION_RESPONSE_CANCELLED); |
[email protected] | 317f96c9 | 2011-05-31 06:53:41 | [diff] [blame] | 184 | return; |
| 185 | } |
| 186 | |
Timothy Loh | 8786fb3 | 2017-09-06 03:04:05 | [diff] [blame] | 187 | PermissionRequestManager* permission_request_manager = |
| 188 | PermissionRequestManager::FromWebContents(web_contents); |
| 189 | if (permission_request_manager) { |
| 190 | bool is_large_quota_request = |
| 191 | params.requested_size > kRequestLargeQuotaThreshold; |
| 192 | permission_request_manager->AddRequest(new QuotaPermissionRequest( |
| 193 | this, params.origin_url, is_large_quota_request, callback)); |
| 194 | return; |
timloh | 5b34b67 | 2017-03-08 01:49:34 | [diff] [blame] | 195 | } |
[email protected] | c032489d | 2014-02-11 19:07:24 | [diff] [blame] | 196 | |
estade | 6d95d1d | 2015-10-02 18:55:23 | [diff] [blame] | 197 | // The tab has no UI service for presenting the permissions request. |
| 198 | LOG(WARNING) << "Attempt to request quota from a background page: " |
nick | 6206d82 | 2016-12-09 20:05:03 | [diff] [blame] | 199 | << render_process_id << "," << params.render_frame_id; |
estade | 6d95d1d | 2015-10-02 18:55:23 | [diff] [blame] | 200 | DispatchCallbackOnIOThread(callback, QUOTA_PERMISSION_RESPONSE_CANCELLED); |
[email protected] | 317f96c9 | 2011-05-31 06:53:41 | [diff] [blame] | 201 | } |
| 202 | |
| 203 | void ChromeQuotaPermissionContext::DispatchCallbackOnIOThread( |
[email protected] | c8d98dd | 2011-10-18 23:12:08 | [diff] [blame] | 204 | const PermissionCallback& callback, |
[email protected] | 9f9749a | 2012-03-02 19:37:00 | [diff] [blame] | 205 | QuotaPermissionResponse response) { |
[email protected] | c8d98dd | 2011-10-18 23:12:08 | [diff] [blame] | 206 | DCHECK_EQ(false, callback.is_null()); |
| 207 | |
[email protected] | 9a88ea99 | 2013-07-10 21:21:57 | [diff] [blame] | 208 | if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) { |
Eric Seckler | 8652dcd5 | 2018-09-20 10:42:28 | [diff] [blame] | 209 | base::PostTaskWithTraits( |
| 210 | FROM_HERE, {content::BrowserThread::IO}, |
tzik | 29ea5c7 | 2017-04-20 02:16:51 | [diff] [blame] | 211 | base::BindOnce( |
| 212 | &ChromeQuotaPermissionContext::DispatchCallbackOnIOThread, this, |
| 213 | callback, response)); |
[email protected] | 317f96c9 | 2011-05-31 06:53:41 | [diff] [blame] | 214 | return; |
| 215 | } |
[email protected] | c8d98dd | 2011-10-18 23:12:08 | [diff] [blame] | 216 | |
| 217 | callback.Run(response); |
[email protected] | 317f96c9 | 2011-05-31 06:53:41 | [diff] [blame] | 218 | } |
[email protected] | 649d1c0 | 2012-04-27 02:56:21 | [diff] [blame] | 219 | |
| 220 | ChromeQuotaPermissionContext::~ChromeQuotaPermissionContext() {} |