Upstream version 11.39.244.0
[platform/framework/web/crosswalk.git] / src / xwalk / runtime / browser / devtools / xwalk_devtools_delegate.cc
1 // Copyright (c) 2012 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 "xwalk/runtime/browser/devtools/xwalk_devtools_delegate.h"
6
7 #include <string>
8
9 #include "base/base64.h"
10 #include "base/memory/ref_counted_memory.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/thread_task_runner_handle.h"
13 #include "content/public/browser/devtools_agent_host.h"
14 #include "content/public/browser/devtools_http_handler.h"
15 #include "content/public/browser/devtools_target.h"
16 #include "content/public/browser/favicon_status.h"
17 #include "content/public/browser/navigation_entry.h"
18 #include "content/public/browser/render_view_host.h"
19 #include "content/public/browser/render_widget_host_view.h"
20 #include "content/public/browser/web_contents.h"
21 #include "content/public/common/url_constants.h"
22 #include "grit/xwalk_resources.h"
23 #include "net/socket/tcp_listen_socket.h"
24 #include "ui/base/resource/resource_bundle.h"
25 #include "ui/snapshot/snapshot.h"
26 #include "xwalk/runtime/browser/runtime.h"
27
28 using content::DevToolsAgentHost;
29 using content::RenderViewHost;
30 using content::RenderWidgetHostView;
31 using content::WebContents;
32
33 namespace {
34
35 const char kTargetTypePage[] = "page";
36 const char kTargetTypeServiceWorker[] = "service_worker";
37 const char kTargetTypeOther[] = "other";
38
39 class Target : public content::DevToolsTarget {
40  public:
41   explicit Target(scoped_refptr<content::DevToolsAgentHost> agent_host);
42
43   virtual std::string GetId() const OVERRIDE { return agent_host_->GetId(); }
44   virtual std::string GetType() const OVERRIDE {
45       switch (agent_host_->GetType()) {
46         case content::DevToolsAgentHost::TYPE_WEB_CONTENTS:
47            return kTargetTypePage;
48          case content::DevToolsAgentHost::TYPE_SERVICE_WORKER:
49            return kTargetTypeServiceWorker;
50          default:
51            break;
52        }
53        return kTargetTypeOther;
54      }
55   virtual std::string GetTitle() const OVERRIDE {
56     return agent_host_->GetTitle();
57   }
58   virtual std::string GetDescription() const OVERRIDE { return std::string(); }
59   virtual GURL GetURL() const OVERRIDE { return  agent_host_->GetURL(); }
60   virtual GURL GetFaviconURL() const OVERRIDE { return favicon_url_; }
61   virtual base::TimeTicks GetLastActivityTime() const OVERRIDE {
62     return last_activity_time_;
63   }
64   virtual std::string GetParentId() const OVERRIDE { return std::string(); }
65   virtual bool IsAttached() const OVERRIDE {
66     return agent_host_->IsAttached();
67   }
68   virtual scoped_refptr<DevToolsAgentHost> GetAgentHost() const OVERRIDE {
69     return agent_host_;
70   }
71   virtual bool Activate() const OVERRIDE;
72   virtual bool Close() const OVERRIDE;
73
74  private:
75   GURL GetFaviconDataURL(WebContents* web_contents) const;
76
77   scoped_refptr<DevToolsAgentHost> agent_host_;
78   std::string id_;
79   std::string title_;
80   GURL favicon_url_;
81   base::TimeTicks last_activity_time_;
82 };
83
84 Target::Target(scoped_refptr<content::DevToolsAgentHost> agent_host)
85     : agent_host_(agent_host) {
86   if (content::WebContents* web_contents = agent_host_->GetWebContents()) {
87     content::NavigationController& controller = web_contents->GetController();
88     content::NavigationEntry* entry = controller.GetActiveEntry();
89     if (entry != NULL && entry->GetURL().is_valid())
90       favicon_url_ = entry->GetFavicon().url;
91     if (favicon_url_.is_empty())
92       favicon_url_ = GetFaviconDataURL(web_contents);
93     last_activity_time_ = web_contents->GetLastActiveTime();
94   }
95 }
96
97 GURL Target::GetFaviconDataURL(WebContents* web_contents) const {
98   // Convert icon image to "data:" url.
99   xwalk::Runtime* runtime =
100       static_cast<xwalk::Runtime*>(web_contents->GetDelegate());
101   if (!runtime || runtime->app_icon().IsEmpty())
102     return GURL();
103   scoped_refptr<base::RefCountedMemory> icon_bytes =
104       runtime->app_icon().Copy1xPNGBytes();
105   std::string str_url;
106   str_url.append(reinterpret_cast<const char*>(icon_bytes->front()),
107                  icon_bytes->size());
108   base::Base64Encode(str_url, &str_url);
109   str_url.insert(0, "data:image/png;base64,");
110   return GURL(str_url);
111 }
112
113 bool Target::Activate() const {
114   return agent_host_->Activate();
115 }
116
117 bool Target::Close() const {
118   return agent_host_->Close();
119 }
120
121 }  // namespace
122
123 namespace xwalk {
124
125 namespace {
126 Runtime* CreateWithDefaultWindow(
127     RuntimeContext* runtime_context, const GURL& url,
128     Runtime::Observer* observer = NULL) {
129   Runtime* runtime = Runtime::Create(runtime_context, observer);
130   runtime->LoadURL(url);
131 #if !defined(OS_ANDROID)
132   RuntimeUIStrategy ui_strategy;
133   NativeAppWindow::CreateParams params;
134   ui_strategy.Show(runtime, params);
135 #endif
136   return runtime;
137 }
138 }  // namespace
139
140 XWalkDevToolsHttpHandlerDelegate::XWalkDevToolsHttpHandlerDelegate() {
141 }
142
143 XWalkDevToolsHttpHandlerDelegate::~XWalkDevToolsHttpHandlerDelegate() {
144 }
145
146 std::string XWalkDevToolsHttpHandlerDelegate::GetDiscoveryPageHTML() {
147   return ResourceBundle::GetSharedInstance().GetRawDataResource(
148       IDR_DEVTOOLS_FRONTEND_PAGE_HTML).as_string();
149 }
150
151 void XWalkDevToolsDelegate::ProcessAndSaveThumbnail(
152     const GURL& url,
153     scoped_refptr<base::RefCountedBytes> png) {
154   const std::vector<unsigned char>& png_data = png->data();
155   std::string png_string_data(reinterpret_cast<const char*>(&png_data[0]),
156                               png_data.size());
157   thumbnail_map_[url] = png_string_data;
158 }
159
160 bool XWalkDevToolsHttpHandlerDelegate::BundlesFrontendResources() {
161   return true;
162 }
163
164 base::FilePath XWalkDevToolsHttpHandlerDelegate::GetDebugFrontendDir() {
165   return base::FilePath();
166 }
167
168 scoped_ptr<net::StreamListenSocket>
169 XWalkDevToolsHttpHandlerDelegate::CreateSocketForTethering(
170     net::StreamListenSocket::Delegate* delegate,
171     std::string* name) {
172   return scoped_ptr<net::StreamListenSocket>();
173 }
174
175 XWalkDevToolsDelegate::XWalkDevToolsDelegate(RuntimeContext* runtime_context)
176     : runtime_context_(runtime_context),
177       weak_factory_(this) {
178 }
179
180 XWalkDevToolsDelegate::~XWalkDevToolsDelegate() {
181 }
182
183 base::DictionaryValue* XWalkDevToolsDelegate::HandleCommand(
184     content::DevToolsAgentHost* agent_host,
185     base::DictionaryValue* command_dict) {
186   return NULL;
187 }
188
189 std::string XWalkDevToolsDelegate::GetPageThumbnailData(const GURL& url) {
190   if (thumbnail_map_.find(url) != thumbnail_map_.end())
191     return thumbnail_map_[url];
192   // TODO(YangangHan): Support real time thumbnail.
193   content::DevToolsAgentHost::List agents =
194       content::DevToolsAgentHost::GetOrCreateAll();
195   for (auto& it : agents) {
196     WebContents* web_contents = it.get()->GetWebContents();
197     if (web_contents && web_contents->GetURL() == url) {
198       RenderWidgetHostView* render_widget_host_view =
199           web_contents->GetRenderViewHost()->GetView();
200       gfx::Rect snapshot_bounds(
201         render_widget_host_view->GetViewBounds().size());
202       ui::GrabViewSnapshotAsync(
203         render_widget_host_view->GetNativeView(),
204         snapshot_bounds,
205         base::ThreadTaskRunnerHandle::Get(),
206         base::Bind(&XWalkDevToolsDelegate::ProcessAndSaveThumbnail,
207                    weak_factory_.GetWeakPtr(),
208                    url));
209         break;
210     }
211   }
212   return std::string();
213 }
214
215 scoped_ptr<content::DevToolsTarget>
216 XWalkDevToolsDelegate::CreateNewTarget(const GURL& url) {
217   Runtime* runtime = CreateWithDefaultWindow(
218       runtime_context_, GURL(url::kAboutBlankURL));
219   return scoped_ptr<content::DevToolsTarget>(
220       new Target(DevToolsAgentHost::GetOrCreateFor(runtime->web_contents())));
221 }
222
223 void XWalkDevToolsDelegate::EnumerateTargets(TargetCallback callback) {
224   TargetList targets;
225   content::DevToolsAgentHost::List agents =
226       content::DevToolsAgentHost::GetOrCreateAll();
227   for (content::DevToolsAgentHost::List::iterator it = agents.begin();
228        it != agents.end(); ++it) {
229 #if !defined(OS_ANDROID)
230     Runtime* runtime =
231         static_cast<Runtime*>((*it)->GetWebContents()->GetDelegate());
232     if (runtime && runtime->remote_debugging_enabled())
233 #endif
234       targets.push_back(new Target(*it));
235   }
236   callback.Run(targets);
237 }
238
239 }  // namespace xwalk