168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// found in the LICENSE file.
468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "android_webview/native/aw_dev_tools_server.h"
668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "android_webview/native/aw_contents.h"
868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/bind.h"
946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/files/file_path.h"
1068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/json/json_writer.h"
1168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/strings/stringprintf.h"
124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/utf_string_conversions.h"
1368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/values.h"
1468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "content/public/browser/android/devtools_auth.h"
154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/devtools_agent_host.h"
1668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "content/public/browser/devtools_http_handler.h"
1768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "content/public/browser/devtools_http_handler_delegate.h"
184e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/devtools_target.h"
1968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "content/public/browser/web_contents.h"
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/common/user_agent.h"
2168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "jni/AwDevToolsServer_jni.h"
2268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "net/socket/unix_domain_socket_posix.h"
2368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
244e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using content::DevToolsAgentHost;
254e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using content::RenderViewHost;
264e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using content::WebContents;
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
2868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace {
2968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
3068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kFrontEndURL[] =
3168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    "http://chrome-devtools-frontend.appspot.com/serve_rev/%s/devtools.html";
3268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kSocketNameFormat[] = "webview_devtools_remote_%d";
3368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)const char kTargetTypePage[] = "page";
354e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
364e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)std::string GetViewDescription(WebContents* web_contents);
374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
384e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)class Target : public content::DevToolsTarget {
394e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) public:
404e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  explicit Target(WebContents* web_contents);
414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
424e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual std::string GetId() const OVERRIDE { return id_; }
4346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  virtual std::string GetParentId() const OVERRIDE { return std::string(); }
444e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual std::string GetType() const OVERRIDE { return kTargetTypePage; }
454e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual std::string GetTitle() const OVERRIDE { return title_; }
464e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual std::string GetDescription() const OVERRIDE { return description_; }
47010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  virtual GURL GetURL() const OVERRIDE { return url_; }
48010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  virtual GURL GetFaviconURL() const OVERRIDE { return GURL(); }
494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual base::TimeTicks GetLastActivityTime() const OVERRIDE {
504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return last_activity_time_;
514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual bool IsAttached() const OVERRIDE {
534e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return agent_host_->IsAttached();
544e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
554e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual scoped_refptr<DevToolsAgentHost> GetAgentHost() const OVERRIDE {
564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return agent_host_;
574e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  }
584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual bool Activate() const OVERRIDE { return false; }
594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual bool Close() const OVERRIDE { return false; }
604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) private:
624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  scoped_refptr<DevToolsAgentHost> agent_host_;
634e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string id_;
644e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string title_;
654e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  std::string description_;
664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  GURL url_;
674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  base::TimeTicks last_activity_time_;
684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)};
694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)Target::Target(WebContents* web_contents) {
714e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  agent_host_ =
724e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      DevToolsAgentHost::GetOrCreateFor(web_contents->GetRenderViewHost());
734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  id_ = agent_host_->GetId();
744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  description_ = GetViewDescription(web_contents);
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  title_ = base::UTF16ToUTF8(web_contents->GetTitle());
764e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  url_ = web_contents->GetURL();
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  last_activity_time_ = web_contents->GetLastActiveTime();
784e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
794e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
8068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Delegate implementation for the devtools http handler for WebView. A new
8168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// instance of this gets created each time web debugging is enabled.
8268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)class AwDevToolsServerDelegate : public content::DevToolsHttpHandlerDelegate {
8368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) public:
8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  AwDevToolsServerDelegate() {}
8568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  virtual ~AwDevToolsServerDelegate() {}
8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
8768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // DevToolsHttpProtocolHandler::Delegate overrides.
8868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  virtual std::string GetDiscoveryPageHTML() OVERRIDE;
8968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
9068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  virtual bool BundlesFrontendResources() OVERRIDE {
9168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return false;
9268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
9368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
9468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  virtual base::FilePath GetDebugFrontendDir() OVERRIDE {
9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return base::FilePath();
9668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
9768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  virtual std::string GetPageThumbnailData(const GURL&) OVERRIDE {
9968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return "";
10068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  virtual scoped_ptr<content::DevToolsTarget> CreateNewTarget(
1031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)      const GURL&) OVERRIDE {
1044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return scoped_ptr<content::DevToolsTarget>();
10568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
10668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1074e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  virtual void EnumerateTargets(TargetCallback callback) OVERRIDE {
1084e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    TargetList targets;
1094e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    std::vector<RenderViewHost*> rvh_list =
1104e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        DevToolsAgentHost::GetValidRenderViewHosts();
1114e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    for (std::vector<RenderViewHost*>::iterator it = rvh_list.begin();
1124e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)         it != rvh_list.end(); ++it) {
1134e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      WebContents* web_contents = WebContents::FromRenderViewHost(*it);
1144e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      if (web_contents)
1154e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)        targets.push_back(new Target(web_contents));
1164e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    }
1174e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    callback.Run(targets);
11868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
11968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
12068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  virtual scoped_ptr<net::StreamListenSocket> CreateSocketForTethering(
12168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      net::StreamListenSocket::Delegate* delegate,
12268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      std::string* name) OVERRIDE {
12368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return scoped_ptr<net::StreamListenSocket>();
12468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
12568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
12668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) private:
12768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AwDevToolsServerDelegate);
12868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)};
12968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
13068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
13168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)std::string AwDevToolsServerDelegate::GetDiscoveryPageHTML() {
13268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  const char html[] =
13368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      "<html>"
13468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      "<head><title>WebView remote debugging</title></head>"
13568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      "<body>Please use <a href=\'chrome://inspect\'>chrome://inspect</a>"
13668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      "</body>"
13768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      "</html>";
13868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return html;
13968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
14068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1414e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)std::string GetViewDescription(WebContents* web_contents) {
142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  const android_webview::BrowserViewRenderer* bvr =
143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      android_webview::AwContents::FromWebContents(web_contents)
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          ->GetBrowserViewRenderer();
14568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!bvr) return "";
14668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::DictionaryValue description;
1472f22f038970e0d1927c41b04bbf5589bd12c5316Torne (Richard Coles)  description.SetBoolean("attached", bvr->attached_to_window());
14868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  description.SetBoolean("visible", bvr->IsVisible());
14968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  gfx::Rect screen_rect = bvr->GetScreenRect();
15068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  description.SetInteger("screenX", screen_rect.x());
15168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  description.SetInteger("screenY", screen_rect.y());
15268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  description.SetBoolean("empty", screen_rect.size().IsEmpty());
15368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!screen_rect.size().IsEmpty()) {
15468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    description.SetInteger("width", screen_rect.width());
15568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    description.SetInteger("height", screen_rect.height());
15668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
15768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  std::string json;
15868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  base::JSONWriter::Write(&description, &json);
15968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return json;
16068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
16168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
16268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}  // namespace
16368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
16468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace android_webview {
16568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
16668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)AwDevToolsServer::AwDevToolsServer()
16768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    : protocol_handler_(NULL) {
16868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
16968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
17068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)AwDevToolsServer::~AwDevToolsServer() {
17168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  Stop();
17268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
17368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
17468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void AwDevToolsServer::Start() {
17568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (protocol_handler_)
17668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
17768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
17868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  protocol_handler_ = content::DevToolsHttpHandler::Start(
17968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      new net::UnixDomainSocketWithAbstractNamespaceFactory(
18068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          base::StringPrintf(kSocketNameFormat, getpid()),
18168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          "",
18268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)          base::Bind(&content::CanUserConnectToDevTools)),
183a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::StringPrintf(kFrontEndURL, content::GetWebKitRevision().c_str()),
18446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      new AwDevToolsServerDelegate(),
18546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::FilePath());
18668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
18768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
18868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void AwDevToolsServer::Stop() {
18968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (!protocol_handler_)
19068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    return;
19168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Note that the call to Stop() below takes care of |protocol_handler_|
19268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // deletion.
19368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  protocol_handler_->Stop();
19468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  protocol_handler_ = NULL;
19568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
19668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
19768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool AwDevToolsServer::IsStarted() const {
19868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return protocol_handler_;
19968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
20068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
20168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool RegisterAwDevToolsServer(JNIEnv* env) {
20268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return RegisterNativesImpl(env);
20368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
20468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
205effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochstatic jlong InitRemoteDebugging(JNIEnv* env,
20668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                jobject obj) {
20768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  AwDevToolsServer* server = new AwDevToolsServer();
208effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  return reinterpret_cast<intptr_t>(server);
20968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
21068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
211effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochstatic void DestroyRemoteDebugging(JNIEnv* env, jobject obj, jlong server) {
21268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  delete reinterpret_cast<AwDevToolsServer*>(server);
21368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
21468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
21568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)static void SetRemoteDebuggingEnabled(JNIEnv* env,
21668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                      jobject obj,
217effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch                                      jlong server,
21868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                                      jboolean enabled) {
21968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  AwDevToolsServer* devtools_server =
22068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)      reinterpret_cast<AwDevToolsServer*>(server);
22168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  if (enabled) {
22268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    devtools_server->Start();
22368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  } else {
22468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    devtools_server->Stop();
22568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
22668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
22768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
22868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}  // namespace android_webview
229