1// Copyright 2014 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 "chrome/browser/devtools/devtools_network_protocol_handler.h"
6
7#include "base/values.h"
8#include "chrome/browser/devtools/devtools_network_conditions.h"
9#include "chrome/browser/devtools/devtools_network_controller.h"
10#include "chrome/browser/devtools/devtools_protocol_constants.h"
11#include "chrome/browser/profiles/profile.h"
12#include "content/public/browser/devtools_agent_host.h"
13#include "content/public/browser/web_contents.h"
14
15DevToolsNetworkProtocolHandler::DevToolsNetworkProtocolHandler() {
16}
17
18DevToolsNetworkProtocolHandler::~DevToolsNetworkProtocolHandler() {
19}
20
21base::DictionaryValue* DevToolsNetworkProtocolHandler::HandleCommand(
22    content::DevToolsAgentHost* agent_host,
23    base::DictionaryValue* command_dict) {
24  scoped_ptr<DevToolsProtocol::Command> command(
25       DevToolsProtocol::ParseCommand(command_dict));
26  if (!command)
27    return NULL;
28
29  namespace network = ::chrome::devtools::Network;
30  const std::string method = command->method();
31  scoped_ptr<DevToolsProtocol::Response> response;
32
33  if (method == network::emulateNetworkConditions::kName) {
34    response = EmulateNetworkConditions(agent_host, command.get());
35  } else if (method == network::canEmulateNetworkConditions::kName) {
36    response = CanEmulateNetworkConditions(agent_host, command.get());
37  }
38
39  if (response)
40    return response->Serialize();
41  return NULL;
42}
43
44Profile* DevToolsNetworkProtocolHandler::GetProfile(
45    content::DevToolsAgentHost* agent_host) {
46  content::WebContents* web_contents = agent_host->GetWebContents();
47  if (!web_contents)
48    return NULL;
49  return Profile::FromBrowserContext(web_contents->GetBrowserContext());
50}
51
52scoped_ptr<DevToolsProtocol::Response>
53DevToolsNetworkProtocolHandler::CanEmulateNetworkConditions(
54    content::DevToolsAgentHost* agent_host,
55    DevToolsProtocol::Command* command) {
56  base::DictionaryValue* result = new base::DictionaryValue();
57  result->SetBoolean(chrome::devtools::kResult, true);
58  return command->SuccessResponse(result);
59}
60
61scoped_ptr<DevToolsProtocol::Response>
62DevToolsNetworkProtocolHandler::EmulateNetworkConditions(
63    content::DevToolsAgentHost* agent_host,
64    DevToolsProtocol::Command* command) {
65  base::DictionaryValue* params = command->params();
66  namespace names = ::chrome::devtools::Network::emulateNetworkConditions;
67
68  bool offline = false;
69  if (!params || !params->GetBoolean(names::kParamOffline, &offline))
70    return command->InvalidParamResponse(names::kParamOffline);
71
72  double latency = 0.0;
73  if (!params->GetDouble(names::kParamLatency, &latency))
74    return command->InvalidParamResponse(names::kParamLatency);
75  if (latency < 0.0)
76    latency = 0.0;
77
78  double download_throughput = 0.0;
79  if (!params->GetDouble(names::kParamDownloadThroughput, &download_throughput))
80    return command->InvalidParamResponse(names::kParamDownloadThroughput);
81  if (download_throughput < 0.0)
82    download_throughput = 0.0;
83
84  double upload_throughput = 0.0;
85  if (!params->GetDouble(names::kParamUploadThroughput, &upload_throughput))
86    return command->InvalidParamResponse(names::kParamUploadThroughput);
87  if (upload_throughput < 0.0)
88    upload_throughput = 0.0;
89
90  scoped_ptr<DevToolsNetworkConditions> conditions(
91      new DevToolsNetworkConditions(
92          offline, latency, download_throughput, upload_throughput));
93
94  UpdateNetworkState(agent_host, conditions.Pass());
95  return command->SuccessResponse(NULL);
96}
97
98void DevToolsNetworkProtocolHandler::UpdateNetworkState(
99    content::DevToolsAgentHost* agent_host,
100    scoped_ptr<DevToolsNetworkConditions> conditions) {
101  Profile* profile = GetProfile(agent_host);
102  if (!profile)
103    return;
104  profile->GetDevToolsNetworkController()->SetNetworkState(
105      agent_host->GetId(), conditions.Pass());
106}
107
108void DevToolsNetworkProtocolHandler::DevToolsAgentStateChanged(
109    content::DevToolsAgentHost* agent_host,
110    bool attached) {
111  scoped_ptr<DevToolsNetworkConditions> conditions;
112  if (attached)
113    conditions.reset(new DevToolsNetworkConditions());
114  UpdateNetworkState(agent_host, conditions.Pass());
115}
116