Chromium Code Reviews| 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() { |