Commit 592f6faa authored by mark a. foltz's avatar mark a. foltz Committed by Commit Bot

[Presentation API] Remove from insecure contexts.

This patch removes the Presentation API from insecure contexts.  The number of presentations started on insecure contexts is 0.0001% of page views on desktop and 0.0004 on Android.

In addition it updates layout tests and WPT to use https: for presentation URLs.

Blink-dev thread:
https://groups.google.com/a/chromium.org/d/topic/blink-dev/lumj0lVdtHA/discussion

chromestatus.com feature entry:
https://www.chromestatus.com/feature/5766218384408576

Bug: 733381
Change-Id: I9ae3025160b0e0bcf987fda0068a0e6bd92c24fd
Reviewed-on: https://chromium-review.googlesource.com/c/1306336Reviewed-by: default avatarMounir Lamouri <mlamouri@chromium.org>
Commit-Queue: mark a. foltz <mfoltz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#604621}
parent 15686105
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
}, 'Call PresentationRequest constructor with an empty sequence. NotSupportedError Exception expected.'); }, 'Call PresentationRequest constructor with an empty sequence. NotSupportedError Exception expected.');
assert_throws('SyntaxError', () => { assert_throws('SyntaxError', () => {
new PresentationRequest('http://@'); new PresentationRequest('https://@');
}, 'Call PresentationRequest constructor with an invalid URL. SyntaxError Exception expected.'); }, 'Call PresentationRequest constructor with an invalid URL. SyntaxError Exception expected.');
assert_throws('NotSupportedError', () => { assert_throws('NotSupportedError', () => {
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
}, 'Call PresentationRequest constructor with an unsupported URL. NotSupportedError expected.'); }, 'Call PresentationRequest constructor with an unsupported URL. NotSupportedError expected.');
assert_throws('SyntaxError', function() { assert_throws('SyntaxError', function() {
new PresentationRequest(['presentation.html', 'http://@']); new PresentationRequest(['presentation.html', 'https://@']);
}, 'Call PresentationRequest constructor with a sequence of URLs, one of them invalid. SyntaxError Exception expected.'); }, 'Call PresentationRequest constructor with a sequence of URLs, one of them invalid. SyntaxError Exception expected.');
assert_throws('NotSupportedError', function() { assert_throws('NotSupportedError', function() {
......
...@@ -12,7 +12,7 @@ async_test(t => { ...@@ -12,7 +12,7 @@ async_test(t => {
internals.settings.setPresentationReceiver(true); internals.settings.setPresentationReceiver(true);
t.add_cleanup(_ => { internals.settings.setPresentationReceiver(false); }); t.add_cleanup(_ => { internals.settings.setPresentationReceiver(false); });
const url = 'http://example.com/a.html'; const url = 'https://example.com/a.html';
const id = 'fakePresentationId'; const id = 'fakePresentationId';
presentationServiceMock.onSetReceiver = () => { presentationServiceMock.onSetReceiver = () => {
......
...@@ -23,7 +23,7 @@ async_test(t => { ...@@ -23,7 +23,7 @@ async_test(t => {
}; };
// This is receiving the user gesture and runs the callback. // This is receiving the user gesture and runs the callback.
waitForClick(() => { waitForClick(() => {
var request = new PresentationRequest("http://example.com"); var request = new PresentationRequest("https://example.com");
request.start().catch(t.step_func_done(ex => { request.start().catch(t.step_func_done(ex => {
assert_equals(ex.name, 'OperationError'); assert_equals(ex.name, 'OperationError');
})); }));
......
...@@ -23,18 +23,18 @@ var testPresentationRequestStart = function(t, requestArgument, connectionUrl) { ...@@ -23,18 +23,18 @@ var testPresentationRequestStart = function(t, requestArgument, connectionUrl) {
}; };
async_test(t => { async_test(t => {
var presentationUrl = "http://example.com/example.html"; var presentationUrl = "https://example.com/example.html";
testPresentationRequestStart(t, presentationUrl, presentationUrl); testPresentationRequestStart(t, presentationUrl, presentationUrl);
}, "Test that the PresentationRequest.start() with single URL resolves with correct PresentationConnection object."); }, "Test that the PresentationRequest.start() with single URL resolves with correct PresentationConnection object.");
async_test(t => { async_test(t => {
var presentationUrls = ["http://example.com/example.html", "cast://google.com/app_id=deadbeef"]; var presentationUrls = ["https://example.com/example.html", "cast://google.com/app_id=deadbeef"];
testPresentationRequestStart(t, presentationUrls, presentationUrls[0]); testPresentationRequestStart(t, presentationUrls, presentationUrls[0]);
}, "Test that the PresentationRequest.start() with multiple URLs resolves with correct PresentationConnection object."); }, "Test that the PresentationRequest.start() with multiple URLs resolves with correct PresentationConnection object.");
async_test(t => { async_test(t => {
var presentationUrl = "http://example.com/\ud801/example.html"; var presentationUrl = "https://example.com/\ud801/example.html";
var connectionUrl = "http://example.com/" + encodeURIComponent('\ufffd') + "/example.html" var connectionUrl = "https://example.com/" + encodeURIComponent('\ufffd') + "/example.html"
testPresentationRequestStart(t, presentationUrl, connectionUrl); testPresentationRequestStart(t, presentationUrl, connectionUrl);
}, "Test that the PresentationRequest.start() with single URL containing special symbol resolves with correct PresentationConnection object."); }, "Test that the PresentationRequest.start() with single URL containing special symbol resolves with correct PresentationConnection object.");
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<script src="../resources/testharnessreport.js"></script> <script src="../resources/testharnessreport.js"></script>
<script> <script>
var presentationUrl = "http://example.com"; var presentationUrl = "https://example.com";
var presentationUrls = [presentationUrl, "cast://google.com/app_id=deadbeef"]; var presentationUrls = [presentationUrl, "cast://google.com/app_id=deadbeef"];
async_test(function(t) { async_test(function(t) {
......
...@@ -12,7 +12,7 @@ assert_not_equals(shouldCallClose, null); ...@@ -12,7 +12,7 @@ assert_not_equals(shouldCallClose, null);
internals.settings.setPresentationReceiver(true); internals.settings.setPresentationReceiver(true);
const pageUrl = 'http://example.com/a.html'; const pageUrl = 'https://example.com/a.html';
const id = 'fakeSessionId'; const id = 'fakeSessionId';
presentationServiceMock.onSetReceiver = () => { presentationServiceMock.onSetReceiver = () => {
......
...@@ -15,7 +15,7 @@ internals.settings.setPresentationReceiver(true); ...@@ -15,7 +15,7 @@ internals.settings.setPresentationReceiver(true);
var connection = null; var connection = null;
const pageUrl = 'http://example.com/a.html'; const pageUrl = 'https://example.com/a.html';
const id = 'fakeSessionId'; const id = 'fakeSessionId';
presentationServiceMock.onSetReceiver = () => { presentationServiceMock.onSetReceiver = () => {
......
...@@ -8,5 +8,5 @@ ...@@ -8,5 +8,5 @@
ImplementedAs=NavigatorPresentation, ImplementedAs=NavigatorPresentation,
RuntimeEnabled=Presentation RuntimeEnabled=Presentation
] partial interface Navigator { ] partial interface Navigator {
[SameObject] readonly attribute Presentation presentation; [SameObject, SecureContext] readonly attribute Presentation presentation;
}; };
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
[ [
RuntimeEnabled=Presentation, RuntimeEnabled=Presentation,
SecureContext,
Exposed=Window Exposed=Window
] interface Presentation { ] interface Presentation {
[MeasureAs=PresentationDefaultRequest] attribute PresentationRequest? defaultRequest; [MeasureAs=PresentationDefaultRequest] attribute PresentationRequest? defaultRequest;
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
[ [
ActiveScriptWrappable, ActiveScriptWrappable,
RuntimeEnabled=Presentation, RuntimeEnabled=Presentation,
SecureContext,
Exposed=Window Exposed=Window
] interface PresentationAvailability : EventTarget { ] interface PresentationAvailability : EventTarget {
readonly attribute boolean value; readonly attribute boolean value;
......
...@@ -12,6 +12,7 @@ enum PresentationConnectionState { ...@@ -12,6 +12,7 @@ enum PresentationConnectionState {
[ [
RuntimeEnabled=Presentation, RuntimeEnabled=Presentation,
SecureContext,
Exposed=Window Exposed=Window
] interface PresentationConnection : EventTarget { ] interface PresentationConnection : EventTarget {
readonly attribute USVString id; readonly attribute USVString id;
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
[ [
Constructor(DOMString type, PresentationConnectionAvailableEventInit eventInitDict), Constructor(DOMString type, PresentationConnectionAvailableEventInit eventInitDict),
RuntimeEnabled=Presentation, RuntimeEnabled=Presentation,
SecureContext,
Exposed=Window Exposed=Window
] interface PresentationConnectionAvailableEvent : Event { ] interface PresentationConnectionAvailableEvent : Event {
[SameObject] readonly attribute PresentationConnection connection; [SameObject] readonly attribute PresentationConnection connection;
......
...@@ -9,6 +9,7 @@ enum PresentationConnectionCloseReason { "error", "closed", "wentaway" }; ...@@ -9,6 +9,7 @@ enum PresentationConnectionCloseReason { "error", "closed", "wentaway" };
[ [
Constructor(DOMString type, PresentationConnectionCloseEventInit eventInitDict), Constructor(DOMString type, PresentationConnectionCloseEventInit eventInitDict),
RuntimeEnabled=Presentation, RuntimeEnabled=Presentation,
SecureContext,
Exposed=Window Exposed=Window
] interface PresentationConnectionCloseEvent : Event { ] interface PresentationConnectionCloseEvent : Event {
readonly attribute PresentationConnectionCloseReason reason; readonly attribute PresentationConnectionCloseReason reason;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
[ [
RuntimeEnabled=Presentation, RuntimeEnabled=Presentation,
SecureContext,
Exposed=Window Exposed=Window
] interface PresentationConnectionList : EventTarget { ] interface PresentationConnectionList : EventTarget {
readonly attribute FrozenArray<PresentationConnection> connections; readonly attribute FrozenArray<PresentationConnection> connections;
......
...@@ -121,7 +121,6 @@ void PresentationController::OnDefaultPresentationStarted( ...@@ -121,7 +121,6 @@ void PresentationController::OnDefaultPresentationStarted(
if (!presentation_ || !presentation_->defaultRequest()) if (!presentation_ || !presentation_->defaultRequest())
return; return;
PresentationRequest::RecordStartOriginTypeAccess(*GetExecutionContext());
auto* connection = ControllerPresentationConnection::Take( auto* connection = ControllerPresentationConnection::Take(
this, *result->presentation_info, presentation_->defaultRequest()); this, *result->presentation_info, presentation_->defaultRequest());
// TODO(btolsch): Convert this and similar calls to just use InterfacePtrInfo // TODO(btolsch): Convert this and similar calls to just use InterfacePtrInfo
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/modules/presentation/presentation.h" #include "third_party/blink/renderer/modules/presentation/presentation.h"
#include "third_party/blink/renderer/modules/presentation/presentation_availability_callbacks.h" #include "third_party/blink/renderer/modules/presentation/presentation_availability_callbacks.h"
#include "third_party/blink/renderer/modules/presentation/presentation_request.h"
#include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/supplementable.h" #include "third_party/blink/renderer/platform/supplementable.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h" #include "third_party/blink/renderer/platform/weborigin/kurl.h"
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
[ [
RuntimeEnabled=Presentation, RuntimeEnabled=Presentation,
SecureContext,
Exposed=Window Exposed=Window
] interface PresentationReceiver { ] interface PresentationReceiver {
[SameObject, CallWith=ScriptState] readonly attribute Promise<PresentationConnectionList> connectionList; [SameObject, CallWith=ScriptState] readonly attribute Promise<PresentationConnectionList> connectionList;
......
...@@ -35,7 +35,7 @@ class MockEventListenerForPresentationReceiver : public EventListener { ...@@ -35,7 +35,7 @@ class MockEventListenerForPresentationReceiver : public EventListener {
class PresentationReceiverTest : public testing::Test { class PresentationReceiverTest : public testing::Test {
public: public:
PresentationReceiverTest() PresentationReceiverTest()
: connection_info_(KURL("http://example.com"), "id") {} : connection_info_(KURL("https://example.com"), "id") {}
void AddConnectionavailableEventListener(EventListener*, void AddConnectionavailableEventListener(EventListener*,
const PresentationReceiver*); const PresentationReceiver*);
void VerifyConnectionListPropertyState(ScriptPromisePropertyBase::State, void VerifyConnectionListPropertyState(ScriptPromisePropertyBase::State,
......
...@@ -38,7 +38,6 @@ Settings* GetSettings(ExecutionContext* execution_context) { ...@@ -38,7 +38,6 @@ Settings* GetSettings(ExecutionContext* execution_context) {
} }
bool IsKnownProtocolForPresentationUrl(const KURL& url) { bool IsKnownProtocolForPresentationUrl(const KURL& url) {
// TODO(crbug.com/733381): Restrict to https + custom schemes.
return url.ProtocolIsInHTTPFamily() || url.ProtocolIs("cast") || return url.ProtocolIsInHTTPFamily() || url.ProtocolIs("cast") ||
url.ProtocolIs("cast-dial"); url.ProtocolIs("cast-dial");
} }
...@@ -132,19 +131,6 @@ bool PresentationRequest::HasPendingActivity() const { ...@@ -132,19 +131,6 @@ bool PresentationRequest::HasPendingActivity() const {
ScriptPromisePropertyBase::kPending; ScriptPromisePropertyBase::kPending;
} }
// static
void PresentationRequest::RecordStartOriginTypeAccess(
ExecutionContext& execution_context) {
if (execution_context.IsSecureContext()) {
UseCounter::Count(&execution_context,
WebFeature::kPresentationRequestStartSecureOrigin);
} else {
Deprecation::CountDeprecation(
&execution_context,
WebFeature::kPresentationRequestStartInsecureOrigin);
}
}
ScriptPromise PresentationRequest::start(ScriptState* script_state) { ScriptPromise PresentationRequest::start(ScriptState* script_state) {
ExecutionContext* execution_context = GetExecutionContext(); ExecutionContext* execution_context = GetExecutionContext();
Settings* context_settings = GetSettings(execution_context); Settings* context_settings = GetSettings(execution_context);
...@@ -171,7 +157,6 @@ ScriptPromise PresentationRequest::start(ScriptState* script_state) { ...@@ -171,7 +157,6 @@ ScriptPromise PresentationRequest::start(ScriptState* script_state) {
DOMExceptionCode::kInvalidStateError, DOMExceptionCode::kInvalidStateError,
"The PresentationRequest is no longer associated to a frame.")); "The PresentationRequest is no longer associated to a frame."));
RecordStartOriginTypeAccess(*execution_context);
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state); ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
controller->GetPresentationService()->StartPresentation( controller->GetPresentationService()->StartPresentation(
...@@ -247,20 +232,6 @@ void PresentationRequest::Trace(blink::Visitor* visitor) { ...@@ -247,20 +232,6 @@ void PresentationRequest::Trace(blink::Visitor* visitor) {
PresentationRequest::PresentationRequest(ExecutionContext* execution_context, PresentationRequest::PresentationRequest(ExecutionContext* execution_context,
const Vector<KURL>& urls) const Vector<KURL>& urls)
: ContextClient(execution_context), urls_(urls) { : ContextClient(execution_context), urls_(urls) {}
RecordConstructorOriginTypeAccess(*execution_context);
}
// static
void PresentationRequest::RecordConstructorOriginTypeAccess(
ExecutionContext& execution_context) {
if (execution_context.IsSecureContext()) {
UseCounter::Count(&execution_context,
WebFeature::kPresentationRequestSecureOrigin);
} else {
UseCounter::Count(&execution_context,
WebFeature::kPresentationRequestInsecureOrigin);
}
}
} // namespace blink } // namespace blink
...@@ -44,8 +44,6 @@ class MODULES_EXPORT PresentationRequest final ...@@ -44,8 +44,6 @@ class MODULES_EXPORT PresentationRequest final
// ScriptWrappable implementation. // ScriptWrappable implementation.
bool HasPendingActivity() const final; bool HasPendingActivity() const final;
static void RecordStartOriginTypeAccess(ExecutionContext&);
ScriptPromise start(ScriptState*); ScriptPromise start(ScriptState*);
ScriptPromise reconnect(ScriptState*, const String& id); ScriptPromise reconnect(ScriptState*, const String& id);
ScriptPromise getAvailability(ScriptState*); ScriptPromise getAvailability(ScriptState*);
...@@ -63,7 +61,6 @@ class MODULES_EXPORT PresentationRequest final ...@@ -63,7 +61,6 @@ class MODULES_EXPORT PresentationRequest final
private: private:
PresentationRequest(ExecutionContext*, const Vector<KURL>&); PresentationRequest(ExecutionContext*, const Vector<KURL>&);
static void RecordConstructorOriginTypeAccess(ExecutionContext&);
Member<PresentationAvailabilityProperty> availability_property_; Member<PresentationAvailabilityProperty> availability_property_;
Vector<KURL> urls_; Vector<KURL> urls_;
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
MeasureAs=PresentationRequestConstructor, MeasureAs=PresentationRequestConstructor,
RaisesException=Constructor, RaisesException=Constructor,
RuntimeEnabled=Presentation, RuntimeEnabled=Presentation,
SecureContext,
Exposed=Window Exposed=Window
] interface PresentationRequest : EventTarget { ] interface PresentationRequest : EventTarget {
[CallWith=ScriptState, MeasureAs=PresentationRequestStart] Promise<PresentationConnection> start(); [CallWith=ScriptState, MeasureAs=PresentationRequestStart] Promise<PresentationConnection> start();
......
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