Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(448)

Unified Diff: third_party/WebKit/Source/modules/sensor/Sensor.cpp

Issue 2458453002: [sensors] Add Permission guard to the generic sensor apis.
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/modules/sensor/Sensor.cpp
diff --git a/third_party/WebKit/Source/modules/sensor/Sensor.cpp b/third_party/WebKit/Source/modules/sensor/Sensor.cpp
index ca613f9e1e8670fb65e75c1ba499ec3b0a9a2004..5c07a6de5e691e9dd6376081ab91d555295fb222 100644
--- a/third_party/WebKit/Source/modules/sensor/Sensor.cpp
+++ b/third_party/WebKit/Source/modules/sensor/Sensor.cpp
@@ -9,16 +9,22 @@
#include "core/dom/ExecutionContextTask.h"
#include "core/inspector/ConsoleMessage.h"
#include "device/generic_sensor/public/interfaces/sensor.mojom-blink.h"
+#include "modules/permissions/PermissionUtils.h"
#include "modules/sensor/SensorErrorEvent.h"
#include "modules/sensor/SensorPollingStrategy.h"
#include "modules/sensor/SensorProviderProxy.h"
#include "modules/sensor/SensorReading.h"
#include "modules/sensor/SensorReadingEvent.h"
+#include "platform/UserGestureIndicator.h"
using namespace device::mojom::blink;
namespace blink {
+using mojom::blink::PermissionName;
+using mojom::blink::PermissionService;
+using mojom::blink::PermissionStatus;
+
Sensor::Sensor(ScriptState* scriptState,
const SensorOptions& sensorOptions,
ExceptionState& exceptionState,
@@ -30,7 +36,8 @@ Sensor::Sensor(ScriptState* scriptState,
m_sensorOptions(sensorOptions),
m_type(type),
m_state(Sensor::SensorState::IDLE),
- m_storedData() {
+ m_storedData(),
+ m_sensorPermission(PermissionStatus::ASK) {
// Check secure context.
String errorMessage;
if (!scriptState->getExecutionContext()->isSecureContext(errorMessage)) {
@@ -46,6 +53,16 @@ Sensor::Sensor(ScriptState* scriptState,
return;
}
+ // Get permission service.
+ PermissionService* permissionService =
+ getPermissionService(scriptState->getExecutionContext());
+
+ if (!permissionService) {
+ exceptionState.throwDOMException(
+ InvalidStateError,
+ "In its current state, the global scope can't request permissions");
+ }
+
// Check the given frequency value.
if (m_sensorOptions.hasFrequency()) {
double frequency = m_sensorOptions.frequency();
@@ -63,7 +80,25 @@ Sensor::Sensor(ScriptState* scriptState,
}
}
-Sensor::~Sensor() = default;
+Sensor::~Sensor() {
+ m_permissionService.reset();
+}
+
+void Sensor::permissionServiceConnectionError() {
+ m_permissionService.reset();
+}
+
+PermissionService* Sensor::getPermissionService(
+ ExecutionContext* executionContext) {
+ if (!m_permissionService &&
+ connectToPermissionService(executionContext,
+ mojo::GetProxy(&m_permissionService))) {
+ m_permissionService.set_connection_error_handler(convertToBaseCallback(
+ WTF::bind(&Sensor::permissionServiceConnectionError,
+ wrapWeakPersistent(this))));
+ }
+ return m_permissionService.get();
+}
void Sensor::start(ScriptState* scriptState, ExceptionState& exceptionState) {
if (m_state != Sensor::SensorState::IDLE &&
@@ -82,7 +117,64 @@ void Sensor::start(ScriptState* scriptState, ExceptionState& exceptionState) {
return;
}
- startListening();
+ // If the algorithm is not allowed to show a popup, throw SecurityError.
+ if (!UserGestureIndicator::consumeUserGesture()) {
+ exceptionState.throwDOMException(
+ SecurityError,
+ "Must be handling a user gesture to show a permission request.");
+ return;
+ }
+
+ // Check permissions.
+ m_permissionService->HasPermission(
shalamov 2016/10/27 08:47:25 What happens if you call start(), then permission
+ createPermissionDescriptor(PermissionName::SENSORS),
+ scriptState->getExecutionContext()->getSecurityOrigin(),
+ convertToBaseCallback(
+ WTF::bind(&Sensor::onPermissionUpdate, wrapPersistent(this),
+ wrapPersistent(scriptState->getExecutionContext()))));
+
+ // Keep listening for next change in permission.
+ // TODO(riju): Re-use same onPermissionUpdate callback for everything?
+ m_permissionService->GetNextPermissionChange(
shalamov 2016/10/27 08:47:25 I think logic should be different. Initially we d
+ createPermissionDescriptor(PermissionName::SENSORS),
+ scriptState->getExecutionContext()->getSecurityOrigin(),
+ m_sensorPermission,
+ convertToBaseCallback(
+ WTF::bind(&Sensor::onPermissionUpdate, wrapPersistent(this),
+ wrapPersistent(scriptState->getExecutionContext()))));
+}
+
+void Sensor::requestPermission(ExecutionContext* executionContext,
+ PermissionStatus status) {
+ m_permissionService->RequestPermission(
+ createPermissionDescriptor(PermissionName::SENSORS),
+ executionContext->getSecurityOrigin(),
+ UserGestureIndicator::processingUserGesture(),
+ convertToBaseCallback(WTF::bind(&Sensor::onPermissionUpdate,
+ wrapPersistent(this),
+ wrapPersistent(executionContext))));
+}
+
+void Sensor::onPermissionUpdate(ExecutionContext* executionContext,
shalamov 2016/10/27 08:47:25 I think permission checking should not be bound to
+ PermissionStatus status) {
+ m_sensorPermission = status;
+
+ // m_permissionService.reset();
+
+ if (m_sensorPermission == PermissionStatus::GRANTED) {
+ startListening();
shalamov 2016/10/27 08:47:25 ditto, what if user called stop() before permissio
+ } else if (m_sensorPermission == PermissionStatus::ASK) {
+ requestPermission(executionContext, status);
+ } else if (m_sensorPermission == PermissionStatus::DENIED) {
+ stopListening();
+
+ ConsoleMessage* consoleMessage = ConsoleMessage::create(
+ JSMessageSource, InfoMessageLevel, "Permission Rejected.");
+ executionContext->addConsoleMessage(consoleMessage);
+
+ reportError(PermissionDeniedError,
+ "start() call has failed as permission was denied.");
+ }
}
void Sensor::stop(ScriptState*, ExceptionState& exceptionState) {
@@ -154,6 +246,7 @@ void Sensor::contextDestroyed() {
if (m_state == Sensor::SensorState::ACTIVE ||
m_state == Sensor::SensorState::ACTIVATING)
stopListening();
+ m_permissionService.reset();
}
void Sensor::onSensorInitialized() {

Powered by Google App Engine
This is Rietveld 408576698