receiver_response.cc 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. // Copyright 2018 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. #include "components/mirroring/service/receiver_response.h"
  5. #include "base/base64.h"
  6. #include "base/bind.h"
  7. #include "base/callback.h"
  8. #include "base/logging.h"
  9. #include "base/strings/string_util.h"
  10. #include "components/mirroring/service/value_util.h"
  11. #include "third_party/jsoncpp/source/include/json/reader.h"
  12. #include "third_party/jsoncpp/source/include/json/writer.h"
  13. namespace mirroring {
  14. namespace {
  15. // Get the response type from the type string value in the JSON message.
  16. ResponseType ResponseTypeFromString(const std::string& type) {
  17. if (type == "ANSWER")
  18. return ResponseType::ANSWER;
  19. if (type == "CAPABILITIES_RESPONSE")
  20. return ResponseType::CAPABILITIES_RESPONSE;
  21. if (type == "RPC")
  22. return ResponseType::RPC;
  23. return ResponseType::UNKNOWN;
  24. }
  25. // JSON helper methods. Note that these are *heavily* based on the
  26. // util/json_helpers.h methods from Open Screen. When the mirroring service
  27. // moves to depend on libcast, the duplicate code should pretty much all go
  28. // away.
  29. bool GetInt(const Json::Value& value, int* out) {
  30. // We are generally very forgiving of missing fields, so don't return an
  31. // error if it is just missing.
  32. if (!value) {
  33. *out = -1;
  34. return true;
  35. }
  36. // If it's present, though, it must be valid.
  37. if (!value.isInt()) {
  38. return false;
  39. }
  40. const int i = value.asInt();
  41. if (i < 0) {
  42. return false;
  43. }
  44. *out = i;
  45. return true;
  46. }
  47. bool GetString(const Json::Value& value, std::string* out) {
  48. if (!value) {
  49. *out = {};
  50. return true;
  51. }
  52. if (!value.isString()) {
  53. return false;
  54. }
  55. *out = value.asString();
  56. return true;
  57. }
  58. template <typename T>
  59. using Parser = base::RepeatingCallback<bool(const Json::Value&, T*)>;
  60. // Returns whether or not an error occurred. For the purpose of this function,
  61. // if the value is empty or not an array, that is not an error, and it thus
  62. // returns true after setting the |out| vector to empty.
  63. template <typename T>
  64. bool GetArray(const Json::Value& value, Parser<T> parser, std::vector<T>* out) {
  65. out->clear();
  66. if (!value.isArray() || value.empty()) {
  67. return true;
  68. }
  69. out->reserve(value.size());
  70. for (auto i : value) {
  71. T v;
  72. if (!parser.Run(i, &v)) {
  73. out->clear();
  74. return false;
  75. }
  76. out->push_back(std::move(v));
  77. }
  78. return true;
  79. }
  80. bool GetStringArray(const Json::Value& value, std::vector<std::string>* out) {
  81. return GetArray<std::string>(value, base::BindRepeating(&GetString), out);
  82. }
  83. ResponseType GetResponseType(const Json::Value& root_node) {
  84. std::string type;
  85. if (!GetString(root_node["type"], &type)) {
  86. return ResponseType::UNKNOWN;
  87. }
  88. return ResponseTypeFromString(base::ToUpperASCII(type));
  89. }
  90. std::string GetDetails(const Json::Value& value) {
  91. if (!value) {
  92. return {};
  93. }
  94. Json::StreamWriterBuilder builder;
  95. return Json::writeString(builder, value);
  96. }
  97. std::unique_ptr<ReceiverError> ParseError(const Json::Value& value) {
  98. auto error = std::make_unique<ReceiverError>();
  99. if (!GetInt(value["code"], &(error->code)) ||
  100. !GetString(value["description"], &(error->description))) {
  101. return {};
  102. }
  103. // We are generally pretty forgiving about details: throwing an error
  104. // because the Receiver didn't properly fill out the detail of an error
  105. // message doesn't really make sense.
  106. error->details = GetDetails(value["details"]);
  107. return error;
  108. }
  109. std::unique_ptr<ReceiverCapability> ParseCapability(const Json::Value& value) {
  110. auto capability = std::make_unique<ReceiverCapability>();
  111. if (!value)
  112. return {};
  113. if (!GetInt(value["remoting"], &(capability->remoting))) {
  114. capability->remoting = ReceiverCapability::kRemotingVersionUnknown;
  115. }
  116. if (!GetStringArray(value["mediaCaps"], &(capability->media_caps))) {
  117. return {};
  118. }
  119. return capability;
  120. }
  121. } // namespace
  122. ReceiverCapability::ReceiverCapability() = default;
  123. ReceiverCapability::~ReceiverCapability() = default;
  124. ReceiverCapability::ReceiverCapability(ReceiverCapability&& receiver_response) =
  125. default;
  126. ReceiverCapability::ReceiverCapability(
  127. const ReceiverCapability& receiver_response) = default;
  128. ReceiverCapability& ReceiverCapability::operator=(
  129. ReceiverCapability&& receiver_response) = default;
  130. ReceiverCapability& ReceiverCapability::operator=(
  131. const ReceiverCapability& receiver_response) = default;
  132. ReceiverError::ReceiverError() = default;
  133. ReceiverError::~ReceiverError() = default;
  134. ReceiverError::ReceiverError(ReceiverError&& receiver_response) = default;
  135. ReceiverError::ReceiverError(const ReceiverError& receiver_response) = default;
  136. ReceiverError& ReceiverError::operator=(ReceiverError&& receiver_response) =
  137. default;
  138. ReceiverError& ReceiverError::operator=(
  139. const ReceiverError& receiver_response) = default;
  140. ReceiverResponse::ReceiverResponse() = default;
  141. ReceiverResponse::~ReceiverResponse() = default;
  142. ReceiverResponse::ReceiverResponse(ReceiverResponse&& receiver_response) =
  143. default;
  144. ReceiverResponse& ReceiverResponse::operator=(
  145. ReceiverResponse&& receiver_response) = default;
  146. // static
  147. std::unique_ptr<ReceiverResponse> ReceiverResponse::Parse(
  148. const std::string& message_data) {
  149. Json::CharReaderBuilder builder;
  150. Json::CharReaderBuilder::strictMode(&builder.settings_);
  151. std::unique_ptr<Json::CharReader> reader(builder.newCharReader());
  152. Json::Value root_node;
  153. std::string error_msg;
  154. const bool succeeded = reader->parse(
  155. message_data.data(), message_data.data() + message_data.length(),
  156. &root_node, &error_msg);
  157. if (!succeeded) {
  158. DVLOG(1) << "Failed to parse reciever message: " << error_msg;
  159. return nullptr;
  160. }
  161. auto response = std::make_unique<ReceiverResponse>();
  162. std::string result;
  163. if (!root_node || !GetInt(root_node["sessionId"], &(response->session_id_)) ||
  164. !GetInt(root_node["seqNum"], &(response->sequence_number_)) ||
  165. !GetString(root_node["result"], &result)) {
  166. return nullptr;
  167. }
  168. response->type_ = GetResponseType(root_node);
  169. // For backwards compatibility with <= M85, RPC responses lack a result field.
  170. response->valid_ = (result == "ok" || response->type_ == ResponseType::RPC);
  171. if (!response->valid_) {
  172. response->error_ = ParseError(root_node["error"]);
  173. return response;
  174. }
  175. switch (response->type_) {
  176. case ResponseType::ANSWER:
  177. response->answer_ = std::make_unique<openscreen::cast::Answer>();
  178. if (!openscreen::cast::Answer::TryParse(root_node["answer"],
  179. response->answer_.get())) {
  180. response->valid_ = false;
  181. }
  182. break;
  183. case ResponseType::CAPABILITIES_RESPONSE:
  184. response->capabilities_ = ParseCapability(root_node["capabilities"]);
  185. if (!response->capabilities_) {
  186. response->valid_ = false;
  187. }
  188. break;
  189. case ResponseType::RPC: {
  190. std::string raw_rpc;
  191. if (!GetString(root_node["rpc"], &raw_rpc) ||
  192. !base::Base64Decode(raw_rpc, &(response->rpc_))) {
  193. response->valid_ = false;
  194. }
  195. } break;
  196. case ResponseType::UNKNOWN:
  197. default:
  198. response->valid_ = false;
  199. break;
  200. }
  201. return response;
  202. }
  203. std::unique_ptr<ReceiverResponse> ReceiverResponse::CloneForTesting() const {
  204. auto clone = std::make_unique<ReceiverResponse>();
  205. clone->type_ = type_;
  206. clone->session_id_ = session_id_;
  207. clone->sequence_number_ = sequence_number_;
  208. clone->valid_ = valid_;
  209. if (!valid_) {
  210. if (error_) {
  211. clone->error_ = std::make_unique<ReceiverError>(*error_);
  212. }
  213. return clone;
  214. }
  215. // We assume that if the message wasn't classified as an error,
  216. // it has a body.
  217. switch (type_) {
  218. case ResponseType::ANSWER:
  219. clone->answer_ = std::make_unique<openscreen::cast::Answer>(*answer_);
  220. break;
  221. case ResponseType::CAPABILITIES_RESPONSE:
  222. clone->capabilities_ =
  223. std::make_unique<ReceiverCapability>(*capabilities_);
  224. break;
  225. case ResponseType::RPC:
  226. clone->rpc_ = rpc_;
  227. break;
  228. case ResponseType::UNKNOWN:
  229. break;
  230. }
  231. return clone;
  232. }
  233. // static
  234. ReceiverResponse ReceiverResponse::CreateAnswerResponseForTesting(
  235. int32_t sequence_number,
  236. std::unique_ptr<openscreen::cast::Answer> answer) {
  237. ReceiverResponse response;
  238. response.type_ = ResponseType::ANSWER;
  239. response.sequence_number_ = sequence_number;
  240. response.answer_ = std::move(answer);
  241. response.valid_ = true;
  242. return response;
  243. }
  244. // static
  245. ReceiverResponse ReceiverResponse::CreateCapabilitiesResponseForTesting(
  246. int32_t sequence_number,
  247. std::unique_ptr<ReceiverCapability> capabilities) {
  248. ReceiverResponse response;
  249. response.type_ = ResponseType::CAPABILITIES_RESPONSE;
  250. response.sequence_number_ = sequence_number;
  251. response.capabilities_ = std::move(capabilities);
  252. response.valid_ = true;
  253. return response;
  254. }
  255. } // namespace mirroring