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
|
// Copyright (c) 2010 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 REMOTING_JINGLE_GLUE_JINGLE_CHANNEL_H_
#define REMOTING_JINGLE_GLUE_JINGLE_CHANNEL_H_
#include <deque>
#include <string>
#include "base/basictypes.h"
#include "base/condition_variable.h"
#include "base/gtest_prod_util.h"
#include "base/lock.h"
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
#include "base/task.h"
#include "third_party/libjingle/source/talk/base/sigslot.h"
namespace base {
class WaitableEvent;
} // namespace base
namespace talk_base {
class StreamInterface;
} // namespace talk_base
namespace media {
class Buffer;
class DataBuffer;
} // namespace media
namespace remoting {
class JingleThread;
class JingleChannel : public base::RefCountedThreadSafe<JingleChannel> {
public:
enum State {
INITIALIZING,
CONNECTING,
OPEN,
CLOSED,
FAILED,
};
class Callback {
public:
virtual ~Callback() {}
// Called when state of the connection is changed.
virtual void OnStateChange(JingleChannel* channel, State state) = 0;
// Called when a new packet is received.
virtual void OnPacketReceived(JingleChannel* channel,
scoped_refptr<media::DataBuffer> data) = 0;
};
virtual ~JingleChannel();
// Puts data to the write buffer.
virtual void Write(scoped_refptr<media::DataBuffer> data);
// Closes the tunnel. If specified, |closed_task| is executed after the
// connection is successfully closed.
virtual void Close();
virtual void Close(Task* closed_task);
// Current state of the tunnel.
State state() const { return state_; }
// JID of the other end of the channel.
const std::string& jid() const { return jid_; }
// Number of bytes currently stored in the write buffer.
size_t write_buffer_size();
protected:
// Needs access to constructor, Init().
friend class JingleClient;
// Constructor used by unit test only.
// TODO(hclam): Have to suppress warnings in MSVC.
JingleChannel();
// Used by JingleClient to create an instance of the channel. |callback|
// must not be NULL.
explicit JingleChannel(Callback* callback);
// Initialized the channel. Ownership of the |stream| is transfered to
// caller. Ownership of |thread| is not.
void Init(JingleThread* thread, talk_base::StreamInterface* stream,
const std::string& jid);
private:
friend class JingleChannelTest;
FRIEND_TEST_ALL_PREFIXES(JingleChannelTest, Init);
FRIEND_TEST_ALL_PREFIXES(JingleChannelTest, Write);
FRIEND_TEST_ALL_PREFIXES(JingleChannelTest, Read);
typedef std::deque<scoped_refptr<media::DataBuffer> > DataQueue;
// Event handler for the stream. It passes stream events from the stream
// to JingleChannel.
class EventHandler : public sigslot::has_slots<> {
protected:
explicit EventHandler(JingleChannel* channel) : channel_(channel) {}
// Constructor used only by unit test.
EventHandler() : channel_(NULL) {}
void OnStreamEvent(talk_base::StreamInterface* stream,
int events, int error) {
channel_->OnStreamEvent(stream, events, error);
}
private:
friend class JingleChannel;
JingleChannel* channel_;
};
friend class EventHandler;
// Event handler for the stream.
void OnStreamEvent(talk_base::StreamInterface* stream,
int events, int error);
// Writes data from the buffer to the stream. Called
// from OnStreamEvent() in the jingle thread.
void DoWrite();
// Reads data from the stream and puts it to the read buffer.
// Called from OnStreamEvent() in the jingle thread.
void DoRead();
// Used by Close() to actually close the channel.
void DoClose();
// Updates state and calels |callback_| if neccessary.
void SetState(State new_state);
// The thread this channel runs on.
JingleThread* thread_;
// The stream of this channel.
scoped_ptr<talk_base::StreamInterface> stream_;
// Current state of the channel.
State state_;
// Callback that is called on channel events. Initialized in the constructor.
// Must not be called if |closed_| is set to true.
Callback* callback_;
// |closed_| must be set to true after Close() is called. |state_lock_| must
// be locked whenever closed_ is accessed.
Lock state_lock_;
bool closed_;
scoped_ptr<Task> closed_task_;
// Event handler for stream events.
EventHandler event_handler_;
// Jid of the other end of the channel.
std::string jid_;
// Write buffer. |write_lock_| should be locked when accessing |write_queue_|
// and |write_buffer_size_|, but isn't necessary for |current_write_buf_|.
// |current_write_buf_| is accessed only by the jingle thread.
// |write_buffer_size_| stores number of bytes currently in |write_queue_|
// and in |current_write_buf_|.
DataQueue write_queue_;
size_t write_buffer_size_;
Lock write_lock_;
scoped_refptr<media::DataBuffer> current_write_buf_;
size_t current_write_buf_pos_;
DISALLOW_COPY_AND_ASSIGN(JingleChannel);
};
} // namespace remoting
#endif // REMOTING_JINGLE_GLUE_JINGLE_CHANNEL_H_
|