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