summaryrefslogtreecommitdiffstats
path: root/chrome/test/automation/automation_proxy.h
blob: 39a0f1c533566350638af487b486b34385a9b2c1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_TEST_AUTOMATION_AUTOMATION_PROXY_H__
#define CHROME_TEST_AUTOMATION_AUTOMATION_PROXY_H__

#include <string>

#include "base/basictypes.h"
#include "base/scoped_ptr.h"
#include "base/thread.h"
#include "chrome/common/ipc_channel_proxy.h"
#include "chrome/common/ipc_message.h"
#include "chrome/test/automation/automation_handle_tracker.h"
#include "chrome/test/automation/automation_messages.h"

class AutomationRequest;
class BrowserProxy;
class WindowProxy;
class TabProxy;
class AutocompleteEditProxy;

// This is an interface that AutomationProxy-related objects can use to
// access the message-sending abilities of the Proxy.
class AutomationMessageSender : public IPC::Message::Sender {
 public:
  // Sends a message synchronously (from the perspective of the caller's
  // thread, at least); it doesn't return until a response has been received.
  // This method takes ownership of the request object passed in.  The caller
  // is responsible for deleting the response object when they're done with it.
  // response_type should be set to the message type of the expected response.
  // A response object will only be available if the method returns true.
  // NOTE: This method will overwrite any routing_id on the request message,
  //       since it uses this field to match the response up with the request.
  virtual bool SendAndWaitForResponse(IPC::Message* request,
                                      IPC::Message** response,
                                      int response_type) = 0;

  // Sends a message synchronously; it doesn't return until a response has been
  // received or a timeout has expired.
  // The function returns true if a response is received, and returns false if
  // there is a failure or timeout (in milliseconds). If return after timeout,
  // is_timeout is set to true.
  // See the comments in SendAndWaitForResponse for other details on usage.
  // NOTE: When timeout occurs, the connection between proxy provider may be
  //       in transit state. Specifically, there might be pending IPC messages,
  //       and the proxy provider might be still working on the previous
  //       request.
  virtual bool SendAndWaitForResponseWithTimeout(IPC::Message* request,
                                                 IPC::Message** response,
                                                 int response_type,
                                                 uint32 timeout_ms,
                                                 bool* is_timeout) = 0;
};

