Home | History | Annotate | Download | only in devtools
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_DEVTOOLS_DEVTOOLS_ADB_BRIDGE_H_
      6 #define CHROME_BROWSER_DEVTOOLS_DEVTOOLS_ADB_BRIDGE_H_
      7 
      8 #include <string>
      9 #include <vector>
     10 
     11 #include "base/callback.h"
     12 #include "base/memory/ref_counted.h"
     13 #include "base/memory/scoped_ptr.h"
     14 #include "chrome/browser/devtools/adb/android_usb_device.h"
     15 #include "components/browser_context_keyed_service/browser_context_keyed_service.h"
     16 #include "components/browser_context_keyed_service/browser_context_keyed_service_factory.h"
     17 #include "content/public/browser/browser_thread.h"
     18 #include "net/socket/tcp_client_socket.h"
     19 
     20 template<typename T> struct DefaultSingletonTraits;
     21 
     22 namespace base {
     23 class MessageLoop;
     24 class DictionaryValue;
     25 class Thread;
     26 }
     27 
     28 namespace content {
     29 class BrowserContext;
     30 }
     31 
     32 namespace crypto {
     33 class RSAPrivateKey;
     34 }
     35 
     36 class PortForwardingController;
     37 class Profile;
     38 
     39 // The format used for constructing DevTools server socket names.
     40 extern const char kDevToolsChannelNameFormat[];
     41 
     42 typedef base::Callback<void(int, const std::string&)> CommandCallback;
     43 typedef base::Callback<void(int result, net::StreamSocket*)> SocketCallback;
     44 
     45 class DevToolsAdbBridge
     46     : public base::RefCountedThreadSafe<
     47           DevToolsAdbBridge,
     48           content::BrowserThread::DeleteOnUIThread> {
     49  public:
     50   typedef base::Callback<void(int result,
     51                               const std::string& response)> Callback;
     52 
     53   class Wrapper : public BrowserContextKeyedService {
     54    public:
     55     explicit Wrapper(Profile* profile);
     56     virtual ~Wrapper();
     57 
     58     DevToolsAdbBridge* Get();
     59    private:
     60     scoped_refptr<DevToolsAdbBridge> bridge_;
     61   };
     62 
     63   class Factory : public BrowserContextKeyedServiceFactory {
     64    public:
     65     // Returns singleton instance of DevToolsAdbBridge.
     66     static Factory* GetInstance();
     67 
     68     // Returns DevToolsAdbBridge associated with |profile|.
     69     static DevToolsAdbBridge* GetForProfile(Profile* profile);
     70 
     71    private:
     72     friend struct DefaultSingletonTraits<Factory>;
     73     friend class DevToolsAdbBridge;
     74 
     75     Factory();
     76     virtual ~Factory();
     77 
     78     // BrowserContextKeyedServiceFactory overrides:
     79     virtual BrowserContextKeyedService* BuildServiceInstanceFor(
     80         content::BrowserContext* context) const OVERRIDE;
     81     DISALLOW_COPY_AND_ASSIGN(Factory);
     82   };
     83 
     84   class AndroidDevice;
     85 
     86   class RemotePage : public base::RefCounted<RemotePage> {
     87    public:
     88     RemotePage(scoped_refptr<DevToolsAdbBridge> bridge,
     89                scoped_refptr<AndroidDevice> device,
     90                const std::string& socket,
     91                const base::DictionaryValue& value);
     92 
     93     std::string id() { return id_; }
     94     std::string url() { return url_; }
     95     std::string title() { return title_; }
     96     std::string description() { return description_; }
     97     std::string favicon_url() { return favicon_url_; }
     98     bool attached() { return debug_url_.empty(); }
     99 
    100     void Inspect(Profile* profile);
    101     void Close();
    102     void Reload();
    103 
    104     void SendProtocolCommand(const std::string& method,
    105                              base::DictionaryValue* params);
    106 
    107    private:
    108     friend class base::RefCounted<RemotePage>;
    109     virtual ~RemotePage();
    110 
    111     scoped_refptr<DevToolsAdbBridge> bridge_;
    112     scoped_refptr<AndroidDevice> device_;
    113     std::string socket_;
    114     std::string id_;
    115     std::string url_;
    116     std::string title_;
    117     std::string description_;
    118     std::string favicon_url_;
    119     std::string debug_url_;
    120     std::string frontend_url_;
    121     DISALLOW_COPY_AND_ASSIGN(RemotePage);
    122   };
    123 
    124   typedef std::vector<scoped_refptr<RemotePage> > RemotePages;
    125 
    126   class RemoteBrowser : public base::RefCounted<RemoteBrowser> {
    127    public:
    128     RemoteBrowser(scoped_refptr<DevToolsAdbBridge> bridge,
    129                   scoped_refptr<AndroidDevice> device,
    130                   const std::string& socket);
    131 
    132     scoped_refptr<AndroidDevice> device() { return device_; }
    133     std::string socket() { return socket_; }
    134 
    135     std::string product() { return product_; }
    136     void set_product(const std::string& product) { product_ = product; }
    137     std::string version() { return version_; }
    138     void set_version(const std::string& version) { version_ = version; }
    139 
    140     RemotePages& pages() { return pages_; }
    141     void AddPage(scoped_refptr<RemotePage> page) { pages_.push_back(page); }
    142 
    143     void Open(const std::string& url);
    144 
    145    private:
    146     friend class base::RefCounted<RemoteBrowser>;
    147     virtual ~RemoteBrowser();
    148 
    149     void PageCreatedOnHandlerThread(
    150         const std::string& url, int result, const std::string& response);
    151 
    152     void PageCreatedOnUIThread(
    153         const std::string& response, const std::string& url);
    154 
    155     scoped_refptr<DevToolsAdbBridge> bridge_;
    156     scoped_refptr<AndroidDevice> device_;
    157     const std::string socket_;
    158     std::string product_;
    159     std::string version_;
    160     RemotePages pages_;
    161 
    162     DISALLOW_COPY_AND_ASSIGN(RemoteBrowser);
    163   };
    164 
    165   typedef std::vector<scoped_refptr<RemoteBrowser> > RemoteBrowsers;
    166 
    167   class RemoteDevice : public base::RefCounted<RemoteDevice> {
    168    public:
    169     typedef int PortStatus;
    170     typedef std::map<int, PortStatus> PortStatusMap;
    171 
    172     explicit RemoteDevice(scoped_refptr<DevToolsAdbBridge> bridge,
    173                           scoped_refptr<AndroidDevice> device);
    174 
    175     scoped_refptr<AndroidDevice> device() { return device_; }
    176     std::string serial() { return device_->serial(); }
    177     std::string model() { return device_->model(); }
    178 
    179     RemoteBrowsers& browsers() { return browsers_; }
    180     void AddBrowser(scoped_refptr<RemoteBrowser> browser) {
    181       browsers_.push_back(browser);
    182     }
    183 
    184     const PortStatusMap& port_status() { return port_status_; }
    185     void set_port_status(const PortStatusMap& port_status) {
    186       port_status_ = port_status;
    187     }
    188 
    189    private:
    190     friend class base::RefCounted<RemoteDevice>;
    191     virtual ~RemoteDevice();
    192 
    193     scoped_refptr<DevToolsAdbBridge> bridge_;
    194     scoped_refptr<AndroidDevice> device_;
    195     RemoteBrowsers browsers_;
    196     PortStatusMap port_status_;
    197 
    198     DISALLOW_COPY_AND_ASSIGN(RemoteDevice);
    199   };
    200 
    201   typedef std::vector<scoped_refptr<RemoteDevice> > RemoteDevices;
    202 
    203   class AndroidDevice : public base::RefCounted<AndroidDevice> {
    204    public:
    205     explicit AndroidDevice(const std::string& serial);
    206 
    207     virtual void RunCommand(const std::string& command,
    208                             const CommandCallback& callback) = 0;
    209     virtual void OpenSocket(const std::string& socket_name,
    210                             const SocketCallback& callback) = 0;
    211     void HttpQuery(const std::string& la_name,
    212                    const std::string& request,
    213                    const CommandCallback& callback);
    214     void HttpUpgrade(const std::string& la_name,
    215                      const std::string& request,
    216                      const SocketCallback& callback);
    217 
    218     std::string serial() { return serial_; }
    219 
    220     std::string model() { return model_; }
    221     void set_model(const std::string& model) { model_ = model; }
    222 
    223    protected:
    224     friend class base::RefCounted<AndroidDevice>;
    225     virtual ~AndroidDevice();
    226 
    227    private:
    228     void OnHttpSocketOpened(const std::string& request,
    229                             const CommandCallback& callback,
    230                             int result,
    231                             net::StreamSocket* socket);
    232     void OnHttpSocketOpened2(const std::string& request,
    233                              const SocketCallback& callback,
    234                              int result,
    235                              net::StreamSocket* socket);
    236 
    237     std::string serial_;
    238     std::string model_;
    239 
    240     DISALLOW_COPY_AND_ASSIGN(AndroidDevice);
    241   };
    242 
    243   typedef std::vector<scoped_refptr<AndroidDevice> > AndroidDevices;
    244   typedef base::Callback<void(const AndroidDevices&)> AndroidDevicesCallback;
    245 
    246   class Listener {
    247    public:
    248     virtual void RemoteDevicesChanged(RemoteDevices* devices) = 0;
    249    protected:
    250     virtual ~Listener() {}
    251   };
    252 
    253   explicit DevToolsAdbBridge(Profile* profile);
    254 
    255   void EnumerateUsbDevices(const AndroidDevicesCallback& callback);
    256   void EnumerateAdbDevices(const AndroidDevicesCallback& callback);
    257 
    258   void AddListener(Listener* listener);
    259   void RemoveListener(Listener* listener);
    260 
    261   base::MessageLoop* GetAdbMessageLoop();
    262 
    263  private:
    264   friend struct content::BrowserThread::DeleteOnThread<
    265       content::BrowserThread::UI>;
    266   friend class base::DeleteHelper<DevToolsAdbBridge>;
    267 
    268   class RefCountedAdbThread : public base::RefCounted<RefCountedAdbThread> {
    269    public:
    270     static scoped_refptr<RefCountedAdbThread> GetInstance();
    271     RefCountedAdbThread();
    272     base::MessageLoop* message_loop();
    273 
    274    private:
    275     friend class base::RefCounted<RefCountedAdbThread>;
    276     static DevToolsAdbBridge::RefCountedAdbThread* instance_;
    277     static void StopThread(base::Thread* thread);
    278 
    279     virtual ~RefCountedAdbThread();
    280     base::Thread* thread_;
    281   };
    282 
    283   virtual ~DevToolsAdbBridge();
    284   void ReceivedUsbDevices(const AndroidDevicesCallback& callback,
    285                           const AndroidUsbDevices& usb_devices);
    286   void ReceivedAdbDevices(const AndroidDevicesCallback& callback,
    287                           int result,
    288                           const std::string& response);
    289 
    290   void RequestRemoteDevices();
    291   void ReceivedRemoteDevices(RemoteDevices* devices);
    292 
    293   Profile* profile_;
    294   scoped_refptr<RefCountedAdbThread> adb_thread_;
    295   bool has_message_loop_;
    296   scoped_ptr<crypto::RSAPrivateKey> rsa_key_;
    297   typedef std::vector<Listener*> Listeners;
    298   Listeners listeners_;
    299   scoped_ptr<PortForwardingController> port_forwarding_controller_;
    300   DISALLOW_COPY_AND_ASSIGN(DevToolsAdbBridge);
    301 };
    302 
    303 #endif  // CHROME_BROWSER_DEVTOOLS_DEVTOOLS_ADB_BRIDGE_H_
    304