[go: nahoru, domu]

blob: acaa0263ad2154ce940a03ab36a06f0d5a45cfbf [file] [log] [blame]
mlamouri4ebe69f2014-11-14 17:25:211// Copyright 2014 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 "content/browser/permissions/permission_service_context.h"
6
dcheng36b6aec92015-12-26 06:16:367#include <utility>
8
Sebastien Marchandf8cbfab2019-01-25 16:02:309#include "base/bind.h"
Keishi Hattori0e45c022021-11-27 09:25:5210#include "base/memory/raw_ptr.h"
Andrey Lushnikovebff0442018-07-12 20:02:5811#include "content/browser/permissions/permission_controller_impl.h"
mlamouri4ebe69f2014-11-14 17:25:2112#include "content/browser/permissions/permission_service_impl.h"
Illia Klimov7709f0c2021-07-05 09:42:3913#include "content/browser/permissions/permission_util.h"
reillyg86dfcea2017-01-04 22:27:5714#include "content/public/browser/browser_context.h"
jam5c2473dc2017-02-06 15:51:2115#include "content/public/browser/navigation_handle.h"
mlamouri4ebe69f2014-11-14 17:25:2116#include "content/public/browser/render_frame_host.h"
timvolodine089c07c2014-12-11 19:32:2617#include "content/public/browser/render_process_host.h"
mlamouri4ebe69f2014-11-14 17:25:2118#include "content/public/browser/web_contents.h"
Mario Sanchez Prada97f66162019-08-06 21:56:4819#include "mojo/public/cpp/bindings/remote.h"
Andy Paicubdb19c72022-04-22 09:24:3120#include "url/origin.h"
reillyg86dfcea2017-01-04 22:27:5721
mlamouri4ebe69f2014-11-14 17:25:2122namespace content {
23
Alexander Timin72a2f0c2021-10-01 01:56:0724// A holder owning document-associated PermissionServiceContext. The holder is
25// used as PermissionServiceContext itself can't inherit from
Sreeja Kamishetty0a0961f2021-10-11 16:23:5326// DocumentUserData, as PermissionServiceContext (unlike
27// DocumentUserData) can be created when RenderFrameHost doesn't exist
Alexander Timin72a2f0c2021-10-01 01:56:0728// (e.g. for service workers).
29struct PermissionServiceContext::DocumentPermissionServiceContextHolder
Sreeja Kamishetty0a0961f2021-10-11 16:23:5330 : public DocumentUserData<DocumentPermissionServiceContextHolder> {
Lukasz Anforowiczcfeb95c2021-10-01 19:33:3531 explicit DocumentPermissionServiceContextHolder(RenderFrameHost* rfh)
Sreeja Kamishetty0a0961f2021-10-11 16:23:5332 : DocumentUserData<DocumentPermissionServiceContextHolder>(rfh),
Lukasz Anforowiczcfeb95c2021-10-01 19:33:3533 permission_service_context(rfh) {}
Alexander Timin72a2f0c2021-10-01 01:56:0734
35 PermissionServiceContext permission_service_context;
36
Sreeja Kamishetty0a0961f2021-10-11 16:23:5337 DOCUMENT_USER_DATA_KEY_DECL();
Alexander Timin72a2f0c2021-10-01 01:56:0738};
39
Sreeja Kamishetty0a0961f2021-10-11 16:23:5340DOCUMENT_USER_DATA_KEY_IMPL(
Daniel Cheng383df852021-10-02 03:28:0141 PermissionServiceContext::DocumentPermissionServiceContextHolder);
Alexander Timin72a2f0c2021-10-01 01:56:0742
reillyg86dfcea2017-01-04 22:27:5743class PermissionServiceContext::PermissionSubscription {
44 public:
Mario Sanchez Prada97f66162019-08-06 21:56:4845 PermissionSubscription(
46 PermissionServiceContext* context,
47 mojo::PendingRemote<blink::mojom::PermissionObserver> observer)
reillyg86dfcea2017-01-04 22:27:5748 : context_(context), observer_(std::move(observer)) {
Mario Sanchez Prada97f66162019-08-06 21:56:4849 observer_.set_disconnect_handler(base::BindOnce(
reillyg86dfcea2017-01-04 22:27:5750 &PermissionSubscription::OnConnectionError, base::Unretained(this)));
51 }
Lei Zhang67b7bf32019-10-08 18:46:0152 PermissionSubscription(const PermissionSubscription&) = delete;
53 PermissionSubscription& operator=(const PermissionSubscription&) = delete;
reillyg86dfcea2017-01-04 22:27:5754
reillyg9c28b5c2017-01-06 20:51:3155 ~PermissionSubscription() {
Balazs Engedyad1489b2021-03-31 07:47:1956 DCHECK(id_);
reillyg9c28b5c2017-01-06 20:51:3157 BrowserContext* browser_context = context_->GetBrowserContext();
Andrey Lushnikovebff0442018-07-12 20:02:5858 if (browser_context) {
59 PermissionControllerImpl::FromBrowserContext(browser_context)
reillyg9c28b5c2017-01-06 20:51:3160 ->UnsubscribePermissionStatusChange(id_);
61 }
62 }
reillyg86dfcea2017-01-04 22:27:5763
64 void OnConnectionError() {
Balazs Engedyad1489b2021-03-31 07:47:1965 DCHECK(id_);
reillyg86dfcea2017-01-04 22:27:5766 context_->ObserverHadConnectionError(id_);
67 }
68
69 void OnPermissionStatusChanged(blink::mojom::PermissionStatus status) {
Ravjit Singh Uppale306d3fa2021-07-05 13:47:4570 if (observer_.is_connected())
71 observer_->OnPermissionStatusChange(status);
reillyg86dfcea2017-01-04 22:27:5772 }
73
Balazs Engedyad1489b2021-03-31 07:47:1974 void set_id(PermissionController::SubscriptionId id) { id_ = id; }
reillyg86dfcea2017-01-04 22:27:5775
76 private:
Keishi Hattori0e45c022021-11-27 09:25:5277 const raw_ptr<PermissionServiceContext> context_;
Mario Sanchez Prada97f66162019-08-06 21:56:4878 mojo::Remote<blink::mojom::PermissionObserver> observer_;
Balazs Engedyad1489b2021-03-31 07:47:1979 PermissionController::SubscriptionId id_;
reillyg86dfcea2017-01-04 22:27:5780};
81
Alexander Timin72a2f0c2021-10-01 01:56:0782// static
83PermissionServiceContext* PermissionServiceContext::GetForCurrentDocument(
84 RenderFrameHost* render_frame_host) {
85 return &DocumentPermissionServiceContextHolder::GetOrCreateForCurrentDocument(
86 render_frame_host)
87 ->permission_service_context;
88}
Carlos Caballeroa09553482021-03-17 15:51:0689
mlamouri4ebe69f2014-11-14 17:25:2190PermissionServiceContext::PermissionServiceContext(
91 RenderFrameHost* render_frame_host)
Ravjit715c2b42021-07-15 15:25:0192 : render_frame_host_(render_frame_host), render_process_host_(nullptr) {
93 render_frame_host->GetProcess()->AddObserver(this);
94}
timvolodine089c07c2014-12-11 19:32:2695
96PermissionServiceContext::PermissionServiceContext(
97 RenderProcessHost* render_process_host)
Carlos Caballeroa09553482021-03-17 15:51:0698 : render_frame_host_(nullptr), render_process_host_(render_process_host) {}
mlamouri4ebe69f2014-11-14 17:25:2199
100PermissionServiceContext::~PermissionServiceContext() {
Ravjit715c2b42021-07-15 15:25:01101 if (render_frame_host_)
102 render_frame_host_->GetProcess()->RemoveObserver(this);
mlamouri4ebe69f2014-11-14 17:25:21103}
104
105void PermissionServiceContext::CreateService(
Mario Sanchez Prada97f66162019-08-06 21:56:48106 mojo::PendingReceiver<blink::mojom::PermissionService> receiver) {
Sam McNally2e5c71f2017-12-11 03:24:27107 DCHECK(render_frame_host_);
Andy Paicubdb19c72022-04-22 09:24:31108 services_.Add(
109 std::make_unique<PermissionServiceImpl>(
110 this, url::Origin::Create(PermissionUtil::GetLastCommittedOriginAsURL(
111 render_frame_host_))),
112 std::move(receiver));
Sam McNally2e5c71f2017-12-11 03:24:27113}
114
115void PermissionServiceContext::CreateServiceForWorker(
Miyoung Shine676be1f2019-09-25 00:47:02116 const url::Origin& origin,
117 mojo::PendingReceiver<blink::mojom::PermissionService> receiver) {
Mario Sanchez Prada97f66162019-08-06 21:56:48118 services_.Add(std::make_unique<PermissionServiceImpl>(this, origin),
119 std::move(receiver));
reillyg86dfcea2017-01-04 22:27:57120}
121
122void PermissionServiceContext::CreateSubscription(
123 PermissionType permission_type,
124 const url::Origin& origin,
Mario Sanchez Prada97f66162019-08-06 21:56:48125 blink::mojom::PermissionStatus current_status,
126 blink::mojom::PermissionStatus last_known_status,
127 mojo::PendingRemote<blink::mojom::PermissionObserver> observer) {
reillyg86dfcea2017-01-04 22:27:57128 BrowserContext* browser_context = GetBrowserContext();
Andrey Lushnikovebff0442018-07-12 20:02:58129 if (!browser_context)
reillyg86dfcea2017-01-04 22:27:57130 return;
131
132 auto subscription =
Jeremy Roman04f27c372017-10-27 15:20:55133 std::make_unique<PermissionSubscription>(this, std::move(observer));
Mario Sanchez Prada97f66162019-08-06 21:56:48134
135 if (current_status != last_known_status) {
136 subscription->OnPermissionStatusChanged(current_status);
137 last_known_status = current_status;
138 }
139
reillyg86dfcea2017-01-04 22:27:57140 GURL requesting_origin(origin.Serialize());
Balazs Engedyad1489b2021-03-31 07:47:19141 auto subscription_id =
Andrey Lushnikovebff0442018-07-12 20:02:58142 PermissionControllerImpl::FromBrowserContext(browser_context)
143 ->SubscribePermissionStatusChange(
Robbie McElrath8d5602a2022-04-01 17:39:18144 permission_type, render_process_host_, render_frame_host_,
145 requesting_origin,
Lei Zhang67b7bf32019-10-08 18:46:01146 base::BindRepeating(
147 &PermissionSubscription::OnPermissionStatusChanged,
148 base::Unretained(subscription.get())));
reillyg86dfcea2017-01-04 22:27:57149 subscription->set_id(subscription_id);
150 subscriptions_[subscription_id] = std::move(subscription);
mlamouri4ebe69f2014-11-14 17:25:21151}
152
Balazs Engedyad1489b2021-03-31 07:47:19153void PermissionServiceContext::ObserverHadConnectionError(
154 PermissionController::SubscriptionId subscription_id) {
Lei Zhang67b7bf32019-10-08 18:46:01155 size_t erased = subscriptions_.erase(subscription_id);
156 DCHECK_EQ(1u, erased);
reillyg86dfcea2017-01-04 22:27:57157}
158
timvolodine089c07c2014-12-11 19:32:26159BrowserContext* PermissionServiceContext::GetBrowserContext() const {
Carlos Caballeroa09553482021-03-17 15:51:06160 if (render_frame_host_)
161 return render_frame_host_->GetBrowserContext();
Dominic Mazzoni94e567bf2017-08-29 18:07:02162
163 if (render_process_host_)
timvolodine089c07c2014-12-11 19:32:26164 return render_process_host_->GetBrowserContext();
Dominic Mazzoni94e567bf2017-08-29 18:07:02165
166 return nullptr;
timvolodine089c07c2014-12-11 19:32:26167}
168
169GURL PermissionServiceContext::GetEmbeddingOrigin() const {
Henrique Ferreirof89870f2022-03-30 17:08:13170 return render_frame_host_ ? PermissionUtil::GetLastCommittedOriginAsURL(
171 render_frame_host_->GetMainFrame())
172 : GURL();
timvolodine089c07c2014-12-11 19:32:26173}
174
Ravjit715c2b42021-07-15 15:25:01175void PermissionServiceContext::RenderProcessHostDestroyed(
176 RenderProcessHost* host) {
177 DCHECK(host == render_frame_host_->GetProcess());
178 subscriptions_.clear();
179 // RenderProcessHostImpl will always outlive 'this', but it gets cleaned up
180 // earlier so we need to listen to this event so we can do our clean up as
181 // well.
182 host->RemoveObserver(this);
183}
184
Lei Zhang67b7bf32019-10-08 18:46:01185} // namespace content