// This is the interface that external processes can use to interact with
// a running instance of the app.
class AutomationProxy : public IPC::Channel::Listener,
                        public AutomationMessageSender {
 public:
  AutomationProxy();
  virtual ~AutomationProxy();

  // IPC callback
  virtual void OnMessageReceived(const IPC::Message& msg);
  virtual void OnChannelError();

  // Close the automation IPC channel.
  void Disconnect();

  // Waits for the app to launch and the automation provider to say hello
  // (the app isn't fully done loading by this point).
  // Returns true if the launch is successful
  bool WaitForAppLaunch();

  // Waits for any initial page loads to complete.
  // NOTE: this only fires once for a run of the application.
  // Returns true if the load is successful
  bool WaitForInitialLoads();

  // Waits for the initial destinations tab to report that it has finished
  // querying.  |load_time| is filled in with how long it took, in milliseconds.
  // NOTE: this only fires once for a run of the application.
  // Returns true if the load is successful.
  bool WaitForInitialNewTabUILoad(int* load_time);

  // Open a new browser window, returning true on success. |show_command|
  // identifies how the window should be shown.
  // False likely indicates an IPC error.
  bool OpenNewBrowserWindow(int show_command);

  // Fills the number of open browser windows into the given variable, returning
  // true on success. False likely indicates an IPC error.
  bool GetBrowserWindowCount(int* num_windows);

  // Block the thread until the window count changes.
  // First parameter is the original window count.
  // The second parameter is updated with the number of window tabs.
  // The third parameter specifies the timeout length for the wait loop.
  // Returns false if the window count does not change before time out.
  // TODO(evanm): this function has a confusing name and semantics; it should
  // be deprecated for WaitForWindowCountToBecome.
  bool WaitForWindowCountToChange(int count, int* new_counter,
                                  int wait_timeout);

  // Block the thread until the window count becomes the provided value.
  // Returns true on success.
  bool WaitForWindowCountToBecome(int target_count, int wait_timeout);

  // Returns the BrowserProxy for the browser window at the given index,
  // transferring ownership of the pointer to the caller.
  // On failure, returns NULL.
  //
  // Use GetBrowserWindowCount to see how many browser windows you can ask for.
  // Window numbers are 0-based.
  BrowserProxy* GetBrowserWindow(int window_index);

  // Returns the BrowserProxy for the browser window which was last active,
  // transferring ownership of the pointer to the caller.
  // If there was no last active browser window, or the last active browser
  // window no longer exists (for example, if it was closed), returns
  // GetBrowserWindow(0).
  BrowserProxy* GetLastActiveBrowserWindow();

  // Returns the WindowProxy for the currently active window, transferring
  // ownership of the pointer to the caller.
  // On failure, returns NULL.
  WindowProxy* GetActiveWindow();

  // Returns the browser this window corresponds to, or NULL if this window
  // is not a browser.  The caller owns the returned BrowserProxy.
  BrowserProxy* GetBrowserForWindow(WindowProxy* window);

  // Same as GetBrowserForWindow except return NULL if response isn't received
  // before the specified timeout.
  BrowserProxy* GetBrowserForWindowWithTimeout(WindowProxy* window,
                                               uint32 timeout_ms,
                                               bool* is_timeout);

  // Returns the WindowProxy for this browser's window. It can be used to
  // retreive view bounds, simulate clicks and key press events.  The caller
  // owns the returned WindowProxy.
  // On failure, returns NULL.
  WindowProxy* GetWindowForBrowser(BrowserProxy* browser);

  // Returns an AutocompleteEdit for this browser's window. It can be used to
  // manipulate the omnibox.  The caller owns the returned pointer.
  // On failure, returns NULL.
  AutocompleteEditProxy* GetAutocompleteEditForBrowser(BrowserProxy* browser);

  // Tells the browser to enable or disable network request filtering.  Returns
  // false if the message fails to send to the browser.
  bool SetFilteredInet(bool enabled);

  // These methods are intended to be called by the background thread
  // to signal that the given event has occurred, and that any corresponding
  // Wait... function can return.
  void SignalAppLaunch();
  void SignalInitialLoads();
  // load_time is how long, in ms, the tab contents took to load.
  void SignalNewTabUITab(int load_time);

  // Returns the ID of the automation IPC channel, so that it can be
  // passed to the app as a launch parameter.
  const std::wstring& channel_id() const { return channel_id_; }

  // AutomationMessageSender implementations.
  virtual bool Send(IPC::Message* message);
  virtual bool SendAndWaitForResponse(IPC::Message* request,
                                      IPC::Message** response,
                                      int response_type);
  virtual bool SendAndWaitForResponseWithTimeout(IPC::Message* request,
                                                 IPC::Message** response,
                                                 int response_type,
                                                 uint32 timeout_ms,
                                                 bool* is_timeout);

  // Returns the current AutomationRequest object.
  AutomationRequest* current_request() { return current_request_; }
  // Clears the current AutomationRequest object.
  void clear_current_request() { current_request_ = NULL; }

  // Wrapper over AutomationHandleTracker::InvalidateHandle. Receives the message
  // from AutomationProxy, unpacks the messages and routes that call to the
  // tracker.
  void InvalidateHandle(const IPC::Message& message);

  // Creates a tab that can hosted in an external process. The function
  // returns a TabProxy representing the tab as well as a window handle
  // that can be reparented in another process.
  TabProxy* CreateExternalTab(HWND* external_tab_container);

 private:
  DISALLOW_EVIL_CONSTRUCTORS(AutomationProxy);

  void InitializeEvents();
  void InitializeChannelID();
  void InitializeThread();
  void InitializeChannel();
  void InitializeHandleTracker();

  std::wstring channel_id_;
  scoped_ptr<Thread> thread_;
  scoped_ptr<IPC::ChannelProxy> channel_;
  scoped_ptr<AutomationHandleTracker> tracker_;

  HANDLE app_launched_;
  HANDLE initial_loads_complete_;
  HANDLE new_tab_ui_load_complete_;
  int new_tab_ui_load_time_;

  AutomationRequest* current_request_;

  static const int kMaxCommandExecutionTime;  // Delay to let the browser
                                              //  execute the command.;
};

#endif  // CHROME_TEST_AUTOMATION_AUTOMATION_PROXY_H__