dev_tools_server.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/android/dev_tools_server.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <pwd.h> 8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include <cstring> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/android/jni_string.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/command_line.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/browser_process.h" 19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/devtools/devtools_adb_bridge.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/top_sites.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h" 227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/ui/android/tab_model/tab_model.h" 237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/ui/android/tab_model/tab_model_list.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/android/devtools_auth.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/devtools_http_handler.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/devtools_http_handler_delegate.h" 287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/web_contents.h" 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/common/content_switches.h" 307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/common/url_constants.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/devtools_discovery_page_resources.h" 32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "jni/DevToolsServer_jni.h" 33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/socket/unix_domain_socket_posix.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h" 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "webkit/common/user_agent/user_agent_util.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kFrontEndURL[] = 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch "http://chrome-devtools-frontend.appspot.com/serve_rev/%s/devtools.html"; 42eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst char kDefaultSocketNamePrefix[] = "chrome"; 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kTetheringSocketName[] = "chrome_devtools_tethering_%d_%d"; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Delegate implementation for the devtools http handler on android. A new 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// instance of this gets created each time devtools is enabled. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DevToolsServerDelegate : public content::DevToolsHttpHandlerDelegate { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DevToolsServerDelegate() 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : last_tethering_socket_(0) { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual std::string GetDiscoveryPageHTML() OVERRIDE { 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TopSites updates itself after a delay. Ask TopSites to update itself 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // when we're about to show the remote debugging landing page. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::BrowserThread::PostTask( 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::BrowserThread::UI, 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&DevToolsServerDelegate::PopulatePageThumbnails)); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ResourceBundle::GetSharedInstance().GetRawDataResource( 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IDR_DEVTOOLS_DISCOVERY_PAGE_HTML).as_string(); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool BundlesFrontendResources() OVERRIDE { 65eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return false; 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual base::FilePath GetDebugFrontendDir() OVERRIDE { 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return base::FilePath(); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual std::string GetPageThumbnailData(const GURL& url) OVERRIDE { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile = 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProfileManager::GetLastUsedProfile()->GetOriginalProfile(); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history::TopSites* top_sites = profile->GetTopSites(); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (top_sites) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::RefCountedMemory> data; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (top_sites->GetPageThumbnail(url, &data)) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return std::string(reinterpret_cast<const char*>(data->front()), 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data->size()); 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ""; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual content::RenderViewHost* CreateNewTarget() OVERRIDE { 867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Profile* profile = 877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) g_browser_process->profile_manager()->GetDefaultProfile(); 887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) TabModel* tab_model = TabModelList::GetTabModelWithProfile(profile); 897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!tab_model) 907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return NULL; 917d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) content::WebContents* web_contents = 927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) tab_model->CreateTabForTesting(GURL(content::kAboutBlankURL)); 937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) if (!web_contents) 947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return NULL; 957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return web_contents->GetRenderViewHost(); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual TargetType GetTargetType(content::RenderViewHost*) OVERRIDE { 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return kTargetTypeTab; 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual std::string GetViewDescription(content::RenderViewHost*) OVERRIDE { 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ""; 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 106c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) virtual scoped_refptr<net::StreamListenSocket> CreateSocketForTethering( 107c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) net::StreamListenSocket::Delegate* delegate, 108c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string* name) OVERRIDE { 109868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) *name = base::StringPrintf( 110868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) kTetheringSocketName, getpid(), ++last_tethering_socket_); 111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return net::UnixDomainSocket::CreateAndListenWithAbstractNamespace( 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) *name, 113868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) "", 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) delegate, 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&content::CanUserConnectToDevTools)); 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void PopulatePageThumbnails() { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Profile* profile = 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ProfileManager::GetLastUsedProfile()->GetOriginalProfile(); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) history::TopSites* top_sites = profile->GetTopSites(); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (top_sites) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) top_sites->SyncWithHistory(); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int last_tethering_socket_; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(DevToolsServerDelegate); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsServer::DevToolsServer() 135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : socket_name_(base::StringPrintf(kDevToolsChannelNameFormat, 136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch kDefaultSocketNamePrefix)), 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protocol_handler_(NULL) { 138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Override the default socket name if one is specified on the command line. 139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (command_line.HasSwitch(switches::kRemoteDebuggingSocketName)) { 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) socket_name_ = command_line.GetSwitchValueASCII( 142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switches::kRemoteDebuggingSocketName); 143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 146eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochDevToolsServer::DevToolsServer(const std::string& socket_name_prefix) 147eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch : socket_name_(base::StringPrintf(kDevToolsChannelNameFormat, 148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch socket_name_prefix.c_str())), 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protocol_handler_(NULL) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsServer::~DevToolsServer() { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Stop(); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsServer::Start() { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (protocol_handler_) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protocol_handler_ = content::DevToolsHttpHandler::Start( 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new net::UnixDomainSocketWithAbstractNamespaceFactory( 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_name_, 163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::StringPrintf("%s_%d", socket_name_.c_str(), getpid()), 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&content::CanUserConnectToDevTools)), 165eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::StringPrintf(kFrontEndURL, 166eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch webkit_glue::GetWebKitRevision().c_str()), 167eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch new DevToolsServerDelegate()); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsServer::Stop() { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!protocol_handler_) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that the call to Stop() below takes care of |protocol_handler_| 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // deletion. 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protocol_handler_->Stop(); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protocol_handler_ = NULL; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DevToolsServer::IsStarted() const { 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return protocol_handler_; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RegisterDevToolsServer(JNIEnv* env) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return RegisterNativesImpl(env); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static jint InitRemoteDebugging(JNIEnv* env, 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) jobject obj, 189eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch jstring socket_name_prefix) { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DevToolsServer* server = new DevToolsServer( 191eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::android::ConvertJavaStringToUTF8(env, socket_name_prefix)); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<jint>(server); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void DestroyRemoteDebugging(JNIEnv* env, jobject obj, jint server) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete reinterpret_cast<DevToolsServer*>(server); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static jboolean IsRemoteDebuggingEnabled(JNIEnv* env, 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) jobject obj, 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) jint server) { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<DevToolsServer*>(server)->IsStarted(); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void SetRemoteDebuggingEnabled(JNIEnv* env, 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) jobject obj, 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) jint server, 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) jboolean enabled) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DevToolsServer* devtools_server = reinterpret_cast<DevToolsServer*>(server); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (enabled) { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) devtools_server->Start(); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) devtools_server->Stop(); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 216