diff options
Diffstat (limited to 'chromium/components/permissions/contexts')
6 files changed, 217 insertions, 51 deletions
diff --git a/chromium/components/permissions/contexts/OWNERS b/chromium/components/permissions/contexts/OWNERS new file mode 100644 index 00000000000..4862047cfa4 --- /dev/null +++ b/chromium/components/permissions/contexts/OWNERS @@ -0,0 +1,6 @@ +file://components/permissions/PERMISSIONS_OWNERS + +per-file *webxr_permission_context*=file://content/browser/xr/OWNERS + +# COMPONENT: Internals>Permissions +# TEAM: permissions-dev@chromium.org diff --git a/chromium/components/permissions/contexts/geolocation_permission_context.cc b/chromium/components/permissions/contexts/geolocation_permission_context.cc index ece50351c21..b62512c32ad 100644 --- a/chromium/components/permissions/contexts/geolocation_permission_context.cc +++ b/chromium/components/permissions/contexts/geolocation_permission_context.cc @@ -43,6 +43,11 @@ void GeolocationPermissionContext::DecidePermission( } } +base::WeakPtr<GeolocationPermissionContext> +GeolocationPermissionContext::GetWeakPtr() { + return weak_factory_.GetWeakPtr(); +} + void GeolocationPermissionContext::UpdateTabContext( const PermissionRequestID& id, const GURL& requesting_frame, diff --git a/chromium/components/permissions/contexts/geolocation_permission_context.h b/chromium/components/permissions/contexts/geolocation_permission_context.h index 6e86b9c215b..bbe8af336ce 100644 --- a/chromium/components/permissions/contexts/geolocation_permission_context.h +++ b/chromium/components/permissions/contexts/geolocation_permission_context.h @@ -7,6 +7,7 @@ #include "base/callback.h" #include "base/macros.h" +#include "base/memory/weak_ptr.h" #include "build/build_config.h" #include "components/content_settings/core/common/content_settings.h" #include "components/permissions/permission_context_base.h" @@ -69,6 +70,8 @@ class GeolocationPermissionContext : public PermissionContextBase { bool user_gesture, BrowserPermissionCallback callback) override; + base::WeakPtr<GeolocationPermissionContext> GetWeakPtr(); + // Make this public for use by the delegate implementation. using PermissionContextBase::NotifyPermissionSet; @@ -85,6 +88,8 @@ class GeolocationPermissionContext : public PermissionContextBase { mojo::Remote<device::mojom::GeolocationControl> geolocation_control_; + base::WeakPtrFactory<GeolocationPermissionContext> weak_factory_{this}; + DISALLOW_COPY_AND_ASSIGN(GeolocationPermissionContext); }; diff --git a/chromium/components/permissions/contexts/geolocation_permission_context_unittest.cc b/chromium/components/permissions/contexts/geolocation_permission_context_unittest.cc index f1102df0a98..8aec360f714 100644 --- a/chromium/components/permissions/contexts/geolocation_permission_context_unittest.cc +++ b/chromium/components/permissions/contexts/geolocation_permission_context_unittest.cc @@ -29,6 +29,7 @@ #include "build/build_config.h" #include "components/content_settings/browser/content_settings_usages_state.h" #include "components/content_settings/browser/tab_specific_content_settings.h" +#include "components/content_settings/browser/test_tab_specific_content_settings_delegate.h" #include "components/content_settings/core/browser/host_content_settings_map.h" #include "components/permissions/features.h" #include "components/permissions/permission_context_base.h" @@ -115,55 +116,6 @@ class TestGeolocationPermissionContextDelegate TestingPrefServiceSimple prefs_; base::Optional<url::Origin> dse_origin_; }; - -class TestTabSpecificContentSettingsDelegate - : public content_settings::TabSpecificContentSettings::Delegate { - public: - explicit TestTabSpecificContentSettingsDelegate( - content::BrowserContext* browser_context) - : browser_context_(browser_context) {} - - // content_settings::TabSpecificContentSettings::Delegate: - void UpdateLocationBar() override {} - - void SetContentSettingRules( - content::RenderProcessHost* process, - const RendererContentSettingRules& rules) override {} - - PrefService* GetPrefs() override { return nullptr; } - - HostContentSettingsMap* GetSettingsMap() override { - return PermissionsClient::Get()->GetSettingsMap(browser_context_); - } - - std::vector<storage::FileSystemType> GetAdditionalFileSystemTypes() override { - return {}; - } - - browsing_data::CookieHelper::IsDeletionDisabledCallback - GetIsDeletionDisabledCallback() override { - return base::NullCallback(); - } - - bool IsMicrophoneCameraStateChanged( - content_settings::TabSpecificContentSettings::MicrophoneCameraState - microphone_camera_state, - const std::string& media_stream_selected_audio_device, - const std::string& media_stream_selected_video_device) override { - return false; - } - - content_settings::TabSpecificContentSettings::MicrophoneCameraState - GetMicrophoneCameraState() override { - return content_settings::TabSpecificContentSettings:: - MICROPHONE_CAMERA_NOT_ACCESSED; - } - - void OnContentBlocked(ContentSettingsType type) override {} - - private: - content::BrowserContext* browser_context_; -}; } // namespace // GeolocationPermissionContextTests ------------------------------------------ @@ -317,8 +269,11 @@ void GeolocationPermissionContextTests::SetUp() { RenderViewHostTestHarness::SetUp(); content_settings::TabSpecificContentSettings::CreateForWebContents( - web_contents(), std::make_unique<TestTabSpecificContentSettingsDelegate>( - browser_context())); + web_contents(), + std::make_unique< + content_settings::TestTabSpecificContentSettingsDelegate>( + /*prefs=*/nullptr, + PermissionsClient::Get()->GetSettingsMap(browser_context()))); auto delegate = std::make_unique<TestGeolocationPermissionContextDelegate>( browser_context()); diff --git a/chromium/components/permissions/contexts/webxr_permission_context.cc b/chromium/components/permissions/contexts/webxr_permission_context.cc new file mode 100644 index 00000000000..82227fa9f66 --- /dev/null +++ b/chromium/components/permissions/contexts/webxr_permission_context.cc @@ -0,0 +1,136 @@ +// Copyright 2019 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/contexts/webxr_permission_context.h" + +#include "base/check.h" +#include "third_party/blink/public/mojom/feature_policy/feature_policy.mojom.h" + +#if defined(OS_ANDROID) +#include "components/permissions/android/android_permission_util.h" +#include "components/permissions/permission_request_id.h" +#include "components/permissions/permissions_client.h" +#include "content/public/browser/web_contents.h" +#endif + +namespace permissions { +WebXrPermissionContext::WebXrPermissionContext( + content::BrowserContext* browser_context, + ContentSettingsType content_settings_type) + : PermissionContextBase(browser_context, + content_settings_type, + blink::mojom::FeaturePolicyFeature::kWebXr), + content_settings_type_(content_settings_type) { + DCHECK(content_settings_type_ == ContentSettingsType::VR || + content_settings_type_ == ContentSettingsType::AR); +} + +WebXrPermissionContext::~WebXrPermissionContext() = default; + +bool WebXrPermissionContext::IsRestrictedToSecureOrigins() const { + return true; +} + +#if defined(OS_ANDROID) +// There are two other permissions that need to check corresponding OS-level +// permissions, and they take two different approaches to this. Geolocation only +// stores the permission ContentSetting if both requests are granted (or if the +// site permission is "Block"). The media permissions follow something more +// similar to this approach, first querying and storing the site-specific +// ContentSetting and then querying for the additional OS permissions as needed. +// However, this is done in MediaStreamDevicesController, not their permission +// context. By persisting and then running additional code as needed, we thus +// mimic that flow, but keep all logic contained into the permission context +// class. +void WebXrPermissionContext::NotifyPermissionSet( + const PermissionRequestID& id, + const GURL& requesting_origin, + const GURL& embedding_origin, + BrowserPermissionCallback callback, + bool persist, + ContentSetting content_setting) { + // Only AR needs to check for additional permissions, and then only if it was + // actually allowed. + if (!(content_settings_type_ == ContentSettingsType::AR && + content_setting == ContentSetting::CONTENT_SETTING_ALLOW)) { + PermissionContextBase::NotifyPermissionSet( + id, requesting_origin, embedding_origin, std::move(callback), persist, + content_setting); + return; + } + + // Whether or not the user will ultimately accept the OS permissions, we want + // to save the content_setting here if we should. + if (persist) { + PermissionContextBase::UpdateContentSetting( + requesting_origin, embedding_origin, content_setting); + } + + content::WebContents* web_contents = + content::WebContents::FromRenderFrameHost( + content::RenderFrameHost::FromID(id.render_process_id(), + id.render_frame_id())); + if (!web_contents) { + // If we can't get the web contents, we don't know the state of the OS + // permission, so assume we don't have it. + OnAndroidPermissionDecided(id, requesting_origin, embedding_origin, + std::move(callback), + false /*permission_granted*/); + return; + } + + // Otherwise, the user granted permission to use AR, so now we need to check + // if we need to prompt for android system permissions. + std::vector<ContentSettingsType> permission_type = {content_settings_type_}; + PermissionRepromptState reprompt_state = + ShouldRepromptUserForPermissions(web_contents, permission_type); + switch (reprompt_state) { + case PermissionRepromptState::kNoNeed: + // We have already returned if permission was denied by the user, and this + // indicates that we have all the OS permissions we need. + OnAndroidPermissionDecided(id, requesting_origin, embedding_origin, + std::move(callback), + true /*permission_granted*/); + return; + + case PermissionRepromptState::kCannotShow: + // If we cannot show the info bar, then we have to assume we don't have + // the permissions we need. + OnAndroidPermissionDecided(id, requesting_origin, embedding_origin, + std::move(callback), + false /*permission_granted*/); + return; + + case PermissionRepromptState::kShow: + // Otherwise, prompt the user that we need additional permissions. + PermissionsClient::Get()->RepromptForAndroidPermissions( + web_contents, permission_type, + base::BindOnce(&WebXrPermissionContext::OnAndroidPermissionDecided, + weak_ptr_factory_.GetWeakPtr(), id, requesting_origin, + embedding_origin, std::move(callback))); + return; + } +} + +void WebXrPermissionContext::OnAndroidPermissionDecided( + const PermissionRequestID& id, + const GURL& requesting_origin, + const GURL& embedding_origin, + BrowserPermissionCallback callback, + bool permission_granted) { + // If we were supposed to persist the setting we've already done so in the + // initial override of |NotifyPermissionSet|. At this point, if the user + // has denied the OS level permission, we want to notify the requestor that + // the permission has been blocked. + // TODO(https://crbug.com/1060163): Ensure that this is taken into account + // when returning navigator.permissions results. + ContentSetting setting = permission_granted + ? ContentSetting::CONTENT_SETTING_ALLOW + : ContentSetting::CONTENT_SETTING_BLOCK; + PermissionContextBase::NotifyPermissionSet( + id, requesting_origin, embedding_origin, std::move(callback), + false /*persist*/, setting); +} +#endif // defined(OS_ANDROID) +} // namespace permissions diff --git a/chromium/components/permissions/contexts/webxr_permission_context.h b/chromium/components/permissions/contexts/webxr_permission_context.h new file mode 100644 index 00000000000..467a6404413 --- /dev/null +++ b/chromium/components/permissions/contexts/webxr_permission_context.h @@ -0,0 +1,59 @@ +// Copyright 2019 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. + +#ifndef COMPONENTS_PERMISSIONS_CONTEXTS_WEBXR_PERMISSION_CONTEXT_H_ +#define COMPONENTS_PERMISSIONS_CONTEXTS_WEBXR_PERMISSION_CONTEXT_H_ + +#include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "build/build_config.h" +#include "components/content_settings/core/common/content_settings_types.h" +#include "components/permissions/permission_context_base.h" + +namespace permissions { +class WebXrPermissionContext : public PermissionContextBase { + public: + WebXrPermissionContext(content::BrowserContext* browser_context, + ContentSettingsType content_settings_type); + ~WebXrPermissionContext() override; + WebXrPermissionContext(const WebXrPermissionContext&) = delete; + WebXrPermissionContext& operator=(const WebXrPermissionContext&) = delete; + + private: + // PermissionContextBase: + bool IsRestrictedToSecureOrigins() const override; + +#if defined(OS_ANDROID) + // On Android we need to do some additional checking for OS level permissions, + // which do not need to happen on Desktop. Note that NotifyPermissionSet is + // only called after a "RequestPermission" call (and not if we are just + // checking the state of the permission), however, the requestSession flow + // requires checking the permission as one of it's steps: (5.6 as of 03/10/20) + // https://immersive-web.github.io/webxr/#dom-xrsystem-requestsession + // When implementing navigator.xr.permission methods, we should ensure that + // GetPermissionStatus is also updated to check these permissions. + void NotifyPermissionSet(const PermissionRequestID& id, + const GURL& requesting_origin, + const GURL& embedding_origin, + BrowserPermissionCallback callback, + bool persist, + ContentSetting content_setting) override; + + void OnAndroidPermissionDecided(const PermissionRequestID& id, + const GURL& requesting_origin, + const GURL& embedding_origin, + BrowserPermissionCallback callback, + bool permission_granted); +#endif + + ContentSettingsType content_settings_type_; + + // Must be the last member, to ensure that it will be + // destroyed first, which will invalidate weak pointers + base::WeakPtrFactory<WebXrPermissionContext> weak_ptr_factory_{this}; +}; + +} // namespace permissions + +#endif // COMPONENTS_PERMISSIONS_CONTEXTS_WEBXR_PERMISSION_CONTEXT_H_ |