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"
1646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/files/file_path.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "base/strings/stringprintf.h"
204e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "base/strings/utf_string_conversions.h"
218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "chrome/browser/android/tab_android.h"
227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/browser_process.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/top_sites.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/ui/android/tab_model/tab_model.h"
267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/ui/android/tab_model/tab_model_list.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/android/devtools_auth.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
294e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/devtools_agent_host.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/devtools_http_handler.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/devtools_http_handler_delegate.h"
324e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/devtools_target.h"
334e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/favicon_status.h"
344e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/navigation_entry.h"
351e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/web_contents.h"
374e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "content/public/browser/web_contents_delegate.h"
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/common/content_switches.h"
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/common/url_constants.h"
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/common/user_agent.h"
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "grit/browser_resources.h"
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "jni/DevToolsServer_jni.h"
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/base/net_errors.h"
445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "net/socket/unix_domain_listen_socket_posix.h"
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/socket/unix_domain_server_socket_posix.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using content::DevToolsAgentHost;
501e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)using content::RenderViewHost;
514e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)using content::WebContents;
524e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// TL;DR: Do not change this string.
56010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)//
57010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Desktop Chrome relies on this format to identify debuggable apps on Android
58010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// (see the code under chrome/browser/devtools/device).
59010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// If this string ever changes it would not be sufficient to change the
60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// corresponding string on the client side. Since debugging an older version of
61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// Chrome for Android from a newer version of desktop Chrome is a very common
62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// scenario, the client code will have to be modified to recognize both the old
63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)// and the new format.
64010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kDevToolsChannelNameFormat[] = "%s_devtools_remote";
65010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kFrontEndURL[] =
67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    "http://chrome-devtools-frontend.appspot.com/serve_rev/%s/devtools.html";
68868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)const char kTetheringSocketName[] = "chrome_devtools_tethering_%d_%d";
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
706e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)bool AuthorizeSocketAccessWithDebugPermission(
716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const net::UnixDomainServerSocket::Credentials& credentials) {
726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  JNIEnv* env = base::android::AttachCurrentThread();
736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return Java_DevToolsServer_checkDebugPermission(
746e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      env, base::android::GetApplicationContext(),
756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      credentials.process_id, credentials.user_id) ||
766e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      content::CanUserConnectToDevTools(credentials);
776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Delegate implementation for the devtools http handler on android. A new
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// instance of this gets created each time devtools is enabled.
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DevToolsServerDelegate : public content::DevToolsHttpHandlerDelegate {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  explicit DevToolsServerDelegate(
846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      const net::UnixDomainServerSocket::AuthCallback& auth_callback)
856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      : last_tethering_socket_(0),
866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        auth_callback_(auth_callback) {
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual std::string GetDiscoveryPageHTML() OVERRIDE {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // TopSites updates itself after a delay. Ask TopSites to update itself
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // when we're about to show the remote debugging landing page.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::BrowserThread::PostTask(
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        content::BrowserThread::UI,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        FROM_HERE,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&DevToolsServerDelegate::PopulatePageThumbnails));
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ResourceBundle::GetSharedInstance().GetRawDataResource(
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        IDR_DEVTOOLS_DISCOVERY_PAGE_HTML).as_string();
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool BundlesFrontendResources() OVERRIDE {
101eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return false;
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual base::FilePath GetDebugFrontendDir() OVERRIDE {
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return base::FilePath();
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  virtual scoped_ptr<net::StreamListenSocket> CreateSocketForTethering(
109c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      net::StreamListenSocket::Delegate* delegate,
110c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      std::string* name) OVERRIDE {
111868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    *name = base::StringPrintf(
112868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)        kTetheringSocketName, getpid(), ++last_tethering_socket_);
1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    return net::deprecated::UnixDomainListenSocket::
1145f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        CreateAndListenWithAbstractNamespace(
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            *name,
1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            "",
1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)            delegate,
1186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)            auth_callback_)
1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        .PassAs<net::StreamListenSocket>();
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void PopulatePageThumbnails() {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile =
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ProfileManager::GetLastUsedProfile()->GetOriginalProfile();
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history::TopSites* top_sites = profile->GetTopSites();
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (top_sites)
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      top_sites->SyncWithHistory();
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  int last_tethering_socket_;
1326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const net::UnixDomainServerSocket::AuthCallback auth_callback_;
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(DevToolsServerDelegate);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Factory for UnixDomainServerSocket. It tries a fallback socket when
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// original socket doesn't work.
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass UnixDomainServerSocketFactory
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : public content::DevToolsHttpHandler::ServerSocketFactory {
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci public:
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  UnixDomainServerSocketFactory(
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const std::string& socket_name,
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      const net::UnixDomainServerSocket::AuthCallback& auth_callback)
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      : content::DevToolsHttpHandler::ServerSocketFactory(socket_name, 0, 1),
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        auth_callback_(auth_callback) {
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci private:
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // content::DevToolsHttpHandler::ServerSocketFactory.
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual scoped_ptr<net::ServerSocket> Create() const OVERRIDE {
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return scoped_ptr<net::ServerSocket>(
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        new net::UnixDomainServerSocket(auth_callback_,
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                        true /* use_abstract_namespace */));
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  virtual scoped_ptr<net::ServerSocket> CreateAndListen() const OVERRIDE {
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<net::ServerSocket> socket = Create();
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!socket)
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return scoped_ptr<net::ServerSocket>();
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (socket->ListenWithAddressAndPort(address_, port_, backlog_) == net::OK)
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return socket.Pass();
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Try a fallback socket name.
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::string fallback_address(
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        base::StringPrintf("%s_%d", address_.c_str(), getpid()));
1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (socket->ListenWithAddressAndPort(fallback_address, port_, backlog_)
1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        == net::OK)
1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      return socket.Pass();
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return scoped_ptr<net::ServerSocket>();
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const net::UnixDomainServerSocket::AuthCallback auth_callback_;
1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DISALLOW_COPY_AND_ASSIGN(UnixDomainServerSocketFactory);
1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci};
1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
182eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen MurdochDevToolsServer::DevToolsServer(const std::string& socket_name_prefix)
183eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    : socket_name_(base::StringPrintf(kDevToolsChannelNameFormat,
184eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                      socket_name_prefix.c_str())),
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      protocol_handler_(NULL) {
18658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  // Override the socket name if one is specified on the command line.
18758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  const CommandLine& command_line = *CommandLine::ForCurrentProcess();
18858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  if (command_line.HasSwitch(switches::kRemoteDebuggingSocketName)) {
18958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    socket_name_ = command_line.GetSwitchValueASCII(
19058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        switches::kRemoteDebuggingSocketName);
19158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)DevToolsServer::~DevToolsServer() {
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Stop();
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void DevToolsServer::Start(bool allow_debug_permission) {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (protocol_handler_)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2026e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  net::UnixDomainServerSocket::AuthCallback auth_callback =
2036e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      allow_debug_permission ?
2046e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          base::Bind(&AuthorizeSocketAccessWithDebugPermission) :
2056e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)          base::Bind(&content::CanUserConnectToDevTools);
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<content::DevToolsHttpHandler::ServerSocketFactory> factory(
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new UnixDomainServerSocketFactory(socket_name_, auth_callback));
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protocol_handler_ = content::DevToolsHttpHandler::Start(
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      factory.Pass(),
210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      base::StringPrintf(kFrontEndURL, content::GetWebKitRevision().c_str()),
2116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      new DevToolsServerDelegate(auth_callback),
21246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      base::FilePath());
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DevToolsServer::Stop() {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!protocol_handler_)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note that the call to Stop() below takes care of |protocol_handler_|
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // deletion.
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protocol_handler_->Stop();
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  protocol_handler_ = NULL;
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool DevToolsServer::IsStarted() const {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return protocol_handler_;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool RegisterDevToolsServer(JNIEnv* env) {
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return RegisterNativesImpl(env);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
232a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static jlong InitRemoteDebugging(JNIEnv* env,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                jobject obj,
234eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                jstring socket_name_prefix) {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DevToolsServer* server = new DevToolsServer(
236eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::android::ConvertJavaStringToUTF8(env, socket_name_prefix));
237a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return reinterpret_cast<intptr_t>(server);
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
240a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)static void DestroyRemoteDebugging(JNIEnv* env, jobject obj, jlong server) {
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete reinterpret_cast<DevToolsServer*>(server);
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static jboolean IsRemoteDebuggingEnabled(JNIEnv* env,
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         jobject obj,
246a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                         jlong server) {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return reinterpret_cast<DevToolsServer*>(server)->IsStarted();
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void SetRemoteDebuggingEnabled(JNIEnv* env,
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      jobject obj,
252a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                      jlong server,
2536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                      jboolean enabled,
2546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                                      jboolean allow_debug_permission) {
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DevToolsServer* devtools_server = reinterpret_cast<DevToolsServer*>(server);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (enabled) {
2576e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    devtools_server->Start(allow_debug_permission);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    devtools_server->Stop();
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
262