forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Media Router] Custom Controls 1 - Add MediaStatus, MediaRouteControl…
…ler, and mojo interfaces This CL adds MediaRouteController that will forward media controller commands from the custom controls WebUI to the Media Router component extension, and will receive MediaStatus updates from the extension which it then will forward to its Observer(s) (= to the WebUI). This patch includes mojo interfaces/structs that were first reviewed in this patch [1]. The MediaController mojo interface will be implemented in the component extension (not a part of Chromium), and will receive commands from MediaRouteController. MediaRouteController implements the MediaStatusObserver mojo interface and receives updates from the extension. Typemapping between media_router::mojom::MediaStatus and media_router::MediaStatus is also included in this CL. Changes in extensions/renderer/ are for exposing the new mojo interfaces to the component extension. The Chromium-side implementation of custom controls redesign will be done in these patches: 1. Mojo/MediaStatus/MediaRouteController: this patch 2. MediaRouter::GetRouteController(): http://crrev/2728543009 3. MRUI/MRWebUIMessageHandler: http://crrev/2731033002 4. Custom controls WebUI: http://crrev/2725503002 Custom controls redesign design doc: https://docs.google.com/document/d/1_8QxdFIiiJX39jR1Wi1Zn9FW-Y66EMvX1GmQZvjN4G0/edit [1] https://codereview.chromium.org/2674363002/ BUG=684636,684635 Review-Url: https://codereview.chromium.org/2727123002 Cr-Commit-Position: refs/heads/master@{#458922}
- Loading branch information
Showing
15 changed files
with
647 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// Copyright 2017 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 "chrome/browser/media/router/media_status.h" | ||
|
||
namespace media_router { | ||
|
||
MediaStatus::MediaStatus() = default; | ||
|
||
MediaStatus::MediaStatus(const MediaStatus& other) = default; | ||
|
||
MediaStatus::~MediaStatus() = default; | ||
|
||
MediaStatus& MediaStatus::operator=(const MediaStatus& other) = default; | ||
|
||
bool MediaStatus::operator==(const MediaStatus& other) const { | ||
return title == other.title && description == other.description && | ||
can_play_pause == other.can_play_pause && can_mute == other.can_mute && | ||
can_set_volume == other.can_set_volume && can_seek == other.can_seek && | ||
is_paused == other.is_paused && is_muted == other.is_muted && | ||
volume == other.volume && duration == other.duration && | ||
current_time == other.current_time; | ||
} | ||
|
||
} // namespace media_router |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
// Copyright 2017 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_MEDIA_STATUS_H_ | ||
#define CHROME_BROWSER_MEDIA_ROUTER_MEDIA_STATUS_H_ | ||
|
||
#include <string> | ||
|
||
#include "base/time/time.h" | ||
|
||
namespace media_router { | ||
|
||
// Represents the current state of a media content. | ||
struct MediaStatus { | ||
public: | ||
MediaStatus(); | ||
MediaStatus(const MediaStatus& other); | ||
~MediaStatus(); | ||
|
||
MediaStatus& operator=(const MediaStatus& other); | ||
bool operator==(const MediaStatus& other) const; | ||
|
||
// The main title of the media. For example, in a MediaStatus representing | ||
// a YouTube Cast session, this could be the title of the video. | ||
std::string title; | ||
|
||
// Text describing the media, or a secondary title. For example, in a | ||
// MediaStatus representing a YouTube Cast session, this could be "YouTube". | ||
std::string description; | ||
|
||
// If this is true, the media can be played and paused. | ||
bool can_play_pause = false; | ||
|
||
// If this is true, the media can be muted and unmuted. | ||
bool can_mute = false; | ||
|
||
// If this is true, the media's volume can be changed. | ||
bool can_set_volume = false; | ||
|
||
// If this is true, the media's current playback position can be changed. | ||
bool can_seek = false; | ||
|
||
bool is_paused = false; | ||
|
||
bool is_muted = false; | ||
|
||
// Current volume of the media, with 1 being the highest and 0 being the | ||
// lowest/no sound. When |is_muted| is true, there should be no sound | ||
// regardless of |volume|. | ||
float volume = 0; | ||
|
||
// The length of the media. A value of zero indicates that this is a media | ||
// with no set duration (e.g. a live stream). | ||
base::TimeDelta duration; | ||
|
||
// Current playback position. Must be less than or equal to |duration|. | ||
base::TimeDelta current_time; | ||
}; | ||
|
||
} // namespace media_router | ||
|
||
#endif // CHROME_BROWSER_MEDIA_ROUTER_MEDIA_STATUS_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// Copyright 2017 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. | ||
|
||
module media_router.mojom; | ||
|
||
import "chrome/browser/media/router/mojo/media_status.mojom"; | ||
import "mojo/common/time.mojom"; | ||
|
||
// Interface for a controller to change the current state of a media content. | ||
// This interface should be kept free of details specific to Media Router, so | ||
// that it can be moved to the media namespace and be reused for other features | ||
// in the future. | ||
interface MediaController { | ||
// Starts playing the media if it is paused. Is a no-op if not supported by | ||
// the media or the media is already playing. | ||
Play(); | ||
|
||
// Pauses the media if it is playing. Is a no-op if not supported by the media | ||
// or the media is already paused. | ||
Pause(); | ||
|
||
// Mutes the media if |mute| is true, and unmutes it if false. Is a no-op if | ||
// not supported by the media. | ||
SetMute(bool mute); | ||
|
||
// Changes the current volume of the media, with 1 being the highest and 0 | ||
// being the lowest/no sound. Does not change the (un)muted state of the | ||
// media. Is a no-op if not supported by the media. | ||
SetVolume(float volume); | ||
|
||
// Sets the current playback position. |time| must be less than or equal to | ||
// the duration of the media. Is a no-op if the media doesn't support seeking. | ||
Seek(mojo.common.mojom.TimeDelta time); | ||
}; |
80 changes: 80 additions & 0 deletions
80
chrome/browser/media/router/mojo/media_route_controller.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// Copyright 2017 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 "chrome/browser/media/router/mojo/media_route_controller.h" | ||
|
||
#include <utility> | ||
|
||
namespace media_router { | ||
|
||
MediaRouteController::Observer::Observer( | ||
scoped_refptr<MediaRouteController> controller) | ||
: controller_(std::move(controller)) { | ||
controller_->AddObserver(this); | ||
} | ||
|
||
MediaRouteController::Observer::~Observer() { | ||
if (controller_) | ||
controller_->RemoveObserver(this); | ||
} | ||
|
||
void MediaRouteController::Observer::InvalidateController() { | ||
controller_->RemoveObserver(this); | ||
controller_ = nullptr; | ||
OnControllerInvalidated(); | ||
} | ||
|
||
void MediaRouteController::Observer::OnControllerInvalidated() {} | ||
|
||
MediaRouteController::MediaRouteController( | ||
const MediaRoute::Id& route_id, | ||
mojom::MediaControllerPtr media_controller) | ||
: route_id_(route_id), media_controller_(std::move(media_controller)) { | ||
DCHECK(media_controller_.is_bound()); | ||
media_controller_.set_connection_error_handler( | ||
base::Bind(&MediaRouteController::Invalidate, base::Unretained(this))); | ||
} | ||
|
||
void MediaRouteController::Play() { | ||
media_controller_->Play(); | ||
} | ||
|
||
void MediaRouteController::Pause() { | ||
media_controller_->Pause(); | ||
} | ||
|
||
void MediaRouteController::Seek(base::TimeDelta time) { | ||
media_controller_->Seek(time); | ||
} | ||
|
||
void MediaRouteController::SetMute(bool mute) { | ||
media_controller_->SetMute(mute); | ||
} | ||
|
||
void MediaRouteController::SetVolume(float volume) { | ||
media_controller_->SetVolume(volume); | ||
} | ||
|
||
void MediaRouteController::OnMediaStatusUpdated(const MediaStatus& status) { | ||
for (Observer& observer : observers_) | ||
observer.OnMediaStatusUpdated(status); | ||
} | ||
|
||
void MediaRouteController::Invalidate() { | ||
for (Observer& observer : observers_) | ||
observer.InvalidateController(); | ||
// |this| is deleted here! | ||
} | ||
|
||
MediaRouteController::~MediaRouteController() {} | ||
|
||
void MediaRouteController::AddObserver(Observer* observer) { | ||
observers_.AddObserver(observer); | ||
} | ||
|
||
void MediaRouteController::RemoveObserver(Observer* observer) { | ||
observers_.RemoveObserver(observer); | ||
} | ||
|
||
} // namespace media_router |
115 changes: 115 additions & 0 deletions
115
chrome/browser/media/router/mojo/media_route_controller.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
// Copyright 2017 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_MOJO_MEDIA_ROUTE_CONTROLLER_H_ | ||
#define CHROME_BROWSER_MEDIA_ROUTER_MOJO_MEDIA_ROUTE_CONTROLLER_H_ | ||
|
||
#include <memory> | ||
|
||
#include "base/memory/ref_counted.h" | ||
#include "base/observer_list.h" | ||
#include "chrome/browser/media/router/media_route.h" | ||
#include "chrome/browser/media/router/mojo/media_controller.mojom.h" | ||
#include "mojo/public/cpp/bindings/binding.h" | ||
|
||
namespace media_router { | ||
|
||
// A controller for a MediaRoute. Forwards commands for controlling the route to | ||
// an out-of-process controller. Notifies its observers whenever there is a | ||
// change in the route's MediaStatus. | ||
// | ||
// It is owned by its observers, each of which holds a scoped_refptr to it. All | ||
// the classes that hold a scoped_refptr must inherit from the Observer class. | ||
// An observer should be instantiated with a scoped_refptr obtained through | ||
// MediaRouter::GetRouteController(). | ||
// | ||
// A MediaRouteController instance is destroyed when all its observers dispose | ||
// their references to it. When the Mojo connection with the out-of-process | ||
// controller is terminated or has an error, OnControllerInvalidated() will be | ||
// called by the MediaRouter or a Mojo error handler to make observers dispose | ||
// their refptrs. | ||
class MediaRouteController : public mojom::MediaStatusObserver, | ||
public base::RefCounted<MediaRouteController> { | ||
public: | ||
// Observes MediaRouteController for MediaStatus updates. The ownership of a | ||
// MediaRouteController is shared by its observers. | ||
class Observer { | ||
public: | ||
// Adds itself as an observer to |controller|. | ||
explicit Observer(scoped_refptr<MediaRouteController> controller); | ||
|
||
// Removes itself as an observer if |controller_| is still valid. | ||
virtual ~Observer(); | ||
|
||
virtual void OnMediaStatusUpdated(const MediaStatus& status) = 0; | ||
|
||
// Returns a reference to the observed MediaRouteController. The reference | ||
// should not be stored by any object that does not subclass ::Observer. | ||
scoped_refptr<MediaRouteController> controller() const { | ||
return controller_; | ||
} | ||
|
||
private: | ||
friend class MediaRouteController; | ||
|
||
// Disposes the reference to the controller. | ||
void InvalidateController(); | ||
|
||
// Called by InvalidateController() after the reference to the controller is | ||
// disposed. Overridden by subclasses to do custom cleanup. | ||
virtual void OnControllerInvalidated(); | ||
|
||
scoped_refptr<MediaRouteController> controller_; | ||
|
||
DISALLOW_COPY_AND_ASSIGN(Observer); | ||
}; | ||
|
||
// Constructs a MediaRouteController that forwards media commands to | ||
// |media_controller|. |media_controller| must be bound to a message pipe. | ||
MediaRouteController(const MediaRoute::Id& route_id, | ||
mojom::MediaControllerPtr media_controller); | ||
|
||
// Media controller methods for forwarding commands to a | ||
// mojom::MediaControllerPtr held in |media_controller_|. | ||
void Play(); | ||
void Pause(); | ||
void Seek(base::TimeDelta time); | ||
void SetMute(bool mute); | ||
void SetVolume(float volume); | ||
|
||
// mojom::MediaStatusObserver: | ||
// Notifies |observers_| of a status update. | ||
void OnMediaStatusUpdated(const MediaStatus& status) override; | ||
|
||
// Called when the connection between |this| and |media_controller_| is no | ||
// longer valid. Notifies |observers_| to dispose their references to |this|. | ||
// |this| gets destroyed when all the references are disposed. | ||
void Invalidate(); | ||
|
||
MediaRoute::Id route_id() const { return route_id_; } | ||
|
||
private: | ||
friend class base::RefCounted<MediaRouteController>; | ||
|
||
~MediaRouteController() override; | ||
|
||
void AddObserver(Observer* observer); | ||
void RemoveObserver(Observer* observer); | ||
|
||
// The ID of the Media Route that |this| controls. | ||
const MediaRoute::Id route_id_; | ||
|
||
// Handle to the mojom::MediaController that receives media commands. | ||
mojom::MediaControllerPtr media_controller_; | ||
|
||
// Observers that |this| notifies of status updates. The observers share the | ||
// ownership of |this| through scoped_refptr. | ||
base::ObserverList<Observer> observers_; | ||
|
||
DISALLOW_COPY_AND_ASSIGN(MediaRouteController); | ||
}; | ||
|
||
} // namespace media_router | ||
|
||
#endif // CHROME_BROWSER_MEDIA_ROUTER_MOJO_MEDIA_ROUTE_CONTROLLER_H_ |
Oops, something went wrong.