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