blob: 0261a56aa06948533061c24d97d7dadb305529f1 [file] [log] [blame]
// Copyright 2015 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 "modules/presentation/PresentationReceiver.h"
#include "bindings/core/v8/ScriptPromise.h"
#include "bindings/core/v8/ScriptPromiseResolver.h"
#include "core/dom/DOMException.h"
#include "core/dom/Document.h"
#include "core/dom/ExceptionCode.h"
#include "core/dom/ExecutionContext.h"
#include "core/frame/Deprecation.h"
#include "core/frame/LocalDOMWindow.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/Navigator.h"
#include "core/frame/UseCounter.h"
#include "modules/presentation/NavigatorPresentation.h"
#include "modules/presentation/Presentation.h"
#include "modules/presentation/PresentationConnection.h"
#include "modules/presentation/PresentationConnectionList.h"
#include "public/platform/modules/presentation/WebPresentationClient.h"
namespace blink {
PresentationReceiver::PresentationReceiver(LocalFrame* frame,
WebPresentationClient* client)
: ContextClient(frame) {
connection_list_ = new PresentationConnectionList(frame->GetDocument());
if (client)
client->SetReceiver(this);
}
// static
PresentationReceiver* PresentationReceiver::From(Document& document) {
if (!document.GetFrame() || !document.GetFrame()->DomWindow())
return nullptr;
Navigator& navigator = *document.GetFrame()->DomWindow()->navigator();
Presentation* presentation = NavigatorPresentation::presentation(navigator);
if (!presentation)
return nullptr;
return presentation->receiver();
}
ScriptPromise PresentationReceiver::connectionList(ScriptState* script_state) {
ExecutionContext* execution_context = ExecutionContext::From(script_state);
RecordOriginTypeAccess(*execution_context);
if (!connection_list_property_) {
connection_list_property_ = new ConnectionListProperty(
execution_context, this, ConnectionListProperty::kReady);
}
if (!connection_list_->IsEmpty() && connection_list_property_->GetState() ==
ScriptPromisePropertyBase::kPending)
connection_list_property_->Resolve(connection_list_);
return connection_list_property_->Promise(script_state->World());
}
WebPresentationConnection* PresentationReceiver::OnReceiverConnectionAvailable(
const WebPresentationInfo& presentation_info) {
// take() will call PresentationReceiver::registerConnection()
// and register the connection.
auto connection = PresentationConnection::Take(this, presentation_info);
// receiver.connectionList property not accessed
if (!connection_list_property_)
return connection;
if (connection_list_property_->GetState() ==
ScriptPromisePropertyBase::kPending) {
connection_list_property_->Resolve(connection_list_);
} else if (connection_list_property_->GetState() ==
ScriptPromisePropertyBase::kResolved) {
connection_list_->DispatchConnectionAvailableEvent(connection);
}
return connection;
}
void PresentationReceiver::DidChangeConnectionState(
WebPresentationConnectionState state) {
// TODO(zhaobin): remove or modify DCHECK when receiver supports more
// connection state change.
DCHECK(state == WebPresentationConnectionState::kTerminated);
for (auto connection : connection_list_->connections()) {
connection->NotifyTargetConnection(state);
connection->DidChangeState(state, false /* shouldDispatchEvent */);
}
}
void PresentationReceiver::TerminateConnection() {
if (!GetFrame())
return;
auto* window = GetFrame()->DomWindow();
if (!window || window->closed())
return;
window->close(window);
}
void PresentationReceiver::RemoveConnection(
WebPresentationConnection* connection) {
DCHECK(connection_list_);
connection_list_->RemoveConnection(connection);
}
void PresentationReceiver::RegisterConnection(
PresentationConnection* connection) {
DCHECK(connection_list_);
connection_list_->AddConnection(connection);
}
// static
void PresentationReceiver::RecordOriginTypeAccess(
ExecutionContext& execution_context) {
if (execution_context.IsSecureContext()) {
UseCounter::Count(&execution_context,
WebFeature::kPresentationReceiverSecureOrigin);
} else {
Deprecation::CountDeprecation(
&execution_context, WebFeature::kPresentationReceiverInsecureOrigin);
}
}
DEFINE_TRACE(PresentationReceiver) {
visitor->Trace(connection_list_);
visitor->Trace(connection_list_property_);
ContextClient::Trace(visitor);
}
} // namespace blink