Commit a61015f8 authored by Derek Cheng's avatar Derek Cheng Committed by Commit Bot

[Cast channel] Remove virtual connection on request from receiver.

Also update a TODO.

Bug: 809249
Change-Id: I80bb4cc046c765de6b1bc5e519cb22628af6bf9e
Reviewed-on: https://chromium-review.googlesource.com/1169875Reviewed-by: default avatarTakumi Fujimoto <takumif@chromium.org>
Commit-Queue: Derek Cheng <imcheng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#581941}
parent e2549f2a
...@@ -237,14 +237,11 @@ void CastMessageHandler::OnMessage(const CastSocket& socket, ...@@ -237,14 +237,11 @@ void CastMessageHandler::OnMessage(const CastSocket& socket,
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DVLOG(2) << __func__ << ", channel_id: " << socket.id() DVLOG(2) << __func__ << ", channel_id: " << socket.id()
<< ", message: " << CastMessageToString(message); << ", message: " << CastMessageToString(message);
// TODO(crbug.com/698940): Support Observers for both kinds of messages.
if (IsCastInternalNamespace(message.namespace_())) { if (IsCastInternalNamespace(message.namespace_())) {
HandleCastInternalMessage(socket, message); HandleCastInternalMessage(socket, message);
} else { } else {
DVLOG(2) << "Got app message from cast channel with namespace: " DVLOG(2) << "Got app message from cast channel with namespace: "
<< message.namespace_(); << message.namespace_();
for (auto& observer : observers_) for (auto& observer : observers_)
observer.OnAppMessage(socket.id(), message); observer.OnAppMessage(socket.id(), message);
} }
...@@ -252,7 +249,7 @@ void CastMessageHandler::OnMessage(const CastSocket& socket, ...@@ -252,7 +249,7 @@ void CastMessageHandler::OnMessage(const CastSocket& socket,
void CastMessageHandler::HandleCastInternalMessage(const CastSocket& socket, void CastMessageHandler::HandleCastInternalMessage(const CastSocket& socket,
const CastMessage& message) { const CastMessage& message) {
// TODO(crbug.com/698940): Handle other messages (VIRTUAL_CONNECT_CLOSE). // TODO(https://crbug.com/809249): Parse message with data_decoder service.
std::unique_ptr<base::DictionaryValue> payload = std::unique_ptr<base::DictionaryValue> payload =
GetDictionaryFromCastMessage(message); GetDictionaryFromCastMessage(message);
if (!payload) if (!payload)
...@@ -271,6 +268,13 @@ void CastMessageHandler::HandleCastInternalMessage(const CastSocket& socket, ...@@ -271,6 +268,13 @@ void CastMessageHandler::HandleCastInternalMessage(const CastSocket& socket,
return; return;
} }
if (type == CastMessageType::kCloseConnection) {
// Source / destination is flipped.
virtual_connections_.erase(VirtualConnection(
socket.id(), message.destination_id(), message.source_id()));
return;
}
InternalMessage internal_message(type, std::move(*payload)); InternalMessage internal_message(type, std::move(*payload));
for (auto& observer : observers_) for (auto& observer : observers_)
observer.OnInternalMessage(socket.id(), internal_message); observer.OnInternalMessage(socket.id(), internal_message);
......
...@@ -22,6 +22,8 @@ namespace { ...@@ -22,6 +22,8 @@ namespace {
constexpr char kTestUserAgentString[] = constexpr char kTestUserAgentString[] =
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) " "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/66.0.3331.0 Safari/537.36"; "Chrome/66.0.3331.0 Safari/537.36";
constexpr char kSourceId[] = "sourceId";
constexpr char kDestinationId[] = "destinationId";
std::string GetMessageType(const CastMessage& message) { std::string GetMessageType(const CastMessage& message) {
std::unique_ptr<base::Value> dict = GetDictionaryFromCastMessage(message); std::unique_ptr<base::Value> dict = GetDictionaryFromCastMessage(message);
...@@ -209,13 +211,34 @@ TEST_F(CastMessageHandlerTest, EnsureConnection) { ...@@ -209,13 +211,34 @@ TEST_F(CastMessageHandlerTest, EnsureConnection) {
EXPECT_CALL(*cast_socket_.mock_transport(), SendMessage(_, _, _)) EXPECT_CALL(*cast_socket_.mock_transport(), SendMessage(_, _, _))
.WillOnce(SaveArg<0>(&virtual_connection_request)); .WillOnce(SaveArg<0>(&virtual_connection_request));
handler_.EnsureConnection(cast_socket_.id(), "sourceId", "destinationId"); handler_.EnsureConnection(cast_socket_.id(), kSourceId, kDestinationId);
EXPECT_EQ(CastMessageType::kConnect, EXPECT_EQ(CastMessageType::kConnect,
ParseMessageType(virtual_connection_request)); ParseMessageType(virtual_connection_request));
// No-op because connection is already created the first time. // No-op because connection is already created the first time.
EXPECT_CALL(*cast_socket_.mock_transport(), SendMessage(_, _, _)).Times(0); EXPECT_CALL(*cast_socket_.mock_transport(), SendMessage(_, _, _)).Times(0);
handler_.EnsureConnection(cast_socket_.id(), "sourceId", "destinationId"); handler_.EnsureConnection(cast_socket_.id(), kSourceId, kDestinationId);
}
TEST_F(CastMessageHandlerTest, CloseConnectionFromReceiver) {
CastMessage virtual_connection_request;
EXPECT_CALL(*cast_socket_.mock_transport(), SendMessage(_, _, _));
handler_.EnsureConnection(cast_socket_.id(), kSourceId, kDestinationId);
CastMessage response;
response.set_namespace_("urn:x-cast:com.google.cast.tp.connection");
response.set_source_id(kDestinationId);
response.set_destination_id(kSourceId);
response.set_payload_type(
CastMessage::PayloadType::CastMessage_PayloadType_STRING);
response.set_payload_utf8(R"({
"type": "CLOSE"
})");
OnMessage(response);
// Re-open virtual connection should cause message to be sent.
EXPECT_CALL(*cast_socket_.mock_transport(), SendMessage(_, _, _));
handler_.EnsureConnection(cast_socket_.id(), kSourceId, kDestinationId);
} }
TEST_F(CastMessageHandlerTest, LaunchSession) { TEST_F(CastMessageHandlerTest, LaunchSession) {
...@@ -291,7 +314,7 @@ TEST_F(CastMessageHandlerTest, SendAppMessage) { ...@@ -291,7 +314,7 @@ TEST_F(CastMessageHandlerTest, SendAppMessage) {
base::Value body(base::Value::Type::DICTIONARY); base::Value body(base::Value::Type::DICTIONARY);
body.SetKey("foo", base::Value("bar")); body.SetKey("foo", base::Value("bar"));
CastMessage message = CastMessage message =
CreateCastMessage("namespace", body, "sourceId", "destinationId"); CreateCastMessage("namespace", body, kSourceId, kDestinationId);
handler_.SendAppMessage(cast_socket_.id(), message); handler_.SendAppMessage(cast_socket_.id(), message);
EXPECT_EQ(CastMessageType::kConnect, EXPECT_EQ(CastMessageType::kConnect,
......
...@@ -39,6 +39,7 @@ constexpr char kKeepAlivePingType[] = "PING"; ...@@ -39,6 +39,7 @@ constexpr char kKeepAlivePingType[] = "PING";
constexpr char kKeepAlivePongType[] = "PONG"; constexpr char kKeepAlivePongType[] = "PONG";
constexpr char kGetAppAvailabilityRequestType[] = "GET_APP_AVAILABILITY"; constexpr char kGetAppAvailabilityRequestType[] = "GET_APP_AVAILABILITY";
constexpr char kConnectionRequestType[] = "CONNECT"; constexpr char kConnectionRequestType[] = "CONNECT";
constexpr char kCloseConnectionRequestType[] = "CLOSE";
constexpr char kBroadcastRequestType[] = "APPLICATION_BROADCAST"; constexpr char kBroadcastRequestType[] = "APPLICATION_BROADCAST";
constexpr char kLaunchRequestType[] = "LAUNCH"; constexpr char kLaunchRequestType[] = "LAUNCH";
constexpr char kStopRequestType[] = "STOP"; constexpr char kStopRequestType[] = "STOP";
...@@ -144,6 +145,8 @@ const char* CastMessageTypeToString(CastMessageType message_type) { ...@@ -144,6 +145,8 @@ const char* CastMessageTypeToString(CastMessageType message_type) {
return kGetAppAvailabilityRequestType; return kGetAppAvailabilityRequestType;
case CastMessageType::kConnect: case CastMessageType::kConnect:
return kConnectionRequestType; return kConnectionRequestType;
case CastMessageType::kCloseConnection:
return kCloseConnectionRequestType;
case CastMessageType::kBroadcast: case CastMessageType::kBroadcast:
return kBroadcastRequestType; return kBroadcastRequestType;
case CastMessageType::kLaunch: case CastMessageType::kLaunch:
...@@ -170,6 +173,8 @@ CastMessageType CastMessageTypeFromString(const std::string& type) { ...@@ -170,6 +173,8 @@ CastMessageType CastMessageTypeFromString(const std::string& type) {
return CastMessageType::kGetAppAvailability; return CastMessageType::kGetAppAvailability;
if (type == kConnectionRequestType) if (type == kConnectionRequestType)
return CastMessageType::kConnect; return CastMessageType::kConnect;
if (type == kCloseConnectionRequestType)
return CastMessageType::kCloseConnection;
if (type == kBroadcastRequestType) if (type == kBroadcastRequestType)
return CastMessageType::kBroadcast; return CastMessageType::kBroadcast;
if (type == kLaunchRequestType) if (type == kLaunchRequestType)
......
...@@ -24,10 +24,11 @@ enum class CastMessageType { ...@@ -24,10 +24,11 @@ enum class CastMessageType {
kPing, kPing,
kPong, kPong,
kGetAppAvailability, kGetAppAvailability,
kConnect, // Virtual connection request kConnect, // Virtual connection request
kBroadcast, // Application broadcast / precache kCloseConnection, // Close virtual connection
kLaunch, // Session launch request kBroadcast, // Application broadcast / precache
kStop, // Session stop request kLaunch, // Session launch request
kStop, // Session stop request
kReceiverStatus, kReceiverStatus,
kLaunchError, kLaunchError,
kOther // Add new types above |kOther|. kOther // Add new types above |kOther|.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment