Update To 11.40.268.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
27 using content::DevToolsAgentHost;
28 using content::RenderViewHost;
29 using content::RenderWidgetHostView;
30 using content::WebContents;
31
32 namespace {
33
34 const char kTargetTypePage[] = "page";
35 const char kTargetTypeServiceWorker[] = "service_worker";
36 const char kTargetTypeOther[] = "other";
37
38 class Target : public content::DevToolsTarget {
39  public:
40   explicit Target(scoped_refptr<content::DevToolsAgentHost> agent_host);
41
42   std::string GetId() const override { return agent_host_->GetId(); }
43   std::string GetType() const override {
44       switch (agent_host_->GetType()) {
45         case content::DevToolsAgentHost::TYPE_WEB_CONTENTS:
46            return kTargetTypePage;
47          case content::DevToolsAgentHost::TYPE_SERVICE_WORKER:
48            return kTargetTypeServiceWorker;
49          default:
50            break;
51        }
52        return kTargetTypeOther;
53      }
54   std::string GetTitle() const override {
55     return agent_host_->GetTitle();
56   }
57   std::string GetDescription() const override { return std::string(); }
58   GURL GetURL() const override { return  agent_host_->GetURL(); }
59   GURL GetFaviconURL() const override { return favicon_url_; }
60   base::TimeTicks GetLastActivityTime() const override {
61     return last_activity_time_;
62   }
63   std::string GetParentId() const override { return std::string(); }
64   bool IsAttached() const override {
65     return agent_host_->IsAttached();
66   }
67   scoped_refptr<DevToolsAgentHost> GetAgentHost() const override {
68     return agent_host_;
69   }
70   bool Activate() const override;
71   bool Close() const override;
72
73  private:
74   GURL GetFaviconDataURL(WebContents* web_contents) const;
75
76   scoped_refptr<DevToolsAgentHost> agent_host_;
77   std::string id_;
78   std::string title_;
79   GURL favicon_url_;
80   base::TimeTicks last_activity_time_;
81 };
82
83 Target::Target(scoped_refptr<content::DevToolsAgentHost> agent_host)
84     : agent_host_(agent_host) {
85   if (content::WebContents* web_contents = agent_host_->GetWebContents()) {
86     content::NavigationController& controller = web_contents->GetController();
87     content::NavigationEntry* entry = controller.GetActiveEntry();
88     if (entry != NULL && entry->GetURL().is_valid())
89       favicon_url_ = entry->GetFavicon().url;
90     if (favicon_url_.is_empty())
91       favicon_url_ = GetFaviconDataURL(web_contents);
92     last_activity_time_ = web_contents->GetLastActiveTime();
93   }
94 }
95
96 GURL Target::GetFaviconDataURL(WebContents* web_contents) const {
97   // Convert icon image to "data:" url.
98 #if defined(OS_ANDROID)
99   // TODO(YangangHan): Add a new base parent class of WebContents
100   // for both Tizen and Android, so we can remove the current macro
101   // in the future.
102   return GURL();
103 #endif
104   xwalk::Runtime* runtime =
105       static_cast<xwalk::Runtime*>(web_contents->GetDelegate());
106   if (!runtime || runtime->app_icon().IsEmpty())
107     return GURL();
108   scoped_refptr<base::RefCountedMemory> icon_bytes =
109       runtime->app_icon().Copy1xPNGBytes();
110   std::string str_url;
111   str_url.append(reinterpret_cast<const char*>(icon_bytes->front()),
112                  icon_bytes->size());
113   base::Base64Encode(str_url, &str_url);
114   str_url.insert(0, "data:image/png;base64,");
115   return GURL(str_url);
116 }
117
118 bool Target::Activate() const {
119   return agent_host_->Activate();
120 }
121
122 bool Target::Close() const {
123   return agent_host_->Close();
124 }
125
126 }  // namespace
127
128 namespace xwalk {
129
130 namespace {
131 Runtime* CreateWithDefaultWindow(
132     XWalkBrowserContext* browser_context, const GURL& url,
133     Runtime::Observer* observer) {
134   Runtime* runtime = Runtime::Create(browser_context);
135   runtime->set_observer(observer);
136   runtime->LoadURL(url);
137 #if !defined(OS_ANDROID)
138   runtime->set_ui_delegate(DefaultRuntimeUIDelegate::Create(runtime));
139   runtime->Show();
140 #endif
141   return runtime;
142 }
143 }  // namespace
144
145 XWalkDevToolsHttpHandlerDelegate::XWalkDevToolsHttpHandlerDelegate() {
146 }
147
148 XWalkDevToolsHttpHandlerDelegate::~XWalkDevToolsHttpHandlerDelegate() {
149 }
150
151 std::string XWalkDevToolsHttpHandlerDelegate::GetDiscoveryPageHTML() {
152   return ResourceBundle::GetSharedInstance().GetRawDataResource(
153       IDR_DEVTOOLS_FRONTEND_PAGE_HTML).as_string();
154 }
155
156 void XWalkDevToolsDelegate::ProcessAndSaveThumbnail(
157     const GURL& url,
158     scoped_refptr<base::RefCountedBytes> png) {
159   const std::vector<unsigned char>& png_data = png->data();
160   std::string png_string_data(reinterpret_cast<const char*>(&png_data[0]),
161                               png_data.size());
162   thumbnail_map_[url] = png_string_data;
163 }
164
165 bool XWalkDevToolsHttpHandlerDelegate::BundlesFrontendResources() {
166   return true;
167 }
168
169 base::FilePath XWalkDevToolsHttpHandlerDelegate::GetDebugFrontendDir() {
170   return base::FilePath();
171 }
172
173 scoped_ptr<net::StreamListenSocket>
174 XWalkDevToolsHttpHandlerDelegate::CreateSocketForTethering(
175     net::StreamListenSocket::Delegate* delegate,
176     std::string* name) {
177   return scoped_ptr<net::StreamListenSocket>();
178 }
179
180 XWalkDevToolsDelegate::XWalkDevToolsDelegate(XWalkBrowserContext* context)
181     : browser_context_(context),
182       weak_factory_(this) {
183 }
184
185 XWalkDevToolsDelegate::~XWalkDevToolsDelegate() {
186 }
187
188 base::DictionaryValue* XWalkDevToolsDelegate::HandleCommand(
189     content::DevToolsAgentHost* agent_host,
190     base::DictionaryValue* command_dict) {
191   return NULL;
192 }
193
194 std::string XWalkDevToolsDelegate::GetPageThumbnailData(const GURL& url) {
195   if (thumbnail_map_.find(url) != thumbnail_map_.end())
196     return thumbnail_map_[url];
197   // TODO(YangangHan): Support real time thumbnail.
198   content::DevToolsAgentHost::List agents =
199       content::DevToolsAgentHost::GetOrCreateAll();
200   for (auto& it : agents) {
201     WebContents* web_contents = it.get()->GetWebContents();
202     if (web_contents && web_contents->GetURL() == url) {
203       RenderWidgetHostView* render_widget_host_view =
204           web_contents->GetRenderWidgetHostView();
205       if (!render_widget_host_view)
206         continue;
207       gfx::Rect snapshot_bounds(
208         render_widget_host_view->GetViewBounds().size());
209       ui::GrabViewSnapshotAsync(
210         render_widget_host_view->GetNativeView(),
211         snapshot_bounds,
212         base::ThreadTaskRunnerHandle::Get(),
213         base::Bind(&XWalkDevToolsDelegate::ProcessAndSaveThumbnail,
214                    weak_factory_.GetWeakPtr(),
215                    url));
216         break;
217     }
218   }
219   return std::string();
220 }
221
222 scoped_ptr<content::DevToolsTarget>
223 XWalkDevToolsDelegate::CreateNewTarget(const GURL& url) {
224   Runtime* runtime = CreateWithDefaultWindow(
225       browser_context_, url, this);
226   runtime->set_remote_debugging_enabled(true);
227   return scoped_ptr<content::DevToolsTarget>(
228       new Target(DevToolsAgentHost::GetOrCreateFor(runtime->web_contents())));
229 }
230
231 void XWalkDevToolsDelegate::EnumerateTargets(TargetCallback callback) {
232   TargetList targets;
233   content::DevToolsAgentHost::List agents =
234       content::DevToolsAgentHost::GetOrCreateAll();
235   for (content::DevToolsAgentHost::List::iterator it = agents.begin();
236        it != agents.end(); ++it) {
237 #if !defined(OS_ANDROID)
238     Runtime* runtime =
239         static_cast<Runtime*>((*it)->GetWebContents()->GetDelegate());
240     if (runtime && runtime->remote_debugging_enabled())
241 #endif
242       targets.push_back(new Target(*it));
243   }
244   callback.Run(targets);
245 }
246
247 void XWalkDevToolsDelegate::OnNewRuntimeAdded(Runtime* runtime) {
248   runtime->set_observer(this);
249   runtime->set_ui_delegate(DefaultRuntimeUIDelegate::Create(runtime));
250   runtime->Show();
251 }
252
253 void XWalkDevToolsDelegate::OnRuntimeClosed(Runtime* runtime) {
254   delete runtime;
255 }
256
257 }  // namespace xwalk