Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Side by Side Diff: extensions/browser/api/cast_channel/keep_alive_delegate.cc

Issue 2926313002: Revert of [cast_channel] Move cast_channel related files from //extensions to //components (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 #include "extensions/browser/api/cast_channel/keep_alive_delegate.h"
6
7 #include <string>
8 #include <utility>
9
10 #include "base/json/json_reader.h"
11 #include "base/json/json_writer.h"
12 #include "extensions/browser/api/cast_channel/cast_socket.h"
13 #include "extensions/browser/api/cast_channel/logger.h"
14 #include "extensions/common/api/cast_channel/cast_channel.pb.h"
15 #include "extensions/common/api/cast_channel/logging.pb.h"
16 #include "net/base/net_errors.h"
17
18 namespace extensions {
19 namespace api {
20 namespace cast_channel {
21 namespace {
22
23 const char kHeartbeatNamespace[] = "urn:x-cast:com.google.cast.tp.heartbeat";
24 const char kPingSenderId[] = "chrome";
25 const char kPingReceiverId[] = "receiver-0";
26 const char kTypeNodeId[] = "type";
27
28 // Parses the JSON-encoded payload of |message| and returns the value in the
29 // "type" field or the empty string if the parse fails or the field is not
30 // found.
31 std::string ParseForPayloadType(const CastMessage& message) {
32 std::unique_ptr<base::Value> parsed_payload(
33 base::JSONReader::Read(message.payload_utf8()));
34 base::DictionaryValue* payload_as_dict;
35 if (!parsed_payload || !parsed_payload->GetAsDictionary(&payload_as_dict))
36 return std::string();
37 std::string type_string;
38 if (!payload_as_dict->GetString(kTypeNodeId, &type_string))
39 return std::string();
40 return type_string;
41 }
42
43 } // namespace
44
45 // static
46 const char KeepAliveDelegate::kHeartbeatPingType[] = "PING";
47
48 // static
49 const char KeepAliveDelegate::kHeartbeatPongType[] = "PONG";
50
51 using ::cast_channel::ChannelError;
52
53 // static
54 CastMessage KeepAliveDelegate::CreateKeepAliveMessage(
55 const char* message_type) {
56 CastMessage output;
57 output.set_protocol_version(CastMessage::CASTV2_1_0);
58 output.set_source_id(kPingSenderId);
59 output.set_destination_id(kPingReceiverId);
60 output.set_namespace_(kHeartbeatNamespace);
61 base::DictionaryValue type_dict;
62 type_dict.SetString(kTypeNodeId, message_type);
63 if (!base::JSONWriter::Write(type_dict, output.mutable_payload_utf8())) {
64 LOG(ERROR) << "Failed to serialize dictionary.";
65 return output;
66 }
67 output.set_payload_type(
68 CastMessage::PayloadType::CastMessage_PayloadType_STRING);
69 return output;
70 }
71
72 KeepAliveDelegate::KeepAliveDelegate(
73 CastSocket* socket,
74 scoped_refptr<Logger> logger,
75 std::unique_ptr<CastTransport::Delegate> inner_delegate,
76 base::TimeDelta ping_interval,
77 base::TimeDelta liveness_timeout)
78 : started_(false),
79 socket_(socket),
80 logger_(logger),
81 inner_delegate_(std::move(inner_delegate)),
82 liveness_timeout_(liveness_timeout),
83 ping_interval_(ping_interval) {
84 DCHECK(ping_interval_ < liveness_timeout_);
85 DCHECK(inner_delegate_);
86 DCHECK(socket_);
87 ping_message_ = CreateKeepAliveMessage(kHeartbeatPingType);
88 pong_message_ = CreateKeepAliveMessage(kHeartbeatPongType);
89 }
90
91 KeepAliveDelegate::~KeepAliveDelegate() {
92 }
93
94 void KeepAliveDelegate::SetTimersForTest(
95 std::unique_ptr<base::Timer> injected_ping_timer,
96 std::unique_ptr<base::Timer> injected_liveness_timer) {
97 ping_timer_ = std::move(injected_ping_timer);
98 liveness_timer_ = std::move(injected_liveness_timer);
99 }
100
101 void KeepAliveDelegate::Start() {
102 DCHECK(thread_checker_.CalledOnValidThread());
103 DCHECK(!started_);
104
105 VLOG(1) << "Starting keep-alive timers.";
106 VLOG(1) << "Ping timeout: " << ping_interval_;
107 VLOG(1) << "Liveness timeout: " << liveness_timeout_;
108
109 // Use injected mock timers, if provided.
110 if (!ping_timer_) {
111 ping_timer_.reset(new base::Timer(true, false));
112 }
113 if (!liveness_timer_) {
114 liveness_timer_.reset(new base::Timer(true, false));
115 }
116
117 ping_timer_->Start(
118 FROM_HERE, ping_interval_,
119 base::Bind(&KeepAliveDelegate::SendKeepAliveMessage,
120 base::Unretained(this), ping_message_, kHeartbeatPingType));
121 liveness_timer_->Start(
122 FROM_HERE, liveness_timeout_,
123 base::Bind(&KeepAliveDelegate::LivenessTimeout, base::Unretained(this)));
124
125 started_ = true;
126 inner_delegate_->Start();
127 }
128
129 void KeepAliveDelegate::ResetTimers() {
130 DCHECK(started_);
131 ping_timer_->Reset();
132 liveness_timer_->Reset();
133 }
134
135 void KeepAliveDelegate::SendKeepAliveMessage(const CastMessage& message,
136 const char* message_type) {
137 DCHECK(thread_checker_.CalledOnValidThread());
138 VLOG(2) << "Sending " << message_type;
139 socket_->transport()->SendMessage(
140 message, base::Bind(&KeepAliveDelegate::SendKeepAliveMessageComplete,
141 base::Unretained(this), message_type));
142 }
143
144 void KeepAliveDelegate::SendKeepAliveMessageComplete(const char* message_type,
145 int rv) {
146 VLOG(2) << "Sending " << message_type << " complete, rv=" << rv;
147 if (rv != net::OK) {
148 // An error occurred while sending the ping response.
149 VLOG(1) << "Error sending " << message_type;
150 logger_->LogSocketEventWithRv(socket_->id(), proto::PING_WRITE_ERROR, rv);
151 OnError(ChannelError::CAST_SOCKET_ERROR);
152 }
153 }
154
155 void KeepAliveDelegate::LivenessTimeout() {
156 OnError(ChannelError::PING_TIMEOUT);
157 Stop();
158 }
159
160 // CastTransport::Delegate interface.
161 void KeepAliveDelegate::OnError(ChannelError error_state) {
162 DCHECK(thread_checker_.CalledOnValidThread());
163 VLOG(1) << "KeepAlive::OnError: "
164 << ::cast_channel::ChannelErrorToString(error_state);
165 inner_delegate_->OnError(error_state);
166 Stop();
167 }
168
169 void KeepAliveDelegate::OnMessage(const CastMessage& message) {
170 DCHECK(thread_checker_.CalledOnValidThread());
171 VLOG(2) << "KeepAlive::OnMessage : " << message.payload_utf8();
172
173 if (started_)
174 ResetTimers();
175
176 // PING and PONG messages are intercepted and handled by KeepAliveDelegate
177 // here. All other messages are passed through to |inner_delegate_|.
178 const std::string payload_type = ParseForPayloadType(message);
179 if (payload_type == kHeartbeatPingType) {
180 VLOG(2) << "Received PING.";
181 if (started_)
182 SendKeepAliveMessage(pong_message_, kHeartbeatPongType);
183 } else if (payload_type == kHeartbeatPongType) {
184 VLOG(2) << "Received PONG.";
185 } else {
186 inner_delegate_->OnMessage(message);
187 }
188 }
189
190 void KeepAliveDelegate::Stop() {
191 if (started_) {
192 started_ = false;
193 ping_timer_->Stop();
194 liveness_timer_->Stop();
195 }
196 }
197
198 } // namespace cast_channel
199 } // namespace api
200 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698