File: media_router_android.h

package info (click to toggle)
chromium 120.0.6099.224-1~deb11u1
  • links: PTS, VCS
  • area: main
  • in suites: bullseye
  • size: 6,112,112 kB
  • sloc: cpp: 32,907,025; ansic: 8,148,123; javascript: 3,679,536; python: 2,031,248; asm: 959,718; java: 804,675; xml: 617,256; sh: 111,417; objc: 100,835; perl: 88,443; cs: 53,032; makefile: 29,579; fortran: 24,137; php: 21,162; tcl: 21,147; sql: 20,809; ruby: 17,735; pascal: 12,864; yacc: 8,045; lisp: 3,388; lex: 1,323; ada: 727; awk: 329; jsp: 267; csh: 117; exp: 43; sed: 37
file content (200 lines) | stat: -rw-r--r-- 8,068 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
// Copyright 2015 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_MEDIA_ROUTER_BROWSER_ANDROID_MEDIA_ROUTER_ANDROID_H_
#define COMPONENTS_MEDIA_ROUTER_BROWSER_ANDROID_MEDIA_ROUTER_ANDROID_H_

#include <stdint.h>

#include <memory>
#include <unordered_map>

#include "base/containers/id_map.h"
#include "base/memory/raw_ptr.h"
#include "base/observer_list.h"
#include "components/media_router/browser/android/media_router_android_bridge.h"
#include "components/media_router/browser/media_router_base.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"

namespace media_router {

// An implementation of MediaRouter interface on Android.
class MediaRouterAndroid : public MediaRouterBase {
 public:
  MediaRouterAndroid();
  ~MediaRouterAndroid() override;

  const MediaRoute* FindRouteBySource(const MediaSource::Id& source_id) const;

  // MediaRouter implementation.
  void Initialize() override;
  void CreateRoute(const MediaSource::Id& source_id,
                   const MediaSink::Id& sink_id,
                   const url::Origin& origin,
                   content::WebContents* web_contents,
                   MediaRouteResponseCallback callback,
                   base::TimeDelta timeout) override;
  void JoinRoute(const MediaSource::Id& source,
                 const std::string& presentation_id,
                 const url::Origin& origin,
                 content::WebContents* web_contents,
                 MediaRouteResponseCallback callback,
                 base::TimeDelta timeout) override;
  void DetachRoute(MediaRoute::Id route_id) override;
  void TerminateRoute(const MediaRoute::Id& route_id) override;
  void SendRouteMessage(const MediaRoute::Id& route_id,
                        const std::string& message) override;
  void SendRouteBinaryMessage(
      const MediaRoute::Id& route_id,
      std::unique_ptr<std::vector<uint8_t>> data) override;
  void OnUserGesture() override;
  std::vector<MediaRoute> GetCurrentRoutes() const override;

  std::unique_ptr<media::FlingingController> GetFlingingController(
      const MediaRoute::Id& route_id) override;

  // The methods called by the Java bridge.
  // Notifies the media router that information about sinks is received for
  // a specific source id.
  void OnSinksReceived(const MediaSource::Id& source_id,
                       const std::vector<MediaSink>& sinks);

  // Notifies the media router about a successful route creation.
  void OnRouteCreated(const MediaRoute::Id& route_id,
                      const MediaSink::Id& sink_id,
                      int request_id,
                      bool is_local);

  // Notifies the media router when the route media source is updated. This can
  // happen during remote playback with the media element's source URL changes.
  void OnRouteMediaSourceUpdated(const MediaRoute::Id& route_id,
                                 const MediaSource::Id& source_id);

  // Notifies the media router that route creation or joining failed.
  void OnCreateRouteRequestError(const std::string& error_text, int request_id);
  void OnJoinRouteRequestError(const std::string& error_text, int request_id);

  // Notifies the media router when the route was terminated.
  void OnRouteTerminated(const MediaRoute::Id& route_id);

  // Notifies the media router when the route was closed with an optional error.
  // Null error indicates no error.
  void OnRouteClosed(const MediaRoute::Id& route_id,
                     const absl::optional<std::string>& error);

  // Notifies the media router about a message received from the media route.
  void OnMessage(const MediaRoute::Id& route_id, const std::string& message);

 private:
  friend class MediaRouterAndroidTest;

