Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / tools / telemetry / telemetry / core / backends / chrome / ios_browser_backend.py
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 import contextlib
6 import json
7 import logging
8 import re
9 import urllib2
10
11 from telemetry.core import util
12 from telemetry.core.backends.chrome import chrome_browser_backend
13 from telemetry.core.backends.chrome import system_info_backend
14
15
16 class IosBrowserBackend(chrome_browser_backend.ChromeBrowserBackend):
17   _DEBUGGER_URL_BUILDER = 'ws://localhost:%i/devtools/page/%i'
18   _DEBUGGER_URL_REGEX = 'ws://localhost:(\d+)/devtools/page/(\d+)'
19   _DEVICE_LIST_URL = 'http://localhost:9221/json'
20
21   def __init__(self, browser_options):
22     super(IosBrowserBackend, self).__init__(
23         supports_tab_control=False,
24         supports_extensions=False,
25         browser_options=browser_options,
26         output_profile_path=".",
27         extensions_to_load=None)
28     self._webviews = []
29     self._port = None
30     self._page = None
31     self.UpdateRunningBrowsersInfo()
32
33   def UpdateRunningBrowsersInfo(self):
34     """ Refresh to match current state of the running browser.
35     """
36     device_urls = self.GetDeviceUrls()
37     urls = self.GetWebSocketDebuggerUrls(device_urls)
38     for url in urls:
39       m = re.match(self._DEBUGGER_URL_REGEX, url)
40       if m:
41         self._webviews.append([int(m.group(1)), int(m.group(2))])
42       else:
43         logging.error('Unexpected url format: %s' % url)
44
45     # TODO(baxley): For now, grab first item from |_webviews|. Ideally, we'd
46     # prefer to have the currently displayed tab, or something similar.
47     if self._webviews:
48       self._port = self._webviews[0][0]
49       self._page = self._webviews[0][1]
50
51   def GetDeviceUrls(self):
52     device_urls = []
53     try:
54       with contextlib.closing(
55           urllib2.urlopen(self._DEVICE_LIST_URL)) as device_list:
56         json_urls = device_list.read()
57         device_urls = json.loads(json_urls)
58         if not device_urls:
59           logging.debug('No iOS devices found. Will not try searching for iOS '
60                         'browsers.')
61           return []
62     except urllib2.URLError as e:
63       logging.debug('Error communicating with iOS device.')
64       logging.debug(str(e))
65       return []
66     return device_urls
67
68   def GetWebSocketDebuggerUrls(self, device_urls):
69     """ Get a list of the websocket debugger URLs to communicate with
70         all running UIWebViews.
71     """
72     data = []
73     # Loop through all devices.
74     for d in device_urls:
75       def GetData():
76         try:
77           with contextlib.closing(
78               urllib2.urlopen('http://%s/json' % d['url'])) as f:
79             json_result = f.read()
80             data = json.loads(json_result)
81             return data
82         except urllib2.URLError as e:
83           logging.debug('Error communicating with iOS device.')
84           logging.debug(e)
85           return False
86       try:
87         # Retry a few times since it can take a few seconds for this API to be
88         # ready, if ios_webkit_debug_proxy is just launched.
89         data = util.WaitFor(GetData, 5)
90       except util.TimeoutException as e:
91         logging.debug('Timeout retrieving data from iOS device')
92         logging.debug(e)
93         return []
94
95     # Find all running UIWebViews.
96     debug_urls = []
97     for j in data:
98       debug_urls.append(j['webSocketDebuggerUrl'])
99
100     return debug_urls
101
102   def GetSystemInfo(self):
103     if self._system_info_backend is None:
104       self._system_info_backend = system_info_backend.SystemInfoBackend(
105           self._port, self._page)
106     return self._system_info_backend.GetSystemInfo()
107
108   def ListInspectableContexts(self):
109     response = json.loads(self.Request(''))
110     if len(response) != len(self._webviews):
111       self.UpdateRunningBrowsersInfo()
112     for i in range(len(response)):
113       response[i]['id'] = 1
114     return response
115
116   def IsBrowserRunning(self):
117     return bool(self._webviews)
118
119   #TODO(baxley): The following were stubbed out to get the sunspider benchmark
120   # running. These should be implemented.
121   @property
122   def browser_directory(self):
123     logging.warn('Not implemented')
124     return None
125
126   @property
127   def profile_directory(self):
128     logging.warn('Not implemented')
129     return None
130
131   def Start(self):
132     logging.warn('Not implemented')
133
134   def AddReplayServerOptions(self, extra_wpr_args):
135     logging.warn('Not implemented')
136     return None
137
138   def extension_backend(self):
139     logging.warn('Not implemented')
140     return None
141
142   def GetBrowserStartupArgs(self):
143     logging.warn('Not implemented')
144     return None
145
146   def HasBrowserFinishedLaunching(self):
147     logging.warn('Not implemented')
148     return False
149
150   def GetStandardOutput(self):
151     raise NotImplementedError()
152
153   def GetStackTrace(self):
154     raise NotImplementedError()