123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- // Copyright (c) 2012 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "components/permissions/quota_permission_context_impl.h"
- #include <stdint.h>
- #include <string>
- #include "base/bind.h"
- #include "base/compiler_specific.h"
- #include "build/build_config.h"
- #include "components/permissions/permission_request.h"
- #include "components/permissions/permission_request_manager.h"
- #include "components/permissions/request_type.h"
- #include "components/strings/grit/components_strings.h"
- #include "components/url_formatter/elide_url.h"
- #include "content/public/browser/browser_task_traits.h"
- #include "content/public/browser/browser_thread.h"
- #include "content/public/browser/navigation_details.h"
- #include "content/public/browser/render_frame_host.h"
- #include "content/public/browser/web_contents.h"
- #include "third_party/blink/public/mojom/quota/quota_types.mojom.h"
- #include "ui/base/l10n/l10n_util.h"
- #include "url/gurl.h"
- #if BUILDFLAG(IS_ANDROID)
- #include "components/resources/android/theme_resources.h"
- #else
- #include "components/vector_icons/vector_icons.h"
- #endif
- namespace permissions {
- namespace {
- // On Android, if the site requested larger quota than this threshold, show a
- // different message to the user.
- const int64_t kRequestLargeQuotaThreshold = 5 * 1024 * 1024;
- // QuotaPermissionRequest ---------------------------------------------
- class QuotaPermissionRequest : public PermissionRequest {
- public:
- QuotaPermissionRequest(
- QuotaPermissionContextImpl* context,
- const GURL& requesting_origin,
- bool is_large_quota_request,
- content::QuotaPermissionContext::PermissionCallback callback);
- QuotaPermissionRequest(const QuotaPermissionRequest&) = delete;
- QuotaPermissionRequest& operator=(const QuotaPermissionRequest&) = delete;
- ~QuotaPermissionRequest() override;
- // PermissionRequest:
- bool IsDuplicateOf(PermissionRequest* other_request) const override;
- #if BUILDFLAG(IS_ANDROID)
- std::u16string GetDialogMessageText() const override;
- #endif
- private:
- void PermissionDecided(ContentSetting result, bool is_one_time);
- void DeleteRequest();
- const scoped_refptr<QuotaPermissionContextImpl> context_;
- const bool is_large_quota_request_;
- content::QuotaPermissionContext::PermissionCallback callback_;
- };
- QuotaPermissionRequest::QuotaPermissionRequest(
- QuotaPermissionContextImpl* context,
- const GURL& requesting_origin,
- bool is_large_quota_request,
- content::QuotaPermissionContext::PermissionCallback callback)
- : PermissionRequest(
- requesting_origin,
- permissions::RequestType::kDiskQuota,
- /*has_gesture=*/false,
- base::BindOnce(&QuotaPermissionRequest::PermissionDecided,
- base::Unretained(this)),
- base::BindOnce(&QuotaPermissionRequest::DeleteRequest,
- base::Unretained(this))),
- context_(context),
- is_large_quota_request_(is_large_quota_request),
- callback_(std::move(callback)) {}
- QuotaPermissionRequest::~QuotaPermissionRequest() {}
- bool QuotaPermissionRequest::IsDuplicateOf(
- PermissionRequest* other_request) const {
- // The downcast here is safe because PermissionRequest::IsDuplicateOf ensures
- // that both requests are of type kDiskQuota.
- return permissions::PermissionRequest::IsDuplicateOf(other_request) &&
- is_large_quota_request_ ==
- static_cast<QuotaPermissionRequest*>(other_request)
- ->is_large_quota_request_;
- }
- #if BUILDFLAG(IS_ANDROID)
- std::u16string QuotaPermissionRequest::GetDialogMessageText() const {
- // If the site requested larger quota than this threshold, show a different
- // message to the user.
- return l10n_util::GetStringFUTF16(
- (is_large_quota_request_ ? IDS_REQUEST_LARGE_QUOTA_INFOBAR_TEXT
- : IDS_REQUEST_QUOTA_INFOBAR_TEXT),
- url_formatter::FormatUrlForSecurityDisplay(requesting_origin()));
- }
- #endif // BUILDFLAG(IS_ANDROID)
- void QuotaPermissionRequest::PermissionDecided(ContentSetting result,
- bool is_one_time) {
- DCHECK(!is_one_time);
- if (result == CONTENT_SETTING_DEFAULT) {
- // Handled by `DeleteRequest`.
- return;
- }
- auto response =
- result == ContentSetting::CONTENT_SETTING_ALLOW
- ? content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_ALLOW
- : content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_DISALLOW;
- context_->DispatchCallbackOnIOThread(std::move(callback_), response);
- }
- void QuotaPermissionRequest::DeleteRequest() {
- if (callback_) {
- context_->DispatchCallbackOnIOThread(
- std::move(callback_),
- content::QuotaPermissionContext::QUOTA_PERMISSION_RESPONSE_CANCELLED);
- }
- delete this;
- }
- } // namespace
- // QuotaPermissionContextImpl -----------------------------------------------
- QuotaPermissionContextImpl::QuotaPermissionContextImpl() {}
- void QuotaPermissionContextImpl::RequestQuotaPermission(
- const content::StorageQuotaParams& params,
- int render_process_id,
- PermissionCallback callback) {
- if (params.storage_type != blink::mojom::StorageType::kPersistent) {
- // For now we only support requesting quota with this interface
- // for Persistent storage type.
- std::move(callback).Run(QUOTA_PERMISSION_RESPONSE_DISALLOW);
- return;
- }
- if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
- content::GetUIThreadTaskRunner({})->PostTask(
- FROM_HERE,
- base::BindOnce(&QuotaPermissionContextImpl::RequestQuotaPermission,
- this, params, render_process_id, std::move(callback)));
- return;
- }
- content::RenderFrameHost* render_frame_host =
- content::RenderFrameHost::FromID(render_process_id,
- params.render_frame_id);
- if (!render_frame_host) {
- // The tab may have gone away or the request may not be from a tab.
- LOG(WARNING) << "Attempt to request quota tabless renderer: "
- << render_process_id << "," << params.render_frame_id;
- DispatchCallbackOnIOThread(std::move(callback),
- QUOTA_PERMISSION_RESPONSE_CANCELLED);
- return;
- }
- PermissionRequestManager* permission_request_manager =
- PermissionRequestManager::FromWebContents(
- content::WebContents::FromRenderFrameHost(render_frame_host));
- if (permission_request_manager) {
- bool is_large_quota_request =
- params.requested_size > kRequestLargeQuotaThreshold;
- permission_request_manager->AddRequest(
- render_frame_host, new QuotaPermissionRequest(this, params.origin_url,
- is_large_quota_request,
- std::move(callback)));
- return;
- }
- // The tab has no UI service for presenting the permissions request.
- LOG(WARNING) << "Attempt to request quota from a background page: "
- << render_process_id << "," << params.render_frame_id;
- DispatchCallbackOnIOThread(std::move(callback),
- QUOTA_PERMISSION_RESPONSE_CANCELLED);
- }
- void QuotaPermissionContextImpl::DispatchCallbackOnIOThread(
- PermissionCallback callback,
- QuotaPermissionResponse response) {
- DCHECK(callback);
- if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)) {
- content::GetIOThreadTaskRunner({})->PostTask(
- FROM_HERE,
- base::BindOnce(&QuotaPermissionContextImpl::DispatchCallbackOnIOThread,
- this, std::move(callback), response));
- return;
- }
- std::move(callback).Run(response);
- }
- QuotaPermissionContextImpl::~QuotaPermissionContextImpl() {}
- } // namespace permissions
|