Chromium Code Reviews| Index: chrome/browser/media/router/offscreen_presentation_manager.h |
| diff --git a/chrome/browser/media/router/offscreen_presentation_manager.h b/chrome/browser/media/router/offscreen_presentation_manager.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..ad6dd1d13937084e7d7d4c6e2f12e4e3cc0f05d1 |
| --- /dev/null |
| +++ b/chrome/browser/media/router/offscreen_presentation_manager.h |
| @@ -0,0 +1,184 @@ |
| +// Copyright 2016 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 CHROME_BROWSER_MEDIA_ROUTER_OFFSCREEN_PRESENTATION_MANAGER_H_ |
| +#define CHROME_BROWSER_MEDIA_ROUTER_OFFSCREEN_PRESENTATION_MANAGER_H_ |
| + |
| +#include <map> |
| +#include <memory> |
| +#include <string> |
| + |
| +#include "base/macros.h" |
| +#include "base/threading/thread_checker.h" |
| +#include "chrome/browser/media/router/render_frame_host_id.h" |
| +#include "components/keyed_service/core/keyed_service.h" |
| +#include "content/public/browser/presentation_service_delegate.h" |
| + |
| +class GURL; |
| + |
| +namespace media_router { |
|
mark a. foltz
2016/10/08 00:33:41
From a layering point of view I wonder if this bel
zhaobin
2016/10/12 02:27:32
Leave it in media/router folder for now. We will m
|
| + |
| +// Instances of this class manages all offscreen presentations started in the |
| +// associated Profile and facilitates communication between the controllers and |
| +// the receiver of an offscreen presentation. |
| +// |
| +// Example usage: |
| +// |
| +// (PresentationConnectionPtr - blink::mojom::PresentationConnectionPtr, mojo |
| +// handler for blink::PresentationConnection object in render process) |
| +// |
| +// Receiver is created to host the offscreen presentation and registers itself |
| +// so that controller frames can connect to it: |
| +// |
| +// OffscreenPresentationManager* manager = |
| +// OffscreenPresentationManagerFactory::GetOrCreateForBrowserContext( |
| +// Profile::FromBrowserContext(web_contents_->GetBrowserContext()) |
|
mark a. foltz
2016/10/08 00:33:41
Where does |web_contents_| come from here? Is it
zhaobin
2016/10/12 02:27:33
For controller, it is from controller's page;
For
|
| +// ->GetOriginalProfile()); |
|
mark a. foltz
2016/10/08 00:33:41
Nit: the factory should take care of returning the
zhaobin
2016/10/12 02:27:33
Done.
|
| +// manager->RegisterOffscreenPresentationReceiver(presentation_id, |
| +// base::Bind(&PresentationServiceImpl::OnReceiverConnectionAvailable)); |
|
mark a. foltz
2016/10/08 00:33:41
Should this be bound to the instance of the PSImpl
zhaobin
2016/10/12 02:27:32
Yes.
The object is bind to the function:
delegat
|
| +// ... |
|
mark a. foltz
2016/10/08 00:33:41
I would add a comment here like,
// Invoked on r
zhaobin
2016/10/12 02:27:33
Done.
|
| +// void PresentationServiceImpl::OnReceiverConnectionAvailable( |
| +// const content::PresentationSessionInfo& session, |
| +// PresentationConnectionPtr&& controller) { |
| +// [Create a PresentationConnection on receiver page. |
| +// Connect receiver PresentationConnectionPtr with controller |
| +// PresenatationConnectionPtr] |
|
mark a. foltz
2016/10/08 00:33:41
Typo
zhaobin
2016/10/12 02:27:32
Done.
|
| +// client_->OnReceiverConnectionAvailable(); |
| +// } |
| +// |
| +// Controller frame establishes connection with the receiver side, resulting |
| +// in a connection with the two endpoints being the controller |
| +// PresentationConnectionPtr and receiver PresentationConnectionPtr. |
| +// Note calling this will trigger receiver frame's |
| +// PresentationServiceImpl::OnReceiverConnectionAvailable. |
| +// |
| +// manager->RegisterOffscreenPresentationController( |
| +// presentation_id, controller_frame_id, controller_ptr); |
| +// |
| +// Send message from controller/receiver to receiver/controller: |
| +// |
| +// In controller's (or receiver's) PresentationConnctionPtr::SendString() { |
| +// ... |
| +// target_connection_->OnSessionMessageReceived(); |
| +// } |
| +// |
| +// A controller or receiver leaves the offscreen presentation (e.g., |
| +// due to navigation) by unregistering themselves from |
| +// OffscreenPresentationConnection object. |
| +// |
| +// When the receiver is no longer associated with an offscreen presentation, it |
| +// shall remove itself from associated controllers and then unregister itself |
| +// with OffscreenPresentationManager. Unregistration will prevent additional |
| +// controllers from establishing a connection with the receiver: |
| +// |
| +// In receiver's PSImpl::Reset() { |
| +// for (controller : offscreen_presentation_observers_) |
| +// controller->RemoveOffscreenPresentationClient(receiver); |
| +// } |
| +// manager->UnregisterOffscreenPresentationReceiver(presentation_id); |
| +// |
| +// This class is not thread safe. All functions must be invoked on the UI |
| +// thread. All callbacks passed into this class will also be invoked on UI |
| +// thread. |
| +class OffscreenPresentationManager : public KeyedService { |
| + public: |
| + ~OffscreenPresentationManager() override; |
| + |
| + // Registers controller PresentationConnectionPtr to presentation |
| + // with |presentation_id|, |render_frame_id|. |
| + // Creates a new presentation if no presentation with |presentation_id| |
| + // exists. |
| + // |controller| Not owned by this class. |
| + void RegisterOffscreenPresentationController( |
| + const std::string& presentation_id, |
| + const GURL& presentation_url, |
| + const RenderFrameHostId& render_frame_id, |
| + content::PresentationConnectionPtr controller); |
| + |
| + // Unregisters controller PSImpl to presentation with |presentation_id|, |
| + // |render_frame_id|. |
| + void UnregisterOffscreenPresentationController( |
| + const std::string& presentation_id, |
| + const RenderFrameHostId& render_frame_id); |
| + |
| + // Registers receiverConnectionAvailablecallback to presentation |
| + // with |presentation_id|. |
| + void OnOffscreenPresentationReceiverCreated( |
| + const std::string& presentation_id, |
| + const GURL& presentation_url, |
| + const content::ReceiverConnectionAvailableCallback& receiver_callback); |
| + |
| + void OnOffscreenPresentationReceiverTerminated( |
| + const std::string& presentation_id); |
| + |
| + private: |
| + // Represents an offscreen presentation registered with |
| + // OffscreenPresentationManager. |
| + // Contains callback to the receiver to inform it of new connections |
| + // established from a controller. |
| + // Contains set of controllers registered to OffscreenPresentationManager |
| + // before corresponding receiver. |
| + class OffscreenPresentation { |
| + public: |
| + explicit OffscreenPresentation(const std::string& presentation_id, |
|
mark a. foltz
2016/10/08 00:33:41
explicit is not needed for two-arg constructors
zhaobin
2016/10/12 02:27:33
Done.
|
| + const GURL& presentation_url); |
| + ~OffscreenPresentation(); |
| + |
| + void RegisterController(const RenderFrameHostId& render_frame_id, |
| + content::PresentationConnectionPtr controller); |
| + |
| + void UnregisterController(const RenderFrameHostId& render_frame_id); |
| + |
| + void RegisterReceiver( |
| + const content::ReceiverConnectionAvailableCallback& receiver_callback); |
| + |
| + private: |
| + friend class OffscreenPresentationManagerTest; |
| + friend class OffscreenPresentationManager; |
| + |
| + // presentation_id for current presentation. |
| + const std::string presentation_id_; |
| + |
| + // URL for current presentation. |
| + const GURL presentation_url_; |
| + |
| + // Bind to receiver frame's |
| + // PresentationServiceImpl::OnReceiverConnectionAvailable. |
| + content::ReceiverConnectionAvailableCallback receiver_callback_; |
| + |
| + // proxy to controller PSImpl |
| + // It only contains controllers registered before receiver_callback_ |
| + // is set. This map will be cleared in RegisterReceiver(). |
| + std::unordered_map<RenderFrameHostId, |
| + content::PresentationConnectionPtr, |
| + RenderFrameHostIdHasher> |
| + pending_controllers_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(OffscreenPresentation); |
| + }; |
| + |
| + private: |
| + friend class OffscreenPresentationManagerFactory; |
| + friend class OffscreenPresentationManagerTest; |
| + |
| + // Used by OffscreenPresentationManagerFactory::GetOrCreateForBrowserContext. |
| + OffscreenPresentationManager(); |
| + |
| + // Creates an offscreen presentation with |
| + // |presentation_id| and |presentation_url|. |
| + OffscreenPresentation* GetOrCreateOffscreenPresentation( |
| + const std::string& presentation_id, |
| + const GURL& presentation_url); |
| + |
| + // Maps from presentation ID to OffscreenPresentation. |
| + std::map<std::string, OffscreenPresentation*> offscreen_presentations_; |
| + |
| + base::ThreadChecker thread_checker_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(OffscreenPresentationManager); |
| +}; |
| + |
| +} // namespace media_router |
| + |
| +#endif // CHROME_BROWSER_MEDIA_ROUTER_OFFSCREEN_PRESENTATION_MANAGER_H_ |