Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / xwalk / runtime / browser / android / xwalk_dev_tools_server.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Copyright 2013 The Chromium Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5
6 #include "xwalk/runtime/browser/android/xwalk_dev_tools_server.h"
7
8 #include <sys/types.h>
9 #include <unistd.h>
10 #include <vector>
11
12 #include "base/android/jni_string.h"
13 #include "base/basictypes.h"
14 #include "base/bind.h"
15 #include "base/callback.h"
16 #include "base/compiler_specific.h"
17 #include "base/logging.h"
18 #include "base/strings/stringprintf.h"
19 #include "base/strings/utf_string_conversions.h"
20 #include "blink_upstream_version.h"  // NOLINT
21 #include "content/public/browser/android/devtools_auth.h"
22 #include "content/public/browser/devtools_agent_host.h"
23 #include "content/public/browser/devtools_http_handler.h"
24 #include "content/public/browser/devtools_http_handler_delegate.h"
25 #include "content/public/browser/devtools_manager_delegate.h"
26 #include "content/public/browser/devtools_target.h"
27 #include "content/public/browser/favicon_status.h"
28 #include "content/public/browser/navigation_entry.h"
29 #include "content/public/browser/render_view_host.h"
30 #include "content/public/browser/web_contents.h"
31 #include "content/public/browser/web_contents_delegate.h"
32 #include "grit/xwalk_resources.h"
33 #include "jni/XWalkDevToolsServer_jni.h"
34 #include "net/socket/unix_domain_listen_socket_posix.h"
35 #include "ui/base/resource/resource_bundle.h"
36
37 using content::DevToolsAgentHost;
38 using content::RenderViewHost;
39 using content::WebContents;
40
41 namespace {
42
43 // FIXME(girish): The frontend URL needs to be served from the domain below
44 // for remote debugging to work in chrome (see chrome's devtools_ui.cc).
45 // Currently, the chrome version is hardcoded because of this dependancy.
46 const char kFrontEndURL[] =
47     "http://chrome-devtools-frontend.appspot.com/serve_rev/%s/devtools.html";
48
49 bool AuthorizeSocketAccessWithDebugPermission(
50      const net::UnixDomainServerSocket::Credentials& credentials) {
51   JNIEnv* env = base::android::AttachCurrentThread();
52   return xwalk::Java_XWalkDevToolsServer_checkDebugPermission(
53       env, base::android::GetApplicationContext(),
54       credentials.process_id, credentials.user_id) ||
55       content::CanUserConnectToDevTools(credentials);
56 }
57
58 // Delegate implementation for the devtools http handler on android. A new
59 // instance of this gets created each time devtools is enabled.
60 class XWalkAndroidDevToolsHttpHandlerDelegate
61   : public content::DevToolsHttpHandlerDelegate {
62  public:
63   XWalkAndroidDevToolsHttpHandlerDelegate() {
64   }
65
66   std::string GetDiscoveryPageHTML() override {
67     return ResourceBundle::GetSharedInstance().GetRawDataResource(
68         IDR_DEVTOOLS_FRONTEND_PAGE_HTML).as_string();
69   }
70
71   bool BundlesFrontendResources() override {
72     return false;
73   }
74
75   base::FilePath GetDebugFrontendDir() override {
76     return base::FilePath();
77   }
78
79   scoped_ptr<net::StreamListenSocket> CreateSocketForTethering(
80       net::StreamListenSocket::Delegate* delegate,
81       std::string* name) override {
82     return scoped_ptr<net::StreamListenSocket>();
83   }
84  private:
85   DISALLOW_COPY_AND_ASSIGN(XWalkAndroidDevToolsHttpHandlerDelegate);
86 };
87
88 // Factory for UnixDomainServerSocket.
89 class UnixDomainServerSocketFactory
90     : public content::DevToolsHttpHandler::ServerSocketFactory {
91  public:
92   explicit UnixDomainServerSocketFactory(
93       const std::string& socket_name,
94       const net::UnixDomainServerSocket::AuthCallback& auth_callback)
95       : content::DevToolsHttpHandler::ServerSocketFactory(socket_name, 0, 1),
96       auth_callback_(auth_callback) {}
97
98  private:
99   // content::DevToolsHttpHandler::ServerSocketFactory.
100   scoped_ptr<net::ServerSocket> Create() const override {
101     return scoped_ptr<net::ServerSocket>(
102         new net::UnixDomainServerSocket(
103             auth_callback_,
104             true /* use_abstract_namespace */));
105   }
106
107   const net::UnixDomainServerSocket::AuthCallback auth_callback_;
108   DISALLOW_COPY_AND_ASSIGN(UnixDomainServerSocketFactory);
109 };
110
111 }  // namespace
112
113 namespace xwalk {
114
115 XWalkDevToolsServer::XWalkDevToolsServer(const std::string& socket_name)
116     : socket_name_(socket_name),
117       protocol_handler_(NULL),
118       allow_debug_permission_(false),
119       allow_socket_access_(false) {
120 }
121
122 XWalkDevToolsServer::~XWalkDevToolsServer() {
123   Stop();
124 }
125
126 // Allow connection from uid specified using AllowConnectionFromUid to devtools
127 // server. This supports the XDK usage: debug bridge wrapper runs in a separate
128 // process and connects to the devtools server.
129 bool XWalkDevToolsServer::CanUserConnectToDevTools(
130     const net::UnixDomainServerSocket::Credentials& credentials) {
131   if (allow_socket_access_)
132     return true;
133   if (allow_debug_permission_)
134     return AuthorizeSocketAccessWithDebugPermission(credentials);
135   return content::CanUserConnectToDevTools(credentials);
136 }
137
138 void XWalkDevToolsServer::Start(bool allow_debug_permission,
139                                 bool allow_socket_access) {
140   allow_debug_permission_ = allow_debug_permission;
141   allow_socket_access_ = allow_socket_access;
142   if (protocol_handler_)
143     return;
144
145   net::UnixDomainServerSocket::AuthCallback auth_callback =
146       base::Bind(&XWalkDevToolsServer::CanUserConnectToDevTools,
147                  base::Unretained(this));
148
149   scoped_ptr<content::DevToolsHttpHandler::ServerSocketFactory> factory(
150       new UnixDomainServerSocketFactory(socket_name_, auth_callback));
151   protocol_handler_ = content::DevToolsHttpHandler::Start(
152       factory.Pass(),
153       base::StringPrintf(kFrontEndURL, BLINK_UPSTREAM_REVISION),
154       new XWalkAndroidDevToolsHttpHandlerDelegate(), base::FilePath());
155 }
156
157 void XWalkDevToolsServer::Stop() {
158   if (!protocol_handler_)
159     return;
160   // Note that the call to Stop() below takes care of |protocol_handler_|
161   // deletion.
162   protocol_handler_->Stop();
163   protocol_handler_ = NULL;
164   allow_socket_access_ = false;
165   allow_debug_permission_ = false;
166 }
167
168 bool XWalkDevToolsServer::IsStarted() const {
169   return protocol_handler_;
170 }
171
172 bool RegisterXWalkDevToolsServer(JNIEnv* env) {
173   return RegisterNativesImpl(env);
174 }
175
176 static jlong InitRemoteDebugging(JNIEnv* env,
177                                 jobject obj,
178                                 jstring socketName) {
179   XWalkDevToolsServer* server = new XWalkDevToolsServer(
180       base::android::ConvertJavaStringToUTF8(env, socketName));
181   return reinterpret_cast<intptr_t>(server);
182 }
183
184 static void DestroyRemoteDebugging(JNIEnv* env, jobject obj, jlong server) {
185   delete reinterpret_cast<XWalkDevToolsServer*>(server);
186 }
187
188 static jboolean IsRemoteDebuggingEnabled(JNIEnv* env,
189                                          jobject obj,
190                                          jlong server) {
191   return reinterpret_cast<XWalkDevToolsServer*>(server)->IsStarted();
192 }
193
194 static void SetRemoteDebuggingEnabled(JNIEnv* env,
195                                       jobject obj,
196                                       jlong server,
197                                       jboolean enabled,
198                                       jboolean allow_debug_permission,
199                                       jboolean allow_socket_access) {
200   XWalkDevToolsServer* devtools_server =
201       reinterpret_cast<XWalkDevToolsServer*>(server);
202   if (enabled == JNI_TRUE) {
203     devtools_server->Start(allow_debug_permission == JNI_TRUE,
204                            allow_socket_access == JNI_TRUE);
205   } else {
206     devtools_server->Stop();
207   }
208 }
209
210 }  // namespace xwalk