  // This class bridges messages between MediaRouterAndroid's messages API and a
  // PresentationConnection.
  class PresentationConnectionProxy final
      : public blink::mojom::PresentationConnection {
   public:
    using OnMessageCallback = base::OnceCallback<void(bool)>;

    PresentationConnectionProxy(MediaRouterAndroid* media_router_android,
                                const MediaRoute::Id& route_id);

    PresentationConnectionProxy(const PresentationConnectionProxy&) = delete;
    PresentationConnectionProxy& operator=(const PresentationConnectionProxy&) =
        delete;

    ~PresentationConnectionProxy() override;

    // Initializes the connection binding and interface request and returns that
    // as a mojom::RoutePresentationConnectionPtr.
    mojom::RoutePresentationConnectionPtr Init();

    // blink::mojom::PresentationConnection overrides.
    void OnMessage(
        blink::mojom::PresentationConnectionMessagePtr message) override;
    void DidChangeState(
        blink::mojom::PresentationConnectionState state) override {}
    // Destroys |this| by removing it from MediaRouterAndroid's collection.
    void DidClose(
        blink::mojom::PresentationConnectionCloseReason reason) override;

    // Sends a text message back to router's peer for this connection (|peer_|).
    void SendMessage(const std::string& message);

    // Sends a TERMINATED state change message directly via |peer_|.
    void Terminate();

   private:
    mojo::PendingRemote<blink::mojom::PresentationConnection> Bind();

    mojo::Remote<blink::mojom::PresentationConnection> peer_;
    mojo::Receiver<blink::mojom::PresentationConnection> receiver_{this};
    // |media_router_android_| owns |this|, so it will outlive |this|.
    raw_ptr<MediaRouterAndroid> media_router_android_;
    MediaRoute::Id route_id_;
  };

  // Removes the route with the given id from |active_routes_| and updates the
  // registered route observers.
  void RemoveRoute(const MediaRoute::Id& route_id);

  // MediaRouter implementation.
  bool RegisterMediaSinksObserver(MediaSinksObserver* observer) override;
  void UnregisterMediaSinksObserver(MediaSinksObserver* observer) override;
  void RegisterMediaRoutesObserver(MediaRoutesObserver* observer) override;
  void UnregisterMediaRoutesObserver(MediaRoutesObserver* observer) override;
  void RegisterPresentationConnectionMessageObserver(
      PresentationConnectionMessageObserver* observer) override;
  void UnregisterPresentationConnectionMessageObserver(
      PresentationConnectionMessageObserver* observer) override;

  void OnPresentationConnectionError(const std::string& route_id);
  void OnRouteRequestError(
      const std::string& error_text,
      int route_request_id,
      base::OnceCallback<void(mojom::RouteRequestResultCode,
                              absl::optional<mojom::MediaRouteProviderId>)>
          callback);

  void SetMediaRouterBridgeForTest(MediaRouterAndroidBridge* bridge) {
    bridge_.reset(bridge);
  }

  std::unique_ptr<MediaRouterAndroidBridge> bridge_;

  using MediaSinksObserverList =
      base::ObserverList<MediaSinksObserver>::Unchecked;
  using MediaSinkObservers =
      std::unordered_map<MediaSource::Id,
                         std::unique_ptr<MediaSinksObserverList>>;
  MediaSinkObservers sinks_observers_;

  base::ObserverList<MediaRoutesObserver> routes_observers_;

  struct MediaRouteRequest {
    MediaRouteRequest(const MediaSource& source,
                      const std::string& presentation_id,
                      MediaRouteResponseCallback callback);
    ~MediaRouteRequest();

    MediaSource media_source;
    std::string presentation_id;
    MediaRouteResponseCallback callback;
  };

  using MediaRouteRequests = base::IDMap<std::unique_ptr<MediaRouteRequest>>;
  MediaRouteRequests route_requests_;

  using MediaRoutes = std::vector<MediaRoute>;
  MediaRoutes active_routes_;

  std::unordered_map<MediaRoute::Id,
                     std::vector<std::unique_ptr<PresentationConnectionProxy>>>
      presentation_connections_;
};

}  // namespace media_router

#endif  // COMPONENTS_MEDIA_ROUTER_BROWSER_ANDROID_MEDIA_ROUTER_ANDROID_H_