Commit fa5c5890 authored by Julie Jeongeun Kim's avatar Julie Jeongeun Kim Committed by Commit Bot

Use [RaisesException] for immediate promise rejections in mediastream

This is a part of effort for using [RaisesException] when synchronously
rejecting a promise.

It uses [RaisesException] for
//third_party/blink/renderer/modules/mediastream.

Bug: 1001114
Change-Id: I3fde5022c2a992e5f04e4419fd9e960c5a42dbb6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1988126Reviewed-by: default avatarTommi <tommi@chromium.org>
Commit-Queue: Julie Kim <jkim@igalia.com>
Cr-Commit-Position: refs/heads/master@{#728760}
parent 1d8aa4c1
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "third_party/blink/renderer/modules/mediastream/media_track_supported_constraints.h" #include "third_party/blink/renderer/modules/mediastream/media_track_supported_constraints.h"
#include "third_party/blink/renderer/modules/mediastream/navigator_media_stream.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_controller.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/heap/heap.h" #include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms.h" #include "third_party/blink/renderer/platform/mediastream/webrtc_uma_histograms.h"
...@@ -63,15 +64,15 @@ MediaDevices::MediaDevices(ExecutionContext* context) ...@@ -63,15 +64,15 @@ MediaDevices::MediaDevices(ExecutionContext* context)
MediaDevices::~MediaDevices() = default; MediaDevices::~MediaDevices() = default;
ScriptPromise MediaDevices::enumerateDevices(ScriptState* script_state) { ScriptPromise MediaDevices::enumerateDevices(ScriptState* script_state,
ExceptionState& exception_state) {
UpdateWebRTCMethodCount(RTCAPIName::kEnumerateDevices); UpdateWebRTCMethodCount(RTCAPIName::kEnumerateDevices);
LocalFrame* frame = LocalFrame* frame =
To<Document>(ExecutionContext::From(script_state))->GetFrame(); To<Document>(ExecutionContext::From(script_state))->GetFrame();
if (!frame) { if (!frame) {
return ScriptPromise::RejectWithDOMException( exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
script_state, "Current frame is detached.");
MakeGarbageCollected<DOMException>(DOMExceptionCode::kNotSupportedError, return ScriptPromise();
"Current frame is detached."));
} }
auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state); auto* resolver = MakeGarbageCollected<ScriptPromiseResolver>(script_state);
...@@ -111,11 +112,10 @@ ScriptPromise MediaDevices::SendUserMediaRequest( ...@@ -111,11 +112,10 @@ ScriptPromise MediaDevices::SendUserMediaRequest(
UserMediaController* user_media = UserMediaController* user_media =
UserMediaController::From(document->GetFrame()); UserMediaController::From(document->GetFrame());
if (!user_media) { if (!user_media) {
return ScriptPromise::RejectWithDOMException( exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
script_state, MakeGarbageCollected<DOMException>( "No media device controller available; "
DOMExceptionCode::kNotSupportedError, "is this a detached window?");
"No media device controller available; is this a " return ScriptPromise();
"detached window?"));
} }
MediaErrorState error_state; MediaErrorState error_state;
...@@ -134,9 +134,9 @@ ScriptPromise MediaDevices::SendUserMediaRequest( ...@@ -134,9 +134,9 @@ ScriptPromise MediaDevices::SendUserMediaRequest(
String error_message; String error_message;
if (!request->IsSecureContextUse(error_message)) { if (!request->IsSecureContextUse(error_message)) {
return ScriptPromise::RejectWithDOMException( exception_state.ThrowDOMException(DOMExceptionCode::kNotSupportedError,
script_state, MakeGarbageCollected<DOMException>( error_message);
DOMExceptionCode::kNotSupportedError, error_message)); return ScriptPromise();
} }
auto promise = resolver->Promise(); auto promise = resolver->Promise();
request->Start(); request->Start();
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
namespace blink { namespace blink {
class ExceptionState;
class LocalFrame; class LocalFrame;
class MediaStreamConstraints; class MediaStreamConstraints;
class MediaTrackSupportedConstraints; class MediaTrackSupportedConstraints;
...@@ -41,7 +42,7 @@ class MODULES_EXPORT MediaDevices final ...@@ -41,7 +42,7 @@ class MODULES_EXPORT MediaDevices final
explicit MediaDevices(ExecutionContext*); explicit MediaDevices(ExecutionContext*);
~MediaDevices() override; ~MediaDevices() override;
ScriptPromise enumerateDevices(ScriptState*); ScriptPromise enumerateDevices(ScriptState*, ExceptionState&);
MediaTrackSupportedConstraints* getSupportedConstraints() const; MediaTrackSupportedConstraints* getSupportedConstraints() const;
ScriptPromise getUserMedia(ScriptState*, ScriptPromise getUserMedia(ScriptState*,
const MediaStreamConstraints*, const MediaStreamConstraints*,
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
] interface MediaDevices : EventTarget { ] interface MediaDevices : EventTarget {
[RuntimeEnabled=OnDeviceChange] attribute EventHandler ondevicechange; [RuntimeEnabled=OnDeviceChange] attribute EventHandler ondevicechange;
[ [
CallWith = ScriptState, HighEntropy, MeasureAs = MediaDevicesEnumerateDevices CallWith = ScriptState, RaisesException, HighEntropy, MeasureAs = MediaDevicesEnumerateDevices
] Promise<sequence<MediaDeviceInfo>> ] Promise<sequence<MediaDeviceInfo>>
enumerateDevices(); enumerateDevices();
MediaTrackSupportedConstraints getSupportedConstraints(); MediaTrackSupportedConstraints getSupportedConstraints();
......
...@@ -163,57 +163,6 @@ class MockMediaDevicesDispatcherHost ...@@ -163,57 +163,6 @@ class MockMediaDevicesDispatcherHost
mojo::Receiver<mojom::blink::MediaDevicesDispatcherHost> receiver_{this}; mojo::Receiver<mojom::blink::MediaDevicesDispatcherHost> receiver_{this};
}; };
class PromiseObserver {
public:
PromiseObserver(ScriptState* script_state, ScriptPromise promise)
: is_rejected_(false), is_fulfilled_(false) {
v8::Local<v8::Function> on_fulfilled = MyScriptFunction::CreateFunction(
script_state, &is_fulfilled_, &saved_arg_);
v8::Local<v8::Function> on_rejected = MyScriptFunction::CreateFunction(
script_state, &is_rejected_, &saved_arg_);
promise.Then(on_fulfilled, on_rejected);
}
bool isDecided() { return is_rejected_ || is_fulfilled_; }
bool isFulfilled() { return is_fulfilled_; }
bool isRejected() { return is_rejected_; }
ScriptValue argument() { return saved_arg_; }
void Trace(blink::Visitor* visitor) { visitor->Trace(saved_arg_); }
private:
class MyScriptFunction : public ScriptFunction {
public:
static v8::Local<v8::Function> CreateFunction(ScriptState* script_state,
bool* flag_to_set,
ScriptValue* arg_to_set) {
MyScriptFunction* self = MakeGarbageCollected<MyScriptFunction>(
script_state, flag_to_set, arg_to_set);
return self->BindToV8Function();
}
MyScriptFunction(ScriptState* script_state,
bool* flag_to_set,
ScriptValue* arg_to_set)
: ScriptFunction(script_state),
flag_to_set_(flag_to_set),
arg_to_set_(arg_to_set) {}
ScriptValue Call(ScriptValue arg) override {
*flag_to_set_ = true;
*arg_to_set_ = arg;
return arg;
}
private:
bool* flag_to_set_;
ScriptValue* arg_to_set_;
};
bool is_rejected_;
bool is_fulfilled_;
ScriptValue saved_arg_;
};
class MediaDevicesTest : public testing::Test { class MediaDevicesTest : public testing::Test {
public: public:
using MediaDeviceInfos = HeapVector<Member<MediaDeviceInfo>>; using MediaDeviceInfos = HeapVector<Member<MediaDeviceInfo>>;
...@@ -298,24 +247,13 @@ TEST_F(MediaDevicesTest, GetUserMediaCanBeCalled) { ...@@ -298,24 +247,13 @@ TEST_F(MediaDevicesTest, GetUserMediaCanBeCalled) {
GetMediaDevices(scope.GetExecutionContext()) GetMediaDevices(scope.GetExecutionContext())
->getUserMedia(scope.GetScriptState(), constraints, ->getUserMedia(scope.GetScriptState(), constraints,
scope.GetExceptionState()); scope.GetExceptionState());
ASSERT_FALSE(promise.IsEmpty()); ASSERT_TRUE(promise.IsEmpty());
PromiseObserver promise_observer(scope.GetScriptState(), promise);
EXPECT_FALSE(promise_observer.isDecided());
v8::MicrotasksScope::PerformCheckpoint(scope.GetIsolate());
EXPECT_TRUE(promise_observer.isDecided());
// In the default test environment, we expect a DOM rejection because // In the default test environment, we expect a DOM rejection because
// the script state's execution context's document's frame doesn't // the script state's execution context's document's frame doesn't
// have an UserMediaController. // have an UserMediaController.
EXPECT_TRUE(promise_observer.isRejected()); DCHECK_EQ(scope.GetExceptionState().Code(),
// TODO(hta): Check that the correct error ("not supported") is returned. ToExceptionCode(DOMExceptionCode::kNotSupportedError));
EXPECT_FALSE(promise_observer.argument().IsNull()); VLOG(1) << "Exception message is" << scope.GetExceptionState().Message();
// This log statement is included as a demonstration of how to get the string
// value of the argument.
VLOG(1) << "Argument is"
<< ToCoreString(promise_observer.argument()
.V8Value()
->ToString(scope.GetContext())
.ToLocalChecked());
} }
TEST_F(MediaDevicesTest, EnumerateDevices) { TEST_F(MediaDevicesTest, EnumerateDevices) {
...@@ -323,8 +261,8 @@ TEST_F(MediaDevicesTest, EnumerateDevices) { ...@@ -323,8 +261,8 @@ TEST_F(MediaDevicesTest, EnumerateDevices) {
auto* media_devices = GetMediaDevices(scope.GetExecutionContext()); auto* media_devices = GetMediaDevices(scope.GetExecutionContext());
media_devices->SetEnumerateDevicesCallbackForTesting( media_devices->SetEnumerateDevicesCallbackForTesting(
WTF::Bind(&MediaDevicesTest::DevicesEnumerated, WTF::Unretained(this))); WTF::Bind(&MediaDevicesTest::DevicesEnumerated, WTF::Unretained(this)));
ScriptPromise promise = ScriptPromise promise = media_devices->enumerateDevices(
media_devices->enumerateDevices(scope.GetScriptState()); scope.GetScriptState(), scope.GetExceptionState());
platform()->RunUntilIdle(); platform()->RunUntilIdle();
ASSERT_FALSE(promise.IsEmpty()); ASSERT_FALSE(promise.IsEmpty());
...@@ -385,8 +323,8 @@ TEST_F(MediaDevicesTest, EnumerateDevicesAfterConnectionError) { ...@@ -385,8 +323,8 @@ TEST_F(MediaDevicesTest, EnumerateDevicesAfterConnectionError) {
CloseBinding(); CloseBinding();
platform()->RunUntilIdle(); platform()->RunUntilIdle();
ScriptPromise promise = ScriptPromise promise = media_devices->enumerateDevices(
media_devices->enumerateDevices(scope.GetScriptState()); scope.GetScriptState(), scope.GetExceptionState());
platform()->RunUntilIdle(); platform()->RunUntilIdle();
ASSERT_FALSE(promise.IsEmpty()); ASSERT_FALSE(promise.IsEmpty());
EXPECT_TRUE(dispatcher_host_connection_error()); EXPECT_TRUE(dispatcher_host_connection_error());
...@@ -403,8 +341,8 @@ TEST_F(MediaDevicesTest, EnumerateDevicesBeforeConnectionError) { ...@@ -403,8 +341,8 @@ TEST_F(MediaDevicesTest, EnumerateDevicesBeforeConnectionError) {
WTF::Unretained(this))); WTF::Unretained(this)));
EXPECT_FALSE(dispatcher_host_connection_error()); EXPECT_FALSE(dispatcher_host_connection_error());
ScriptPromise promise = ScriptPromise promise = media_devices->enumerateDevices(
media_devices->enumerateDevices(scope.GetScriptState()); scope.GetScriptState(), scope.GetExceptionState());
platform()->RunUntilIdle(); platform()->RunUntilIdle();
ASSERT_FALSE(promise.IsEmpty()); ASSERT_FALSE(promise.IsEmpty());
......
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