Commit f404dd47 authored by Mikhail Pozdnyakov's avatar Mikhail Pozdnyakov Committed by Commit Bot

[Sensors] Add Feature Policy integration

This patch implements the upcoming specification changes:
https://github.com/w3c/sensors/pull/328

The sensors API can be used inside nested browsing contexts
in a secure way.

Bug: 
Change-Id: Ia6353d5a0d9a7c8817666a04aa859ed2c13b0520
Reviewed-on: https://chromium-review.googlesource.com/789040
Commit-Queue: Kentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarRaymes Khoury <raymes@chromium.org>
Reviewed-by: default avatarTom Sepez <tsepez@chromium.org>
Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#525293}
parent e13922b1
This is a testharness.js-based test.
Harness Error. harness_status.status = 1 , harness_status.message = Uncaught ReferenceError: GravitySensor is not defined
FAIL Accelerometer: Feature-Policy header accelerometer 'none' disallows the top-level document. assert_throws: function "() => {new sensorType()}" did not throw
PASS Accelerometer: Feature-Policy header accelerometer 'none' disallows the top-level document.
PASS Accelerometer: Feature-Policy header accelerometer 'none' disallows same-origin iframes.
PASS Accelerometer: Feature-Policy header accelerometer 'none' disallows cross-origin iframes.
FAIL LinearAccelerationSensor: Feature-Policy header accelerometer 'none' disallows the top-level document. assert_throws: function "() => {new sensorType()}" did not throw
PASS LinearAccelerationSensor: Feature-Policy header accelerometer 'none' disallows the top-level document.
PASS LinearAccelerationSensor: Feature-Policy header accelerometer 'none' disallows same-origin iframes.
PASS LinearAccelerationSensor: Feature-Policy header accelerometer 'none' disallows cross-origin iframes.
Harness: the test ran to completion.
......
This is a testharness.js-based test.
Harness Error. harness_status.status = 1 , harness_status.message = Uncaught ReferenceError: GravitySensor is not defined
FAIL Accelerometer: Feature-Policy allow='accelerometer' attribute allows same-origin relocation assert_true: 'new Accelerometer()' expected true got false
PASS Accelerometer: Feature-Policy allow='accelerometer' attribute allows same-origin relocation
PASS Accelerometer: Feature-Policy allow='accelerometer' attribute disallows cross-origin relocation
FAIL LinearAccelerationSensor: Feature-Policy allow='accelerometer' attribute allows same-origin relocation assert_true: 'new LinearAccelerationSensor()' expected true got false
PASS LinearAccelerationSensor: Feature-Policy allow='accelerometer' attribute allows same-origin relocation
PASS LinearAccelerationSensor: Feature-Policy allow='accelerometer' attribute disallows cross-origin relocation
Harness: the test ran to completion.
This is a testharness.js-based test.
Harness Error. harness_status.status = 1 , harness_status.message = Uncaught ReferenceError: GravitySensor is not defined
FAIL Accelerometer: Feature-Policy allow='accelerometer' attribute allows same-origin iframe assert_true: 'new Accelerometer()' expected true got false
FAIL Accelerometer: Feature-Policy allow='accelerometer' attribute allows cross-origin iframe assert_true: 'new Accelerometer()' expected true got false
FAIL LinearAccelerationSensor: Feature-Policy allow='accelerometer' attribute allows same-origin iframe assert_true: 'new LinearAccelerationSensor()' expected true got false
FAIL LinearAccelerationSensor: Feature-Policy allow='accelerometer' attribute allows cross-origin iframe assert_true: 'new LinearAccelerationSensor()' expected true got false
PASS Accelerometer: Feature-Policy allow='accelerometer' attribute allows same-origin iframe
PASS Accelerometer: Feature-Policy allow='accelerometer' attribute allows cross-origin iframe
PASS LinearAccelerationSensor: Feature-Policy allow='accelerometer' attribute allows same-origin iframe
PASS LinearAccelerationSensor: Feature-Policy allow='accelerometer' attribute allows cross-origin iframe
Harness: the test ran to completion.
This is a testharness.js-based test.
Harness Error. harness_status.status = 1 , harness_status.message = Uncaught ReferenceError: GravitySensor is not defined
PASS Accelerometer: Feature-Policy header accelerometer * allows the top-level document.
FAIL Accelerometer: Feature-Policy header accelerometer * allows same-origin iframes. assert_true: 'new Accelerometer()' expected true got false
FAIL Accelerometer: Feature-Policy header accelerometer * allows cross-origin iframes. assert_true: 'new Accelerometer()' expected true got false
PASS Accelerometer: Feature-Policy header accelerometer * allows same-origin iframes.
PASS Accelerometer: Feature-Policy header accelerometer * allows cross-origin iframes.
PASS LinearAccelerationSensor: Feature-Policy header accelerometer * allows the top-level document.
FAIL LinearAccelerationSensor: Feature-Policy header accelerometer * allows same-origin iframes. assert_true: 'new LinearAccelerationSensor()' expected true got false
FAIL LinearAccelerationSensor: Feature-Policy header accelerometer * allows cross-origin iframes. assert_true: 'new LinearAccelerationSensor()' expected true got false
PASS LinearAccelerationSensor: Feature-Policy header accelerometer * allows same-origin iframes.
PASS LinearAccelerationSensor: Feature-Policy header accelerometer * allows cross-origin iframes.
Harness: the test ran to completion.
This is a testharness.js-based test.
Harness Error. harness_status.status = 1 , harness_status.message = Uncaught ReferenceError: GravitySensor is not defined
PASS Accelerometer: Feature-Policy header accelerometer 'self' allows the top-level document.
FAIL Accelerometer: Feature-Policy header accelerometer 'self' allows same-origin iframes. assert_true: 'new Accelerometer()' expected true got false
PASS Accelerometer: Feature-Policy header accelerometer 'self' allows same-origin iframes.
PASS Accelerometer: Feature-Policy header accelerometer 'self' disallows cross-origin iframes.
PASS LinearAccelerationSensor: Feature-Policy header accelerometer 'self' allows the top-level document.
FAIL LinearAccelerationSensor: Feature-Policy header accelerometer 'self' allows same-origin iframes. assert_true: 'new LinearAccelerationSensor()' expected true got false
PASS LinearAccelerationSensor: Feature-Policy header accelerometer 'self' allows same-origin iframes.
PASS LinearAccelerationSensor: Feature-Policy header accelerometer 'self' disallows cross-origin iframes.
Harness: the test ran to completion.
This is a testharness.js-based test.
FAIL Gyroscope: Feature-Policy header gyroscope 'none' disallows the top-level document. assert_throws: function "() => {new sensorType()}" did not throw
PASS Gyroscope: Feature-Policy header gyroscope 'none' disallows same-origin iframes.
PASS Gyroscope: Feature-Policy header gyroscope 'none' disallows cross-origin iframes.
Harness: the test ran to completion.
This is a testharness.js-based test.
FAIL Gyroscope: Feature-Policy allow='gyroscope' attribute allows same-origin relocation assert_true: 'new Gyroscope()' expected true got false
PASS Gyroscope: Feature-Policy allow='gyroscope' attribute disallows cross-origin relocation
Harness: the test ran to completion.
This is a testharness.js-based test.
FAIL Gyroscope: Feature-Policy allow='gyroscope' attribute allows same-origin iframe assert_true: 'new Gyroscope()' expected true got false
FAIL Gyroscope: Feature-Policy allow='gyroscope' attribute allows cross-origin iframe assert_true: 'new Gyroscope()' expected true got false
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Gyroscope: Feature-Policy header gyroscope * allows the top-level document.
FAIL Gyroscope: Feature-Policy header gyroscope * allows same-origin iframes. assert_true: 'new Gyroscope()' expected true got false
FAIL Gyroscope: Feature-Policy header gyroscope * allows cross-origin iframes. assert_true: 'new Gyroscope()' expected true got false
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS Gyroscope: Feature-Policy header gyroscope 'self' allows the top-level document.
FAIL Gyroscope: Feature-Policy header gyroscope 'self' allows same-origin iframes. assert_true: 'new Gyroscope()' expected true got false
PASS Gyroscope: Feature-Policy header gyroscope 'self' disallows cross-origin iframes.
Harness: the test ran to completion.
This is a testharness.js-based test.
Harness Error. harness_status.status = 1 , harness_status.message = Uncaught ReferenceError: UncalibratedMagnetometer is not defined
FAIL Magnetometer: Feature-Policy header magnetometer 'none' disallows the top-level document. assert_throws: function "() => {new sensorType()}" did not throw
PASS Magnetometer: Feature-Policy header magnetometer 'none' disallows the top-level document.
PASS Magnetometer: Feature-Policy header magnetometer 'none' disallows same-origin iframes.
PASS Magnetometer: Feature-Policy header magnetometer 'none' disallows cross-origin iframes.
Harness: the test ran to completion.
......
This is a testharness.js-based test.
Harness Error. harness_status.status = 1 , harness_status.message = Uncaught ReferenceError: UncalibratedMagnetometer is not defined
FAIL Magnetometer: Feature-Policy allow='magnetometer' attribute allows same-origin relocation assert_true: 'new Magnetometer()' expected true got false
PASS Magnetometer: Feature-Policy allow='magnetometer' attribute allows same-origin relocation
PASS Magnetometer: Feature-Policy allow='magnetometer' attribute disallows cross-origin relocation
Harness: the test ran to completion.
This is a testharness.js-based test.
Harness Error. harness_status.status = 1 , harness_status.message = Uncaught ReferenceError: UncalibratedMagnetometer is not defined
FAIL Magnetometer: Feature-Policy allow='magnetometer' attribute allows same-origin iframe assert_true: 'new Magnetometer()' expected true got false
FAIL Magnetometer: Feature-Policy allow='magnetometer' attribute allows cross-origin iframe assert_true: 'new Magnetometer()' expected true got false
PASS Magnetometer: Feature-Policy allow='magnetometer' attribute allows same-origin iframe
PASS Magnetometer: Feature-Policy allow='magnetometer' attribute allows cross-origin iframe
Harness: the test ran to completion.
This is a testharness.js-based test.
Harness Error. harness_status.status = 1 , harness_status.message = Uncaught ReferenceError: UncalibratedMagnetometer is not defined
PASS Magnetometer: Feature-Policy header magnetometer * allows the top-level document.
FAIL Magnetometer: Feature-Policy header magnetometer * allows same-origin iframes. assert_true: 'new Magnetometer()' expected true got false
FAIL Magnetometer: Feature-Policy header magnetometer * allows cross-origin iframes. assert_true: 'new Magnetometer()' expected true got false
PASS Magnetometer: Feature-Policy header magnetometer * allows same-origin iframes.
PASS Magnetometer: Feature-Policy header magnetometer * allows cross-origin iframes.
Harness: the test ran to completion.
This is a testharness.js-based test.
Harness Error. harness_status.status = 1 , harness_status.message = Uncaught ReferenceError: UncalibratedMagnetometer is not defined
PASS Magnetometer: Feature-Policy header magnetometer 'self' allows the top-level document.
FAIL Magnetometer: Feature-Policy header magnetometer 'self' allows same-origin iframes. assert_true: 'new Magnetometer()' expected true got false
PASS Magnetometer: Feature-Policy header magnetometer 'self' allows same-origin iframes.
PASS Magnetometer: Feature-Policy header magnetometer 'self' disallows cross-origin iframes.
Harness: the test ran to completion.
This is a testharness.js-based test.
FAIL AbsoluteOrientationSensor: Feature-Policy header accelerometer 'none';gyroscope 'none';magnetometer 'none' disallows the top-level document. assert_throws: function "() => {new sensorType()}" did not throw
PASS AbsoluteOrientationSensor: Feature-Policy header accelerometer 'none';gyroscope 'none';magnetometer 'none' disallows same-origin iframes.
PASS AbsoluteOrientationSensor: Feature-Policy header accelerometer 'none';gyroscope 'none';magnetometer 'none' disallows cross-origin iframes.
Harness: the test ran to completion.
This is a testharness.js-based test.
FAIL AbsoluteOrientationSensor: Feature-Policy allow='accelerometer gyroscope magnetometer' attribute allows same-origin relocation assert_true: 'new AbsoluteOrientationSensor()' expected true got false
PASS AbsoluteOrientationSensor: Feature-Policy allow='accelerometer gyroscope magnetometer' attribute disallows cross-origin relocation
Harness: the test ran to completion.
This is a testharness.js-based test.
FAIL AbsoluteOrientationSensor: Feature-Policy allow='accelerometer gyroscope magnetometer' attribute allows same-origin iframe assert_true: 'new AbsoluteOrientationSensor()' expected true got false
FAIL AbsoluteOrientationSensor: Feature-Policy allow='accelerometer gyroscope magnetometer' attribute allows cross-origin iframe assert_true: 'new AbsoluteOrientationSensor()' expected true got false
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS AbsoluteOrientationSensor: Feature-Policy header accelerometer *;gyroscope *;magnetometer * allows the top-level document.
FAIL AbsoluteOrientationSensor: Feature-Policy header accelerometer *;gyroscope *;magnetometer * allows same-origin iframes. assert_true: 'new AbsoluteOrientationSensor()' expected true got false
FAIL AbsoluteOrientationSensor: Feature-Policy header accelerometer *;gyroscope *;magnetometer * allows cross-origin iframes. assert_true: 'new AbsoluteOrientationSensor()' expected true got false
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS AbsoluteOrientationSensor: Feature-Policy header accelerometer 'self';gyroscope 'self';magnetometer 'self' allows the top-level document.
FAIL AbsoluteOrientationSensor: Feature-Policy header accelerometer 'self';gyroscope 'self';magnetometer 'self' allows same-origin iframes. assert_true: 'new AbsoluteOrientationSensor()' expected true got false
PASS AbsoluteOrientationSensor: Feature-Policy header accelerometer 'self';gyroscope 'self';magnetometer 'self' disallows cross-origin iframes.
Harness: the test ran to completion.
This is a testharness.js-based test.
FAIL RelativeOrientationSensor: Feature-Policy header accelerometer 'none';gyroscope 'none' disallows the top-level document. assert_throws: function "() => {new sensorType()}" did not throw
PASS RelativeOrientationSensor: Feature-Policy header accelerometer 'none';gyroscope 'none' disallows same-origin iframes.
PASS RelativeOrientationSensor: Feature-Policy header accelerometer 'none';gyroscope 'none' disallows cross-origin iframes.
Harness: the test ran to completion.
This is a testharness.js-based test.
FAIL RelativeOrientationSensor: Feature-Policy allow='accelerometer gyroscope' attribute allows same-origin relocation assert_true: 'new RelativeOrientationSensor()' expected true got false
PASS RelativeOrientationSensor: Feature-Policy allow='accelerometer gyroscope' attribute disallows cross-origin relocation
Harness: the test ran to completion.
This is a testharness.js-based test.
FAIL RelativeOrientationSensor: Feature-Policy allow='accelerometer gyroscope' attribute allows same-origin iframe assert_true: 'new RelativeOrientationSensor()' expected true got false
FAIL RelativeOrientationSensor: Feature-Policy allow='accelerometer gyroscope' attribute allows cross-origin iframe assert_true: 'new RelativeOrientationSensor()' expected true got false
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS RelativeOrientationSensor: Feature-Policy header accelerometer *;gyroscope * allows the top-level document.
FAIL RelativeOrientationSensor: Feature-Policy header accelerometer *;gyroscope * allows same-origin iframes. assert_true: 'new RelativeOrientationSensor()' expected true got false
FAIL RelativeOrientationSensor: Feature-Policy header accelerometer *;gyroscope * allows cross-origin iframes. assert_true: 'new RelativeOrientationSensor()' expected true got false
Harness: the test ran to completion.
This is a testharness.js-based test.
PASS RelativeOrientationSensor: Feature-Policy header accelerometer 'self';gyroscope 'self' allows the top-level document.
FAIL RelativeOrientationSensor: Feature-Policy header accelerometer 'self';gyroscope 'self' allows same-origin iframes. assert_true: 'new RelativeOrientationSensor()' expected true got false
PASS RelativeOrientationSensor: Feature-Policy header accelerometer 'self';gyroscope 'self' disallows cross-origin iframes.
Harness: the test ran to completion.
......@@ -26,10 +26,12 @@ function verify_sensor_reading({x, y, z, timestamp}, is_null) {
runGenericSensorTests(Accelerometer,
update_sensor_reading,
verify_sensor_reading);
verify_sensor_reading,
['accelerometer']);
runGenericSensorTests(LinearAccelerationSensor,
update_sensor_reading,
verify_sensor_reading);
verify_sensor_reading,
['accelerometer']);
</script>
......@@ -24,5 +24,8 @@ function verify_sensor_reading({illuminance, timestamp}, is_null) {
return illuminance === kDefaultReadingValue && timestamp !== null;
}
runGenericSensorTests(AmbientLightSensor, update_sensor_reading, verify_sensor_reading);
runGenericSensorTests(AmbientLightSensor,
update_sensor_reading,
verify_sensor_reading,
['ambient-light-sensor']);
</script>
......@@ -24,6 +24,6 @@ function verify_sensor_reading({x, y, z, timestamp}, is_null) {
return [x, y, z].every((r, i) => r === kDefaultReading[i]) && timestamp !== null;
}
runGenericSensorTests(Gyroscope, update_sensor_reading, verify_sensor_reading);
runGenericSensorTests(Gyroscope, update_sensor_reading, verify_sensor_reading, ['gyroscope']);
</script>
......@@ -24,5 +24,5 @@ function verify_sensor_reading({x, y, z, timestamp}, is_null) {
return [x, y, z].every((r, i) => r === kDefaultReading[i]) && timestamp !== null;
}
runGenericSensorTests(Magnetometer, update_sensor_reading, verify_sensor_reading);
runGenericSensorTests(Magnetometer, update_sensor_reading, verify_sensor_reading, ['magnetometer']);
</script>
......@@ -99,13 +99,19 @@ async function checkPopulateMatrix(sensor, sensorType) {
return mockSensor.removeConfigurationCalled();
}
runGenericSensorTests(AbsoluteOrientationSensor, update_sensor_reading, verify_sensor_reading);
runGenericSensorTests(AbsoluteOrientationSensor,
update_sensor_reading,
verify_sensor_reading,
['accelerometer', 'gyroscope', 'magnetometer']);
sensor_test(sensor => {
return checkPopulateMatrix(sensor, AbsoluteOrientationSensor);
}, 'Test AbsoluteOrientationSensor.populateMatrix() method works correctly.');
runGenericSensorTests(RelativeOrientationSensor, update_sensor_reading, verify_sensor_reading);
runGenericSensorTests(RelativeOrientationSensor,
update_sensor_reading,
verify_sensor_reading,
['accelerometer', 'gyroscope']);
sensor_test(sensor => {
return checkPopulateMatrix(sensor, RelativeOrientationSensor);
......
......@@ -4,7 +4,7 @@
// a called by the test to provide the mock values for sensor. |verifyReading|
// is called so that the value read in JavaScript are the values expected (the ones
// sent by |updateReading|).
function runGenericSensorTests(sensorType, updateReading, verifyReading) {
function runGenericSensorTests(sensorType, updateReading, verifyReading, featurePolicies) {
sensor_test(sensor => {
sensor.mockSensorProvider.setGetSensorShouldFail(true);
let sensorObject = new sensorType;
......@@ -360,6 +360,7 @@ function runGenericSensorTests(sensorType, updateReading, verifyReading) {
promise_test(() => {
return new Promise((resolve,reject) => {
let iframe = document.createElement('iframe');
iframe.allow = featurePolicies.join(' \'none\'; ') + ' \'none\';';
iframe.srcdoc = '<script>' +
' window.onmessage = message => {' +
' if (message.data === "LOADED") {' +
......@@ -382,7 +383,35 @@ function runGenericSensorTests(sensorType, updateReading, verifyReading) {
}
}
});
}, `${sensorType.name}: Test that sensor cannot be constructed within iframe.`);
}, `${sensorType.name}: Test that sensor cannot be constructed within iframe disallowed to use feature policy.`);
promise_test(() => {
return new Promise((resolve,reject) => {
let iframe = document.createElement('iframe');
iframe.allow = featurePolicies.join(';') + ';';
iframe.srcdoc = '<script>' +
' window.onmessage = message => {' +
' if (message.data === "LOADED") {' +
' try {' +
' new ' + sensorType.name + '();' +
' parent.postMessage("PASS", "*");' +
' } catch (e) {' +
' parent.postMessage("FAIL", "*");' +
' }' +
' }' +
' };' +
'<\/script>';
iframe.onload = () => iframe.contentWindow.postMessage('LOADED', '*');
document.body.appendChild(iframe);
window.onmessage = message => {
if (message.data == 'PASS') {
resolve();
} else if (message.data == 'FAIL') {
reject();
}
}
});
}, `${sensorType.name}: Test that sensor can be constructed within an iframe allowed to use feature policy.`);
sensor_test(async sensor => {
let sensorObject = new sensorType();
......
......@@ -30,7 +30,10 @@ AbsoluteOrientationSensor::AbsoluteOrientationSensor(
: OrientationSensor(execution_context,
options,
exception_state,
SensorType::ABSOLUTE_ORIENTATION_QUATERNION) {}
SensorType::ABSOLUTE_ORIENTATION_QUATERNION,
{FeaturePolicyFeature::kAccelerometer,
FeaturePolicyFeature::kGyroscope,
FeaturePolicyFeature::kMagnetometer}) {}
void AbsoluteOrientationSensor::Trace(blink::Visitor* visitor) {
OrientationSensor::Trace(visitor);
......
......@@ -12,7 +12,8 @@ Accelerometer* Accelerometer::Create(ExecutionContext* execution_context,
const SensorOptions& options,
ExceptionState& exception_state) {
return new Accelerometer(execution_context, options, exception_state,
SensorType::ACCELEROMETER);
SensorType::ACCELEROMETER,
{FeaturePolicyFeature::kAccelerometer});
}
// static
......@@ -24,8 +25,13 @@ Accelerometer* Accelerometer::Create(ExecutionContext* execution_context,
Accelerometer::Accelerometer(ExecutionContext* execution_context,
const SensorOptions& options,
ExceptionState& exception_state,
SensorType sensor_type)
: Sensor(execution_context, options, exception_state, sensor_type) {}
SensorType sensor_type,
const Vector<FeaturePolicyFeature>& features)
: Sensor(execution_context,
options,
exception_state,
sensor_type,
features) {}
double Accelerometer::x(bool& is_null) const {
INIT_IS_NULL_AND_RETURN(is_null, 0.0);
......
......@@ -28,7 +28,8 @@ class Accelerometer : public Sensor {
Accelerometer(ExecutionContext*,
const SensorOptions&,
ExceptionState&,
device::mojom::blink::SensorType);
device::mojom::blink::SensorType,
const Vector<FeaturePolicyFeature>&);
};
} // namespace blink
......
......@@ -32,7 +32,8 @@ AmbientLightSensor::AmbientLightSensor(ExecutionContext* execution_context,
: Sensor(execution_context,
options,
exception_state,
SensorType::AMBIENT_LIGHT) {}
SensorType::AMBIENT_LIGHT,
{FeaturePolicyFeature::kAmbientLightSensor}) {}
double AmbientLightSensor::illuminance(bool& is_null) const {
INIT_IS_NULL_AND_RETURN(is_null, 0.0);
......
include_rules = [
"+common/feature_policy",
"-modules",
"+modules/EventModules.h",
"+modules/EventTargetModules.h",
......
......@@ -27,7 +27,8 @@ Gyroscope::Gyroscope(ExecutionContext* execution_context,
: Sensor(execution_context,
options,
exception_state,
SensorType::GYROSCOPE) {}
SensorType::GYROSCOPE,
{FeaturePolicyFeature::kGyroscope}) {}
double Gyroscope::x(bool& is_null) const {
INIT_IS_NULL_AND_RETURN(is_null, 0.0);
......
......@@ -30,7 +30,8 @@ LinearAccelerationSensor::LinearAccelerationSensor(
: Accelerometer(execution_context,
options,
exception_state,
SensorType::LINEAR_ACCELERATION) {}
SensorType::LINEAR_ACCELERATION,
{FeaturePolicyFeature::kAccelerometer}) {}
void LinearAccelerationSensor::Trace(blink::Visitor* visitor) {
Accelerometer::Trace(visitor);
......
......@@ -27,7 +27,8 @@ Magnetometer::Magnetometer(ExecutionContext* execution_context,
: Sensor(execution_context,
options,
exception_state,
SensorType::MAGNETOMETER) {}
SensorType::MAGNETOMETER,
{FeaturePolicyFeature::kMagnetometer}) {}
double Magnetometer::x(bool& is_null) const {
INIT_IS_NULL_AND_RETURN(is_null, 0.0);
......
......@@ -114,11 +114,13 @@ bool OrientationSensor::isReadingDirty() const {
return reading_dirty_ || !hasReading();
}
OrientationSensor::OrientationSensor(ExecutionContext* execution_context,
const SensorOptions& options,
ExceptionState& exception_state,
device::mojom::blink::SensorType type)
: Sensor(execution_context, options, exception_state, type),
OrientationSensor::OrientationSensor(
ExecutionContext* execution_context,
const SensorOptions& options,
ExceptionState& exception_state,
device::mojom::blink::SensorType type,
const Vector<FeaturePolicyFeature>& features)
: Sensor(execution_context, options, exception_state, type, features),
reading_dirty_(true) {}
void OrientationSensor::OnSensorReadingChanged() {
......
......@@ -26,7 +26,8 @@ class OrientationSensor : public Sensor {
OrientationSensor(ExecutionContext*,
const SensorOptions&,
ExceptionState&,
device::mojom::blink::SensorType);
device::mojom::blink::SensorType,
const Vector<FeaturePolicyFeature>& features);
private:
// SensorProxy override.
......
......@@ -30,7 +30,9 @@ RelativeOrientationSensor::RelativeOrientationSensor(
: OrientationSensor(execution_context,
options,
exception_state,
SensorType::RELATIVE_ORIENTATION_QUATERNION) {}
SensorType::RELATIVE_ORIENTATION_QUATERNION,
{FeaturePolicyFeature::kAccelerometer,
FeaturePolicyFeature::kGyroscope}) {}
void RelativeOrientationSensor::Trace(blink::Visitor* visitor) {
OrientationSensor::Trace(visitor);
......
......@@ -12,6 +12,7 @@
#include "modules/sensor/SensorErrorEvent.h"
#include "modules/sensor/SensorProviderProxy.h"
#include "platform/LayoutTestSupport.h"
#include "platform/feature_policy/FeaturePolicy.h"
#include "public/platform/TaskType.h"
#include "services/device/public/cpp/generic_sensor/sensor_traits.h"
#include "services/device/public/interfaces/sensor.mojom-blink.h"
......@@ -20,12 +21,22 @@ namespace blink {
namespace {
const double kWaitingIntervalThreshold = 0.01;
bool AreFeaturesEnabled(LocalFrame* frame,
const Vector<FeaturePolicyFeature>& features) {
return std::all_of(features.begin(), features.end(),
[frame](FeaturePolicyFeature feature) {
return frame->IsFeatureEnabled(feature);
});
}
} // namespace
Sensor::Sensor(ExecutionContext* execution_context,
const SensorOptions& sensor_options,
ExceptionState& exception_state,
device::mojom::blink::SensorType type)
device::mojom::blink::SensorType type,
const Vector<FeaturePolicyFeature>& features)
: ContextLifecycleObserver(execution_context),
sensor_options_(sensor_options),
type_(type),
......@@ -33,12 +44,12 @@ Sensor::Sensor(ExecutionContext* execution_context,
last_reported_timestamp_(0.0) {
// [SecureContext] in idl.
DCHECK(execution_context->IsSecureContext());
DCHECK(!features.IsEmpty());
LocalFrame* frame = ToDocument(execution_context)->GetFrame();
// Check top-level browsing context.
if (!ToDocument(execution_context)->domWindow()->GetFrame() ||
!ToDocument(execution_context)->GetFrame()->IsMainFrame()) {
if (!frame || !AreFeaturesEnabled(frame, features)) {
exception_state.ThrowSecurityError(
"Must be in a top-level browsing context");
"Access to sensor features is disallowed by feature policy");
return;
}
......
......@@ -6,6 +6,7 @@
#define Sensor_h
#include "bindings/core/v8/ActiveScriptWrappable.h"
#include "common/feature_policy/feature_policy.h"
#include "core/dom/ContextLifecycleObserver.h"
#include "core/dom/DOMHighResTimeStamp.h"
#include "core/dom/DOMTimeStamp.h"
......@@ -65,7 +66,8 @@ class Sensor : public EventTargetWithInlineData,
Sensor(ExecutionContext*,
const SensorOptions&,
ExceptionState&,
device::mojom::blink::SensorType);
device::mojom::blink::SensorType,
const Vector<FeaturePolicyFeature>&);
using SensorConfigurationPtr = device::mojom::blink::SensorConfigurationPtr;
using SensorConfiguration = device::mojom::blink::SensorConfiguration;
......
......@@ -203,6 +203,10 @@ bool IsSupportedInFeaturePolicy(FeaturePolicyFeature feature) {
case FeaturePolicyFeature::kPayment:
case FeaturePolicyFeature::kUsb:
case FeaturePolicyFeature::kWebVr:
case FeaturePolicyFeature::kAccelerometer:
case FeaturePolicyFeature::kAmbientLightSensor:
case FeaturePolicyFeature::kGyroscope:
case FeaturePolicyFeature::kMagnetometer:
return true;
case FeaturePolicyFeature::kSyncXHR:
case FeaturePolicyFeature::kVibrate:
......@@ -229,6 +233,13 @@ const FeatureNameMap& GetDefaultFeatureNameMap() {
FeaturePolicyFeature::kGeolocation);
default_feature_name_map.Set("midi", FeaturePolicyFeature::kMidiFeature);
default_feature_name_map.Set("vr", FeaturePolicyFeature::kWebVr);
default_feature_name_map.Set("accelerometer",
FeaturePolicyFeature::kAccelerometer);
default_feature_name_map.Set("ambient-light-sensor",
FeaturePolicyFeature::kAmbientLightSensor);
default_feature_name_map.Set("gyroscope", FeaturePolicyFeature::kGyroscope);
default_feature_name_map.Set("magnetometer",
FeaturePolicyFeature::kMagnetometer);
if (RuntimeEnabledFeatures::FeaturePolicyExperimentalFeaturesEnabled()) {
default_feature_name_map.Set("vibrate", FeaturePolicyFeature::kVibrate);
default_feature_name_map.Set("cookie",
......
......@@ -269,6 +269,14 @@ const FeaturePolicy::FeatureList& FeaturePolicy::GetDefaultFeatureList() {
{FeaturePolicyFeature::kUsb,
FeaturePolicy::FeatureDefault::EnableForSelf},
{FeaturePolicyFeature::kWebVr,
FeaturePolicy::FeatureDefault::EnableForSelf},
{FeaturePolicyFeature::kAccelerometer,
FeaturePolicy::FeatureDefault::EnableForSelf},
{FeaturePolicyFeature::kAmbientLightSensor,
FeaturePolicy::FeatureDefault::EnableForSelf},
{FeaturePolicyFeature::kGyroscope,
FeaturePolicy::FeatureDefault::EnableForSelf},
{FeaturePolicyFeature::kMagnetometer,
FeaturePolicy::FeatureDefault::EnableForSelf}}));
return default_feature_list;
}
......
......@@ -73,6 +73,14 @@ enum FeaturePolicyFeature {
kAccessibilityEvents,
// Controls use of WebVR API.
kWebVr,
// The following features control access to the corresponding sensor classes.
// Fusion sensor APIs (e.g. LinearAcceleration, OrientationSensor-based
// classes)require all of the features that are inputs into that API to be
// enabled for the feature to be allowed.
kAccelerometer,
kAmbientLightSensor,
kGyroscope,
kMagnetometer,
};
// This struct holds feature policy whitelist data that needs to be replicated
......
......@@ -51,7 +51,15 @@ enum class FeaturePolicyFeature {
kAccessibilityEvents,
// Controls use of WebVR API.
kWebVr,
LAST_FEATURE = kWebVr
// The following features control access to the corresponding sensor classes.
// Fusion sensor APIs (e.g. LinearAcceleration, OrientationSensor-based
// classes)require all of the features that are inputs into that API to be
// enabled for the feature to be allowed.
kAccelerometer,
kAmbientLightSensor,
kGyroscope,
kMagnetometer,
LAST_FEATURE = kMagnetometer
};
} // namespace blink
......
......@@ -57,6 +57,14 @@ STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kUsb,
::blink::mojom::FeaturePolicyFeature::kUsb);
STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kWebVr,
::blink::mojom::FeaturePolicyFeature::kWebVr);
STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kAccelerometer,
::blink::mojom::FeaturePolicyFeature::kAccelerometer);
STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kAmbientLightSensor,
::blink::mojom::FeaturePolicyFeature::kAmbientLightSensor);
STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kGyroscope,
::blink::mojom::FeaturePolicyFeature::kGyroscope);
STATIC_ASSERT_ENUM(::blink::FeaturePolicyFeature::kMagnetometer,
::blink::mojom::FeaturePolicyFeature::kMagnetometer);
// TODO(crbug.com/789818) - Merge these 2 WebSandboxFlags enums.
STATIC_ASSERT_ENUM(::blink::WebSandboxFlags::kNone,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment