1 // Copyright 2015 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef COMPONENTS_MEDIA_ROUTER_BROWSER_ANDROID_MEDIA_ROUTER_ANDROID_H_ 6 #define COMPONENTS_MEDIA_ROUTER_BROWSER_ANDROID_MEDIA_ROUTER_ANDROID_H_ 7 8 #include <stdint.h> 9 10 #include <memory> 11 #include <unordered_map> 12 13 #include "base/containers/id_map.h" 14 #include "base/macros.h" 15 #include "base/observer_list.h" 16 #include "components/media_router/browser/android/media_router_android_bridge.h" 17 #include "components/media_router/browser/media_router_base.h" 18 #include "mojo/public/cpp/bindings/pending_remote.h" 19 #include "mojo/public/cpp/bindings/receiver.h" 20 #include "mojo/public/cpp/bindings/remote.h" 21 22 namespace media_router { 23 24 // An implementation of MediaRouter interface on Android. 25 class MediaRouterAndroid : public MediaRouterBase { 26 public: 27 MediaRouterAndroid(); 28 ~MediaRouterAndroid() override; 29 30 const MediaRoute* FindRouteBySource(const MediaSource::Id& source_id) const; 31 32 // MediaRouter implementation. 33 void CreateRoute(const MediaSource::Id& source_id, 34 const MediaSink::Id& sink_id, 35 const url::Origin& origin, 36 content::WebContents* web_contents, 37 MediaRouteResponseCallback callback, 38 base::TimeDelta timeout, 39 bool incognito) override; 40 void JoinRoute(const MediaSource::Id& source, 41 const std::string& presentation_id, 42 const url::Origin& origin, 43 content::WebContents* web_contents, 44 MediaRouteResponseCallback callback, 45 base::TimeDelta timeout, 46 bool incognito) override; 47 void ConnectRouteByRouteId(const MediaSource::Id& source, 48 const MediaRoute::Id& route_id, 49 const url::Origin& origin, 50 content::WebContents* web_contents, 51 MediaRouteResponseCallback callback, 52 base::TimeDelta timeout, 53 bool incognito) override; 54 void DetachRoute(const MediaRoute::Id& route_id) override; 55 void TerminateRoute(const MediaRoute::Id& route_id) override; 56 void SendRouteMessage(const MediaRoute::Id& route_id, 57 const std::string& message) override; 58 void SendRouteBinaryMessage( 59 const MediaRoute::Id& route_id, 60 std::unique_ptr<std::vector<uint8_t>> data) override; 61 void OnUserGesture() override; 62 std::unique_ptr<media::FlingingController> GetFlingingController( 63 const MediaRoute::Id& route_id) override; 64 65 // The methods called by the Java bridge. 66 // Notifies the media router that information about sinks is received for 67 // a specific source id. 68 void OnSinksReceived(const MediaSource::Id& source_id, 69 const std::vector<MediaSink>& sinks); 70 71 // Notifies the media router about a successful route creation. 72 void OnRouteCreated(const MediaRoute::Id& route_id, 73 const MediaSink::Id& sink_id, 74 int request_id, 75 bool is_local); 76 77 // Notifies the media router that route creation or joining failed. 78 void OnRouteRequestError(const std::string& error_text, int request_id); 79 80 // Notifies the media router when the route was terminated. 81 void OnRouteTerminated(const MediaRoute::Id& route_id); 82 83 // Notifies the media router when the route was closed with an optional error. 84 // Null error indicates no error. 85 void OnRouteClosed(const MediaRoute::Id& route_id, 86 const base::Optional<std::string>& error); 87 88 // Notifies the media router about a message received from the media route. 89 void OnMessage(const MediaRoute::Id& route_id, const std::string& message); 90 91 private: 92 friend class MediaRouterAndroidTest; 93 94 // This class bridges messages between MediaRouterAndroid's messages API and a 95 // PresentationConnection. 96 class PresentationConnectionProxy final 97 : public blink::mojom::PresentationConnection { 98 public: 99 using OnMessageCallback = base::OnceCallback<void(bool)>; 100 101 PresentationConnectionProxy(MediaRouterAndroid* media_router_android, 102 const MediaRoute::Id& route_id); 103 ~PresentationConnectionProxy() override; 104 105 // Initializes the connection binding and interface request and returns that 106 // as a mojom::RoutePresentationConnectionPtr. 107 mojom::RoutePresentationConnectionPtr Init(); 108 109 // blink::mojom::PresentationConnection overrides. 110 void OnMessage( 111 blink::mojom::PresentationConnectionMessagePtr message) override; DidChangeState(blink::mojom::PresentationConnectionState state)112 void DidChangeState( 113 blink::mojom::PresentationConnectionState state) override {} 114 // Destroys |this| by removing it from MediaRouterAndroid's collection. 115 void DidClose( 116 blink::mojom::PresentationConnectionCloseReason reason) override; 117 118 // Sends a text message back to router's peer for this connection (|peer_|). 119 void SendMessage(const std::string& message); 120 121 // Sends a TERMINATED state change message directly via |peer_|. 122 void Terminate(); 123 124 private: 125 mojo::PendingRemote<blink::mojom::PresentationConnection> Bind(); 126 127 mojo::Remote<blink::mojom::PresentationConnection> peer_; 128 mojo::Receiver<blink::mojom::PresentationConnection> receiver_{this}; 129 // |media_router_android_| owns |this|, so it will outlive |this|. 130 MediaRouterAndroid* media_router_android_; 131 MediaRoute::Id route_id_; 132 133 DISALLOW_COPY_AND_ASSIGN(PresentationConnectionProxy); 134 }; 135 136 // Removes the route with the given id from |active_routes_| and updates the 137 // registered route observers. 138 void RemoveRoute(const MediaRoute::Id& route_id); 139 140 // MediaRouter implementation. 141 bool RegisterMediaSinksObserver(MediaSinksObserver* observer) override; 142 void UnregisterMediaSinksObserver(MediaSinksObserver* observer) override; 143 void RegisterMediaRoutesObserver(MediaRoutesObserver* observer) override; 144 void UnregisterMediaRoutesObserver(MediaRoutesObserver* observer) override; 145 void RegisterRouteMessageObserver(RouteMessageObserver* observer) override; 146 void UnregisterRouteMessageObserver(RouteMessageObserver* observer) override; 147 148 void OnPresentationConnectionError(const std::string& route_id); 149 SetMediaRouterBridgeForTest(MediaRouterAndroidBridge * bridge)150 void SetMediaRouterBridgeForTest(MediaRouterAndroidBridge* bridge) { 151 bridge_.reset(bridge); 152 } 153 154 std::unique_ptr<MediaRouterAndroidBridge> bridge_; 155 156 using MediaSinksObserverList = 157 base::ObserverList<MediaSinksObserver>::Unchecked; 158 using MediaSinkObservers = 159 std::unordered_map<MediaSource::Id, 160 std::unique_ptr<MediaSinksObserverList>>; 161 MediaSinkObservers sinks_observers_; 162 163 base::ObserverList<MediaRoutesObserver>::Unchecked routes_observers_; 164 165 struct MediaRouteRequest { 166 MediaRouteRequest(const MediaSource& source, 167 const std::string& presentation_id, 168 MediaRouteResponseCallback callback); 169 ~MediaRouteRequest(); 170 171 MediaSource media_source; 172 std::string presentation_id; 173 MediaRouteResponseCallback callback; 174 }; 175 176 using MediaRouteRequests = base::IDMap<std::unique_ptr<MediaRouteRequest>>; 177 MediaRouteRequests route_requests_; 178 179 using MediaRoutes = std::vector<MediaRoute>; 180 MediaRoutes active_routes_; 181 182 std::unordered_map<MediaRoute::Id, 183 std::vector<std::unique_ptr<PresentationConnectionProxy>>> 184 presentation_connections_; 185 186 DISALLOW_COPY_AND_ASSIGN(MediaRouterAndroid); 187 }; 188 189 } // namespace media_router 190 191 #endif // COMPONENTS_MEDIA_ROUTER_BROWSER_ANDROID_MEDIA_ROUTER_ANDROID_H_ 192