1// Copyright (c) 2011 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/debugger/inspectable_tab_proxy.h"
6
7#include "base/string_number_conversions.h"
8#include "base/string_util.h"
9#include "chrome/browser/debugger/debugger_remote_service.h"
10#include "chrome/browser/debugger/devtools_client_host.h"
11#include "chrome/browser/sessions/session_id.h"
12#include "chrome/browser/tabs/tab_strip_model.h"
13#include "chrome/browser/ui/browser_list.h"
14#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
15#include "chrome/common/devtools_messages.h"
16#include "content/browser/tab_contents/tab_contents.h"
17
18DevToolsClientHostImpl::DevToolsClientHostImpl(
19    int32 id,
20    DebuggerRemoteService* service,
21    InspectableTabProxy::IdToClientHostMap* map)
22    : id_(id),
23      service_(service),
24      map_(map) {}
25
26DevToolsClientHostImpl::~DevToolsClientHostImpl() {
27  map_->erase(this->id_);
28}
29
30// The debugged tab has closed.
31void DevToolsClientHostImpl::InspectedTabClosing() {
32  TabClosed();
33  delete this;
34}
35
36// The remote debugger has detached.
37void DevToolsClientHostImpl::Close() {
38  NotifyCloseListener();
39  delete this;
40}
41
42void DevToolsClientHostImpl::SendMessageToClient(
43    const IPC::Message& msg) {
44  // TODO(prybin): Restore FrameNavigate.
45  IPC_BEGIN_MESSAGE_MAP(DevToolsClientHostImpl, msg)
46    IPC_MESSAGE_HANDLER(DevToolsClientMsg_DebuggerOutput, OnDebuggerOutput);
47    IPC_MESSAGE_UNHANDLED_ERROR()
48  IPC_END_MESSAGE_MAP()
49}
50
51void DevToolsClientHostImpl::TabReplaced(TabContentsWrapper* new_tab) {
52  map_->erase(id_);
53  id_ = new_tab->controller().session_id().id();
54  (*map_)[id_] = this;
55}
56
57void DevToolsClientHostImpl::OnDebuggerOutput(const std::string& data) {
58  service_->DebuggerOutput(id_, data);
59}
60
61void DevToolsClientHostImpl::FrameNavigating(const std::string& url) {
62  service_->FrameNavigate(id_, url);
63}
64
65void DevToolsClientHostImpl::TabClosed() {
66  service_->TabClosed(id_);
67}
68
69InspectableTabProxy::InspectableTabProxy() {}
70
71InspectableTabProxy::~InspectableTabProxy() {}
72
73const InspectableTabProxy::ControllersMap&
74    InspectableTabProxy::controllers_map() {
75  controllers_map_.clear();
76  for (BrowserList::const_iterator it = BrowserList::begin(),
77       end = BrowserList::end(); it != end; ++it) {
78    TabStripModel* model = (*it)->tabstrip_model();
79    for (int i = 0, size = model->count(); i < size; ++i) {
80      NavigationController& controller =
81          model->GetTabContentsAt(i)->controller();
82      controllers_map_[controller.session_id().id()] = &controller;
83    }
84  }
85  return controllers_map_;
86}
87
88DevToolsClientHostImpl* InspectableTabProxy::ClientHostForTabId(
89    int32 id) {
90  InspectableTabProxy::IdToClientHostMap::const_iterator it =
91      id_to_client_host_map_.find(id);
92  if (it == id_to_client_host_map_.end()) {
93    return NULL;
94  }
95  return it->second;
96}
97
98DevToolsClientHost* InspectableTabProxy::NewClientHost(
99    int32 id,
100    DebuggerRemoteService* service) {
101  DevToolsClientHostImpl* client_host =
102      new DevToolsClientHostImpl(id, service, &id_to_client_host_map_);
103  id_to_client_host_map_[id] = client_host;
104  return client_host;
105}
106
107void InspectableTabProxy::OnRemoteDebuggerDetached() {
108  while (!id_to_client_host_map_.empty()) {
109    IdToClientHostMap::iterator it = id_to_client_host_map_.begin();
110    it->second->debugger_remote_service()->DetachFromTab(
111        base::IntToString(it->first), NULL);
112  }
113}
114