blob: d0f0f580e9446ac84cc9f04bee259f3c83fc7533 [file] [log] [blame]
// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/background_fetch/background_fetch_permission_context.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/download/download_request_limiter.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/web_contents.h"
#include "services/network/public/mojom/permissions_policy/permissions_policy_feature.mojom.h"
BackgroundFetchPermissionContext::BackgroundFetchPermissionContext(
content::BrowserContext* browser_context)
: ContentSettingPermissionContextBase(
browser_context,
ContentSettingsType::BACKGROUND_FETCH,
network::mojom::PermissionsPolicyFeature::kNotFound) {}
ContentSetting
BackgroundFetchPermissionContext::GetContentSettingStatusInternal(
content::RenderFrameHost* render_frame_host,
const GURL& requesting_origin,
const GURL& embedding_origin) const {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
if (render_frame_host && !render_frame_host->GetParent()) {
DownloadRequestLimiter* limiter =
g_browser_process->download_request_limiter();
DCHECK(limiter);
auto status = limiter->GetDownloadStatus(
content::WebContents::FromRenderFrameHost(render_frame_host));
switch (status) {
case DownloadRequestLimiter::DownloadStatus::ALLOW_ONE_DOWNLOAD:
case DownloadRequestLimiter::DownloadStatus::ALLOW_ALL_DOWNLOADS:
return CONTENT_SETTING_ALLOW;
case DownloadRequestLimiter::DownloadStatus::PROMPT_BEFORE_DOWNLOAD:
return CONTENT_SETTING_ASK;
case DownloadRequestLimiter::DownloadStatus::DOWNLOADS_NOT_ALLOWED:
return CONTENT_SETTING_BLOCK;
}
NOTREACHED();
}
// |render_frame_host| is either a nullptr, which means we're being called
// from a worker context, or it's not a top level frame. In either case, use
// content settings.
auto* host_content_settings_map =
HostContentSettingsMapFactory::GetForProfile(browser_context());
DCHECK(host_content_settings_map);
// The set of valid settings for automatic downloads is defined as
// {CONTENT_SETTING_ALLOW, CONTENT_SETTING_ASK, CONTENT_SETTING_BLOCK}.
ContentSetting setting = host_content_settings_map->GetContentSetting(
requesting_origin, requesting_origin,
ContentSettingsType::AUTOMATIC_DOWNLOADS);
// Due to privacy concerns as outlined in https://crbug.com/896311 the most
// permissive state BGF can be in for non top level frames or service workers
// is ASK. This causes background fetches that do not originate in a main
// frame to start paused.
if (setting == CONTENT_SETTING_ALLOW)
setting = CONTENT_SETTING_ASK;
return setting;
}
void BackgroundFetchPermissionContext::DecidePermission(
std::unique_ptr<permissions::PermissionRequestData> request_data,
permissions::BrowserPermissionCallback callback) {
// The user should never be prompted to authorize Background Fetch
// from BackgroundFetchPermissionContext.
// BackgroundFetchDelegateImpl invokes CanDownload() on DownloadRequestLimiter
// to prompt the user.
NOTREACHED();
}
void BackgroundFetchPermissionContext::NotifyPermissionSet(
const permissions::PermissionRequestData& request_data,
permissions::BrowserPermissionCallback callback,
bool persist,
PermissionDecision decision,
bool is_final_decision) {
DCHECK(!persist);
DCHECK(is_final_decision);
permissions::ContentSettingPermissionContextBase::NotifyPermissionSet(
request_data, std::move(callback), persist, decision, is_final_decision);
}