Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / tools / telemetry / telemetry / core / backends / chrome / inspector_backend_list.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 collections
6 import logging
7
8 from telemetry.core.backends.chrome import inspector_backend
9
10
11 def DebuggerUrlToId(debugger_url):
12   return debugger_url.split('/')[-1]
13
14
15 class InspectorBackendList(collections.Sequence):
16   """A dynamic sequence of active InspectorBackends."""
17
18   def __init__(self, browser_backend, backend_wrapper):
19     """Constructor.
20
21     Args:
22       browser_backend: The BrowserBackend instance to query for
23           InspectorBackends.
24       backend_wrapper: A public interface for wrapping each
25           InspectorBackend. It must accept an argument of the
26           InspectorBackend to wrap, and an argument of the
27           InspectorBackendList, and may expose whatever methods
28           are desired on top of that backend.
29     """
30     self._browser_backend = browser_backend
31     # A ordered mapping of context IDs to inspectable contexts.
32     self._inspectable_contexts_dict = collections.OrderedDict()
33     # A cache of inspector backends, by context ID.
34     self._inspector_backend_dict = {}
35     # A wrapper class for InspectorBackends.
36     self._backend_wrapper = backend_wrapper
37
38   def GetContextInfo(self, context_id):
39     return self._inspectable_contexts_dict[context_id]
40
41   def ShouldIncludeContext(self, _context):
42     """Override this method to control which contexts are included."""
43     return True
44
45   #TODO(nednguyen): Remove this method and turn inspector_backend_list API to
46   # dictionary-like API (crbug.com/398467)
47   def __getitem__(self, index):
48     self._Update()
49     if index >= len(self._inspectable_contexts_dict.keys()):
50       logging.error('About to explode: _inspectable_contexts_dict.keys() = %s',
51                     repr({
52                       "index": index,
53                       "keys": self._inspectable_contexts_dict.keys()
54                     }))
55     context_id = self._inspectable_contexts_dict.keys()[index]
56     return self.GetBackendFromContextId(context_id)
57
58   def GetBackendFromContextId(self, context_id):
59     self._Update()
60     if context_id not in self._inspectable_contexts_dict:
61       raise KeyError('Cannot find a context with id=%s' % context_id)
62     if context_id not in self._inspector_backend_dict:
63       backend = inspector_backend.InspectorBackend(
64           self._browser_backend,
65           self._inspectable_contexts_dict[context_id])
66       backend = self._backend_wrapper(backend, self)
67       self._inspector_backend_dict[context_id] = backend
68     return self._inspector_backend_dict[context_id]
69
70   def __iter__(self):
71     self._Update()
72     return self._inspectable_contexts_dict.keys().__iter__()
73
74   def __len__(self):
75     self._Update()
76     return len(self._inspectable_contexts_dict)
77
78   def _Update(self):
79     contexts = self._browser_backend.ListInspectableContexts()
80     context_ids = [context['id'] for context in contexts]
81
82     # Append all new inspectable contexts to the dict.
83     for context in contexts:
84       if not self.ShouldIncludeContext(context):
85         continue
86       if context['id'] in self._inspectable_contexts_dict:
87         continue
88       self._inspectable_contexts_dict[context['id']] = context
89
90     # Remove all inspectable contexts that have gone away from the dict.
91     for context_id in self._inspectable_contexts_dict.keys():
92       if context_id not in context_ids:
93         del self._inspectable_contexts_dict[context_id]
94       else:
95         # Also remove inspectable contexts that have no websocketDebuggerUrls.
96         context = next(context for context in contexts
97                       if context['id'] == context_id)
98         if (context_id not in self._inspector_backend_dict.keys() and
99             'webSocketDebuggerUrl' not in context):
100           logging.debug('webSocketDebuggerUrl missing, removing %s'
101                         % context_id)
102           del self._inspectable_contexts_dict[context_id]
103
104     # Clean up any backends for contexts that have gone away.
105     for context_id in self._inspector_backend_dict.keys():
106       if context_id not in self._inspectable_contexts_dict:
107         del self._inspector_backend_dict[context_id]