blob: 7f8de6195dbc1f6d3d7928ed5a8da0ae1dd82687 [file] [log] [blame]
Avi Drissman4e1b7bc32022-09-15 14:03:501// Copyright 2017 The Chromium Authors
Conley Owens47f4fbf12017-08-02 01:56:522// 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/geolocation/geolocation_service_impl.h"
6
Jan Wilken Dörrie1494205b2020-03-26 09:32:537#include <utility>
8
Avi Drissmanadac21992023-01-11 23:46:399#include "base/functional/bind.h"
Florian Jacky80e35302023-09-15 16:40:4210#include "content/browser/permissions/permission_controller_impl.h"
Illia Klimova181b7d2022-03-15 08:17:4711#include "content/public/browser/browser_context.h"
12#include "content/public/browser/permission_controller.h"
Florian Jacky65b7d102025-04-07 10:02:5213#include "content/public/browser/permission_descriptor_util.h"
Andy Paicu0a6d4b502023-08-29 15:13:0914#include "content/public/browser/permission_request_description.h"
Conley Owens47f4fbf12017-08-02 01:56:5215#include "content/public/browser/render_frame_host.h"
Mario Sanchez Pradafa6dda8c2019-11-25 18:20:1916#include "content/public/browser/render_process_host.h"
Matt Reynoldsf10fd2f2019-04-01 19:39:2917#include "mojo/public/cpp/bindings/callback_helpers.h"
Florian Jacky80e35302023-09-15 16:40:4218#include "services/device/public/mojom/geoposition.mojom.h"
Sandor «Alex» Majorc41217f2025-02-14 23:33:1319#include "services/network/public/mojom/permissions_policy/permissions_policy_feature.mojom.h"
Andy Paicua6d6d852022-04-28 18:08:3620#include "third_party/blink/public/common/permissions/permission_utils.h"
Conley Owens47f4fbf12017-08-02 01:56:5221
Alvin Ji0ff27272024-03-13 21:57:2722#if BUILDFLAG(IS_IOS)
23#include "services/device/public/cpp/geolocation/geolocation_system_permission_manager.h"
24#endif
25
Conley Owens47f4fbf12017-08-02 01:56:5226namespace content {
27
Illia Klimova181b7d2022-03-15 08:17:4728GeolocationServiceImplContext::GeolocationServiceImplContext() = default;
Conley Owens47f4fbf12017-08-02 01:56:5229
Illia Klimova181b7d2022-03-15 08:17:4730GeolocationServiceImplContext::~GeolocationServiceImplContext() = default;
Conley Owens47f4fbf12017-08-02 01:56:5231
32void GeolocationServiceImplContext::RequestPermission(
33 RenderFrameHost* render_frame_host,
34 bool user_gesture,
WangHui4dafed922021-03-09 01:02:1735 PermissionCallback callback) {
Balazs Engedye30e9612021-04-02 10:37:2936 if (has_pending_permission_request_) {
Conley Owens9613ff9a2017-11-27 21:06:5537 mojo::ReportBadMessage(
38 "GeolocationService client may only create one Geolocation at a "
39 "time.");
40 return;
41 }
42
Balazs Engedye30e9612021-04-02 10:37:2943 has_pending_permission_request_ = true;
Illia Klimova181b7d2022-03-15 08:17:4744
45 render_frame_host->GetBrowserContext()
46 ->GetPermissionController()
47 ->RequestPermissionFromCurrentDocument(
Andy Paicu0a6d4b502023-08-29 15:13:0948 render_frame_host,
Florian Jacky65b7d102025-04-07 10:02:5249 PermissionRequestDescription(
50 content::PermissionDescriptorUtil::
51 CreatePermissionDescriptorForPermissionType(
52 blink::PermissionType::GEOLOCATION),
53 user_gesture),
Florian Jackyaaf42832025-08-19 04:03:2654 base::BindOnce(&GeolocationServiceImplContext::HandlePermissionResult,
Illia Klimova181b7d2022-03-15 08:17:4755 weak_factory_.GetWeakPtr(), std::move(callback)));
Conley Owens47f4fbf12017-08-02 01:56:5256}
57
Florian Jackyaaf42832025-08-19 04:03:2658void GeolocationServiceImplContext::HandlePermissionResult(
WangHui4dafed922021-03-09 01:02:1759 PermissionCallback callback,
Florian Jackyaaf42832025-08-19 04:03:2660 PermissionResult permission_result) {
Balazs Engedye30e9612021-04-02 10:37:2961 has_pending_permission_request_ = false;
Florian Jackyaaf42832025-08-19 04:03:2662 std::move(callback).Run(permission_result);
Conley Owens47f4fbf12017-08-02 01:56:5263}
64
65GeolocationServiceImpl::GeolocationServiceImpl(
Ke He7319dbe2017-11-09 05:54:4466 device::mojom::GeolocationContext* geolocation_context,
Conley Owens47f4fbf12017-08-02 01:56:5267 RenderFrameHost* render_frame_host)
68 : geolocation_context_(geolocation_context),
Conley Owens47f4fbf12017-08-02 01:56:5269 render_frame_host_(render_frame_host) {
70 DCHECK(geolocation_context);
Conley Owens47f4fbf12017-08-02 01:56:5271 DCHECK(render_frame_host);
72}
73
Yifan Luo8e5d3d52024-10-22 19:18:1674GeolocationServiceImpl::~GeolocationServiceImpl() {
75 DecrementActivityCount();
76}
Conley Owens47f4fbf12017-08-02 01:56:5277
78void GeolocationServiceImpl::Bind(
Mario Sanchez Pradafa6dda8c2019-11-25 18:20:1979 mojo::PendingReceiver<blink::mojom::GeolocationService> receiver) {
Illia Klimova181b7d2022-03-15 08:17:4780 receiver_set_.Add(this, std::move(receiver),
81 std::make_unique<GeolocationServiceImplContext>());
Yifan Luo8e5d3d52024-10-22 19:18:1682 receiver_set_.set_disconnect_handler(base::BindRepeating(
83 &GeolocationServiceImpl::OnDisconnected, base::Unretained(this)));
Jan Lanik819b60372024-01-12 12:58:2684#if BUILDFLAG(IS_IOS)
Alvin Ji0ff27272024-03-13 21:57:2785 device::GeolocationSystemPermissionManager*
86 geolocation_system_permission_manager =
87 device::GeolocationSystemPermissionManager::GetInstance();
88 if (geolocation_system_permission_manager) {
89 geolocation_system_permission_manager->RequestSystemPermission();
Jan Lanik819b60372024-01-12 12:58:2690 }
91#endif
Conley Owens47f4fbf12017-08-02 01:56:5292}
93
94void GeolocationServiceImpl::CreateGeolocation(
Gyuyoung Kim0c32116d2019-08-30 03:27:3595 mojo::PendingReceiver<device::mojom::Geolocation> receiver,
Matt Reynoldsf10fd2f2019-04-01 19:39:2996 bool user_gesture,
97 CreateGeolocationCallback callback) {
Raymes Khoury8dbfbd72018-08-21 07:31:1698 if (!render_frame_host_->IsFeatureEnabled(
Sandor «Alex» Majore9545a72025-01-31 20:40:4699 network::mojom::PermissionsPolicyFeature::kGeolocation)) {
Matt Reynoldsf10fd2f2019-04-01 19:39:29100 std::move(callback).Run(blink::mojom::PermissionStatus::DENIED);
Conley Owens47f4fbf12017-08-02 01:56:52101 return;
102 }
103
Matt Reynoldsf10fd2f2019-04-01 19:39:29104 // If the geolocation service is destroyed before the callback is run, ensure
105 // it is called with DENIED status.
106 auto scoped_callback = mojo::WrapCallbackWithDefaultInvokeIfNotRun(
107 std::move(callback), blink::mojom::PermissionStatus::DENIED);
108
Mario Sanchez Pradafa6dda8c2019-11-25 18:20:19109 receiver_set_.current_context()->RequestPermission(
Conley Owens47f4fbf12017-08-02 01:56:52110 render_frame_host_, user_gesture,
Alvin Ji9e137ea2025-02-20 05:03:02111 // The owning RenderFrameHost might be destroyed before the permission
112 // request finishes. To avoid calling a callback on a destroyed object,
113 // use a WeakPtr and skip the callback if the object is invalid.
Makoto Shimazu51176e62019-10-10 14:43:17114 base::BindOnce(
Florian Jackyaaf42832025-08-19 04:03:26115 &GeolocationServiceImpl::CreateGeolocationWithPermissionResult,
Alvin Ji8c6078e2025-02-14 22:52:27116 weak_factory_.GetWeakPtr(), std::move(receiver),
Jan Wilken Dörrie1494205b2020-03-26 09:32:53117 std::move(scoped_callback)));
Conley Owens47f4fbf12017-08-02 01:56:52118}
119
Florian Jackyaaf42832025-08-19 04:03:26120void GeolocationServiceImpl::CreateGeolocationWithPermissionResult(
Gyuyoung Kim0c32116d2019-08-30 03:27:35121 mojo::PendingReceiver<device::mojom::Geolocation> receiver,
Matt Reynoldsf10fd2f2019-04-01 19:39:29122 CreateGeolocationCallback callback,
Florian Jackyaaf42832025-08-19 04:03:26123 PermissionResult permission_result) {
124 std::move(callback).Run(permission_result.status);
125 if (permission_result.status != blink::mojom::PermissionStatus::GRANTED) {
Conley Owens47f4fbf12017-08-02 01:56:52126 return;
Florian Jackyaaf42832025-08-19 04:03:26127 }
Conley Owens47f4fbf12017-08-02 01:56:52128
Yifan Luo8e5d3d52024-10-22 19:18:16129 IncrementActivityCount();
130
Florian Jacky80e35302023-09-15 16:40:42131 requesting_origin_ =
132 render_frame_host_->GetMainFrame()->GetLastCommittedOrigin();
133 auto requesting_url =
Ella Gea4791e43d2022-09-01 06:14:31134 render_frame_host_->GetMainFrame()->GetLastCommittedURL();
Florian Jacky80e35302023-09-15 16:40:42135
Matt Reynolds9e5062942024-06-11 21:27:56136 geolocation_context_->BindGeolocation(
137 std::move(receiver), requesting_url,
138 device::mojom::GeolocationClientId::kGeolocationServiceImpl);
Florian Jacky80e35302023-09-15 16:40:42139 subscription_id_ =
140 PermissionControllerImpl::FromBrowserContext(
141 render_frame_host_->GetBrowserContext())
Balazs Engedy33b441e2023-12-12 18:53:42142 ->SubscribeToPermissionStatusChange(
Florian Jacky80e35302023-09-15 16:40:42143 blink::PermissionType::GEOLOCATION,
144 /*render_process_host=*/nullptr, render_frame_host_,
145 requesting_url,
Andy Paicu9d70da42024-05-10 22:24:39146 /*should_include_device_status=*/false,
Florian Jacky80e35302023-09-15 16:40:42147 base::BindRepeating(
148 &GeolocationServiceImpl::HandlePermissionStatusChange,
149 weak_factory_.GetWeakPtr()));
150}
151
152void GeolocationServiceImpl::HandlePermissionStatusChange(
153 blink::mojom::PermissionStatus permission_status) {
154 if (permission_status != blink::mojom::PermissionStatus::GRANTED &&
155 subscription_id_.value()) {
156 PermissionControllerImpl::FromBrowserContext(
157 render_frame_host_->GetBrowserContext())
Balazs Engedy33b441e2023-12-12 18:53:42158 ->UnsubscribeFromPermissionStatusChange(subscription_id_);
Florian Jacky80e35302023-09-15 16:40:42159 geolocation_context_->OnPermissionRevoked(requesting_origin_);
Yifan Luo8e5d3d52024-10-22 19:18:16160 DecrementActivityCount();
161 }
162}
163
164void GeolocationServiceImpl::OnDisconnected() {
165 if (receiver_set_.empty()) {
166 DecrementActivityCount();
167 }
168}
169
170void GeolocationServiceImpl::IncrementActivityCount() {
171 is_sending_updates_ = true;
172 auto* web_contents = WebContents::FromRenderFrameHost(render_frame_host_);
173 static_cast<WebContentsImpl*>(web_contents)
174 ->IncrementGeolocationActiveFrameCount();
175}
176
177void GeolocationServiceImpl::DecrementActivityCount() {
178 if (is_sending_updates_) {
179 is_sending_updates_ = false;
180 auto* web_contents = WebContents::FromRenderFrameHost(render_frame_host_);
181 static_cast<WebContentsImpl*>(web_contents)
182 ->DecrementGeolocationActiveFrameCount();
Florian Jacky80e35302023-09-15 16:40:42183 }
Conley Owens47f4fbf12017-08-02 01:56:52184}
185
186} // namespace content