• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 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_TEST_CHROMEDRIVER_CHROME_DEVTOOLS_CLIENT_IMPL_H_
6 #define CHROME_TEST_CHROMEDRIVER_CHROME_DEVTOOLS_CLIENT_IMPL_H_
7 
8 #include <list>
9 #include <map>
10 #include <string>
11 
12 #include "base/basictypes.h"
13 #include "base/callback.h"
14 #include "base/compiler_specific.h"
15 #include "base/memory/linked_ptr.h"
16 #include "base/memory/scoped_ptr.h"
17 #include "chrome/test/chromedriver/chrome/devtools_client.h"
18 #include "chrome/test/chromedriver/net/sync_websocket_factory.h"
19 #include "url/gurl.h"
20 
21 namespace base {
22 class DictionaryValue;
23 }
24 
25 namespace internal {
26 
27 enum InspectorMessageType {
28   kEventMessageType = 0,
29   kCommandResponseMessageType
30 };
31 
32 struct InspectorEvent {
33   InspectorEvent();
34   ~InspectorEvent();
35   std::string method;
36   scoped_ptr<base::DictionaryValue> params;
37 };
38 
39 struct InspectorCommandResponse {
40   InspectorCommandResponse();
41   ~InspectorCommandResponse();
42   int id;
43   std::string error;
44   scoped_ptr<base::DictionaryValue> result;
45 };
46 
47 }  // namespace internal
48 
49 class DevToolsEventListener;
50 class Status;
51 class SyncWebSocket;
52 
53 class DevToolsClientImpl : public DevToolsClient {
54  public:
55   typedef base::Callback<Status()> FrontendCloserFunc;
56   DevToolsClientImpl(const SyncWebSocketFactory& factory,
57                      const std::string& url,
58                      const std::string& id,
59                      const FrontendCloserFunc& frontend_closer_func);
60 
61   typedef base::Callback<bool(
62       const std::string&,
63       int,
64       internal::InspectorMessageType*,
65       internal::InspectorEvent*,
66       internal::InspectorCommandResponse*)> ParserFunc;
67   DevToolsClientImpl(const SyncWebSocketFactory& factory,
68                      const std::string& url,
69                      const std::string& id,
70                      const FrontendCloserFunc& frontend_closer_func,
71                      const ParserFunc& parser_func);
72 
73   virtual ~DevToolsClientImpl();
74 
75   void SetParserFuncForTesting(const ParserFunc& parser_func);
76 
77   // Overridden from DevToolsClient:
78   virtual const std::string& GetId() OVERRIDE;
79   virtual bool WasCrashed() OVERRIDE;
80   virtual Status ConnectIfNecessary() OVERRIDE;
81   virtual Status SendCommand(const std::string& method,
82                              const base::DictionaryValue& params) OVERRIDE;
83   virtual Status SendCommandAndGetResult(
84       const std::string& method,
85       const base::DictionaryValue& params,
86       scoped_ptr<base::DictionaryValue>* result) OVERRIDE;
87   virtual void AddListener(DevToolsEventListener* listener) OVERRIDE;
88   virtual Status HandleEventsUntil(
89       const ConditionalFunc& conditional_func,
90       const base::TimeDelta& timeout) OVERRIDE;
91   virtual Status HandleReceivedEvents() OVERRIDE;
92 
93  private:
94   enum ResponseState {
95     // The client is waiting for the response.
96     kWaiting,
97     // The command response will not be received because it is blocked by an
98     // alert that the command triggered.
99     kBlocked,
100     // The client no longer cares about the response.
101     kIgnored,
102     // The response has been received.
103     kReceived
104   };
105   struct ResponseInfo {
106     explicit ResponseInfo(const std::string& method);
107     ~ResponseInfo();
108 
109     ResponseState state;
110     std::string method;
111     internal::InspectorCommandResponse response;
112   };
113   typedef std::map<int, linked_ptr<ResponseInfo> > ResponseInfoMap;
114 
115   Status SendCommandInternal(
116       const std::string& method,
117       const base::DictionaryValue& params,
118       scoped_ptr<base::DictionaryValue>* result);
119   Status ProcessNextMessage(int expected_id, const base::TimeDelta& timeout);
120   Status ProcessEvent(const internal::InspectorEvent& event);
121   Status ProcessCommandResponse(
122       const internal::InspectorCommandResponse& response);
123   Status EnsureListenersNotifiedOfConnect();
124   Status EnsureListenersNotifiedOfEvent();
125   Status EnsureListenersNotifiedOfCommandResponse();
126 
127   scoped_ptr<SyncWebSocket> socket_;
128   GURL url_;
129   bool crashed_;
130   const std::string id_;
131   FrontendCloserFunc frontend_closer_func_;
132   ParserFunc parser_func_;
133   std::list<DevToolsEventListener*> listeners_;
134   std::list<DevToolsEventListener*> unnotified_connect_listeners_;
135   std::list<DevToolsEventListener*> unnotified_event_listeners_;
136   const internal::InspectorEvent* unnotified_event_;
137   std::list<DevToolsEventListener*> unnotified_cmd_response_listeners_;
138   linked_ptr<ResponseInfo> unnotified_cmd_response_info_;
139   ResponseInfoMap response_info_map_;
140   int next_id_;
141   int stack_count_;
142 
143   DISALLOW_COPY_AND_ASSIGN(DevToolsClientImpl);
144 };
145 
146 namespace internal {
147 
148 bool ParseInspectorMessage(
149     const std::string& message,
150     int expected_id,
151     InspectorMessageType* type,
152     InspectorEvent* event,
153     InspectorCommandResponse* command_response);
154 
155 }  // namespace internal
156 
157 #endif  // CHROME_TEST_CHROMEDRIVER_CHROME_DEVTOOLS_CLIENT_IMPL_H_
158