summaryrefslogtreecommitdiffstats
path: root/chrome/browser/debugger/devtools_remote_service.cc
blob: a8f57a3fb07afc020f6c45919c5957664c31804c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Copyright (c) 2011 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 "chrome/browser/debugger/devtools_remote_service.h"

#include <string>

#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "base/memory/scoped_ptr.h"
#include "base/values.h"
#include "chrome/browser/debugger/devtools_manager.h"
#include "chrome/browser/debugger/devtools_protocol_handler.h"
#include "chrome/browser/debugger/devtools_remote_message.h"
#include "chrome/browser/debugger/inspectable_tab_proxy.h"
#include "chrome/browser/sessions/restore_tab_helper.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "content/browser/tab_contents/navigation_controller.h"
#include "content/browser/tab_contents/navigation_entry.h"
#include "content/common/devtools_messages.h"

const char DevToolsRemoteServiceCommand::kPing[] = "ping";
const char DevToolsRemoteServiceCommand::kVersion[] = "version";
const char DevToolsRemoteServiceCommand::kListTabs[] = "list_tabs";

const char DevToolsRemoteService::kToolName[] = "DevToolsService";

namespace {
const char kCommandKey[] = "command";
const char kDataKey[] = "data";
const char kResultKey[] = "result";
}  // namespace

DevToolsRemoteService::DevToolsRemoteService(DevToolsProtocolHandler* delegate)
    : delegate_(delegate) {}

DevToolsRemoteService::~DevToolsRemoteService() {}

void DevToolsRemoteService::HandleMessage(
    const DevToolsRemoteMessage& message) {
  scoped_ptr<Value> request(base::JSONReader::Read(message.content(), false));
  if (request.get() == NULL) {
    // Bad JSON
    NOTREACHED();
    return;
  }
  DictionaryValue* json;
  if (request->IsType(Value::TYPE_DICTIONARY)) {
    json = static_cast<DictionaryValue*>(request.get());
    if (!json->HasKey(kCommandKey)) {
      NOTREACHED();  // Broken protocol - no "command" specified
      return;
    }
  } else {
    NOTREACHED();  // Broken protocol - not a JS object
    return;
  }
  ProcessJson(json, message);
}

void DevToolsRemoteService::ProcessJson(DictionaryValue* json,
                                        const DevToolsRemoteMessage& message) {
  static const std::string kOkResponse = "ok";  // "Ping" response
  static const std::string kVersion = "0.1";  // Current protocol version
  std::string command;
  DictionaryValue response;

  json->GetString(kCommandKey, &command);
  response.SetString(kCommandKey, command);

  if (command == DevToolsRemoteServiceCommand::kPing) {
    response.SetInteger(kResultKey, Result::kOk);
    response.SetString(kDataKey, kOkResponse);
  } else if (command == DevToolsRemoteServiceCommand::kVersion) {
    response.SetInteger(kResultKey, Result::kOk);
    response.SetString(kDataKey, kVersion);
  } else if (command == DevToolsRemoteServiceCommand::kListTabs) {
    ListValue* data = new ListValue();
    const InspectableTabProxy::TabMap& tab_map =
        delegate_->inspectable_tab_proxy()->tab_map();
    for (InspectableTabProxy::TabMap::const_iterator it =
        tab_map.begin(), end = tab_map.end(); it != end; ++it) {
      NavigationEntry* entry = it->second->controller().GetActiveEntry();
      if (entry == NULL) {
        continue;
      }
      if (entry->url().is_valid()) {
        ListValue* tab = new ListValue();
        tab->Append(Value::CreateIntegerValue(
                        it->second->restore_tab_helper()->session_id().id()));
        tab->Append(Value::CreateStringValue(entry->url().spec()));
        data->Append(tab);
      }
    }
    response.SetInteger(kResultKey, Result::kOk);
    response.Set(kDataKey, data);
  } else {
    // Unknown protocol command.
    NOTREACHED();
    response.SetInteger(kResultKey, Result::kUnknownCommand);
  }
  std::string response_json;
  base::JSONWriter::Write(&response, false, &response_json);
  scoped_ptr<DevToolsRemoteMessage> response_message(
      DevToolsRemoteMessageBuilder::instance().Create(message.tool(),
                                                      message.destination(),
                                                      response_json));
  delegate_->Send(*response_message.get());
}