blob: ddcf5e6c821a2119e8576165d1dd6670d6043436 [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.
#ifndef CONTENT_RENDERER_PRESENTATION_PRESENTATION_DISPATCHER_H_
#define CONTENT_RENDERER_PRESENTATION_PRESENTATION_DISPATCHER_H_
#include <stddef.h>
#include <stdint.h>
#include <map>
#include <memory>
#include <queue>
#include <set>
#include <string>
#include <vector>
#include "base/compiler_specific.h"
#include "base/id_map.h"
#include "base/macros.h"
#include "content/common/content_export.h"
#include "content/public/renderer/render_frame_observer.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "third_party/WebKit/public/platform/modules/presentation/WebPresentationClient.h"
#include "third_party/WebKit/public/platform/modules/presentation/presentation.mojom.h"
#include "url/gurl.h"
namespace blink {
class WebPresentationAvailabilityObserver;
class WebPresentationReceiver;
class WebString;
class WebURL;
template <typename T>
class WebVector;
} // namespace blink
namespace content {
class TestPresentationDispatcher;
// PresentationDispatcher is a delegate for Presentation API messages used by
// Blink. It forwards the calls to the Mojo PresentationService.
class CONTENT_EXPORT PresentationDispatcher
: public RenderFrameObserver,
public NON_EXPORTED_BASE(blink::WebPresentationClient),
public NON_EXPORTED_BASE(blink::mojom::PresentationServiceClient) {
public:
explicit PresentationDispatcher(RenderFrame* render_frame);
~PresentationDispatcher() override;
private:
friend class TestPresentationDispatcher;
FRIEND_TEST_ALL_PREFIXES(PresentationDispatcherTest, TestStartSession);
FRIEND_TEST_ALL_PREFIXES(PresentationDispatcherTest, TestStartSessionError);
FRIEND_TEST_ALL_PREFIXES(PresentationDispatcherTest, TestJoinSession);
FRIEND_TEST_ALL_PREFIXES(PresentationDispatcherTest, TestJoinSessionError);
FRIEND_TEST_ALL_PREFIXES(PresentationDispatcherTest, TestSendString);
FRIEND_TEST_ALL_PREFIXES(PresentationDispatcherTest, TestSendArrayBuffer);
FRIEND_TEST_ALL_PREFIXES(PresentationDispatcherTest, TestSendBlobData);
FRIEND_TEST_ALL_PREFIXES(PresentationDispatcherTest, TestCloseSession);
FRIEND_TEST_ALL_PREFIXES(PresentationDispatcherTest, TestTerminateSession);
FRIEND_TEST_ALL_PREFIXES(PresentationDispatcherTest,
TestListenForScreenAvailability);
FRIEND_TEST_ALL_PREFIXES(PresentationDispatcherTest,
TestSetDefaultPresentationUrls);
struct SendMessageRequest {
SendMessageRequest(blink::mojom::PresentationSessionInfoPtr session_info,
blink::mojom::ConnectionMessagePtr message);
~SendMessageRequest();
blink::mojom::PresentationSessionInfoPtr session_info;
blink::mojom::ConnectionMessagePtr message;
};
static SendMessageRequest* CreateSendTextMessageRequest(
const blink::WebURL& presentationUrl,
const blink::WebString& presentationId,
const blink::WebString& message);
static SendMessageRequest* CreateSendBinaryMessageRequest(
const blink::WebURL& presentationUrl,
const blink::WebString& presentationId,
blink::mojom::PresentationMessageType type,
const uint8_t* data,
size_t length);
// WebPresentationClient implementation.
void setController(blink::WebPresentationController* controller) override;
void setReceiver(blink::WebPresentationReceiver*) override;
void startSession(const blink::WebVector<blink::WebURL>& presentationUrls,
std::unique_ptr<blink::WebPresentationConnectionCallback>
callback) override;
void joinSession(const blink::WebVector<blink::WebURL>& presentationUrls,
const blink::WebString& presentationId,
std::unique_ptr<blink::WebPresentationConnectionCallback>
callback) override;
void sendString(const blink::WebURL& presentationUrl,
const blink::WebString& presentationId,
const blink::WebString& message) override;
void sendArrayBuffer(const blink::WebURL& presentationUrl,
const blink::WebString& presentationId,
const uint8_t* data,
size_t length) override;
void sendBlobData(const blink::WebURL& presentationUrl,
const blink::WebString& presentationId,
const uint8_t* data,
size_t length) override;
void closeSession(const blink::WebURL& presentationUrl,
const blink::WebString& presentationId) override;
void terminateSession(const blink::WebURL& presentationUrl,
const blink::WebString& presentationId) override;
void getAvailability(
const blink::WebURL& availabilityUrl,
std::unique_ptr<blink::WebPresentationAvailabilityCallbacks> callbacks)
override;
void startListening(blink::WebPresentationAvailabilityObserver*) override;
void stopListening(blink::WebPresentationAvailabilityObserver*) override;
void setDefaultPresentationUrls(
const blink::WebVector<blink::WebURL>& presentationUrls) override;
// RenderFrameObserver implementation.
void DidCommitProvisionalLoad(
bool is_new_navigation,
bool is_same_page_navigation) override;
void OnDestruct() override;
// blink::mojom::PresentationServiceClient
void OnScreenAvailabilityNotSupported(const GURL& url) override;
void OnScreenAvailabilityUpdated(const GURL& url, bool available) override;
void OnConnectionStateChanged(
blink::mojom::PresentationSessionInfoPtr session_info,
blink::mojom::PresentationConnectionState state) override;
void OnConnectionClosed(
blink::mojom::PresentationSessionInfoPtr session_info,
blink::mojom::PresentationConnectionCloseReason reason,
const std::string& message) override;
void OnConnectionMessagesReceived(
blink::mojom::PresentationSessionInfoPtr session_info,
std::vector<blink::mojom::ConnectionMessagePtr> messages) override;
void OnDefaultSessionStarted(
blink::mojom::PresentationSessionInfoPtr session_info) override;
void OnSessionCreated(
std::unique_ptr<blink::WebPresentationConnectionCallback> callback,
blink::mojom::PresentationSessionInfoPtr session_info,
blink::mojom::PresentationErrorPtr error);
void OnReceiverConnectionAvailable(
blink::mojom::PresentationSessionInfoPtr,
blink::mojom::PresentationConnectionPtr,
blink::mojom::PresentationConnectionRequest) override;
// Call to PresentationService to send the message in |request|.
// |session_info| and |message| of |reuqest| will be consumed.
// |HandleSendMessageRequests| will be invoked after the send is attempted.
void DoSendMessage(SendMessageRequest* request);
void HandleSendMessageRequests(bool success);
virtual void ConnectToPresentationServiceIfNeeded();
void UpdateListeningState();
// Used as a weak reference. Can be null since lifetime is bound to the frame.
blink::WebPresentationController* controller_;
blink::WebPresentationReceiver* receiver_;
blink::mojom::PresentationServicePtr presentation_service_;
mojo::Binding<blink::mojom::PresentationServiceClient> binding_;
// Message requests are queued here and only one message at a time is sent
// over mojo channel.
using MessageRequestQueue = std::queue<std::unique_ptr<SendMessageRequest>>;
MessageRequestQueue message_request_queue_;
enum class ListeningState {
INACTIVE,
WAITING,
ACTIVE,
};
using AvailabilityCallbacksMap =
IDMap<std::unique_ptr<blink::WebPresentationAvailabilityCallbacks>>;
using AvailabilityObserversSet =
std::set<blink::WebPresentationAvailabilityObserver*>;
// Tracks status of presentation displays availability for |availability_url|.
struct AvailabilityStatus {
explicit AvailabilityStatus(const GURL& availability_url);
~AvailabilityStatus();
const GURL url;
bool last_known_availability;
ListeningState listening_state;
AvailabilityCallbacksMap availability_callbacks;
AvailabilityObserversSet availability_observers;
};
// Map of AvailabilityStatus for known URLs.
std::map<GURL, std::unique_ptr<AvailabilityStatus>>
availability_status_;
// Updates the listening state of availability for |status| and notifies the
// client.
void UpdateListeningState(AvailabilityStatus* status);
DISALLOW_COPY_AND_ASSIGN(PresentationDispatcher);
};
} // namespace content
#endif // CONTENT_RENDERER_PRESENTATION_PRESENTATION_DISPATCHER_H_