1 // Copyright 2014 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_DEVICE_DEVTOOLS_ANDROID_BRIDGE_H_ 6 #define CHROME_BROWSER_DEVTOOLS_DEVICE_DEVTOOLS_ANDROID_BRIDGE_H_ 7 8 #include <string> 9 #include <vector> 10 11 #include "base/callback.h" 12 #include "base/cancelable_callback.h" 13 #include "base/memory/ref_counted.h" 14 #include "base/memory/scoped_ptr.h" 15 #include "base/prefs/pref_change_registrar.h" 16 #include "chrome/browser/devtools/device/android_device_manager.h" 17 #include "components/keyed_service/content/browser_context_keyed_service_factory.h" 18 #include "components/keyed_service/core/keyed_service.h" 19 #include "content/public/browser/devtools_agent_host.h" 20 #include "ui/gfx/size.h" 21 22 template<typename T> struct DefaultSingletonTraits; 23 24 namespace base { 25 class MessageLoop; 26 class DictionaryValue; 27 class ListValue; 28 class Thread; 29 } 30 31 namespace content { 32 class BrowserContext; 33 } 34 35 class DevToolsTargetImpl; 36 class PortForwardingController; 37 class Profile; 38 39 class DevToolsAndroidBridge 40 : public base::RefCountedThreadSafe< 41 DevToolsAndroidBridge, 42 content::BrowserThread::DeleteOnUIThread> { 43 public: 44 typedef base::Callback<void(int result, 45 const std::string& response)> Callback; 46 47 class Wrapper : public KeyedService { 48 public: 49 explicit Wrapper(content::BrowserContext* context); 50 virtual ~Wrapper(); 51 52 DevToolsAndroidBridge* Get(); 53 private: 54 scoped_refptr<DevToolsAndroidBridge> bridge_; 55 }; 56 57 class Factory : public BrowserContextKeyedServiceFactory { 58 public: 59 // Returns singleton instance of DevToolsAndroidBridge. 60 static Factory* GetInstance(); 61 62 // Returns DevToolsAndroidBridge associated with |profile|. 63 static DevToolsAndroidBridge* GetForProfile(Profile* profile); 64 65 private: 66 friend struct DefaultSingletonTraits<Factory>; 67 68 Factory(); 69 virtual ~Factory(); 70 71 // BrowserContextKeyedServiceFactory overrides: 72 virtual KeyedService* BuildServiceInstanceFor( 73 content::BrowserContext* context) const OVERRIDE; 74 DISALLOW_COPY_AND_ASSIGN(Factory); 75 }; 76 77 class RemotePage { 78 public: 79 virtual ~RemotePage() {} 80 virtual DevToolsTargetImpl* GetTarget() = 0; 81 virtual std::string GetFrontendURL() = 0; 82 }; 83 84 typedef base::Callback<void(RemotePage*)> RemotePageCallback; 85 typedef base::Callback<void(int, const std::string&)> JsonRequestCallback; 86 typedef AndroidDeviceManager::Device Device; 87 typedef AndroidDeviceManager::AndroidWebSocket AndroidWebSocket; 88 89 class RemoteBrowser : public base::RefCounted<RemoteBrowser> { 90 public: 91 RemoteBrowser(scoped_refptr<Device> device, 92 const AndroidDeviceManager::BrowserInfo& browser_info); 93 94 std::string serial() { return device_->serial(); } 95 std::string socket() { return socket_; } 96 97 std::string display_name() { return display_name_; } 98 void set_display_name(const std::string& name) { display_name_ = name; } 99 100 std::string version() { return version_; } 101 void set_version(const std::string& version) { version_ = version; } 102 103 bool IsChrome() const; 104 bool IsWebView() const; 105 106 typedef std::vector<int> ParsedVersion; 107 ParsedVersion GetParsedVersion() const; 108 109 std::vector<RemotePage*> CreatePages(); 110 void SetPageDescriptors(const base::ListValue&); 111 112 void SendJsonRequest(const std::string& request, 113 const JsonRequestCallback& callback); 114 115 void SendProtocolCommand(const std::string& debug_url, 116 const std::string& method, 117 base::DictionaryValue* params, 118 const base::Closure callback); 119 120 void Open(const std::string& url, 121 const RemotePageCallback& callback); 122 123 scoped_refptr<content::DevToolsAgentHost> GetAgentHost(); 124 125 AndroidWebSocket* CreateWebSocket( 126 const std::string& url, 127 DevToolsAndroidBridge::AndroidWebSocket::Delegate* delegate); 128 129 private: 130 friend class base::RefCounted<RemoteBrowser>; 131 virtual ~RemoteBrowser(); 132 133 void InnerOpen(const std::string& url, 134 const JsonRequestCallback& callback); 135 136 void PageCreatedOnUIThread( 137 const JsonRequestCallback& callback, 138 const std::string& url, int result, const std::string& response); 139 140 void NavigatePageOnUIThread(const JsonRequestCallback& callback, 141 int result, 142 const std::string& response, 143 const std::string& url); 144 145 void RespondToOpenOnUIThread( 146 const DevToolsAndroidBridge::RemotePageCallback& callback, 147 int result, 148 const std::string& response); 149 150 scoped_refptr<Device> device_; 151 const std::string socket_; 152 std::string display_name_; 153 const AndroidDeviceManager::BrowserInfo::Type type_; 154 std::string version_; 155 scoped_ptr<base::ListValue> page_descriptors_; 156 157 DISALLOW_COPY_AND_ASSIGN(RemoteBrowser); 158 }; 159 160 typedef std::vector<scoped_refptr<RemoteBrowser> > RemoteBrowsers; 161 162 class RemoteDevice : public base::RefCounted<RemoteDevice> { 163 public: 164 RemoteDevice(scoped_refptr<Device> device, 165 const AndroidDeviceManager::DeviceInfo& device_info); 166 167 std::string serial() { return device_->serial(); } 168 std::string model() { return model_; } 169 bool is_connected() { return connected_; } 170 RemoteBrowsers& browsers() { return browsers_; } 171 gfx::Size screen_size() { return screen_size_; } 172 173 void OpenSocket(const std::string& socket_name, 174 const AndroidDeviceManager::SocketCallback& callback); 175 176 private: 177 friend class base::RefCounted<RemoteDevice>; 178 virtual ~RemoteDevice(); 179 180 scoped_refptr<Device> device_; 181 std::string model_; 182 bool connected_; 183 RemoteBrowsers browsers_; 184 gfx::Size screen_size_; 185 186 DISALLOW_COPY_AND_ASSIGN(RemoteDevice); 187 }; 188 189 typedef std::vector<scoped_refptr<RemoteDevice> > RemoteDevices; 190 191 class DeviceListListener { 192 public: 193 virtual void DeviceListChanged(const RemoteDevices& devices) = 0; 194 protected: 195 virtual ~DeviceListListener() {} 196 }; 197 198 explicit DevToolsAndroidBridge(Profile* profile); 199 void AddDeviceListListener(DeviceListListener* listener); 200 void RemoveDeviceListListener(DeviceListListener* listener); 201 202 class DeviceCountListener { 203 public: 204 virtual void DeviceCountChanged(int count) = 0; 205 protected: 206 virtual ~DeviceCountListener() {} 207 }; 208 209 void AddDeviceCountListener(DeviceCountListener* listener); 210 void RemoveDeviceCountListener(DeviceCountListener* listener); 211 212 typedef int PortStatus; 213 typedef std::map<int, PortStatus> PortStatusMap; 214 typedef std::map<std::string, PortStatusMap> DevicesStatus; 215 216 class PortForwardingListener { 217 public: 218 typedef DevToolsAndroidBridge::PortStatusMap PortStatusMap; 219 typedef DevToolsAndroidBridge::DevicesStatus DevicesStatus; 220 221 virtual void PortStatusChanged(const DevicesStatus&) = 0; 222 protected: 223 virtual ~PortForwardingListener() {} 224 }; 225 226 void AddPortForwardingListener(PortForwardingListener* listener); 227 void RemovePortForwardingListener(PortForwardingListener* listener); 228 229 void set_device_providers_for_test( 230 const AndroidDeviceManager::DeviceProviders& device_providers) { 231 device_manager_->SetDeviceProviders(device_providers); 232 } 233 234 void set_task_scheduler_for_test( 235 base::Callback<void(const base::Closure&)> scheduler) { 236 task_scheduler_ = scheduler; 237 } 238 239 static bool HasDevToolsWindow(const std::string& agent_id); 240 241 private: 242 friend struct content::BrowserThread::DeleteOnThread< 243 content::BrowserThread::UI>; 244 friend class base::DeleteHelper<DevToolsAndroidBridge>; 245 246 virtual ~DevToolsAndroidBridge(); 247 248 void StartDeviceListPolling(); 249 void StopDeviceListPolling(); 250 bool NeedsDeviceListPolling(); 251 void RequestDeviceList( 252 const base::Callback<void(const RemoteDevices&)>& callback); 253 void ReceivedDeviceList(const RemoteDevices& devices); 254 void StartDeviceCountPolling(); 255 void StopDeviceCountPolling(); 256 void RequestDeviceCount(const base::Callback<void(int)>& callback); 257 void ReceivedDeviceCount(int count); 258 259 static void ScheduleTaskDefault(const base::Closure& task); 260 261 void CreateDeviceProviders(); 262 263 Profile* profile_; 264 scoped_refptr<AndroidDeviceManager> device_manager_; 265 RemoteDevices devices_; 266 267 typedef std::vector<DeviceListListener*> DeviceListListeners; 268 DeviceListListeners device_list_listeners_; 269 base::CancelableCallback<void(const RemoteDevices&)> device_list_callback_; 270 271 typedef std::vector<DeviceCountListener*> DeviceCountListeners; 272 DeviceCountListeners device_count_listeners_; 273 base::CancelableCallback<void(int)> device_count_callback_; 274 base::Callback<void(const base::Closure&)> task_scheduler_; 275 276 typedef std::vector<PortForwardingListener*> PortForwardingListeners; 277 PortForwardingListeners port_forwarding_listeners_; 278 scoped_ptr<PortForwardingController> port_forwarding_controller_; 279 280 PrefChangeRegistrar pref_change_registrar_; 281 DISALLOW_COPY_AND_ASSIGN(DevToolsAndroidBridge); 282 }; 283 284 #endif // CHROME_BROWSER_DEVTOOLS_DEVICE_DEVTOOLS_ANDROID_BRIDGE_H_ 285