| // Copyright 2013 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. |
| |
| #include "extensions/browser/api/diagnostics/diagnostics_api.h" |
| |
| #include "base/bind.h" |
| #include "base/callback.h" |
| #include "base/json/json_reader.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/values.h" |
| #include "chromeos/dbus/dbus_thread_manager.h" |
| #include "chromeos/dbus/debug_daemon/debug_daemon_client.h" |
| |
| namespace extensions { |
| |
| namespace { |
| |
| const char kErrorPingFailed[] = "Failed to send ping packet"; |
| |
| const char kCount[] = "count"; |
| const char kDefaultCount[] = "1"; |
| const char kTTL[] = "ttl"; |
| const char kTimeout[] = "timeout"; |
| const char kSize[] = "size"; |
| |
| bool ParseResult(const std::string& status, std::string* ip, double* latency) { |
| // Parses the result and returns IP and latency. |
| std::unique_ptr<base::Value> parsed_value( |
| base::JSONReader::ReadDeprecated(status)); |
| if (!parsed_value) |
| return false; |
| |
| base::DictionaryValue* result = NULL; |
| if (!parsed_value->GetAsDictionary(&result) || result->DictSize() != 1) |
| return false; |
| |
| // Returns the first item. |
| base::DictionaryValue::Iterator iterator(*result); |
| |
| const base::DictionaryValue* info; |
| if (!iterator.value().GetAsDictionary(&info)) |
| return false; |
| |
| if (!info->GetDouble("avg", latency)) |
| return false; |
| |
| *ip = iterator.key(); |
| return true; |
| } |
| |
| } // namespace |
| |
| namespace SendPacket = api::diagnostics::SendPacket; |
| |
| DiagnosticsSendPacketFunction::DiagnosticsSendPacketFunction() = default; |
| DiagnosticsSendPacketFunction::~DiagnosticsSendPacketFunction() = default; |
| |
| ExtensionFunction::ResponseAction DiagnosticsSendPacketFunction::Run() { |
| auto params = api::diagnostics::SendPacket::Params::Create(args()); |
| |
| std::map<std::string, std::string> config; |
| config[kCount] = kDefaultCount; |
| if (params->options.ttl) |
| config[kTTL] = base::NumberToString(*params->options.ttl); |
| if (params->options.timeout) |
| config[kTimeout] = base::NumberToString(*params->options.timeout); |
| if (params->options.size) |
| config[kSize] = base::NumberToString(*params->options.size); |
| |
| chromeos::DBusThreadManager::Get() |
| ->GetDebugDaemonClient() |
| ->TestICMPWithOptions( |
| params->options.ip, config, |
| base::BindOnce(&DiagnosticsSendPacketFunction::OnTestICMPCompleted, |
| this)); |
| |
| return RespondLater(); |
| } |
| |
| void DiagnosticsSendPacketFunction::OnTestICMPCompleted( |
| absl::optional<std::string> status) { |
| std::string ip; |
| double latency; |
| if (!status.has_value() || !ParseResult(status.value(), &ip, &latency)) { |
| Respond(Error(kErrorPingFailed)); |
| return; |
| } |
| |
| api::diagnostics::SendPacketResult result; |
| result.ip = ip; |
| result.latency = latency; |
| Respond(OneArgument(base::Value(SendPacket::Results::Create(result)))); |
| } |
| |
| } // namespace extensions |