Commit 3d8e2c2a authored by Guido Urdaneta's avatar Guido Urdaneta Committed by Commit Bot

[AudioOutputDevices] Check frame before checking device authorization.

This attempts to address an unusual crash involving WebLocalFrame and
SetSinkIdResolver.
This CL also removes a timer to fire an asynchronous task and uses
a per-frame task runner instead.

Bug: 941380
Change-Id: I9acf17ca3fd7d3dd8253b4e278adf583f4205f85
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1524267Reviewed-by: default avatarMarina Ciocea <marinaciocea@chromium.org>
Commit-Queue: Guido Urdaneta <guidou@chromium.org>
Cr-Commit-Position: refs/heads/master@{#641563}
parent b8ead26c
......@@ -17,6 +17,7 @@
#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
#include "third_party/blink/renderer/modules/audio_output_devices/set_sink_id_callbacks.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
namespace blink {
......@@ -34,11 +35,10 @@ class SetSinkIdResolver : public ScriptPromiseResolver {
void Trace(blink::Visitor*) override;
private:
void TimerFired(TimerBase*);
void DoSetSinkId();
Member<HTMLMediaElement> element_;
String sink_id_;
TaskRunnerTimer<SetSinkIdResolver> timer_;
DISALLOW_COPY_AND_ASSIGN(SetSinkIdResolver);
};
......@@ -57,24 +57,23 @@ SetSinkIdResolver::SetSinkIdResolver(ScriptState* script_state,
const String& sink_id)
: ScriptPromiseResolver(script_state),
element_(element),
sink_id_(sink_id),
timer_(ExecutionContext::From(script_state)
->GetTaskRunner(TaskType::kMiscPlatformAPI),
this,
&SetSinkIdResolver::TimerFired) {}
sink_id_(sink_id) {}
void SetSinkIdResolver::StartAsync() {
timer_.StartOneShot(TimeDelta(), FROM_HERE);
ExecutionContext* context = GetExecutionContext();
if (!context)
return;
context->GetTaskRunner(TaskType::kInternalMedia)
->PostTask(FROM_HERE, WTF::Bind(&SetSinkIdResolver::DoSetSinkId,
WrapWeakPersistent(this)));
}
void SetSinkIdResolver::TimerFired(TimerBase* timer) {
void SetSinkIdResolver::DoSetSinkId() {
ExecutionContext* context = GetExecutionContext();
std::unique_ptr<SetSinkIdCallbacks> callbacks =
std::make_unique<SetSinkIdCallbacks>(this, *element_, sink_id_);
WebMediaPlayer* web_media_player = element_->GetWebMediaPlayer();
if (web_media_player) {
// Using release() to transfer ownership because |webMediaPlayer| is a
// platform object that takes raw pointers.
web_media_player->SetSinkId(sink_id_, std::move(callbacks));
return;
}
......@@ -93,8 +92,15 @@ void SetSinkIdResolver::TimerFired(TimerBase* timer) {
auto& document = To<Document>(*context);
WebLocalFrameImpl* web_frame =
WebLocalFrameImpl::FromFrame(document.GetFrame());
web_frame->Client()->CheckIfAudioSinkExistsAndIsAuthorized(
sink_id_, std::move(callbacks));
if (web_frame && web_frame->Client()) {
web_frame->Client()->CheckIfAudioSinkExistsAndIsAuthorized(
sink_id_, std::move(callbacks));
} else {
Reject(DOMException::Create(
DOMExceptionCode::kSecurityError,
"Impossible to authorize device if there is no frame"));
return;
}
}
void SetSinkIdResolver::Trace(blink::Visitor* visitor) {
......
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