Commit 6e7a3bc8 authored by Emircan Uysaler's avatar Emircan Uysaler Committed by Commit Bot

Add blink code handling getDisplayMedia()

This is the first CL in adding getDisplayMedia() support in chromium. See the
bug and linked design doc for the detailed plan.

This CL adds getDisplayMedia() interface behind runtime enabled features flag
"GetDisplayMedia". This call will use the same call stack as getUserMedia() but
have different media request type and handling of constraints.
- Adds WebUserMediaRequest enums to differentiate this call.
- Adds specific handling of constraints in UserMediaRequest::Create(). As
defined in the spec, this accepts empty constraints.
- Currently ends up in a NotSupported error as chromium changes are landing.
- Adds first set of Layout Tests to check these expectations.

Intent To Implement:
https://groups.google.com/a/chromium.org/forum/#!msg/Blink-dev/j7k2nI_9nng/OE6IvgJyAQAJ

Bug: 326740
Change-Id: I03c54cab259a57db99449d9c4510c484f22c5b93
Reviewed-on: https://chromium-review.googlesource.com/1155942Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Reviewed-by: default avatarGuido Urdaneta <guidou@chromium.org>
Commit-Queue: Emircan Uysaler <emircan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#580733}
parent 4970b15b
<!DOCTYPE HTML>
<html>
<head>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<script>
promise_test(function() {
assert_idl_attribute(navigator, 'getDisplayMedia');
return navigator.getDisplayMedia().then(function(s) {
fail('getDisplayMedia should have failed');
}).catch(function(e) {
assert_equals(e.name, 'NotSupportedError');
});
}, 'getDisplayMedia() call');
</script>
</body>
</html>
......@@ -4665,6 +4665,7 @@ interface Navigator
getter xr
method constructor
method getBattery
method getDisplayMedia
method getGamepads
method getInstalledRelatedApps
method getUserMedia
......
......@@ -60,6 +60,11 @@ class BLINK_EXPORT WebUserMediaRequest {
kKillSwitchOn
};
enum class MediaType {
kUserMedia,
kDisplayMedia,
};
WebUserMediaRequest() = default;
WebUserMediaRequest(const WebUserMediaRequest& request) { Assign(request); }
~WebUserMediaRequest() { Reset(); }
......@@ -74,6 +79,7 @@ class BLINK_EXPORT WebUserMediaRequest {
bool Equals(const WebUserMediaRequest&) const;
void Assign(const WebUserMediaRequest&);
MediaType MediaRequestType() const;
bool Audio() const;
bool Video() const;
WebMediaConstraints AudioConstraints() const;
......
......@@ -57,6 +57,11 @@ void WebUserMediaRequest::Reset() {
private_.Reset();
}
WebUserMediaRequest::MediaType WebUserMediaRequest::MediaRequestType() const {
DCHECK(!IsNull());
return private_->MediaRequestType();
}
bool WebUserMediaRequest::Audio() const {
DCHECK(!IsNull());
return private_->Audio();
......
......@@ -30,6 +30,8 @@ blink_modules_sources("mediastream") {
"media_stream_track_content_hint.h",
"media_stream_track_event.cc",
"media_stream_track_event.h",
"navigator_display_media.cc",
"navigator_display_media.h",
"navigator_media_stream.cc",
"navigator_media_stream.h",
"navigator_user_media.cc",
......
......@@ -20,7 +20,6 @@
#include "third_party/blink/renderer/modules/mediastream/media_stream_constraints.h"
#include "third_party/blink/renderer/modules/mediastream/navigator_media_stream.h"
#include "third_party/blink/renderer/modules/mediastream/user_media_controller.h"
#include "third_party/blink/renderer/modules/mediastream/user_media_request.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
......@@ -105,6 +104,16 @@ ScriptPromise MediaDevices::enumerateDevices(ScriptState* script_state) {
ScriptPromise MediaDevices::getUserMedia(ScriptState* script_state,
const MediaStreamConstraints& options,
ExceptionState& exception_state) {
return SendUserMediaRequest(script_state,
WebUserMediaRequest::MediaType::kUserMedia,
options, exception_state);
}
ScriptPromise MediaDevices::SendUserMediaRequest(
ScriptState* script_state,
WebUserMediaRequest::MediaType media_type,
const MediaStreamConstraints& options,
ExceptionState& exception_state) {
ScriptPromiseResolver* resolver = ScriptPromiseResolver::Create(script_state);
PromiseResolverCallbacks* callbacks =
PromiseResolverCallbacks::Create(resolver);
......@@ -121,7 +130,7 @@ ScriptPromise MediaDevices::getUserMedia(ScriptState* script_state,
MediaErrorState error_state;
UserMediaRequest* request = UserMediaRequest::Create(
document, user_media, options, callbacks, error_state);
document, user_media, media_type, options, callbacks, error_state);
if (!request) {
DCHECK(error_state.HadException());
if (error_state.CanGenerateException()) {
......
......@@ -13,6 +13,7 @@
#include "third_party/blink/renderer/core/dom/pausable_object.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/mediastream/media_device_info.h"
#include "third_party/blink/renderer/modules/mediastream/user_media_request.h"
#include "third_party/blink/renderer/modules/modules_export.h"
#include "third_party/blink/renderer/platform/async_method_runner.h"
#include "third_party/blink/renderer/platform/heap/heap_allocator.h"
......@@ -44,6 +45,10 @@ class MODULES_EXPORT MediaDevices final
ScriptPromise getUserMedia(ScriptState*,
const MediaStreamConstraints&,
ExceptionState&);
ScriptPromise SendUserMediaRequest(ScriptState*,
WebUserMediaRequest::MediaType,
const MediaStreamConstraints&,
ExceptionState&);
// EventTarget overrides.
const AtomicString& InterfaceName() const override;
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/modules/mediastream/navigator_display_media.h"
#include "third_party/blink/public/platform/platform.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/modules/mediastream/media_devices.h"
#include "third_party/blink/renderer/modules/mediastream/navigator_user_media.h"
namespace blink {
ScriptPromise NavigatorDisplayMedia::getDisplayMedia(
ScriptState* script_state,
Navigator& navigator,
const MediaStreamConstraints& options,
ExceptionState& exception_state) {
MediaDevices* const media_devices =
NavigatorUserMedia::mediaDevices(navigator);
if (!media_devices) {
return ScriptPromise::RejectWithDOMException(
script_state, DOMException::Create(DOMExceptionCode::kNotSupportedError,
"Current frame is detached."));
}
return media_devices->SendUserMediaRequest(
script_state, WebUserMediaRequest::MediaType::kDisplayMedia, options,
exception_state);
}
} // namespace blink
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_NAVIGATOR_DISPLAY_MEDIA_H_
#define THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_NAVIGATOR_DISPLAY_MEDIA_H_
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/core/frame/navigator.h"
namespace blink {
class ExceptionState;
class MediaStreamConstraints;
class ScriptPromise;
class ScriptState;
class NavigatorDisplayMedia {
STATIC_ONLY(NavigatorDisplayMedia);
public:
static ScriptPromise getDisplayMedia(ScriptState*,
Navigator&,
const MediaStreamConstraints&,
ExceptionState&);
};
} // namespace blink
#endif // THIRD_PARTY_BLINK_RENDERER_MODULES_MEDIASTREAM_NAVIGATOR_DISPLAY_MEDIA_H_
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// https://w3c.github.io/mediacapture-screen-share/
[
ImplementedAs = NavigatorDisplayMedia,
RuntimeEnabled = GetDisplayMedia
] partial interface Navigator {
[CallWith = ScriptState, RaisesException] Promise<MediaStream>
getDisplayMedia(optional MediaStreamConstraints constraints);
};
......@@ -44,12 +44,14 @@ UserMediaClient::UserMediaClient(WebUserMediaClient* client)
: client_(client) {}
void UserMediaClient::RequestUserMedia(UserMediaRequest* request) {
if (client_) {
// TODO(emircan): Hook up kDisplayMedia calls.
if (client_ && request->MediaRequestType() !=
WebUserMediaRequest::MediaType::kDisplayMedia) {
client_->RequestUserMedia(request);
} else {
request->Fail(WebUserMediaRequest::Error::kNotSupported,
"User Media support is disabled");
return;
}
request->Fail(WebUserMediaRequest::Error::kNotSupported,
"User Media support is disabled");
}
void UserMediaClient::CancelUserMediaRequest(UserMediaRequest* request) {
......
......@@ -362,6 +362,7 @@ class UserMediaRequest::V8Callbacks final : public UserMediaRequest::Callbacks {
UserMediaRequest* UserMediaRequest::Create(
ExecutionContext* context,
UserMediaController* controller,
WebUserMediaRequest::MediaType media_type,
const MediaStreamConstraints& options,
Callbacks* callbacks,
MediaErrorState& error_state) {
......@@ -375,10 +376,17 @@ UserMediaRequest* UserMediaRequest::Create(
if (error_state.HadException())
return nullptr;
if (audio.IsNull() && video.IsNull()) {
error_state.ThrowTypeError(
"At least one of audio and video must be requested");
return nullptr;
switch (media_type) {
case WebUserMediaRequest::MediaType::kUserMedia: {
if (audio.IsNull() && video.IsNull()) {
error_state.ThrowTypeError(
"At least one of audio and video must be requested");
return nullptr;
}
break;
}
case WebUserMediaRequest::MediaType::kDisplayMedia:
break;
}
if (!audio.IsNull())
......@@ -386,7 +394,8 @@ UserMediaRequest* UserMediaRequest::Create(
if (!video.IsNull())
CountVideoConstraintUses(context, video);
return new UserMediaRequest(context, controller, audio, video, callbacks);
return new UserMediaRequest(context, controller, media_type, audio, video,
callbacks);
}
UserMediaRequest* UserMediaRequest::Create(
......@@ -396,23 +405,27 @@ UserMediaRequest* UserMediaRequest::Create(
V8NavigatorUserMediaSuccessCallback* success_callback,
V8NavigatorUserMediaErrorCallback* error_callback,
MediaErrorState& error_state) {
return Create(context, controller, options,
V8Callbacks::Create(success_callback, error_callback),
return Create(context, controller, WebUserMediaRequest::MediaType::kUserMedia,
options, V8Callbacks::Create(success_callback, error_callback),
error_state);
}
UserMediaRequest* UserMediaRequest::CreateForTesting(
const WebMediaConstraints& audio,
const WebMediaConstraints& video) {
return new UserMediaRequest(nullptr, nullptr, audio, video, nullptr);
return new UserMediaRequest(nullptr, nullptr,
WebUserMediaRequest::MediaType::kUserMedia, audio,
video, nullptr);
}
UserMediaRequest::UserMediaRequest(ExecutionContext* context,
UserMediaController* controller,
WebUserMediaRequest::MediaType media_type,
WebMediaConstraints audio,
WebMediaConstraints video,
Callbacks* callbacks)
: ContextLifecycleObserver(context),
media_type_(media_type),
audio_(audio),
video_(video),
should_disable_hardware_noise_suppression_(
......@@ -432,6 +445,10 @@ UserMediaRequest::UserMediaRequest(ExecutionContext* context,
UserMediaRequest::~UserMediaRequest() = default;
WebUserMediaRequest::MediaType UserMediaRequest::MediaRequestType() const {
return media_type_;
}
bool UserMediaRequest::Audio() const {
return !audio_.IsNull();
}
......
......@@ -73,6 +73,7 @@ class MODULES_EXPORT UserMediaRequest final
static UserMediaRequest* Create(ExecutionContext*,
UserMediaController*,
WebUserMediaRequest::MediaType media_type,
const MediaStreamConstraints& options,
Callbacks*,
MediaErrorState&);
......@@ -94,6 +95,7 @@ class MODULES_EXPORT UserMediaRequest final
void FailConstraint(const String& constraint_name, const String& message);
void Fail(WebUserMediaRequest::Error name, const String& message);
WebUserMediaRequest::MediaType MediaRequestType() const;
bool Audio() const;
bool Video() const;
WebMediaConstraints AudioConstraints() const;
......@@ -115,10 +117,12 @@ class MODULES_EXPORT UserMediaRequest final
private:
UserMediaRequest(ExecutionContext*,
UserMediaController*,
WebUserMediaRequest::MediaType media_type,
WebMediaConstraints audio,
WebMediaConstraints video,
Callbacks*);
WebUserMediaRequest::MediaType media_type_;
WebMediaConstraints audio_;
WebMediaConstraints video_;
bool should_disable_hardware_noise_suppression_;
......
......@@ -737,6 +737,7 @@ modules_dependency_idl_files =
"mediasource/html_video_element_media_source.idl",
"mediasource/url_media_source.idl",
"mediastream/media_stream_track_content_hint.idl",
"mediastream/navigator_display_media.idl",
"mediastream/navigator_media_stream.idl",
"mediastream/navigator_user_media.idl",
"mediastream/url_media_stream.idl",
......
......@@ -563,6 +563,10 @@
name: "GamepadVibration",
status: "experimental",
},
{
name: "GetDisplayMedia",
status: "experimental",
},
{
name: "HeapCompaction",
status: "stable",
......
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