aw_dev_tools_server.cc revision 68043e1e95eeb07d5cae7aca370b26518b0867d6
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) 768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "android_webview/browser/in_process_view_renderer.h" 868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/bind.h" 968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/json/json_writer.h" 1068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/strings/stringprintf.h" 1168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/values.h" 1268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "content/public/browser/android/devtools_auth.h" 1368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "content/public/browser/devtools_http_handler.h" 1468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "content/public/browser/devtools_http_handler_delegate.h" 1568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "content/public/browser/web_contents.h" 1668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "jni/AwDevToolsServer_jni.h" 1768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "net/socket/unix_domain_socket_posix.h" 1868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "webkit/common/user_agent/user_agent_util.h" 1968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace { 2168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kFrontEndURL[] = 2368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "http://chrome-devtools-frontend.appspot.com/serve_rev/%s/devtools.html"; 2468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const char kSocketNameFormat[] = "webview_devtools_remote_%d"; 2568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 2668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Delegate implementation for the devtools http handler for WebView. A new 2768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// instance of this gets created each time web debugging is enabled. 2868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)class AwDevToolsServerDelegate : public content::DevToolsHttpHandlerDelegate { 2968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) public: 3068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) AwDevToolsServerDelegate() {} 3168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) virtual ~AwDevToolsServerDelegate() {} 3268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 3368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // DevToolsHttpProtocolHandler::Delegate overrides. 3468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) virtual std::string GetDiscoveryPageHTML() OVERRIDE; 3568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 3668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) virtual bool BundlesFrontendResources() OVERRIDE { 3768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return false; 3868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 3968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 4068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) virtual base::FilePath GetDebugFrontendDir() OVERRIDE { 4168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return base::FilePath(); 4268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 4368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 4468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) virtual std::string GetPageThumbnailData(const GURL&) OVERRIDE { 4568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return ""; 4668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 4768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 4868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) virtual content::RenderViewHost* CreateNewTarget() OVERRIDE { 4968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return NULL; 5068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 5168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 5268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) virtual TargetType GetTargetType(content::RenderViewHost*) OVERRIDE { 5368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return kTargetTypeTab; 5468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 5568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 5668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) virtual std::string GetViewDescription(content::RenderViewHost*) OVERRIDE; 5768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 5868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) virtual scoped_ptr<net::StreamListenSocket> CreateSocketForTethering( 5968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) net::StreamListenSocket::Delegate* delegate, 6068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::string* name) OVERRIDE { 6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return scoped_ptr<net::StreamListenSocket>(); 6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 6368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 6468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) private: 6568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AwDevToolsServerDelegate); 6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}; 6768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 6868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)std::string AwDevToolsServerDelegate::GetDiscoveryPageHTML() { 7068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const char html[] = 7168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "<html>" 7268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "<head><title>WebView remote debugging</title></head>" 7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "<body>Please use <a href=\'chrome://inspect\'>chrome://inspect</a>" 7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "</body>" 7568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "</html>"; 7668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return html; 7768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 7868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 7968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)std::string AwDevToolsServerDelegate::GetViewDescription( 8068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) content::RenderViewHost* rvh) { 8168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) content::WebContents* web_contents = 8268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) content::WebContents::FromRenderViewHost(rvh); 8368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!web_contents) return ""; 8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 8568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) android_webview::BrowserViewRenderer* bvr 8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) = android_webview::InProcessViewRenderer::FromWebContents(web_contents); 8768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!bvr) return ""; 8868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::DictionaryValue description; 8968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) description.SetBoolean("attached", bvr->IsAttachedToWindow()); 9068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) description.SetBoolean("visible", bvr->IsVisible()); 9168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) gfx::Rect screen_rect = bvr->GetScreenRect(); 9268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) description.SetInteger("screenX", screen_rect.x()); 9368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) description.SetInteger("screenY", screen_rect.y()); 9468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) description.SetBoolean("empty", screen_rect.size().IsEmpty()); 9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!screen_rect.size().IsEmpty()) { 9668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) description.SetInteger("width", screen_rect.width()); 9768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) description.SetInteger("height", screen_rect.height()); 9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 9968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::string json; 10068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::JSONWriter::Write(&description, &json); 10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return json; 10268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 10368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 10468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} // namespace 10568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 10668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace android_webview { 10768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 10868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)AwDevToolsServer::AwDevToolsServer() 10968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) : protocol_handler_(NULL) { 11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 11268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)AwDevToolsServer::~AwDevToolsServer() { 11368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Stop(); 11468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 11568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 11668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void AwDevToolsServer::Start() { 11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (protocol_handler_) 11868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 11968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 12068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) protocol_handler_ = content::DevToolsHttpHandler::Start( 12168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) new net::UnixDomainSocketWithAbstractNamespaceFactory( 12268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::StringPrintf(kSocketNameFormat, getpid()), 12368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) "", 12468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::Bind(&content::CanUserConnectToDevTools)), 12568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) base::StringPrintf(kFrontEndURL, 12668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) webkit_glue::GetWebKitRevision().c_str()), 12768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) new AwDevToolsServerDelegate()); 12868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 12968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 13068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void AwDevToolsServer::Stop() { 13168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!protocol_handler_) 13268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return; 13368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // Note that the call to Stop() below takes care of |protocol_handler_| 13468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // deletion. 13568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) protocol_handler_->Stop(); 13668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) protocol_handler_ = NULL; 13768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 13868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 13968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool AwDevToolsServer::IsStarted() const { 14068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return protocol_handler_; 14168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 14268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 14368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool RegisterAwDevToolsServer(JNIEnv* env) { 14468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return RegisterNativesImpl(env); 14568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 14668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 14768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)static jint InitRemoteDebugging(JNIEnv* env, 14868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) jobject obj) { 14968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) AwDevToolsServer* server = new AwDevToolsServer(); 15068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return reinterpret_cast<jint>(server); 15168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 15268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 15368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)static void DestroyRemoteDebugging(JNIEnv* env, jobject obj, jint server) { 15468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) delete reinterpret_cast<AwDevToolsServer*>(server); 15568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 15668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 15768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)static void SetRemoteDebuggingEnabled(JNIEnv* env, 15868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) jobject obj, 15968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) jint server, 16068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) jboolean enabled) { 16168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) AwDevToolsServer* devtools_server = 16268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) reinterpret_cast<AwDevToolsServer*>(server); 16368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (enabled) { 16468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) devtools_server->Start(); 16568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 16668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) devtools_server->Stop(); 16768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 16868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 16968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 17068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} // namespace android_webview 171