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
|
// 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 MEDIA_REMOTING_SHARED_SESSION_H_
#define MEDIA_REMOTING_SHARED_SESSION_H_
#include <vector>
#include "base/callback.h"
#include "base/memory/weak_ptr.h"
#include "base/threading/thread_checker.h"
#include "media/mojo/interfaces/remoting.mojom.h"
#include "media/remoting/rpc_broker.h"
#include "mojo/public/cpp/bindings/binding.h"
namespace media {
namespace remoting {
// A single shared remoting session for multiple clients. The session will
// start remoting when receiving the first request. Once remoting is started,
// it will be stopped when any of the following happens:
// 1) Receives the request from any client to stop remoting.
// 2) Remote sink is gone.
// 3) Any client requests to permanently terminate the session.
// 4) All clients are destroyed.
//
// This class is ref-counted because, in some cases, an instance will have
// shared ownership between RendererController and RemotingCdmController.
class SharedSession final : public mojom::RemotingSource,
public base::RefCountedThreadSafe<SharedSession> {
public:
// State transition diagram:
//
// .--> SESSION_UNAVAILABLE
// | | ^
// | V |
// | SESSION_CAN_START
// | |
// | V
// | .---SESSION_STARTING --.
// | | | |
// | | V |
// | | SESSION_STARTED----|
// | | | |
// | | V |
// | '-> SESSION_STOPPING |
// '-----' | |
// V V
// SESSION_PERMANENTLY_STOPPED
enum SessionState {
// Remoting sink is not available. Can't start remoting.
SESSION_UNAVAILABLE,
// Remoting sink is available, Can start remoting.
SESSION_CAN_START,
// Starting a remoting session.
SESSION_STARTING,
// Remoting session is successively started.
SESSION_STARTED,
// Stopping the session.
SESSION_STOPPING,
// Remoting session is permanently stopped. This state indicates that the
// video stack cannot continue operation. For example, if a remoting session
// involving CDM content was stopped, there is no way to continue playback
// because the CDM is required but is no longer available.
SESSION_PERMANENTLY_STOPPED,
};
class Client {
public:
// Get notified whether the remoting session is successively started.
virtual void OnStarted(bool success) = 0;
// Get notified when session state changes.
virtual void OnSessionStateChanged() = 0;
};
SharedSession(mojom::RemotingSourceRequest source_request,
mojom::RemoterPtr remoter);
// Get the current session state.
SessionState state() const {
DCHECK(thread_checker_.CalledOnValidThread());
return state_;
}
mojom::RemotingSinkCapabilities sink_capabilities() const {
return sink_capabilities_;
}
bool is_remote_decryption_available() const {
return sink_capabilities_ ==
mojom::RemotingSinkCapabilities::CONTENT_DECRYPTION_AND_RENDERING;
}
// RemotingSource implementations.
void OnSinkAvailable(mojom::RemotingSinkCapabilities capabilities) override;
void OnSinkGone() override;
void OnStarted() override;
void OnStartFailed(mojom::RemotingStartFailReason reason) override;
void OnMessageFromSink(const std::vector<uint8_t>& message) override;
void OnStopped(mojom::RemotingStopReason reason) override;
using DataPipeStartCallback =
base::Callback<void(mojom::RemotingDataStreamSenderPtrInfo audio,
mojom::RemotingDataStreamSenderPtrInfo video,
mojo::ScopedDataPipeProducerHandle audio_handle,
mojo::ScopedDataPipeProducerHandle video_handle)>;
void StartDataPipe(std::unique_ptr<mojo::DataPipe> audio_data_pipe,
std::unique_ptr<mojo::DataPipe> video_data_pipe,
const DataPipeStartCallback& done_callback);
// Requests to start remoting. Will try start a remoting session if not
// started yet. |client| will get informed whether the session is
// successifully started throught OnStarted().
void StartRemoting(Client* client);
// Requests to stop the current remoting session if started. When the session
// is stopping, all clients will get notified.
void StopRemoting(Client* client);
// Permanently terminates the current remoting session.
void Shutdown();
// Add/remove a client to/from |clients_|.
// Note: Clients can only added/removed through these methods.
// Remoting session will be stopped if all clients are gone.
void AddClient(Client* client);
void RemoveClient(Client* client);
RpcBroker* rpc_broker() { return &rpc_broker_; }
private:
friend class base::RefCountedThreadSafe<SharedSession>;
~SharedSession() override;
// Updates the current session state and notifies all the clients if state
// changes.
void UpdateAndNotifyState(SessionState state);
// Callback from RpcBroker when sending message to remote sink.
void SendMessageToSink(std::unique_ptr<std::vector<uint8_t>> message);
// Handles dispatching of incoming and outgoing RPC messages.
RpcBroker rpc_broker_;
const mojo::Binding<mojom::RemotingSource> binding_;
const mojom::RemoterPtr remoter_;
// When the sink is available, this describes its capabilities. When not
// available, this is always NONE. Updated by OnSinkAvailable/Gone().
mojom::RemotingSinkCapabilities sink_capabilities_ =
mojom::RemotingSinkCapabilities::NONE;
// The current state.
SessionState state_ = SESSION_UNAVAILABLE;
// Clients are added/removed to/from this list by calling Add/RemoveClient().
// All the clients are not belong to this class. They are supposed to call
// RemoveClient() before they are gone.
std::vector<Client*> clients_;
// This is used to check all the methods are called on the current thread in
// debug builds.
base::ThreadChecker thread_checker_;
};
} // namespace remoting
} // namespace media
#endif // MEDIA_REMOTING_SHARED_SESSION_H_
|