1 // Copyright (c) 2011 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 #include "chrome/browser/automation/testing_automation_provider.h"
6
7 #include <map>
8 #include <set>
9 #include <string>
10 #include <vector>
11
12 #include "base/command_line.h"
13 #include "base/file_path.h"
14 #include "base/json/json_reader.h"
15 #include "base/json/json_writer.h"
16 #include "base/json/string_escape.h"
17 #include "base/path_service.h"
18 #include "base/process.h"
19 #include "base/process_util.h"
20 #include "base/stringprintf.h"
21 #include "base/threading/thread_restrictions.h"
22 #include "base/time.h"
23 #include "base/utf_string_conversions.h"
24 #include "chrome/app/chrome_command_ids.h"
25 #include "chrome/browser/autocomplete/autocomplete.h"
26 #include "chrome/browser/autocomplete/autocomplete_edit.h"
27 #include "chrome/browser/autocomplete/autocomplete_match.h"
28 #include "chrome/browser/autofill/autofill_manager.h"
29 #include "chrome/browser/autofill/credit_card.h"
30 #include "chrome/browser/autofill/personal_data_manager.h"
31 #include "chrome/browser/automation/automation_autocomplete_edit_tracker.h"
32 #include "chrome/browser/automation/automation_browser_tracker.h"
33 #include "chrome/browser/automation/automation_provider_json.h"
34 #include "chrome/browser/automation/automation_provider_list.h"
35 #include "chrome/browser/automation/automation_provider_observers.h"
36 #include "chrome/browser/automation/automation_tab_tracker.h"
37 #include "chrome/browser/automation/automation_util.h"
38 #include "chrome/browser/automation/automation_window_tracker.h"
39 #include "chrome/browser/automation/ui_controls.h"
40 #include "chrome/browser/blocked_content_container.h"
41 #include "chrome/browser/bookmarks/bookmark_model.h"
42 #include "chrome/browser/bookmarks/bookmark_storage.h"
43 #include "chrome/browser/browser_process.h"
44 #include "chrome/browser/browser_shutdown.h"
45 #include "chrome/browser/debugger/devtools_manager.h"
46 #include "chrome/browser/download/download_prefs.h"
47 #include "chrome/browser/download/download_shelf.h"
48 #include "chrome/browser/download/save_package.h"
49 #include "chrome/browser/extensions/extension_host.h"
50 #include "chrome/browser/extensions/extension_service.h"
51 #include "chrome/browser/extensions/extension_updater.h"
52 #include "chrome/browser/history/top_sites.h"
53 #include "chrome/browser/importer/importer_host.h"
54 #include "chrome/browser/instant/instant_controller.h"
55 #include "chrome/browser/notifications/balloon.h"
56 #include "chrome/browser/notifications/balloon_collection.h"
57 #include "chrome/browser/notifications/notification.h"
58 #include "chrome/browser/notifications/notification_ui_manager.h"
59 #include "chrome/browser/password_manager/password_store.h"
60 #include "chrome/browser/platform_util.h"
61 #include "chrome/browser/prefs/pref_service.h"
62 #include "chrome/browser/profiles/profile.h"
63 #include "chrome/browser/profiles/profile_manager.h"
64 #include "chrome/browser/search_engines/template_url.h"
65 #include "chrome/browser/search_engines/template_url_model.h"
66 #include "chrome/browser/tab_contents/confirm_infobar_delegate.h"
67 #include "chrome/browser/tab_contents/link_infobar_delegate.h"
68 #include "chrome/browser/themes/theme_service.h"
69 #include "chrome/browser/themes/theme_service_factory.h"
70 #include "chrome/browser/translate/translate_infobar_delegate.h"
71 #include "chrome/browser/translate/translate_tab_helper.h"
72 #include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h"
73 #include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog_queue.h"
74 #include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h"
75 #include "chrome/browser/ui/browser_window.h"
76 #include "chrome/browser/ui/download/download_tab_helper.h"
77 #include "chrome/browser/ui/find_bar/find_bar.h"
78 #include "chrome/browser/ui/login/login_prompt.h"
79 #include "chrome/browser/ui/omnibox/location_bar.h"
80 #include "chrome/browser/ui/search_engines/keyword_editor_controller.h"
81 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
82 #include "chrome/browser/ui/webui/active_downloads_ui.h"
83 #include "chrome/browser/ui/webui/shown_sections_handler.h"
84 #include "chrome/common/automation_messages.h"
85 #include "chrome/common/chrome_constants.h"
86 #include "chrome/common/chrome_paths.h"
87 #include "chrome/common/chrome_switches.h"
88 #include "chrome/common/extensions/extension.h"
89 #include "chrome/common/extensions/extension_extent.h"
90 #include "chrome/common/extensions/url_pattern.h"
91 #include "chrome/common/pref_names.h"
92 #include "chrome/common/url_constants.h"
93 #include "content/browser/renderer_host/render_process_host.h"
94 #include "content/browser/renderer_host/render_view_host.h"
95 #include "content/browser/tab_contents/interstitial_page.h"
96 #include "content/common/common_param_traits.h"
97 #include "content/common/notification_service.h"
98 #include "net/base/cookie_store.h"
99 #include "third_party/WebKit/Source/WebKit/chromium/public/WebInputEvent.h"
100 #include "ui/base/events.h"
101 #include "ui/base/message_box_flags.h"
102 #include "webkit/plugins/npapi/plugin_list.h"
103
104 namespace {
105
SendMouseClick(int flags)106 void SendMouseClick(int flags) {
107 ui_controls::MouseButton button = ui_controls::LEFT;
108 if ((flags & ui::EF_LEFT_BUTTON_DOWN) ==
109 ui::EF_LEFT_BUTTON_DOWN) {
110 button = ui_controls::LEFT;
111 } else if ((flags & ui::EF_RIGHT_BUTTON_DOWN) ==
112 ui::EF_RIGHT_BUTTON_DOWN) {
113 button = ui_controls::RIGHT;
114 } else if ((flags & ui::EF_MIDDLE_BUTTON_DOWN) ==
115 ui::EF_MIDDLE_BUTTON_DOWN) {
116 button = ui_controls::MIDDLE;
117 } else {
118 NOTREACHED();
119 }
120
121 ui_controls::SendMouseClick(button);
122 }
123
124 class AutomationInterstitialPage : public InterstitialPage {
125 public:
AutomationInterstitialPage(TabContents * tab,const GURL & url,const std::string & contents)126 AutomationInterstitialPage(TabContents* tab,
127 const GURL& url,
128 const std::string& contents)
129 : InterstitialPage(tab, true, url),
130 contents_(contents) {
131 }
132
GetHTMLContents()133 virtual std::string GetHTMLContents() { return contents_; }
134
135 private:
136 const std::string contents_;
137
138 DISALLOW_COPY_AND_ASSIGN(AutomationInterstitialPage);
139 };
140
141 } // namespace
142
TestingAutomationProvider(Profile * profile)143 TestingAutomationProvider::TestingAutomationProvider(Profile* profile)
144 : AutomationProvider(profile),
145 #if defined(TOOLKIT_VIEWS)
146 popup_menu_waiter_(NULL),
147 #endif
148 redirect_query_(0) {
149 BrowserList::AddObserver(this);
150 registrar_.Add(this, NotificationType::SESSION_END,
151 NotificationService::AllSources());
152 }
153
~TestingAutomationProvider()154 TestingAutomationProvider::~TestingAutomationProvider() {
155 BrowserList::RemoveObserver(this);
156 }
157
OnBrowserAdded(const Browser * browser)158 void TestingAutomationProvider::OnBrowserAdded(const Browser* browser) {
159 }
160
OnBrowserRemoved(const Browser * browser)161 void TestingAutomationProvider::OnBrowserRemoved(const Browser* browser) {
162 // For backwards compatibility with the testing automation interface, we
163 // want the automation provider (and hence the process) to go away when the
164 // last browser goes away.
165 if (BrowserList::empty() && !CommandLine::ForCurrentProcess()->HasSwitch(
166 switches::kKeepAliveForTest)) {
167 // If you change this, update Observer for NotificationType::SESSION_END
168 // below.
169 MessageLoop::current()->PostTask(FROM_HERE,
170 NewRunnableMethod(this, &TestingAutomationProvider::OnRemoveProvider));
171 }
172 }
173
OnSourceProfilesLoaded()174 void TestingAutomationProvider::OnSourceProfilesLoaded() {
175 DCHECK_NE(static_cast<ImporterList*>(NULL), importer_list_.get());
176
177 // Get the correct profile based on the browser that the user provided.
178 importer::SourceProfile source_profile;
179 size_t i = 0;
180 size_t importers_count = importer_list_->count();
181 for ( ; i < importers_count; ++i) {
182 importer::SourceProfile profile = importer_list_->GetSourceProfileAt(i);
183 if (profile.importer_name == import_settings_data_.browser_name) {
184 source_profile = profile;
185 break;
186 }
187 }
188 // If we made it to the end of the loop, then the input was bad.
189 if (i == importers_count) {
190 AutomationJSONReply(this, import_settings_data_.reply_message)
191 .SendError("Invalid browser name string found.");
192 return;
193 }
194
195 scoped_refptr<ImporterHost> importer_host(new ImporterHost);
196 importer_host->SetObserver(
197 new AutomationProviderImportSettingsObserver(
198 this, import_settings_data_.reply_message));
199
200 Profile* target_profile = import_settings_data_.browser->profile();
201 importer_host->StartImportSettings(source_profile,
202 target_profile,
203 import_settings_data_.import_items,
204 new ProfileWriter(target_profile),
205 import_settings_data_.first_run);
206 }
207
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)208 void TestingAutomationProvider::Observe(NotificationType type,
209 const NotificationSource& source,
210 const NotificationDetails& details) {
211 DCHECK(type == NotificationType::SESSION_END);
212 // OnBrowserRemoved does a ReleaseLater. When session end is received we exit
213 // before the task runs resulting in this object not being deleted. This
214 // Release balance out the Release scheduled by OnBrowserRemoved.
215 Release();
216 }
217
OnMessageReceived(const IPC::Message & message)218 bool TestingAutomationProvider::OnMessageReceived(
219 const IPC::Message& message) {
220 bool handled = true;
221 bool deserialize_success = true;
222 IPC_BEGIN_MESSAGE_MAP_EX(TestingAutomationProvider,
223 message,
224 deserialize_success)
225 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseBrowser, CloseBrowser)
226 IPC_MESSAGE_HANDLER(AutomationMsg_CloseBrowserRequestAsync,
227 CloseBrowserAsync)
228 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateTab, ActivateTab)
229 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_AppendTab, AppendTab)
230 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveTabIndex, GetActiveTabIndex)
231 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CloseTab, CloseTab)
232 IPC_MESSAGE_HANDLER(AutomationMsg_GetCookies, GetCookies)
233 IPC_MESSAGE_HANDLER(AutomationMsg_SetCookie, SetCookie)
234 IPC_MESSAGE_HANDLER(AutomationMsg_DeleteCookie, DeleteCookie)
235 IPC_MESSAGE_HANDLER(AutomationMsg_ShowCollectedCookiesDialog,
236 ShowCollectedCookiesDialog)
237 IPC_MESSAGE_HANDLER_DELAY_REPLY(
238 AutomationMsg_NavigateToURLBlockUntilNavigationsComplete,
239 NavigateToURLBlockUntilNavigationsComplete)
240 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsync, NavigationAsync)
241 IPC_MESSAGE_HANDLER(AutomationMsg_NavigationAsyncWithDisposition,
242 NavigationAsyncWithDisposition)
243 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_Reload, Reload)
244 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_SetAuth, SetAuth)
245 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_CancelAuth, CancelAuth)
246 IPC_MESSAGE_HANDLER(AutomationMsg_NeedsAuth, NeedsAuth)
247 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_RedirectsFrom,
248 GetRedirectsFrom)
249 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindowCount, GetBrowserWindowCount)
250 IPC_MESSAGE_HANDLER(AutomationMsg_NormalBrowserWindowCount,
251 GetNormalBrowserWindowCount)
252 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserWindow, GetBrowserWindow)
253 IPC_MESSAGE_HANDLER(AutomationMsg_GetBrowserLocale, GetBrowserLocale)
254 IPC_MESSAGE_HANDLER(AutomationMsg_LastActiveBrowserWindow,
255 GetLastActiveBrowserWindow)
256 IPC_MESSAGE_HANDLER(AutomationMsg_ActiveWindow, GetActiveWindow)
257 IPC_MESSAGE_HANDLER(AutomationMsg_FindNormalBrowserWindow,
258 FindNormalBrowserWindow)
259 IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowActive, IsWindowActive)
260 IPC_MESSAGE_HANDLER(AutomationMsg_ActivateWindow, ActivateWindow)
261 IPC_MESSAGE_HANDLER(AutomationMsg_IsWindowMaximized, IsWindowMaximized)
262 IPC_MESSAGE_HANDLER(AutomationMsg_WindowExecuteCommandAsync,
263 ExecuteBrowserCommandAsync)
264 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WindowExecuteCommand,
265 ExecuteBrowserCommand)
266 IPC_MESSAGE_HANDLER(AutomationMsg_TerminateSession, TerminateSession)
267 IPC_MESSAGE_HANDLER(AutomationMsg_WindowViewBounds, WindowGetViewBounds)
268 IPC_MESSAGE_HANDLER(AutomationMsg_GetWindowBounds, GetWindowBounds)
269 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowBounds, SetWindowBounds)
270 IPC_MESSAGE_HANDLER(AutomationMsg_SetWindowVisible, SetWindowVisible)
271 IPC_MESSAGE_HANDLER(AutomationMsg_WindowClick, WindowSimulateClick)
272 IPC_MESSAGE_HANDLER(AutomationMsg_WindowMouseMove, WindowSimulateMouseMove)
273 IPC_MESSAGE_HANDLER(AutomationMsg_WindowKeyPress, WindowSimulateKeyPress)
274 IPC_MESSAGE_HANDLER(AutomationMsg_TabCount, GetTabCount)
275 IPC_MESSAGE_HANDLER(AutomationMsg_Type, GetType)
276 IPC_MESSAGE_HANDLER(AutomationMsg_Tab, GetTab)
277 IPC_MESSAGE_HANDLER(AutomationMsg_TabProcessID, GetTabProcessID)
278 IPC_MESSAGE_HANDLER(AutomationMsg_TabTitle, GetTabTitle)
279 IPC_MESSAGE_HANDLER(AutomationMsg_TabIndex, GetTabIndex)
280 IPC_MESSAGE_HANDLER(AutomationMsg_TabURL, GetTabURL)
281 IPC_MESSAGE_HANDLER(AutomationMsg_ShelfVisibility, GetShelfVisibility)
282 IPC_MESSAGE_HANDLER(AutomationMsg_IsFullscreen, IsFullscreen)
283 IPC_MESSAGE_HANDLER(AutomationMsg_IsFullscreenBubbleVisible,
284 GetFullscreenBubbleVisibility)
285 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditForBrowser,
286 GetAutocompleteEditForBrowser)
287 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetText,
288 GetAutocompleteEditText)
289 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditSetText,
290 SetAutocompleteEditText)
291 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditIsQueryInProgress,
292 AutocompleteEditIsQueryInProgress)
293 IPC_MESSAGE_HANDLER(AutomationMsg_AutocompleteEditGetMatches,
294 AutocompleteEditGetMatches)
295 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForAutocompleteEditFocus,
296 WaitForAutocompleteEditFocus)
297 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_DomOperation,
298 ExecuteJavascript)
299 IPC_MESSAGE_HANDLER(AutomationMsg_ConstrainedWindowCount,
300 GetConstrainedWindowCount)
301 #if defined(TOOLKIT_VIEWS)
302 IPC_MESSAGE_HANDLER(AutomationMsg_GetFocusedViewID, GetFocusedViewID)
303 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForFocusedViewIDToChange,
304 WaitForFocusedViewIDToChange)
305 IPC_MESSAGE_HANDLER(AutomationMsg_StartTrackingPopupMenus,
306 StartTrackingPopupMenus)
307 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForPopupMenuToOpen,
308 WaitForPopupMenuToOpen)
309 #endif // defined(TOOLKIT_VIEWS)
310 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_InspectElement,
311 HandleInspectElementRequest)
312 IPC_MESSAGE_HANDLER(AutomationMsg_DownloadDirectory, GetDownloadDirectory)
313 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_OpenNewBrowserWindowOfType,
314 OpenNewBrowserWindowOfType)
315 IPC_MESSAGE_HANDLER(AutomationMsg_WindowForBrowser, GetWindowForBrowser)
316 IPC_MESSAGE_HANDLER(AutomationMsg_BrowserForWindow, GetBrowserForWindow)
317 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ShowInterstitialPage,
318 ShowInterstitialPage)
319 IPC_MESSAGE_HANDLER(AutomationMsg_HideInterstitialPage,
320 HideInterstitialPage)
321 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForTabToBeRestored,
322 WaitForTabToBeRestored)
323 IPC_MESSAGE_HANDLER(AutomationMsg_GetSecurityState, GetSecurityState)
324 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageType, GetPageType)
325 IPC_MESSAGE_HANDLER(AutomationMsg_GetMetricEventDuration,
326 GetMetricEventDuration)
327 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ActionOnSSLBlockingPage,
328 ActionOnSSLBlockingPage)
329 IPC_MESSAGE_HANDLER(AutomationMsg_BringBrowserToFront, BringBrowserToFront)
330 IPC_MESSAGE_HANDLER(AutomationMsg_IsMenuCommandEnabled,
331 IsMenuCommandEnabled)
332 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_PrintNow, PrintNow)
333 IPC_MESSAGE_HANDLER(AutomationMsg_SavePage, SavePage)
334 IPC_MESSAGE_HANDLER(AutomationMsg_OpenFindInPage,
335 HandleOpenFindInPageRequest)
336 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowVisibility,
337 GetFindWindowVisibility)
338 IPC_MESSAGE_HANDLER(AutomationMsg_FindWindowLocation,
339 HandleFindWindowLocationRequest)
340 IPC_MESSAGE_HANDLER(AutomationMsg_BookmarkBarVisibility,
341 GetBookmarkBarVisibility)
342 IPC_MESSAGE_HANDLER(AutomationMsg_GetBookmarksAsJSON,
343 GetBookmarksAsJSON)
344 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForBookmarkModelToLoad,
345 WaitForBookmarkModelToLoad)
346 IPC_MESSAGE_HANDLER(AutomationMsg_AddBookmarkGroup,
347 AddBookmarkGroup)
348 IPC_MESSAGE_HANDLER(AutomationMsg_AddBookmarkURL,
349 AddBookmarkURL)
350 IPC_MESSAGE_HANDLER(AutomationMsg_ReparentBookmark,
351 ReparentBookmark)
352 IPC_MESSAGE_HANDLER(AutomationMsg_SetBookmarkTitle,
353 SetBookmarkTitle)
354 IPC_MESSAGE_HANDLER(AutomationMsg_SetBookmarkURL,
355 SetBookmarkURL)
356 IPC_MESSAGE_HANDLER(AutomationMsg_RemoveBookmark,
357 RemoveBookmark)
358 IPC_MESSAGE_HANDLER(AutomationMsg_GetInfoBarCount, GetInfoBarCount)
359 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_ClickInfoBarAccept,
360 ClickInfoBarAccept)
361 IPC_MESSAGE_HANDLER(AutomationMsg_GetLastNavigationTime,
362 GetLastNavigationTime)
363 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForNavigation,
364 WaitForNavigation)
365 IPC_MESSAGE_HANDLER(AutomationMsg_SetIntPreference, SetIntPreference)
366 IPC_MESSAGE_HANDLER(AutomationMsg_ShowingAppModalDialog,
367 GetShowingAppModalDialog)
368 IPC_MESSAGE_HANDLER(AutomationMsg_ClickAppModalDialogButton,
369 ClickAppModalDialogButton)
370 IPC_MESSAGE_HANDLER(AutomationMsg_SetStringPreference, SetStringPreference)
371 IPC_MESSAGE_HANDLER(AutomationMsg_GetBooleanPreference,
372 GetBooleanPreference)
373 IPC_MESSAGE_HANDLER(AutomationMsg_SetBooleanPreference,
374 SetBooleanPreference)
375 IPC_MESSAGE_HANDLER_DELAY_REPLY(
376 AutomationMsg_WaitForBrowserWindowCountToBecome,
377 WaitForBrowserWindowCountToBecome)
378 IPC_MESSAGE_HANDLER_DELAY_REPLY(
379 AutomationMsg_WaitForAppModalDialogToBeShown,
380 WaitForAppModalDialogToBeShown)
381 IPC_MESSAGE_HANDLER_DELAY_REPLY(
382 AutomationMsg_GoBackBlockUntilNavigationsComplete,
383 GoBackBlockUntilNavigationsComplete)
384 IPC_MESSAGE_HANDLER_DELAY_REPLY(
385 AutomationMsg_GoForwardBlockUntilNavigationsComplete,
386 GoForwardBlockUntilNavigationsComplete)
387 IPC_MESSAGE_HANDLER(AutomationMsg_SavePackageShouldPromptUser,
388 SavePackageShouldPromptUser)
389 IPC_MESSAGE_HANDLER(AutomationMsg_WindowTitle, GetWindowTitle)
390 IPC_MESSAGE_HANDLER(AutomationMsg_SetShelfVisibility, SetShelfVisibility)
391 IPC_MESSAGE_HANDLER(AutomationMsg_BlockedPopupCount, GetBlockedPopupCount)
392 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_SendJSONRequest,
393 SendJSONRequest)
394 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForTabCountToBecome,
395 WaitForTabCountToBecome)
396 IPC_MESSAGE_HANDLER_DELAY_REPLY(AutomationMsg_WaitForInfoBarCount,
397 WaitForInfoBarCount)
398 IPC_MESSAGE_HANDLER(AutomationMsg_GetPageCurrentEncoding,
399 GetPageCurrentEncoding)
400 IPC_MESSAGE_HANDLER(AutomationMsg_ShutdownSessionService,
401 ShutdownSessionService)
402 IPC_MESSAGE_HANDLER(AutomationMsg_SetContentSetting, SetContentSetting)
403 IPC_MESSAGE_HANDLER(AutomationMsg_LoadBlockedPlugins, LoadBlockedPlugins)
404 IPC_MESSAGE_HANDLER(AutomationMsg_ResetToDefaultTheme, ResetToDefaultTheme)
405 IPC_MESSAGE_HANDLER_DELAY_REPLY(
406 AutomationMsg_WaitForProcessLauncherThreadToGoIdle,
407 WaitForProcessLauncherThreadToGoIdle)
408 IPC_MESSAGE_HANDLER(AutomationMsg_GetParentBrowserOfTab,
409 GetParentBrowserOfTab)
410
411 IPC_MESSAGE_UNHANDLED(
412 handled = AutomationProvider::OnMessageReceived(message))
413 IPC_END_MESSAGE_MAP_EX()
414 if (!deserialize_success)
415 OnMessageDeserializationFailure();
416 return handled;
417 }
418
OnChannelError()419 void TestingAutomationProvider::OnChannelError() {
420 if (!reinitialize_on_channel_error_ &&
421 browser_shutdown::GetShutdownType() == browser_shutdown::NOT_VALID)
422 BrowserList::CloseAllBrowsersAndExit();
423 AutomationProvider::OnChannelError();
424 }
425
CloseBrowser(int browser_handle,IPC::Message * reply_message)426 void TestingAutomationProvider::CloseBrowser(int browser_handle,
427 IPC::Message* reply_message) {
428 if (!browser_tracker_->ContainsHandle(browser_handle))
429 return;
430
431 Browser* browser = browser_tracker_->GetResource(browser_handle);
432 new BrowserClosedNotificationObserver(browser, this, reply_message);
433 browser->window()->Close();
434 }
435
CloseBrowserAsync(int browser_handle)436 void TestingAutomationProvider::CloseBrowserAsync(int browser_handle) {
437 if (!browser_tracker_->ContainsHandle(browser_handle))
438 return;
439
440 Browser* browser = browser_tracker_->GetResource(browser_handle);
441 browser->window()->Close();
442 }
443
ActivateTab(int handle,int at_index,int * status)444 void TestingAutomationProvider::ActivateTab(int handle,
445 int at_index,
446 int* status) {
447 *status = -1;
448 if (browser_tracker_->ContainsHandle(handle) && at_index > -1) {
449 Browser* browser = browser_tracker_->GetResource(handle);
450 if (at_index >= 0 && at_index < browser->tab_count()) {
451 browser->ActivateTabAt(at_index, true);
452 *status = 0;
453 }
454 }
455 }
456
AppendTab(int handle,const GURL & url,IPC::Message * reply_message)457 void TestingAutomationProvider::AppendTab(int handle,
458 const GURL& url,
459 IPC::Message* reply_message) {
460 int append_tab_response = -1; // -1 is the error code
461 NotificationObserver* observer = NULL;
462
463 if (browser_tracker_->ContainsHandle(handle)) {
464 Browser* browser = browser_tracker_->GetResource(handle);
465 observer = new TabAppendedNotificationObserver(browser, this,
466 reply_message);
467 TabContentsWrapper* contents =
468 browser->AddSelectedTabWithURL(url, PageTransition::TYPED);
469 if (contents) {
470 append_tab_response =
471 GetIndexForNavigationController(&contents->controller(), browser);
472 }
473 }
474
475 if (append_tab_response < 0) {
476 // Appending tab failed. Clean up and send failure response.
477
478 if (observer)
479 delete observer;
480
481 AutomationMsg_AppendTab::WriteReplyParams(reply_message,
482 append_tab_response);
483 Send(reply_message);
484 }
485 }
486
GetActiveTabIndex(int handle,int * active_tab_index)487 void TestingAutomationProvider::GetActiveTabIndex(int handle,
488 int* active_tab_index) {
489 *active_tab_index = -1; // -1 is the error code
490 if (browser_tracker_->ContainsHandle(handle)) {
491 Browser* browser = browser_tracker_->GetResource(handle);
492 *active_tab_index = browser->active_index();
493 }
494 }
495
CloseTab(int tab_handle,bool wait_until_closed,IPC::Message * reply_message)496 void TestingAutomationProvider::CloseTab(int tab_handle,
497 bool wait_until_closed,
498 IPC::Message* reply_message) {
499 if (tab_tracker_->ContainsHandle(tab_handle)) {
500 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
501 int index;
502 Browser* browser = Browser::GetBrowserForController(controller, &index);
503 DCHECK(browser);
504 new TabClosedNotificationObserver(this, wait_until_closed, reply_message);
505 browser->CloseTabContents(controller->tab_contents());
506 return;
507 }
508
509 AutomationMsg_CloseTab::WriteReplyParams(reply_message, false);
510 Send(reply_message);
511 }
512
GetCookies(const GURL & url,int handle,int * value_size,std::string * value)513 void TestingAutomationProvider::GetCookies(const GURL& url, int handle,
514 int* value_size,
515 std::string* value) {
516 TabContents *contents = tab_tracker_->ContainsHandle(handle) ?
517 tab_tracker_->GetResource(handle)->tab_contents() : NULL;
518 automation_util::GetCookies(url, contents, value_size, value);
519 }
520
SetCookie(const GURL & url,const std::string & value,int handle,int * response_value)521 void TestingAutomationProvider::SetCookie(const GURL& url,
522 const std::string& value,
523 int handle,
524 int* response_value) {
525 TabContents *contents = tab_tracker_->ContainsHandle(handle) ?
526 tab_tracker_->GetResource(handle)->tab_contents() : NULL;
527 automation_util::SetCookie(url, value, contents, response_value);
528 }
529
DeleteCookie(const GURL & url,const std::string & cookie_name,int handle,bool * success)530 void TestingAutomationProvider::DeleteCookie(const GURL& url,
531 const std::string& cookie_name,
532 int handle, bool* success) {
533 TabContents *contents = tab_tracker_->ContainsHandle(handle) ?
534 tab_tracker_->GetResource(handle)->tab_contents() : NULL;
535 automation_util::DeleteCookie(url, cookie_name, contents, success);
536 }
537
ShowCollectedCookiesDialog(int handle,bool * success)538 void TestingAutomationProvider::ShowCollectedCookiesDialog(
539 int handle, bool* success) {
540 *success = false;
541 if (tab_tracker_->ContainsHandle(handle)) {
542 TabContents* tab_contents =
543 tab_tracker_->GetResource(handle)->tab_contents();
544 tab_contents->delegate()->ShowCollectedCookiesDialog(tab_contents);
545 *success = true;
546 }
547 }
548
NavigateToURLBlockUntilNavigationsComplete(int handle,const GURL & url,int number_of_navigations,IPC::Message * reply_message)549 void TestingAutomationProvider::NavigateToURLBlockUntilNavigationsComplete(
550 int handle, const GURL& url, int number_of_navigations,
551 IPC::Message* reply_message) {
552 if (tab_tracker_->ContainsHandle(handle)) {
553 NavigationController* tab = tab_tracker_->GetResource(handle);
554
555 // Simulate what a user would do. Activate the tab and then navigate.
556 // We could allow navigating in a background tab in future.
557 Browser* browser = FindAndActivateTab(tab);
558
559 if (browser) {
560 new NavigationNotificationObserver(tab, this, reply_message,
561 number_of_navigations, false, false);
562
563 // TODO(darin): avoid conversion to GURL.
564 browser->OpenURL(url, GURL(), CURRENT_TAB, PageTransition::TYPED);
565 return;
566 }
567 }
568
569 AutomationMsg_NavigateToURLBlockUntilNavigationsComplete::WriteReplyParams(
570 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
571 Send(reply_message);
572 }
573
NavigationAsync(int handle,const GURL & url,bool * status)574 void TestingAutomationProvider::NavigationAsync(int handle,
575 const GURL& url,
576 bool* status) {
577 NavigationAsyncWithDisposition(handle, url, CURRENT_TAB, status);
578 }
579
NavigationAsyncWithDisposition(int handle,const GURL & url,WindowOpenDisposition disposition,bool * status)580 void TestingAutomationProvider::NavigationAsyncWithDisposition(
581 int handle,
582 const GURL& url,
583 WindowOpenDisposition disposition,
584 bool* status) {
585 *status = false;
586
587 if (tab_tracker_->ContainsHandle(handle)) {
588 NavigationController* tab = tab_tracker_->GetResource(handle);
589
590 // Simulate what a user would do. Activate the tab and then navigate.
591 // We could allow navigating in a background tab in future.
592 Browser* browser = FindAndActivateTab(tab);
593
594 if (browser) {
595 // Don't add any listener unless a callback mechanism is desired.
596 // TODO(vibhor): Do this if such a requirement arises in future.
597 browser->OpenURL(url, GURL(), disposition, PageTransition::TYPED);
598 *status = true;
599 }
600 }
601 }
602
Reload(int handle,IPC::Message * reply_message)603 void TestingAutomationProvider::Reload(int handle,
604 IPC::Message* reply_message) {
605 if (tab_tracker_->ContainsHandle(handle)) {
606 NavigationController* tab = tab_tracker_->GetResource(handle);
607 Browser* browser = FindAndActivateTab(tab);
608 if (browser && browser->command_updater()->IsCommandEnabled(IDC_RELOAD)) {
609 new NavigationNotificationObserver(
610 tab, this, reply_message, 1, false, false);
611 browser->Reload(CURRENT_TAB);
612 return;
613 }
614 }
615
616 AutomationMsg_Reload::WriteReplyParams(
617 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
618 Send(reply_message);
619 }
620
SetAuth(int tab_handle,const std::wstring & username,const std::wstring & password,IPC::Message * reply_message)621 void TestingAutomationProvider::SetAuth(int tab_handle,
622 const std::wstring& username,
623 const std::wstring& password,
624 IPC::Message* reply_message) {
625 if (tab_tracker_->ContainsHandle(tab_handle)) {
626 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
627 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
628
629 if (iter != login_handler_map_.end()) {
630 // If auth is needed again after this, assume login has failed. This is
631 // not strictly correct, because a navigation can require both proxy and
632 // server auth, but it should be OK for now.
633 LoginHandler* handler = iter->second;
634 new NavigationNotificationObserver(
635 tab, this, reply_message, 1, false, false);
636 handler->SetAuth(WideToUTF16Hack(username), WideToUTF16Hack(password));
637 return;
638 }
639 }
640
641 AutomationMsg_SetAuth::WriteReplyParams(
642 reply_message, AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
643 Send(reply_message);
644 }
645
CancelAuth(int tab_handle,IPC::Message * reply_message)646 void TestingAutomationProvider::CancelAuth(int tab_handle,
647 IPC::Message* reply_message) {
648 if (tab_tracker_->ContainsHandle(tab_handle)) {
649 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
650 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
651
652 if (iter != login_handler_map_.end()) {
653 // If auth is needed again after this, something is screwy.
654 LoginHandler* handler = iter->second;
655 new NavigationNotificationObserver(
656 tab, this, reply_message, 1, false, false);
657 handler->CancelAuth();
658 return;
659 }
660 }
661
662 AutomationMsg_CancelAuth::WriteReplyParams(
663 reply_message, AUTOMATION_MSG_NAVIGATION_AUTH_NEEDED);
664 Send(reply_message);
665 }
666
NeedsAuth(int tab_handle,bool * needs_auth)667 void TestingAutomationProvider::NeedsAuth(int tab_handle, bool* needs_auth) {
668 *needs_auth = false;
669
670 if (tab_tracker_->ContainsHandle(tab_handle)) {
671 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
672 LoginHandlerMap::iterator iter = login_handler_map_.find(tab);
673
674 if (iter != login_handler_map_.end()) {
675 // The LoginHandler will be in our map IFF the tab needs auth.
676 *needs_auth = true;
677 }
678 }
679 }
680
GetRedirectsFrom(int tab_handle,const GURL & source_url,IPC::Message * reply_message)681 void TestingAutomationProvider::GetRedirectsFrom(int tab_handle,
682 const GURL& source_url,
683 IPC::Message* reply_message) {
684 if (redirect_query_) {
685 LOG(ERROR) << "Can only handle one redirect query at once.";
686 } else if (tab_tracker_->ContainsHandle(tab_handle)) {
687 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
688 HistoryService* history_service =
689 tab->profile()->GetHistoryService(Profile::EXPLICIT_ACCESS);
690
691 DCHECK(history_service) << "Tab " << tab_handle << "'s profile " <<
692 "has no history service";
693 if (history_service) {
694 DCHECK(!reply_message_);
695 reply_message_ = reply_message;
696 // Schedule a history query for redirects. The response will be sent
697 // asynchronously from the callback the history system uses to notify us
698 // that it's done: OnRedirectQueryComplete.
699 redirect_query_ = history_service->QueryRedirectsFrom(
700 source_url, &consumer_,
701 NewCallback(this,
702 &TestingAutomationProvider::OnRedirectQueryComplete));
703 return; // Response will be sent when query completes.
704 }
705 }
706
707 // Send failure response.
708 std::vector<GURL> empty;
709 AutomationMsg_RedirectsFrom::WriteReplyParams(reply_message, false, empty);
710 Send(reply_message);
711 }
712
GetBrowserWindowCount(int * window_count)713 void TestingAutomationProvider::GetBrowserWindowCount(int* window_count) {
714 *window_count = static_cast<int>(BrowserList::size());
715 }
716
GetNormalBrowserWindowCount(int * window_count)717 void TestingAutomationProvider::GetNormalBrowserWindowCount(int* window_count) {
718 *window_count = static_cast<int>(
719 BrowserList::GetBrowserCountForType(profile_, Browser::TYPE_NORMAL));
720 }
721
GetBrowserWindow(int index,int * handle)722 void TestingAutomationProvider::GetBrowserWindow(int index, int* handle) {
723 *handle = 0;
724 Browser* browser = automation_util::GetBrowserAt(index);
725 if (browser)
726 *handle = browser_tracker_->Add(browser);
727 }
728
FindNormalBrowserWindow(int * handle)729 void TestingAutomationProvider::FindNormalBrowserWindow(int* handle) {
730 *handle = 0;
731 Browser* browser = BrowserList::FindBrowserWithType(profile_,
732 Browser::TYPE_NORMAL,
733 false);
734 if (browser)
735 *handle = browser_tracker_->Add(browser);
736 }
737
GetLastActiveBrowserWindow(int * handle)738 void TestingAutomationProvider::GetLastActiveBrowserWindow(int* handle) {
739 *handle = 0;
740 Browser* browser = BrowserList::GetLastActive();
741 if (browser)
742 *handle = browser_tracker_->Add(browser);
743 }
744
GetActiveWindow(int * handle)745 void TestingAutomationProvider::GetActiveWindow(int* handle) {
746 *handle = 0;
747 Browser* browser = BrowserList::GetLastActive();
748 if (browser) {
749 gfx::NativeWindow window = browser->window()->GetNativeHandle();
750 *handle = window_tracker_->Add(window);
751 }
752 }
753
ExecuteBrowserCommandAsync(int handle,int command,bool * success)754 void TestingAutomationProvider::ExecuteBrowserCommandAsync(int handle,
755 int command,
756 bool* success) {
757 *success = false;
758 if (browser_tracker_->ContainsHandle(handle)) {
759 Browser* browser = browser_tracker_->GetResource(handle);
760 if (browser->command_updater()->SupportsCommand(command) &&
761 browser->command_updater()->IsCommandEnabled(command)) {
762 browser->ExecuteCommand(command);
763 *success = true;
764 }
765 }
766 }
767
ExecuteBrowserCommand(int handle,int command,IPC::Message * reply_message)768 void TestingAutomationProvider::ExecuteBrowserCommand(
769 int handle, int command, IPC::Message* reply_message) {
770 // List of commands which just finish synchronously and don't require
771 // setting up an observer.
772 static const int kSynchronousCommands[] = {
773 IDC_HOME,
774 IDC_SELECT_NEXT_TAB,
775 IDC_SELECT_PREVIOUS_TAB,
776 IDC_SHOW_BOOKMARK_MANAGER,
777 };
778 if (browser_tracker_->ContainsHandle(handle)) {
779 Browser* browser = browser_tracker_->GetResource(handle);
780 if (browser->command_updater()->SupportsCommand(command) &&
781 browser->command_updater()->IsCommandEnabled(command)) {
782 // First check if we can handle the command without using an observer.
783 for (size_t i = 0; i < arraysize(kSynchronousCommands); i++) {
784 if (command == kSynchronousCommands[i]) {
785 browser->ExecuteCommand(command);
786 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message,
787 true);
788 Send(reply_message);
789 return;
790 }
791 }
792
793 // Use an observer if we have one, otherwise fail.
794 if (ExecuteBrowserCommandObserver::CreateAndRegisterObserver(
795 this, browser, command, reply_message)) {
796 browser->ExecuteCommand(command);
797 return;
798 }
799 }
800 }
801 AutomationMsg_WindowExecuteCommand::WriteReplyParams(reply_message, false);
802 Send(reply_message);
803 }
804
GetBrowserLocale(string16 * locale)805 void TestingAutomationProvider::GetBrowserLocale(string16* locale) {
806 *locale = ASCIIToUTF16(g_browser_process->GetApplicationLocale());
807 }
808
IsWindowActive(int handle,bool * success,bool * is_active)809 void TestingAutomationProvider::IsWindowActive(int handle,
810 bool* success,
811 bool* is_active) {
812 if (window_tracker_->ContainsHandle(handle)) {
813 *is_active =
814 platform_util::IsWindowActive(window_tracker_->GetResource(handle));
815 *success = true;
816 } else {
817 *success = false;
818 *is_active = false;
819 }
820 }
821
WindowSimulateClick(const IPC::Message & message,int handle,const gfx::Point & click,int flags)822 void TestingAutomationProvider::WindowSimulateClick(const IPC::Message& message,
823 int handle,
824 const gfx::Point& click,
825 int flags) {
826 if (window_tracker_->ContainsHandle(handle)) {
827 // TODO(phajdan.jr): This is flaky. We should wait for the final click.
828 ui_controls::SendMouseMoveNotifyWhenDone(
829 click.x(), click.y(), NewRunnableFunction(&SendMouseClick, flags));
830 }
831 }
832
WindowSimulateMouseMove(const IPC::Message & message,int handle,const gfx::Point & location)833 void TestingAutomationProvider::WindowSimulateMouseMove(
834 const IPC::Message& message,
835 int handle,
836 const gfx::Point& location) {
837 if (window_tracker_->ContainsHandle(handle))
838 ui_controls::SendMouseMove(location.x(), location.y());
839 }
840
WindowSimulateKeyPress(const IPC::Message & message,int handle,int key,int flags)841 void TestingAutomationProvider::WindowSimulateKeyPress(
842 const IPC::Message& message,
843 int handle,
844 int key,
845 int flags) {
846 if (!window_tracker_->ContainsHandle(handle))
847 return;
848
849 gfx::NativeWindow window = window_tracker_->GetResource(handle);
850 // The key event is sent to whatever window is active.
851 ui_controls::SendKeyPress(window, static_cast<ui::KeyboardCode>(key),
852 ((flags & ui::EF_CONTROL_DOWN) ==
853 ui::EF_CONTROL_DOWN),
854 ((flags & ui::EF_SHIFT_DOWN) ==
855 ui::EF_SHIFT_DOWN),
856 ((flags & ui::EF_ALT_DOWN) ==
857 ui::EF_ALT_DOWN),
858 ((flags & ui::EF_COMMAND_DOWN) ==
859 ui::EF_COMMAND_DOWN));
860 }
861
WebkitMouseClick(DictionaryValue * args,IPC::Message * reply_message)862 void TestingAutomationProvider::WebkitMouseClick(DictionaryValue* args,
863 IPC::Message* reply_message) {
864 TabContents* tab_contents;
865 std::string error;
866 if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
867 AutomationJSONReply(this, reply_message).SendError(error);
868 return;
869 }
870
871 WebKit::WebMouseEvent mouse_event;
872 if (!args->GetInteger("x", &mouse_event.x) ||
873 !args->GetInteger("y", &mouse_event.y)) {
874 AutomationJSONReply(this, reply_message)
875 .SendError("(X,Y) coordinates missing or invalid");
876 return;
877 }
878
879 int button;
880 if (!args->GetInteger("button", &button)) {
881 AutomationJSONReply(this, reply_message)
882 .SendError("Mouse button missing or invalid");
883 return;
884 }
885 if (button == automation::kLeftButton) {
886 mouse_event.button = WebKit::WebMouseEvent::ButtonLeft;
887 } else if (button == automation::kRightButton) {
888 mouse_event.button = WebKit::WebMouseEvent::ButtonRight;
889 } else if (button == automation::kMiddleButton) {
890 mouse_event.button = WebKit::WebMouseEvent::ButtonMiddle;
891 } else {
892 AutomationJSONReply(this, reply_message)
893 .SendError("Invalid button press requested");
894 return;
895 }
896
897 mouse_event.type = WebKit::WebInputEvent::MouseDown;
898 mouse_event.clickCount = 1;
899
900 tab_contents->render_view_host()->ForwardMouseEvent(mouse_event);
901
902 mouse_event.type = WebKit::WebInputEvent::MouseUp;
903 new InputEventAckNotificationObserver(this, reply_message, mouse_event.type);
904 tab_contents->render_view_host()->ForwardMouseEvent(mouse_event);
905 }
906
WebkitMouseMove(DictionaryValue * args,IPC::Message * reply_message)907 void TestingAutomationProvider::WebkitMouseMove(
908 DictionaryValue* args, IPC::Message* reply_message) {
909 TabContents* tab_contents;
910 std::string error;
911 if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
912 AutomationJSONReply(this, reply_message).SendError(error);
913 return;
914 }
915
916 WebKit::WebMouseEvent mouse_event;
917 if (!args->GetInteger("x", &mouse_event.x) ||
918 !args->GetInteger("y", &mouse_event.y)) {
919 AutomationJSONReply(this, reply_message)
920 .SendError("(X,Y) coordinates missing or invalid");
921 return;
922 }
923
924 mouse_event.type = WebKit::WebInputEvent::MouseMove;
925 new InputEventAckNotificationObserver(this, reply_message, mouse_event.type);
926 tab_contents->render_view_host()->ForwardMouseEvent(mouse_event);
927 }
928
WebkitMouseDrag(DictionaryValue * args,IPC::Message * reply_message)929 void TestingAutomationProvider::WebkitMouseDrag(DictionaryValue* args,
930 IPC::Message* reply_message) {
931 TabContents* tab_contents;
932 std::string error;
933 if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
934 AutomationJSONReply(this, reply_message).SendError(error);
935 return;
936 }
937
938 WebKit::WebMouseEvent mouse_event;
939 int start_x, start_y, end_x, end_y;
940 if (!args->GetInteger("start_x", &start_x) ||
941 !args->GetInteger("start_y", &start_y) ||
942 !args->GetInteger("end_x", &end_x) ||
943 !args->GetInteger("end_y", &end_y)) {
944 AutomationJSONReply(this, reply_message)
945 .SendError("Invalid start/end positions");
946 return;
947 }
948
949 mouse_event.type = WebKit::WebInputEvent::MouseMove;
950 // Step 1- Move the mouse to the start position.
951 mouse_event.x = start_x;
952 mouse_event.y = start_y;
953 tab_contents->render_view_host()->ForwardMouseEvent(mouse_event);
954
955 // Step 2- Left click mouse down, the mouse button is fixed.
956 mouse_event.type = WebKit::WebInputEvent::MouseDown;
957 mouse_event.button = WebKit::WebMouseEvent::ButtonLeft;
958 mouse_event.clickCount = 1;
959 tab_contents->render_view_host()->ForwardMouseEvent(mouse_event);
960
961 // Step 3 - Move the mouse to the end position.
962 // TODO(JMikhail): See if we should simulate the by not making such
963 // a drastic jump by placing incrmental stops along the way.
964 mouse_event.type = WebKit::WebInputEvent::MouseMove;
965 mouse_event.x = end_x;
966 mouse_event.y = end_y;
967 mouse_event.clickCount = 0;
968 tab_contents->render_view_host()->ForwardMouseEvent(mouse_event);
969
970 // Step 4 - Release the left mouse button.
971 mouse_event.type = WebKit::WebInputEvent::MouseUp;
972 mouse_event.clickCount = 1;
973 new InputEventAckNotificationObserver(this, reply_message, mouse_event.type);
974 tab_contents->render_view_host()->ForwardMouseEvent(mouse_event);
975 }
976
GetTabCount(int handle,int * tab_count)977 void TestingAutomationProvider::GetTabCount(int handle, int* tab_count) {
978 *tab_count = -1; // -1 is the error code
979
980 if (browser_tracker_->ContainsHandle(handle)) {
981 Browser* browser = browser_tracker_->GetResource(handle);
982 *tab_count = browser->tab_count();
983 }
984 }
985
GetType(int handle,int * type_as_int)986 void TestingAutomationProvider::GetType(int handle, int* type_as_int) {
987 *type_as_int = -1; // -1 is the error code
988
989 if (browser_tracker_->ContainsHandle(handle)) {
990 Browser* browser = browser_tracker_->GetResource(handle);
991 *type_as_int = static_cast<int>(browser->type());
992 }
993 }
994
GetTab(int win_handle,int tab_index,int * tab_handle)995 void TestingAutomationProvider::GetTab(int win_handle,
996 int tab_index,
997 int* tab_handle) {
998 *tab_handle = 0;
999 if (browser_tracker_->ContainsHandle(win_handle) && (tab_index >= 0)) {
1000 Browser* browser = browser_tracker_->GetResource(win_handle);
1001 if (tab_index < browser->tab_count()) {
1002 TabContents* tab_contents = browser->GetTabContentsAt(tab_index);
1003 *tab_handle = tab_tracker_->Add(&tab_contents->controller());
1004 }
1005 }
1006 }
1007
GetTabProcessID(int handle,int * process_id)1008 void TestingAutomationProvider::GetTabProcessID(int handle, int* process_id) {
1009 *process_id = -1;
1010
1011 if (tab_tracker_->ContainsHandle(handle)) {
1012 *process_id = 0;
1013 TabContents* tab_contents =
1014 tab_tracker_->GetResource(handle)->tab_contents();
1015 RenderProcessHost* rph = tab_contents->GetRenderProcessHost();
1016 if (rph)
1017 *process_id = base::GetProcId(rph->GetHandle());
1018 }
1019 }
1020
GetTabTitle(int handle,int * title_string_size,std::wstring * title)1021 void TestingAutomationProvider::GetTabTitle(int handle,
1022 int* title_string_size,
1023 std::wstring* title) {
1024 *title_string_size = -1; // -1 is the error code
1025 if (tab_tracker_->ContainsHandle(handle)) {
1026 NavigationController* tab = tab_tracker_->GetResource(handle);
1027 NavigationEntry* entry = tab->GetActiveEntry();
1028 if (entry != NULL) {
1029 *title = UTF16ToWideHack(entry->GetTitleForDisplay(""));
1030 } else {
1031 *title = std::wstring();
1032 }
1033 *title_string_size = static_cast<int>(title->size());
1034 }
1035 }
1036
GetTabIndex(int handle,int * tabstrip_index)1037 void TestingAutomationProvider::GetTabIndex(int handle, int* tabstrip_index) {
1038 *tabstrip_index = -1; // -1 is the error code
1039
1040 if (tab_tracker_->ContainsHandle(handle)) {
1041 NavigationController* tab = tab_tracker_->GetResource(handle);
1042 Browser* browser = Browser::GetBrowserForController(tab, NULL);
1043 *tabstrip_index = browser->tabstrip_model()->GetIndexOfController(tab);
1044 }
1045 }
1046
GetTabURL(int handle,bool * success,GURL * url)1047 void TestingAutomationProvider::GetTabURL(int handle,
1048 bool* success,
1049 GURL* url) {
1050 *success = false;
1051 if (tab_tracker_->ContainsHandle(handle)) {
1052 NavigationController* tab = tab_tracker_->GetResource(handle);
1053 // Return what the user would see in the location bar.
1054 *url = tab->GetActiveEntry()->virtual_url();
1055 *success = true;
1056 }
1057 }
1058
GetShelfVisibility(int handle,bool * visible)1059 void TestingAutomationProvider::GetShelfVisibility(int handle, bool* visible) {
1060 *visible = false;
1061
1062 if (browser_tracker_->ContainsHandle(handle)) {
1063 Browser* browser = browser_tracker_->GetResource(handle);
1064 if (browser) {
1065 #if defined(OS_CHROMEOS)
1066 *visible = ActiveDownloadsUI::GetPopup(browser->profile());
1067 #else
1068 *visible = browser->window()->IsDownloadShelfVisible();
1069 #endif
1070 }
1071 }
1072 }
1073
IsFullscreen(int handle,bool * visible)1074 void TestingAutomationProvider::IsFullscreen(int handle, bool* visible) {
1075 *visible = false;
1076
1077 if (browser_tracker_->ContainsHandle(handle)) {
1078 Browser* browser = browser_tracker_->GetResource(handle);
1079 if (browser)
1080 *visible = browser->window()->IsFullscreen();
1081 }
1082 }
1083
GetFullscreenBubbleVisibility(int handle,bool * visible)1084 void TestingAutomationProvider::GetFullscreenBubbleVisibility(int handle,
1085 bool* visible) {
1086 *visible = false;
1087
1088 if (browser_tracker_->ContainsHandle(handle)) {
1089 Browser* browser = browser_tracker_->GetResource(handle);
1090 if (browser)
1091 *visible = browser->window()->IsFullscreenBubbleVisible();
1092 }
1093 }
1094
GetAutocompleteEditText(int autocomplete_edit_handle,bool * success,string16 * text)1095 void TestingAutomationProvider::GetAutocompleteEditText(
1096 int autocomplete_edit_handle,
1097 bool* success,
1098 string16* text) {
1099 *success = false;
1100 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
1101 *text = autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
1102 GetText();
1103 *success = true;
1104 }
1105 }
1106
SetAutocompleteEditText(int autocomplete_edit_handle,const string16 & text,bool * success)1107 void TestingAutomationProvider::SetAutocompleteEditText(
1108 int autocomplete_edit_handle,
1109 const string16& text,
1110 bool* success) {
1111 *success = false;
1112 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
1113 autocomplete_edit_tracker_->GetResource(autocomplete_edit_handle)->
1114 SetUserText(text);
1115 *success = true;
1116 }
1117 }
1118
AutocompleteEditGetMatches(int autocomplete_edit_handle,bool * success,std::vector<AutocompleteMatchData> * matches)1119 void TestingAutomationProvider::AutocompleteEditGetMatches(
1120 int autocomplete_edit_handle,
1121 bool* success,
1122 std::vector<AutocompleteMatchData>* matches) {
1123 *success = false;
1124 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
1125 const AutocompleteResult& result = autocomplete_edit_tracker_->
1126 GetResource(autocomplete_edit_handle)->model()->result();
1127 for (AutocompleteResult::const_iterator i = result.begin();
1128 i != result.end(); ++i)
1129 matches->push_back(AutocompleteMatchData(*i));
1130 *success = true;
1131 }
1132 }
1133
1134 // Waits for the autocomplete edit to receive focus
WaitForAutocompleteEditFocus(int autocomplete_edit_handle,IPC::Message * reply_message)1135 void TestingAutomationProvider::WaitForAutocompleteEditFocus(
1136 int autocomplete_edit_handle,
1137 IPC::Message* reply_message) {
1138 if (!autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
1139 AutomationMsg_WaitForAutocompleteEditFocus::WriteReplyParams(
1140 reply_message_, false);
1141 Send(reply_message);
1142 return;
1143 }
1144
1145 AutocompleteEditModel* model = autocomplete_edit_tracker_->
1146 GetResource(autocomplete_edit_handle)-> model();
1147 if (model->has_focus()) {
1148 AutomationMsg_WaitForAutocompleteEditFocus::WriteReplyParams(
1149 reply_message, true);
1150 Send(reply_message);
1151 return;
1152 }
1153
1154 // The observer deletes itself when the notification arrives.
1155 new AutocompleteEditFocusedObserver(this, model, reply_message);
1156 }
1157
GetAutocompleteEditForBrowser(int browser_handle,bool * success,int * autocomplete_edit_handle)1158 void TestingAutomationProvider::GetAutocompleteEditForBrowser(
1159 int browser_handle,
1160 bool* success,
1161 int* autocomplete_edit_handle) {
1162 *success = false;
1163 *autocomplete_edit_handle = 0;
1164
1165 if (browser_tracker_->ContainsHandle(browser_handle)) {
1166 Browser* browser = browser_tracker_->GetResource(browser_handle);
1167 LocationBar* loc_bar = browser->window()->GetLocationBar();
1168 AutocompleteEditView* edit_view = loc_bar->location_entry();
1169 // Add() returns the existing handle for the resource if any.
1170 *autocomplete_edit_handle = autocomplete_edit_tracker_->Add(edit_view);
1171 *success = true;
1172 }
1173 }
1174
AutocompleteEditIsQueryInProgress(int autocomplete_edit_handle,bool * success,bool * query_in_progress)1175 void TestingAutomationProvider::AutocompleteEditIsQueryInProgress(
1176 int autocomplete_edit_handle,
1177 bool* success,
1178 bool* query_in_progress) {
1179 *success = false;
1180 *query_in_progress = false;
1181 if (autocomplete_edit_tracker_->ContainsHandle(autocomplete_edit_handle)) {
1182 *query_in_progress = !autocomplete_edit_tracker_->
1183 GetResource(autocomplete_edit_handle)->model()->
1184 autocomplete_controller()->done();
1185 *success = true;
1186 }
1187 }
1188
ExecuteJavascript(int handle,const std::wstring & frame_xpath,const std::wstring & script,IPC::Message * reply_message)1189 void TestingAutomationProvider::ExecuteJavascript(
1190 int handle,
1191 const std::wstring& frame_xpath,
1192 const std::wstring& script,
1193 IPC::Message* reply_message) {
1194 TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
1195 if (!tab_contents) {
1196 AutomationMsg_DomOperation::WriteReplyParams(reply_message, std::string());
1197 Send(reply_message);
1198 return;
1199 }
1200
1201 // Set the routing id of this message with the controller.
1202 // This routing id needs to be remembered for the reverse
1203 // communication while sending back the response of
1204 // this javascript execution.
1205 std::string set_automation_id;
1206 base::SStringPrintf(&set_automation_id,
1207 "window.domAutomationController.setAutomationId(%d);",
1208 reply_message->routing_id());
1209
1210 new DomOperationMessageSender(this, reply_message, false);
1211 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
1212 WideToUTF16Hack(frame_xpath), UTF8ToUTF16(set_automation_id));
1213 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
1214 WideToUTF16Hack(frame_xpath), WideToUTF16Hack(script));
1215 }
1216
GetConstrainedWindowCount(int handle,int * count)1217 void TestingAutomationProvider::GetConstrainedWindowCount(int handle,
1218 int* count) {
1219 *count = -1; // -1 is the error code
1220 if (tab_tracker_->ContainsHandle(handle)) {
1221 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
1222 TabContents* tab_contents = nav_controller->tab_contents();
1223 if (tab_contents)
1224 *count = static_cast<int>(tab_contents->child_windows_.size());
1225 }
1226 }
1227
HandleInspectElementRequest(int handle,int x,int y,IPC::Message * reply_message)1228 void TestingAutomationProvider::HandleInspectElementRequest(
1229 int handle, int x, int y, IPC::Message* reply_message) {
1230 TabContents* tab_contents = GetTabContentsForHandle(handle, NULL);
1231 if (tab_contents) {
1232 DCHECK(!reply_message_);
1233 reply_message_ = reply_message;
1234
1235 DevToolsManager::GetInstance()->InspectElement(
1236 tab_contents->render_view_host(), x, y);
1237 } else {
1238 AutomationMsg_InspectElement::WriteReplyParams(reply_message, -1);
1239 Send(reply_message);
1240 }
1241 }
1242
GetDownloadDirectory(int handle,FilePath * download_directory)1243 void TestingAutomationProvider::GetDownloadDirectory(
1244 int handle, FilePath* download_directory) {
1245 if (tab_tracker_->ContainsHandle(handle)) {
1246 NavigationController* tab = tab_tracker_->GetResource(handle);
1247 DownloadManager* dlm = tab->profile()->GetDownloadManager();
1248 *download_directory = dlm->download_prefs()->download_path();
1249 }
1250 }
1251
OpenNewBrowserWindowOfType(int type,bool show,IPC::Message * reply_message)1252 void TestingAutomationProvider::OpenNewBrowserWindowOfType(
1253 int type, bool show, IPC::Message* reply_message) {
1254 new BrowserOpenedNotificationObserver(this, reply_message);
1255 // We may have no current browser windows open so don't rely on
1256 // asking an existing browser to execute the IDC_NEWWINDOW command
1257 Browser* browser = new Browser(static_cast<Browser::Type>(type), profile_);
1258 browser->InitBrowserWindow();
1259 browser->AddBlankTab(true);
1260 if (show)
1261 browser->window()->Show();
1262 }
1263
GetWindowForBrowser(int browser_handle,bool * success,int * handle)1264 void TestingAutomationProvider::GetWindowForBrowser(int browser_handle,
1265 bool* success,
1266 int* handle) {
1267 *success = false;
1268 *handle = 0;
1269
1270 if (browser_tracker_->ContainsHandle(browser_handle)) {
1271 Browser* browser = browser_tracker_->GetResource(browser_handle);
1272 gfx::NativeWindow win = browser->window()->GetNativeHandle();
1273 // Add() returns the existing handle for the resource if any.
1274 *handle = window_tracker_->Add(win);
1275 *success = true;
1276 }
1277 }
1278
GetBrowserForWindow(int window_handle,bool * success,int * browser_handle)1279 void TestingAutomationProvider::GetBrowserForWindow(int window_handle,
1280 bool* success,
1281 int* browser_handle) {
1282 *success = false;
1283 *browser_handle = 0;
1284
1285 gfx::NativeWindow window = window_tracker_->GetResource(window_handle);
1286 if (!window)
1287 return;
1288
1289 BrowserList::const_iterator iter = BrowserList::begin();
1290 for (;iter != BrowserList::end(); ++iter) {
1291 gfx::NativeWindow this_window = (*iter)->window()->GetNativeHandle();
1292 if (window == this_window) {
1293 // Add() returns the existing handle for the resource if any.
1294 *browser_handle = browser_tracker_->Add(*iter);
1295 *success = true;
1296 return;
1297 }
1298 }
1299 }
1300
ShowInterstitialPage(int tab_handle,const std::string & html_text,IPC::Message * reply_message)1301 void TestingAutomationProvider::ShowInterstitialPage(
1302 int tab_handle,
1303 const std::string& html_text,
1304 IPC::Message* reply_message) {
1305 if (tab_tracker_->ContainsHandle(tab_handle)) {
1306 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
1307 TabContents* tab_contents = controller->tab_contents();
1308
1309 new NavigationNotificationObserver(controller, this, reply_message, 1,
1310 false, false);
1311
1312 AutomationInterstitialPage* interstitial =
1313 new AutomationInterstitialPage(tab_contents,
1314 GURL("about:interstitial"),
1315 html_text);
1316 interstitial->Show();
1317 return;
1318 }
1319
1320 AutomationMsg_ShowInterstitialPage::WriteReplyParams(
1321 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
1322 Send(reply_message);
1323 }
1324
HideInterstitialPage(int tab_handle,bool * success)1325 void TestingAutomationProvider::HideInterstitialPage(int tab_handle,
1326 bool* success) {
1327 *success = false;
1328 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, NULL);
1329 if (tab_contents && tab_contents->interstitial_page()) {
1330 tab_contents->interstitial_page()->DontProceed();
1331 *success = true;
1332 }
1333 }
1334
WaitForTabToBeRestored(int tab_handle,IPC::Message * reply_message)1335 void TestingAutomationProvider::WaitForTabToBeRestored(
1336 int tab_handle,
1337 IPC::Message* reply_message) {
1338 if (tab_tracker_->ContainsHandle(tab_handle)) {
1339 NavigationController* tab = tab_tracker_->GetResource(tab_handle);
1340 restore_tracker_.reset(
1341 new NavigationControllerRestoredObserver(this, tab, reply_message));
1342 } else {
1343 AutomationMsg_WaitForTabToBeRestored::WriteReplyParams(
1344 reply_message, false);
1345 Send(reply_message);
1346 }
1347 }
1348
GetSecurityState(int handle,bool * success,SecurityStyle * security_style,int * ssl_cert_status,int * insecure_content_status)1349 void TestingAutomationProvider::GetSecurityState(int handle,
1350 bool* success,
1351 SecurityStyle* security_style,
1352 int* ssl_cert_status,
1353 int* insecure_content_status) {
1354 if (tab_tracker_->ContainsHandle(handle)) {
1355 NavigationController* tab = tab_tracker_->GetResource(handle);
1356 NavigationEntry* entry = tab->GetActiveEntry();
1357 *success = true;
1358 *security_style = entry->ssl().security_style();
1359 *ssl_cert_status = entry->ssl().cert_status();
1360 *insecure_content_status = entry->ssl().content_status();
1361 } else {
1362 *success = false;
1363 *security_style = SECURITY_STYLE_UNKNOWN;
1364 *ssl_cert_status = 0;
1365 *insecure_content_status = 0;
1366 }
1367 }
1368
GetPageType(int handle,bool * success,PageType * page_type)1369 void TestingAutomationProvider::GetPageType(
1370 int handle,
1371 bool* success,
1372 PageType* page_type) {
1373 if (tab_tracker_->ContainsHandle(handle)) {
1374 NavigationController* tab = tab_tracker_->GetResource(handle);
1375 NavigationEntry* entry = tab->GetActiveEntry();
1376 *page_type = entry->page_type();
1377 *success = true;
1378 // In order to return the proper result when an interstitial is shown and
1379 // no navigation entry were created for it we need to ask the TabContents.
1380 if (*page_type == NORMAL_PAGE &&
1381 tab->tab_contents()->showing_interstitial_page())
1382 *page_type = INTERSTITIAL_PAGE;
1383 } else {
1384 *success = false;
1385 *page_type = NORMAL_PAGE;
1386 }
1387 }
1388
GetMetricEventDuration(const std::string & event_name,int * duration_ms)1389 void TestingAutomationProvider::GetMetricEventDuration(
1390 const std::string& event_name,
1391 int* duration_ms) {
1392 *duration_ms = metric_event_duration_observer_->GetEventDurationMs(
1393 event_name);
1394 }
1395
ActionOnSSLBlockingPage(int handle,bool proceed,IPC::Message * reply_message)1396 void TestingAutomationProvider::ActionOnSSLBlockingPage(
1397 int handle,
1398 bool proceed,
1399 IPC::Message* reply_message) {
1400 if (tab_tracker_->ContainsHandle(handle)) {
1401 NavigationController* tab = tab_tracker_->GetResource(handle);
1402 NavigationEntry* entry = tab->GetActiveEntry();
1403 if (entry->page_type() == INTERSTITIAL_PAGE) {
1404 TabContents* tab_contents = tab->tab_contents();
1405 InterstitialPage* ssl_blocking_page =
1406 InterstitialPage::GetInterstitialPage(tab_contents);
1407 if (ssl_blocking_page) {
1408 if (proceed) {
1409 new NavigationNotificationObserver(tab, this, reply_message, 1,
1410 false, false);
1411 ssl_blocking_page->Proceed();
1412 return;
1413 }
1414 ssl_blocking_page->DontProceed();
1415 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(
1416 reply_message, AUTOMATION_MSG_NAVIGATION_SUCCESS);
1417 Send(reply_message);
1418 return;
1419 }
1420 }
1421 }
1422 // We failed.
1423 AutomationMsg_ActionOnSSLBlockingPage::WriteReplyParams(
1424 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
1425 Send(reply_message);
1426 }
1427
BringBrowserToFront(int browser_handle,bool * success)1428 void TestingAutomationProvider::BringBrowserToFront(int browser_handle,
1429 bool* success) {
1430 *success = false;
1431 if (browser_tracker_->ContainsHandle(browser_handle)) {
1432 Browser* browser = browser_tracker_->GetResource(browser_handle);
1433 browser->window()->Activate();
1434 *success = true;
1435 }
1436 }
1437
IsMenuCommandEnabled(int browser_handle,int message_num,bool * menu_item_enabled)1438 void TestingAutomationProvider::IsMenuCommandEnabled(int browser_handle,
1439 int message_num,
1440 bool* menu_item_enabled) {
1441 *menu_item_enabled = false;
1442 if (browser_tracker_->ContainsHandle(browser_handle)) {
1443 Browser* browser = browser_tracker_->GetResource(browser_handle);
1444 *menu_item_enabled =
1445 browser->command_updater()->IsCommandEnabled(message_num);
1446 }
1447 }
1448
PrintNow(int tab_handle,IPC::Message * reply_message)1449 void TestingAutomationProvider::PrintNow(int tab_handle,
1450 IPC::Message* reply_message) {
1451 NavigationController* tab = NULL;
1452 TabContents* tab_contents = GetTabContentsForHandle(tab_handle, &tab);
1453 if (tab_contents) {
1454 FindAndActivateTab(tab);
1455
1456 NotificationObserver* observer =
1457 new DocumentPrintedNotificationObserver(this, reply_message);
1458
1459 TabContentsWrapper* wrapper =
1460 TabContentsWrapper::GetCurrentWrapperForContents(tab_contents);
1461 if (!wrapper->print_view_manager()->PrintNow()) {
1462 // Clean up the observer. It will send the reply message.
1463 delete observer;
1464 }
1465
1466 // Return now to avoid sending reply message twice.
1467 return;
1468 }
1469
1470 AutomationMsg_PrintNow::WriteReplyParams(reply_message, false);
1471 Send(reply_message);
1472 }
1473
SavePage(int tab_handle,const FilePath & file_name,const FilePath & dir_path,int type,bool * success)1474 void TestingAutomationProvider::SavePage(int tab_handle,
1475 const FilePath& file_name,
1476 const FilePath& dir_path,
1477 int type,
1478 bool* success) {
1479 SavePackage::SavePackageType save_type =
1480 static_cast<SavePackage::SavePackageType>(type);
1481 if (save_type < SavePackage::SAVE_AS_ONLY_HTML ||
1482 save_type > SavePackage::SAVE_AS_COMPLETE_HTML) {
1483 *success = false;
1484 return;
1485 }
1486
1487 if (!tab_tracker_->ContainsHandle(tab_handle)) {
1488 *success = false;
1489 return;
1490 }
1491
1492 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
1493 Browser* browser = FindAndActivateTab(nav);
1494 if (!browser->command_updater()->IsCommandEnabled(IDC_SAVE_PAGE)) {
1495 *success = false;
1496 return;
1497 }
1498
1499 TabContentsWrapper* wrapper =
1500 TabContentsWrapper::GetCurrentWrapperForContents(nav->tab_contents());
1501 wrapper->download_tab_helper()->SavePage(file_name, dir_path, save_type);
1502 *success = true;
1503 }
1504
HandleOpenFindInPageRequest(const IPC::Message & message,int handle)1505 void TestingAutomationProvider::HandleOpenFindInPageRequest(
1506 const IPC::Message& message, int handle) {
1507 if (browser_tracker_->ContainsHandle(handle)) {
1508 Browser* browser = browser_tracker_->GetResource(handle);
1509 browser->FindInPage(false, false);
1510 }
1511 }
1512
GetFindWindowVisibility(int handle,bool * visible)1513 void TestingAutomationProvider::GetFindWindowVisibility(int handle,
1514 bool* visible) {
1515 *visible = false;
1516 Browser* browser = browser_tracker_->GetResource(handle);
1517 if (browser) {
1518 FindBarTesting* find_bar =
1519 browser->GetFindBarController()->find_bar()->GetFindBarTesting();
1520 find_bar->GetFindBarWindowInfo(NULL, visible);
1521 }
1522 }
1523
HandleFindWindowLocationRequest(int handle,int * x,int * y)1524 void TestingAutomationProvider::HandleFindWindowLocationRequest(int handle,
1525 int* x,
1526 int* y) {
1527 gfx::Point position(0, 0);
1528 bool visible = false;
1529 if (browser_tracker_->ContainsHandle(handle)) {
1530 Browser* browser = browser_tracker_->GetResource(handle);
1531 FindBarTesting* find_bar =
1532 browser->GetFindBarController()->find_bar()->GetFindBarTesting();
1533 find_bar->GetFindBarWindowInfo(&position, &visible);
1534 }
1535
1536 *x = position.x();
1537 *y = position.y();
1538 }
1539
1540 // Bookmark bar visibility is based on the pref (e.g. is it in the toolbar).
1541 // Presence in the NTP is NOT considered visible by this call.
GetBookmarkBarVisibility(int handle,bool * visible,bool * animating)1542 void TestingAutomationProvider::GetBookmarkBarVisibility(int handle,
1543 bool* visible,
1544 bool* animating) {
1545 *visible = false;
1546 *animating = false;
1547
1548 if (browser_tracker_->ContainsHandle(handle)) {
1549 Browser* browser = browser_tracker_->GetResource(handle);
1550 if (browser) {
1551 #if 0 // defined(TOOLKIT_VIEWS) && defined(OS_LINUX)
1552 // TODO(jrg): Was removed in rev43789 for perf. Need to investigate.
1553
1554 // IsBookmarkBarVisible() line looks correct but is not
1555 // consistent across platforms. Specifically, on Mac/Linux, it
1556 // returns false if the bar is hidden in a pref (even if visible
1557 // on the NTP). On ChromeOS, it returned true if on NTP
1558 // independent of the pref. Making the code more consistent
1559 // caused a perf bot regression on Windows (which shares views).
1560 // See http://crbug.com/40225
1561 *visible = browser->profile()->GetPrefs()->GetBoolean(
1562 prefs::kShowBookmarkBar);
1563 #else
1564 *visible = browser->window()->IsBookmarkBarVisible();
1565 #endif
1566 *animating = browser->window()->IsBookmarkBarAnimating();
1567 }
1568 }
1569 }
1570
GetBookmarksAsJSON(int handle,std::string * bookmarks_as_json,bool * success)1571 void TestingAutomationProvider::GetBookmarksAsJSON(
1572 int handle,
1573 std::string* bookmarks_as_json,
1574 bool *success) {
1575 *success = false;
1576 if (browser_tracker_->ContainsHandle(handle)) {
1577 Browser* browser = browser_tracker_->GetResource(handle);
1578 if (browser) {
1579 if (!browser->profile()->GetBookmarkModel()->IsLoaded()) {
1580 return;
1581 }
1582 scoped_refptr<BookmarkStorage> storage(new BookmarkStorage(
1583 browser->profile(),
1584 browser->profile()->GetBookmarkModel()));
1585 *success = storage->SerializeData(bookmarks_as_json);
1586 }
1587 }
1588 }
1589
WaitForBookmarkModelToLoad(int handle,IPC::Message * reply_message)1590 void TestingAutomationProvider::WaitForBookmarkModelToLoad(
1591 int handle,
1592 IPC::Message* reply_message) {
1593 if (browser_tracker_->ContainsHandle(handle)) {
1594 Browser* browser = browser_tracker_->GetResource(handle);
1595 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1596 if (model->IsLoaded()) {
1597 AutomationMsg_WaitForBookmarkModelToLoad::WriteReplyParams(
1598 reply_message, true);
1599 Send(reply_message);
1600 } else {
1601 // The observer will delete itself when done.
1602 new AutomationProviderBookmarkModelObserver(this, reply_message,
1603 model);
1604 }
1605 }
1606 }
1607
AddBookmarkGroup(int handle,int64 parent_id,int index,std::wstring title,bool * success)1608 void TestingAutomationProvider::AddBookmarkGroup(int handle,
1609 int64 parent_id,
1610 int index,
1611 std::wstring title,
1612 bool* success) {
1613 if (browser_tracker_->ContainsHandle(handle)) {
1614 Browser* browser = browser_tracker_->GetResource(handle);
1615 if (browser) {
1616 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1617 if (!model->IsLoaded()) {
1618 *success = false;
1619 return;
1620 }
1621 const BookmarkNode* parent = model->GetNodeByID(parent_id);
1622 DCHECK(parent);
1623 if (parent) {
1624 const BookmarkNode* child = model->AddFolder(parent, index,
1625 WideToUTF16Hack(title));
1626 DCHECK(child);
1627 if (child)
1628 *success = true;
1629 }
1630 }
1631 }
1632 *success = false;
1633 }
1634
AddBookmarkURL(int handle,int64 parent_id,int index,std::wstring title,const GURL & url,bool * success)1635 void TestingAutomationProvider::AddBookmarkURL(int handle,
1636 int64 parent_id,
1637 int index,
1638 std::wstring title,
1639 const GURL& url,
1640 bool* success) {
1641 if (browser_tracker_->ContainsHandle(handle)) {
1642 Browser* browser = browser_tracker_->GetResource(handle);
1643 if (browser) {
1644 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1645 if (!model->IsLoaded()) {
1646 *success = false;
1647 return;
1648 }
1649 const BookmarkNode* parent = model->GetNodeByID(parent_id);
1650 DCHECK(parent);
1651 if (parent) {
1652 const BookmarkNode* child = model->AddURL(parent, index,
1653 WideToUTF16Hack(title), url);
1654 DCHECK(child);
1655 if (child)
1656 *success = true;
1657 }
1658 }
1659 }
1660 *success = false;
1661 }
1662
ReparentBookmark(int handle,int64 id,int64 new_parent_id,int index,bool * success)1663 void TestingAutomationProvider::ReparentBookmark(int handle,
1664 int64 id,
1665 int64 new_parent_id,
1666 int index,
1667 bool* success) {
1668 if (browser_tracker_->ContainsHandle(handle)) {
1669 Browser* browser = browser_tracker_->GetResource(handle);
1670 if (browser) {
1671 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1672 if (!model->IsLoaded()) {
1673 *success = false;
1674 return;
1675 }
1676 const BookmarkNode* node = model->GetNodeByID(id);
1677 DCHECK(node);
1678 const BookmarkNode* new_parent = model->GetNodeByID(new_parent_id);
1679 DCHECK(new_parent);
1680 if (node && new_parent) {
1681 model->Move(node, new_parent, index);
1682 *success = true;
1683 }
1684 }
1685 }
1686 *success = false;
1687 }
1688
SetBookmarkTitle(int handle,int64 id,std::wstring title,bool * success)1689 void TestingAutomationProvider::SetBookmarkTitle(int handle,
1690 int64 id,
1691 std::wstring title,
1692 bool* success) {
1693 if (browser_tracker_->ContainsHandle(handle)) {
1694 Browser* browser = browser_tracker_->GetResource(handle);
1695 if (browser) {
1696 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1697 if (!model->IsLoaded()) {
1698 *success = false;
1699 return;
1700 }
1701 const BookmarkNode* node = model->GetNodeByID(id);
1702 DCHECK(node);
1703 if (node) {
1704 model->SetTitle(node, WideToUTF16Hack(title));
1705 *success = true;
1706 }
1707 }
1708 }
1709 *success = false;
1710 }
1711
SetBookmarkURL(int handle,int64 id,const GURL & url,bool * success)1712 void TestingAutomationProvider::SetBookmarkURL(int handle,
1713 int64 id,
1714 const GURL& url,
1715 bool* success) {
1716 if (browser_tracker_->ContainsHandle(handle)) {
1717 Browser* browser = browser_tracker_->GetResource(handle);
1718 if (browser) {
1719 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1720 if (!model->IsLoaded()) {
1721 *success = false;
1722 return;
1723 }
1724 const BookmarkNode* node = model->GetNodeByID(id);
1725 DCHECK(node);
1726 if (node) {
1727 model->SetURL(node, url);
1728 *success = true;
1729 }
1730 }
1731 }
1732 *success = false;
1733 }
1734
RemoveBookmark(int handle,int64 id,bool * success)1735 void TestingAutomationProvider::RemoveBookmark(int handle,
1736 int64 id,
1737 bool* success) {
1738 if (browser_tracker_->ContainsHandle(handle)) {
1739 Browser* browser = browser_tracker_->GetResource(handle);
1740 if (browser) {
1741 BookmarkModel* model = browser->profile()->GetBookmarkModel();
1742 if (!model->IsLoaded()) {
1743 *success = false;
1744 return;
1745 }
1746 const BookmarkNode* node = model->GetNodeByID(id);
1747 DCHECK(node);
1748 if (node) {
1749 const BookmarkNode* parent = node->parent();
1750 DCHECK(parent);
1751 model->Remove(parent, parent->GetIndexOf(node));
1752 *success = true;
1753 }
1754 }
1755 }
1756 *success = false;
1757 }
1758
GetInfoBarCount(int handle,size_t * count)1759 void TestingAutomationProvider::GetInfoBarCount(int handle, size_t* count) {
1760 *count = static_cast<size_t>(-1); // -1 means error.
1761 if (tab_tracker_->ContainsHandle(handle)) {
1762 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
1763 if (nav_controller)
1764 *count = nav_controller->tab_contents()->infobar_count();
1765 }
1766 }
1767
ClickInfoBarAccept(int handle,size_t info_bar_index,bool wait_for_navigation,IPC::Message * reply_message)1768 void TestingAutomationProvider::ClickInfoBarAccept(
1769 int handle,
1770 size_t info_bar_index,
1771 bool wait_for_navigation,
1772 IPC::Message* reply_message) {
1773 bool success = false;
1774 if (tab_tracker_->ContainsHandle(handle)) {
1775 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
1776 if (nav_controller) {
1777 if (info_bar_index < nav_controller->tab_contents()->infobar_count()) {
1778 if (wait_for_navigation) {
1779 new NavigationNotificationObserver(nav_controller, this,
1780 reply_message, 1, false, false);
1781 }
1782 InfoBarDelegate* delegate =
1783 nav_controller->tab_contents()->GetInfoBarDelegateAt(
1784 info_bar_index);
1785 if (delegate->AsConfirmInfoBarDelegate())
1786 delegate->AsConfirmInfoBarDelegate()->Accept();
1787 success = true;
1788 }
1789 }
1790 }
1791
1792 // This "!wait_for_navigation || !success condition" logic looks suspicious.
1793 // It will send a failure message when success is true but
1794 // |wait_for_navigation| is false.
1795 // TODO(phajdan.jr): investgate whether the reply param (currently
1796 // AUTOMATION_MSG_NAVIGATION_ERROR) should depend on success.
1797 if (!wait_for_navigation || !success)
1798 AutomationMsg_ClickInfoBarAccept::WriteReplyParams(
1799 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
1800 }
1801
GetLastNavigationTime(int handle,int64 * last_navigation_time)1802 void TestingAutomationProvider::GetLastNavigationTime(
1803 int handle,
1804 int64* last_navigation_time) {
1805 base::Time time(tab_tracker_->GetLastNavigationTime(handle));
1806 *last_navigation_time = time.ToInternalValue();
1807 }
1808
WaitForNavigation(int handle,int64 last_navigation_time,IPC::Message * reply_message)1809 void TestingAutomationProvider::WaitForNavigation(int handle,
1810 int64 last_navigation_time,
1811 IPC::Message* reply_message) {
1812 NavigationController* controller = tab_tracker_->GetResource(handle);
1813 base::Time time(tab_tracker_->GetLastNavigationTime(handle));
1814
1815 if (time.ToInternalValue() > last_navigation_time || !controller) {
1816 AutomationMsg_WaitForNavigation::WriteReplyParams(reply_message,
1817 controller == NULL ? AUTOMATION_MSG_NAVIGATION_ERROR :
1818 AUTOMATION_MSG_NAVIGATION_SUCCESS);
1819 Send(reply_message);
1820 return;
1821 }
1822
1823 new NavigationNotificationObserver(
1824 controller, this, reply_message, 1, true, false);
1825 }
1826
SetIntPreference(int handle,const std::string & name,int value,bool * success)1827 void TestingAutomationProvider::SetIntPreference(int handle,
1828 const std::string& name,
1829 int value,
1830 bool* success) {
1831 *success = false;
1832 if (browser_tracker_->ContainsHandle(handle)) {
1833 Browser* browser = browser_tracker_->GetResource(handle);
1834 browser->profile()->GetPrefs()->SetInteger(name.c_str(), value);
1835 *success = true;
1836 }
1837 }
1838
SetStringPreference(int handle,const std::string & name,const std::string & value,bool * success)1839 void TestingAutomationProvider::SetStringPreference(int handle,
1840 const std::string& name,
1841 const std::string& value,
1842 bool* success) {
1843 *success = false;
1844 if (browser_tracker_->ContainsHandle(handle)) {
1845 Browser* browser = browser_tracker_->GetResource(handle);
1846 browser->profile()->GetPrefs()->SetString(name.c_str(), value);
1847 *success = true;
1848 }
1849 }
1850
GetBooleanPreference(int handle,const std::string & name,bool * success,bool * value)1851 void TestingAutomationProvider::GetBooleanPreference(int handle,
1852 const std::string& name,
1853 bool* success,
1854 bool* value) {
1855 *success = false;
1856 *value = false;
1857 if (browser_tracker_->ContainsHandle(handle)) {
1858 Browser* browser = browser_tracker_->GetResource(handle);
1859 *value = browser->profile()->GetPrefs()->GetBoolean(name.c_str());
1860 *success = true;
1861 }
1862 }
1863
SetBooleanPreference(int handle,const std::string & name,bool value,bool * success)1864 void TestingAutomationProvider::SetBooleanPreference(int handle,
1865 const std::string& name,
1866 bool value,
1867 bool* success) {
1868 *success = false;
1869 if (browser_tracker_->ContainsHandle(handle)) {
1870 Browser* browser = browser_tracker_->GetResource(handle);
1871 browser->profile()->GetPrefs()->SetBoolean(name.c_str(), value);
1872 *success = true;
1873 }
1874 }
1875
GetShowingAppModalDialog(bool * showing_dialog,int * dialog_button)1876 void TestingAutomationProvider::GetShowingAppModalDialog(bool* showing_dialog,
1877 int* dialog_button) {
1878 AppModalDialog* active_dialog =
1879 AppModalDialogQueue::GetInstance()->active_dialog();
1880 if (!active_dialog) {
1881 *showing_dialog = false;
1882 *dialog_button = ui::MessageBoxFlags::DIALOGBUTTON_NONE;
1883 return;
1884 }
1885 NativeAppModalDialog* native_dialog = active_dialog->native_dialog();
1886 *showing_dialog = (native_dialog != NULL);
1887 if (*showing_dialog)
1888 *dialog_button = native_dialog->GetAppModalDialogButtons();
1889 else
1890 *dialog_button = ui::MessageBoxFlags::DIALOGBUTTON_NONE;
1891 }
1892
ClickAppModalDialogButton(int button,bool * success)1893 void TestingAutomationProvider::ClickAppModalDialogButton(int button,
1894 bool* success) {
1895 *success = false;
1896
1897 NativeAppModalDialog* native_dialog =
1898 AppModalDialogQueue::GetInstance()->active_dialog()->native_dialog();
1899 if (native_dialog &&
1900 (native_dialog->GetAppModalDialogButtons() & button) == button) {
1901 if ((button & ui::MessageBoxFlags::DIALOGBUTTON_OK) ==
1902 ui::MessageBoxFlags::DIALOGBUTTON_OK) {
1903 native_dialog->AcceptAppModalDialog();
1904 *success = true;
1905 }
1906 if ((button & ui::MessageBoxFlags::DIALOGBUTTON_CANCEL) ==
1907 ui::MessageBoxFlags::DIALOGBUTTON_CANCEL) {
1908 DCHECK(!*success) << "invalid param, OK and CANCEL specified";
1909 native_dialog->CancelAppModalDialog();
1910 *success = true;
1911 }
1912 }
1913 }
1914
WaitForBrowserWindowCountToBecome(int target_count,IPC::Message * reply_message)1915 void TestingAutomationProvider::WaitForBrowserWindowCountToBecome(
1916 int target_count,
1917 IPC::Message* reply_message) {
1918 if (static_cast<int>(BrowserList::size()) == target_count) {
1919 AutomationMsg_WaitForBrowserWindowCountToBecome::WriteReplyParams(
1920 reply_message, true);
1921 Send(reply_message);
1922 return;
1923 }
1924
1925 // Set up an observer (it will delete itself).
1926 new BrowserCountChangeNotificationObserver(target_count, this, reply_message);
1927 }
1928
WaitForAppModalDialogToBeShown(IPC::Message * reply_message)1929 void TestingAutomationProvider::WaitForAppModalDialogToBeShown(
1930 IPC::Message* reply_message) {
1931 if (AppModalDialogQueue::GetInstance()->HasActiveDialog()) {
1932 AutomationMsg_WaitForAppModalDialogToBeShown::WriteReplyParams(
1933 reply_message, true);
1934 Send(reply_message);
1935 return;
1936 }
1937
1938 // Set up an observer (it will delete itself).
1939 new AppModalDialogShownObserver(this, reply_message);
1940 }
1941
GoBackBlockUntilNavigationsComplete(int handle,int number_of_navigations,IPC::Message * reply_message)1942 void TestingAutomationProvider::GoBackBlockUntilNavigationsComplete(
1943 int handle, int number_of_navigations, IPC::Message* reply_message) {
1944 if (tab_tracker_->ContainsHandle(handle)) {
1945 NavigationController* tab = tab_tracker_->GetResource(handle);
1946 Browser* browser = FindAndActivateTab(tab);
1947 if (browser && browser->command_updater()->IsCommandEnabled(IDC_BACK)) {
1948 new NavigationNotificationObserver(tab, this, reply_message,
1949 number_of_navigations, false, false);
1950 browser->GoBack(CURRENT_TAB);
1951 return;
1952 }
1953 }
1954
1955 AutomationMsg_GoBackBlockUntilNavigationsComplete::WriteReplyParams(
1956 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
1957 Send(reply_message);
1958 }
1959
GoForwardBlockUntilNavigationsComplete(int handle,int number_of_navigations,IPC::Message * reply_message)1960 void TestingAutomationProvider::GoForwardBlockUntilNavigationsComplete(
1961 int handle, int number_of_navigations, IPC::Message* reply_message) {
1962 if (tab_tracker_->ContainsHandle(handle)) {
1963 NavigationController* tab = tab_tracker_->GetResource(handle);
1964 Browser* browser = FindAndActivateTab(tab);
1965 if (browser && browser->command_updater()->IsCommandEnabled(IDC_FORWARD)) {
1966 new NavigationNotificationObserver(tab, this, reply_message,
1967 number_of_navigations, false, false);
1968 browser->GoForward(CURRENT_TAB);
1969 return;
1970 }
1971 }
1972
1973 AutomationMsg_GoForwardBlockUntilNavigationsComplete::WriteReplyParams(
1974 reply_message, AUTOMATION_MSG_NAVIGATION_ERROR);
1975 Send(reply_message);
1976 }
1977
SavePackageShouldPromptUser(bool should_prompt)1978 void TestingAutomationProvider::SavePackageShouldPromptUser(
1979 bool should_prompt) {
1980 SavePackage::SetShouldPromptUser(should_prompt);
1981 }
1982
SetShelfVisibility(int handle,bool visible)1983 void TestingAutomationProvider::SetShelfVisibility(int handle, bool visible) {
1984 if (browser_tracker_->ContainsHandle(handle)) {
1985 Browser* browser = browser_tracker_->GetResource(handle);
1986 if (browser) {
1987 #if defined(OS_CHROMEOS)
1988 Browser* popup_browser =
1989 ActiveDownloadsUI::GetPopup(browser->profile());
1990 if (!popup_browser && visible)
1991 ActiveDownloadsUI::OpenPopup(browser->profile());
1992 if (popup_browser && !visible)
1993 popup_browser->CloseWindow();
1994 #else
1995 if (visible)
1996 browser->window()->GetDownloadShelf()->Show();
1997 else
1998 browser->window()->GetDownloadShelf()->Close();
1999 #endif
2000 }
2001 }
2002 }
2003
GetBlockedPopupCount(int handle,int * count)2004 void TestingAutomationProvider::GetBlockedPopupCount(int handle, int* count) {
2005 *count = -1; // -1 is the error code
2006 if (tab_tracker_->ContainsHandle(handle)) {
2007 NavigationController* nav_controller = tab_tracker_->GetResource(handle);
2008 TabContents* tab_contents = nav_controller->tab_contents();
2009 if (tab_contents) {
2010 BlockedContentContainer* container =
2011 tab_contents->blocked_content_container();
2012 if (container) {
2013 *count = static_cast<int>(container->GetBlockedContentsCount());
2014 } else {
2015 // If we don't have a container, we don't have any blocked popups to
2016 // contain!
2017 *count = 0;
2018 }
2019 }
2020 }
2021 }
2022
SendJSONRequest(int handle,const std::string & json_request,IPC::Message * reply_message)2023 void TestingAutomationProvider::SendJSONRequest(int handle,
2024 const std::string& json_request,
2025 IPC::Message* reply_message) {
2026 scoped_ptr<Value> values;
2027 base::JSONReader reader;
2028 std::string error;
2029 values.reset(reader.ReadAndReturnError(json_request, true, NULL, &error));
2030 if (!error.empty()) {
2031 AutomationJSONReply(this, reply_message).SendError(error);
2032 return;
2033 }
2034
2035 // Make sure input is a dict with a string command.
2036 std::string command;
2037 DictionaryValue* dict_value = NULL;
2038 if (values->GetType() != Value::TYPE_DICTIONARY) {
2039 AutomationJSONReply(this, reply_message).SendError("not a dict");
2040 return;
2041 }
2042 // Ownership remains with "values" variable.
2043 dict_value = static_cast<DictionaryValue*>(values.get());
2044 if (!dict_value->GetStringASCII(std::string("command"), &command)) {
2045 AutomationJSONReply(this, reply_message)
2046 .SendError("no command key in dict or not a string command");
2047 return;
2048 }
2049
2050 // Map json commands to their handlers.
2051 std::map<std::string, JsonHandler> handler_map;
2052 handler_map["WaitForAllTabsToStopLoading"] =
2053 &TestingAutomationProvider::WaitForAllTabsToStopLoading;
2054 handler_map["GetIndicesFromTab"] =
2055 &TestingAutomationProvider::GetIndicesFromTab;
2056 handler_map["NavigateToURL"] =
2057 &TestingAutomationProvider::NavigateToURL;
2058 handler_map["ExecuteJavascript"] =
2059 &TestingAutomationProvider::ExecuteJavascriptJSON;
2060 handler_map["GoForward"] =
2061 &TestingAutomationProvider::GoForward;
2062 handler_map["GoBack"] =
2063 &TestingAutomationProvider::GoBack;
2064 handler_map["Reload"] =
2065 &TestingAutomationProvider::ReloadJSON;
2066 handler_map["GetTabURL"] =
2067 &TestingAutomationProvider::GetTabURLJSON;
2068 handler_map["GetTabTitle"] =
2069 &TestingAutomationProvider::GetTabTitleJSON;
2070 handler_map["CaptureEntirePage"] =
2071 &TestingAutomationProvider::CaptureEntirePageJSON;
2072 handler_map["GetCookies"] =
2073 &TestingAutomationProvider::GetCookiesJSON;
2074 handler_map["DeleteCookie"] =
2075 &TestingAutomationProvider::DeleteCookieJSON;
2076 handler_map["SetCookie"] =
2077 &TestingAutomationProvider::SetCookieJSON;
2078 handler_map["GetTabIds"] =
2079 &TestingAutomationProvider::GetTabIds;
2080 handler_map["IsTabIdValid"] =
2081 &TestingAutomationProvider::IsTabIdValid;
2082 handler_map["CloseTab"] =
2083 &TestingAutomationProvider::CloseTabJSON;
2084 handler_map["WebkitMouseMove"] =
2085 &TestingAutomationProvider::WebkitMouseMove;
2086 handler_map["WebkitMouseClick"] =
2087 &TestingAutomationProvider::WebkitMouseClick;
2088 handler_map["WebkitMouseDrag"] =
2089 &TestingAutomationProvider::WebkitMouseDrag;
2090 handler_map["SendWebkitKeyEvent"] =
2091 &TestingAutomationProvider::SendWebkitKeyEvent;
2092 handler_map["SendOSLevelKeyEventToTab"] =
2093 &TestingAutomationProvider::SendOSLevelKeyEventToTab;
2094 handler_map["ActivateTab"] =
2095 &TestingAutomationProvider::ActivateTabJSON;
2096 handler_map["UpdateExtensionsNow"] =
2097 &TestingAutomationProvider::UpdateExtensionsNow;
2098 handler_map["GetChromeDriverAutomationVersion"] =
2099 &TestingAutomationProvider::GetChromeDriverAutomationVersion;
2100 #if defined(OS_CHROMEOS)
2101 handler_map["GetLoginInfo"] = &TestingAutomationProvider::GetLoginInfo;
2102 handler_map["LoginAsGuest"] = &TestingAutomationProvider::LoginAsGuest;
2103 handler_map["Login"] = &TestingAutomationProvider::Login;
2104
2105 handler_map["LockScreen"] = &TestingAutomationProvider::LockScreen;
2106 handler_map["UnlockScreen"] = &TestingAutomationProvider::UnlockScreen;
2107 handler_map["SignoutInScreenLocker"] =
2108 &TestingAutomationProvider::SignoutInScreenLocker;
2109
2110 handler_map["GetBatteryInfo"] = &TestingAutomationProvider::GetBatteryInfo;
2111
2112 handler_map["GetNetworkInfo"] = &TestingAutomationProvider::GetNetworkInfo;
2113 handler_map["NetworkScan"] = &TestingAutomationProvider::NetworkScan;
2114 handler_map["GetProxySettings"] =
2115 &TestingAutomationProvider::GetProxySettings;
2116 handler_map["SetProxySettings"] =
2117 &TestingAutomationProvider::SetProxySettings;
2118 handler_map["ConnectToWifiNetwork"] =
2119 &TestingAutomationProvider::ConnectToWifiNetwork;
2120 handler_map["ConnectToHiddenWifiNetwork"] =
2121 &TestingAutomationProvider::ConnectToHiddenWifiNetwork;
2122 handler_map["DisconnectFromWifiNetwork"] =
2123 &TestingAutomationProvider::DisconnectFromWifiNetwork;
2124
2125 handler_map["GetUpdateInfo"] = &TestingAutomationProvider::GetUpdateInfo;
2126 handler_map["UpdateCheck"] = &TestingAutomationProvider::UpdateCheck;
2127 handler_map["SetReleaseTrack"] = &TestingAutomationProvider::SetReleaseTrack;
2128 #endif // defined(OS_CHROMEOS)
2129
2130 std::map<std::string, BrowserJsonHandler> browser_handler_map;
2131 browser_handler_map["DisablePlugin"] =
2132 &TestingAutomationProvider::DisablePlugin;
2133 browser_handler_map["EnablePlugin"] =
2134 &TestingAutomationProvider::EnablePlugin;
2135 browser_handler_map["GetPluginsInfo"] =
2136 &TestingAutomationProvider::GetPluginsInfo;
2137
2138 browser_handler_map["GetBrowserInfo"] =
2139 &TestingAutomationProvider::GetBrowserInfo;
2140
2141 browser_handler_map["GetNavigationInfo"] =
2142 &TestingAutomationProvider::GetNavigationInfo;
2143
2144 browser_handler_map["PerformActionOnInfobar"] =
2145 &TestingAutomationProvider::PerformActionOnInfobar;
2146
2147 browser_handler_map["GetHistoryInfo"] =
2148 &TestingAutomationProvider::GetHistoryInfo;
2149 browser_handler_map["AddHistoryItem"] =
2150 &TestingAutomationProvider::AddHistoryItem;
2151
2152 browser_handler_map["GetOmniboxInfo"] =
2153 &TestingAutomationProvider::GetOmniboxInfo;
2154 browser_handler_map["SetOmniboxText"] =
2155 &TestingAutomationProvider::SetOmniboxText;
2156 browser_handler_map["OmniboxAcceptInput"] =
2157 &TestingAutomationProvider::OmniboxAcceptInput;
2158 browser_handler_map["OmniboxMovePopupSelection"] =
2159 &TestingAutomationProvider::OmniboxMovePopupSelection;
2160
2161 browser_handler_map["GetInstantInfo"] =
2162 &TestingAutomationProvider::GetInstantInfo;
2163
2164 browser_handler_map["LoadSearchEngineInfo"] =
2165 &TestingAutomationProvider::LoadSearchEngineInfo;
2166 browser_handler_map["GetSearchEngineInfo"] =
2167 &TestingAutomationProvider::GetSearchEngineInfo;
2168 browser_handler_map["AddOrEditSearchEngine"] =
2169 &TestingAutomationProvider::AddOrEditSearchEngine;
2170 browser_handler_map["PerformActionOnSearchEngine"] =
2171 &TestingAutomationProvider::PerformActionOnSearchEngine;
2172
2173 browser_handler_map["GetPrefsInfo"] =
2174 &TestingAutomationProvider::GetPrefsInfo;
2175 browser_handler_map["SetPrefs"] = &TestingAutomationProvider::SetPrefs;
2176
2177 browser_handler_map["SetWindowDimensions"] =
2178 &TestingAutomationProvider::SetWindowDimensions;
2179
2180 browser_handler_map["GetDownloadsInfo"] =
2181 &TestingAutomationProvider::GetDownloadsInfo;
2182 browser_handler_map["WaitForAllDownloadsToComplete"] =
2183 &TestingAutomationProvider::WaitForDownloadsToComplete;
2184 browser_handler_map["PerformActionOnDownload"] =
2185 &TestingAutomationProvider::PerformActionOnDownload;
2186
2187 browser_handler_map["GetInitialLoadTimes"] =
2188 &TestingAutomationProvider::GetInitialLoadTimes;
2189
2190 browser_handler_map["SaveTabContents"] =
2191 &TestingAutomationProvider::SaveTabContents;
2192
2193 browser_handler_map["ImportSettings"] =
2194 &TestingAutomationProvider::ImportSettings;
2195
2196 browser_handler_map["AddSavedPassword"] =
2197 &TestingAutomationProvider::AddSavedPassword;
2198 browser_handler_map["RemoveSavedPassword"] =
2199 &TestingAutomationProvider::RemoveSavedPassword;
2200 browser_handler_map["GetSavedPasswords"] =
2201 &TestingAutomationProvider::GetSavedPasswords;
2202
2203 browser_handler_map["ClearBrowsingData"] =
2204 &TestingAutomationProvider::ClearBrowsingData;
2205
2206 browser_handler_map["GetBlockedPopupsInfo"] =
2207 &TestingAutomationProvider::GetBlockedPopupsInfo;
2208 browser_handler_map["UnblockAndLaunchBlockedPopup"] =
2209 &TestingAutomationProvider::UnblockAndLaunchBlockedPopup;
2210
2211 // SetTheme() implemented using InstallExtension().
2212 browser_handler_map["GetThemeInfo"] =
2213 &TestingAutomationProvider::GetThemeInfo;
2214
2215 // InstallExtension() present in pyauto.py.
2216 browser_handler_map["GetExtensionsInfo"] =
2217 &TestingAutomationProvider::GetExtensionsInfo;
2218 browser_handler_map["UninstallExtensionById"] =
2219 &TestingAutomationProvider::UninstallExtensionById;
2220
2221 browser_handler_map["FindInPage"] = &TestingAutomationProvider::FindInPage;
2222
2223 browser_handler_map["SelectTranslateOption"] =
2224 &TestingAutomationProvider::SelectTranslateOption;
2225 browser_handler_map["GetTranslateInfo"] =
2226 &TestingAutomationProvider::GetTranslateInfo;
2227
2228 browser_handler_map["GetAutofillProfile"] =
2229 &TestingAutomationProvider::GetAutofillProfile;
2230 browser_handler_map["FillAutofillProfile"] =
2231 &TestingAutomationProvider::FillAutofillProfile;
2232
2233 browser_handler_map["GetActiveNotifications"] =
2234 &TestingAutomationProvider::GetActiveNotifications;
2235 browser_handler_map["CloseNotification"] =
2236 &TestingAutomationProvider::CloseNotification;
2237 browser_handler_map["WaitForNotificationCount"] =
2238 &TestingAutomationProvider::WaitForNotificationCount;
2239
2240 browser_handler_map["SignInToSync"] =
2241 &TestingAutomationProvider::SignInToSync;
2242 browser_handler_map["GetSyncInfo"] = &TestingAutomationProvider::GetSyncInfo;
2243 browser_handler_map["AwaitSyncCycleCompletion"] =
2244 &TestingAutomationProvider::AwaitSyncCycleCompletion;
2245 browser_handler_map["EnableSyncForDatatypes"] =
2246 &TestingAutomationProvider::EnableSyncForDatatypes;
2247 browser_handler_map["DisableSyncForDatatypes"] =
2248 &TestingAutomationProvider::DisableSyncForDatatypes;
2249
2250 browser_handler_map["GetNTPInfo"] =
2251 &TestingAutomationProvider::GetNTPInfo;
2252 browser_handler_map["MoveNTPMostVisitedThumbnail"] =
2253 &TestingAutomationProvider::MoveNTPMostVisitedThumbnail;
2254 browser_handler_map["RemoveNTPMostVisitedThumbnail"] =
2255 &TestingAutomationProvider::RemoveNTPMostVisitedThumbnail;
2256 browser_handler_map["UnpinNTPMostVisitedThumbnail"] =
2257 &TestingAutomationProvider::UnpinNTPMostVisitedThumbnail;
2258 browser_handler_map["RestoreAllNTPMostVisitedThumbnails"] =
2259 &TestingAutomationProvider::RestoreAllNTPMostVisitedThumbnails;
2260
2261 browser_handler_map["KillRendererProcess"] =
2262 &TestingAutomationProvider::KillRendererProcess;
2263
2264 browser_handler_map["GetNTPThumbnailMode"] =
2265 &TestingAutomationProvider::GetNTPThumbnailMode;
2266 browser_handler_map["SetNTPThumbnailMode"] =
2267 &TestingAutomationProvider::SetNTPThumbnailMode;
2268 browser_handler_map["GetNTPMenuMode"] =
2269 &TestingAutomationProvider::GetNTPMenuMode;
2270 browser_handler_map["SetNTPMenuMode"] =
2271 &TestingAutomationProvider::SetNTPMenuMode;
2272
2273 browser_handler_map["LaunchApp"] = &TestingAutomationProvider::LaunchApp;
2274 browser_handler_map["SetAppLaunchType"] =
2275 &TestingAutomationProvider::SetAppLaunchType;
2276
2277 if (handler_map.find(std::string(command)) != handler_map.end()) {
2278 (this->*handler_map[command])(dict_value, reply_message);
2279 } else if (browser_handler_map.find(std::string(command)) !=
2280 browser_handler_map.end()) {
2281 Browser* browser = NULL;
2282 if (!browser_tracker_->ContainsHandle(handle) ||
2283 !(browser = browser_tracker_->GetResource(handle))) {
2284 AutomationJSONReply(this, reply_message).SendError("No browser object.");
2285 return;
2286 }
2287 (this->*browser_handler_map[command])(browser, dict_value, reply_message);
2288 } else {
2289 std::string error_string = "Unknown command. Options: ";
2290 for (std::map<std::string, JsonHandler>::const_iterator it =
2291 handler_map.begin(); it != handler_map.end(); ++it) {
2292 error_string += it->first + ", ";
2293 }
2294 for (std::map<std::string, BrowserJsonHandler>::const_iterator it =
2295 browser_handler_map.begin(); it != browser_handler_map.end(); ++it) {
2296 error_string += it->first + ", ";
2297 }
2298 AutomationJSONReply(this, reply_message).SendError(error_string);
2299 }
2300 }
2301
2302 // Sample json input: { "command": "SetWindowDimensions",
2303 // "x": 20, # optional
2304 // "y": 20, # optional
2305 // "width": 800, # optional
2306 // "height": 600 } # optional
SetWindowDimensions(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)2307 void TestingAutomationProvider::SetWindowDimensions(
2308 Browser* browser,
2309 DictionaryValue* args,
2310 IPC::Message* reply_message) {
2311 gfx::Rect rect = browser->window()->GetRestoredBounds();
2312 int x, y, width, height;
2313 if (args->GetInteger("x", &x))
2314 rect.set_x(x);
2315 if (args->GetInteger("y", &y))
2316 rect.set_y(y);
2317 if (args->GetInteger("width", &width))
2318 rect.set_width(width);
2319 if (args->GetInteger("height", &height))
2320 rect.set_height(height);
2321 browser->window()->SetBounds(rect);
2322 AutomationJSONReply(this, reply_message).SendSuccess(NULL);
2323 }
2324
GetInfobarsInfo(TabContents * tc)2325 ListValue* TestingAutomationProvider::GetInfobarsInfo(TabContents* tc) {
2326 // Each infobar may have different properties depending on the type.
2327 ListValue* infobars = new ListValue;
2328 for (size_t i = 0; i < tc->infobar_count(); ++i) {
2329 DictionaryValue* infobar_item = new DictionaryValue;
2330 InfoBarDelegate* infobar = tc->GetInfoBarDelegateAt(i);
2331 if (infobar->AsConfirmInfoBarDelegate()) {
2332 // Also covers ThemeInstalledInfoBarDelegate.
2333 infobar_item->SetString("type", "confirm_infobar");
2334 ConfirmInfoBarDelegate* confirm_infobar =
2335 infobar->AsConfirmInfoBarDelegate();
2336 infobar_item->SetString("text", confirm_infobar->GetMessageText());
2337 infobar_item->SetString("link_text", confirm_infobar->GetLinkText());
2338 ListValue* buttons_list = new ListValue;
2339 int buttons = confirm_infobar->GetButtons();
2340 if (buttons & ConfirmInfoBarDelegate::BUTTON_OK) {
2341 StringValue* button_label = new StringValue(
2342 confirm_infobar->GetButtonLabel(
2343 ConfirmInfoBarDelegate::BUTTON_OK));
2344 buttons_list->Append(button_label);
2345 }
2346 if (buttons & ConfirmInfoBarDelegate::BUTTON_CANCEL) {
2347 StringValue* button_label = new StringValue(
2348 confirm_infobar->GetButtonLabel(
2349 ConfirmInfoBarDelegate::BUTTON_CANCEL));
2350 buttons_list->Append(button_label);
2351 }
2352 infobar_item->Set("buttons", buttons_list);
2353 } else if (infobar->AsLinkInfoBarDelegate()) {
2354 infobar_item->SetString("type", "link_infobar");
2355 LinkInfoBarDelegate* link_infobar = infobar->AsLinkInfoBarDelegate();
2356 infobar_item->SetString("link_text", link_infobar->GetLinkText());
2357 } else if (infobar->AsTranslateInfoBarDelegate()) {
2358 infobar_item->SetString("type", "translate_infobar");
2359 TranslateInfoBarDelegate* translate_infobar =
2360 infobar->AsTranslateInfoBarDelegate();
2361 infobar_item->SetString("original_lang_code",
2362 translate_infobar->GetOriginalLanguageCode());
2363 infobar_item->SetString("target_lang_code",
2364 translate_infobar->GetTargetLanguageCode());
2365 } else if (infobar->AsExtensionInfoBarDelegate()) {
2366 infobar_item->SetString("type", "extension_infobar");
2367 } else {
2368 infobar_item->SetString("type", "unknown_infobar");
2369 }
2370 infobars->Append(infobar_item);
2371 }
2372 return infobars;
2373 }
2374
2375 // Sample json input: { "command": "PerformActionOnInfobar",
2376 // "action": "dismiss",
2377 // "infobar_index": 0,
2378 // "tab_index": 0 }
2379 // Sample output: {}
PerformActionOnInfobar(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)2380 void TestingAutomationProvider::PerformActionOnInfobar(
2381 Browser* browser,
2382 DictionaryValue* args,
2383 IPC::Message* reply_message) {
2384 AutomationJSONReply reply(this, reply_message);
2385 int tab_index;
2386 int infobar_index_int;
2387 std::string action;
2388 if (!args->GetInteger("tab_index", &tab_index) ||
2389 !args->GetInteger("infobar_index", &infobar_index_int) ||
2390 !args->GetString("action", &action)) {
2391 reply.SendError("Invalid or missing args");
2392 return;
2393 }
2394 TabContents* tab_contents = browser->GetTabContentsAt(tab_index);
2395 if (!tab_contents) {
2396 reply.SendError(StringPrintf("No such tab at index %d", tab_index));
2397 return;
2398 }
2399 InfoBarDelegate* infobar = NULL;
2400 size_t infobar_index = static_cast<size_t>(infobar_index_int);
2401 if (infobar_index >= tab_contents->infobar_count() ||
2402 !(infobar = tab_contents->GetInfoBarDelegateAt(infobar_index))) {
2403 reply.SendError(StringPrintf("No such infobar at index %" PRIuS,
2404 infobar_index));
2405 return;
2406 }
2407 if ("dismiss" == action) {
2408 infobar->InfoBarDismissed();
2409 tab_contents->RemoveInfoBar(infobar);
2410 reply.SendSuccess(NULL);
2411 return;
2412 }
2413 if ("accept" == action || "cancel" == action) {
2414 ConfirmInfoBarDelegate* confirm_infobar;
2415 if (!(confirm_infobar = infobar->AsConfirmInfoBarDelegate())) {
2416 reply.SendError("Not a confirm infobar");
2417 return;
2418 }
2419 if ("accept" == action) {
2420 if (confirm_infobar->Accept())
2421 tab_contents->RemoveInfoBar(infobar);
2422 } else if ("cancel" == action) {
2423 if (confirm_infobar->Cancel())
2424 tab_contents->RemoveInfoBar(infobar);
2425 }
2426 reply.SendSuccess(NULL);
2427 return;
2428 }
2429 reply.SendError("Invalid action");
2430 }
2431
2432 namespace {
2433
2434 // Task to get info about BrowserChildProcessHost. Must run on IO thread to
2435 // honor the semantics of BrowserChildProcessHost.
2436 // Used by AutomationProvider::GetBrowserInfo().
2437 class GetChildProcessHostInfoTask : public Task {
2438 public:
GetChildProcessHostInfoTask(base::WaitableEvent * event,ListValue * child_processes)2439 GetChildProcessHostInfoTask(base::WaitableEvent* event,
2440 ListValue* child_processes)
2441 : event_(event),
2442 child_processes_(child_processes) {}
2443
Run()2444 virtual void Run() {
2445 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
2446 for (BrowserChildProcessHost::Iterator iter; !iter.Done(); ++iter) {
2447 // Only add processes which are already started,
2448 // since we need their handle.
2449 if ((*iter)->handle() == base::kNullProcessHandle) {
2450 continue;
2451 }
2452 ChildProcessInfo* info = *iter;
2453 DictionaryValue* item = new DictionaryValue;
2454 item->SetString("name", WideToUTF16Hack(info->name()));
2455 item->SetString("type",
2456 ChildProcessInfo::GetTypeNameInEnglish(info->type()));
2457 item->SetInteger("pid", base::GetProcId(info->handle()));
2458 child_processes_->Append(item);
2459 }
2460 event_->Signal();
2461 }
2462
2463 private:
2464 base::WaitableEvent* const event_; // weak
2465 ListValue* child_processes_;
2466
2467 DISALLOW_COPY_AND_ASSIGN(GetChildProcessHostInfoTask);
2468 };
2469
2470 } // namespace
2471
2472 // Sample json input: { "command": "GetBrowserInfo" }
2473 // Refer to GetBrowserInfo() in chrome/test/pyautolib/pyauto.py for
2474 // sample json output.
GetBrowserInfo(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)2475 void TestingAutomationProvider::GetBrowserInfo(
2476 Browser* browser,
2477 DictionaryValue* args,
2478 IPC::Message* reply_message) {
2479 base::ThreadRestrictions::ScopedAllowIO allow_io; // needed for PathService
2480 DictionaryValue* properties = new DictionaryValue;
2481 properties->SetString("ChromeVersion", chrome::kChromeVersion);
2482 properties->SetString("BrowserProcessExecutableName",
2483 chrome::kBrowserProcessExecutableName);
2484 properties->SetString("HelperProcessExecutableName",
2485 chrome::kHelperProcessExecutableName);
2486 properties->SetString("BrowserProcessExecutablePath",
2487 chrome::kBrowserProcessExecutablePath);
2488 properties->SetString("HelperProcessExecutablePath",
2489 chrome::kHelperProcessExecutablePath);
2490 properties->SetString("command_line_string",
2491 CommandLine::ForCurrentProcess()->command_line_string());
2492 FilePath dumps_path;
2493 PathService::Get(chrome::DIR_CRASH_DUMPS, &dumps_path);
2494 properties->SetString("DIR_CRASH_DUMPS", dumps_path.value());
2495
2496 std::string branding;
2497 #if defined(GOOGLE_CHROME_BUILD)
2498 branding = "Google Chrome";
2499 #elif defined(CHROMIUM_BUILD)
2500 branding = "Chromium";
2501 #else
2502 branding = "Unknown Branding";
2503 #endif
2504 properties->SetString("branding", branding);
2505
2506 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2507 return_value->Set("properties", properties);
2508
2509 return_value->SetInteger("browser_pid", base::GetCurrentProcId());
2510 // Add info about all windows in a list of dictionaries, one dictionary
2511 // item per window.
2512 ListValue* windows = new ListValue;
2513 int windex = 0;
2514 for (BrowserList::const_iterator it = BrowserList::begin();
2515 it != BrowserList::end();
2516 ++it, ++windex) {
2517 DictionaryValue* browser_item = new DictionaryValue;
2518 browser = *it;
2519 browser_item->SetInteger("index", windex);
2520 // Window properties
2521 gfx::Rect rect = browser->window()->GetRestoredBounds();
2522 browser_item->SetInteger("x", rect.x());
2523 browser_item->SetInteger("y", rect.y());
2524 browser_item->SetInteger("width", rect.width());
2525 browser_item->SetInteger("height", rect.height());
2526 browser_item->SetBoolean("fullscreen",
2527 browser->window()->IsFullscreen());
2528 browser_item->SetInteger("selected_tab", browser->active_index());
2529 browser_item->SetBoolean("incognito",
2530 browser->profile()->IsOffTheRecord());
2531 // For each window, add info about all tabs in a list of dictionaries,
2532 // one dictionary item per tab.
2533 ListValue* tabs = new ListValue;
2534 for (int i = 0; i < browser->tab_count(); ++i) {
2535 TabContents* tc = browser->GetTabContentsAt(i);
2536 DictionaryValue* tab = new DictionaryValue;
2537 tab->SetInteger("index", i);
2538 tab->SetString("url", tc->GetURL().spec());
2539 tab->SetInteger("renderer_pid",
2540 base::GetProcId(tc->GetRenderProcessHost()->GetHandle()));
2541 tab->Set("infobars", GetInfobarsInfo(tc));
2542 tab->SetBoolean("pinned", browser->IsTabPinned(i));
2543 tabs->Append(tab);
2544 }
2545 browser_item->Set("tabs", tabs);
2546
2547 windows->Append(browser_item);
2548 }
2549 return_value->Set("windows", windows);
2550
2551 return_value->SetString("child_process_path",
2552 ChildProcessHost::GetChildPath(true).value());
2553 // Child processes are the processes for plugins and other workers.
2554 // Add all child processes in a list of dictionaries, one dictionary item
2555 // per child process.
2556 ListValue* child_processes = new ListValue;
2557 base::WaitableEvent event(true /* manual reset */,
2558 false /* not initially signaled */);
2559 CHECK(BrowserThread::PostTask(
2560 BrowserThread::IO, FROM_HERE,
2561 new GetChildProcessHostInfoTask(&event, child_processes)));
2562 event.Wait();
2563 return_value->Set("child_processes", child_processes);
2564
2565 // Add all extension processes in a list of dictionaries, one dictionary
2566 // item per extension process.
2567 ListValue* extension_processes = new ListValue;
2568 ProfileManager* profile_manager = g_browser_process->profile_manager();
2569 std::vector<Profile*> profiles(profile_manager->GetLoadedProfiles());
2570 for (size_t i = 0; i < profiles.size(); ++i) {
2571 ExtensionProcessManager* process_manager =
2572 profiles[i]->GetExtensionProcessManager();
2573 if (!process_manager)
2574 continue;
2575 ExtensionProcessManager::const_iterator jt;
2576 for (jt = process_manager->begin(); jt != process_manager->end(); ++jt) {
2577 ExtensionHost* ex_host = *jt;
2578 // Don't add dead extension processes.
2579 if (!ex_host->IsRenderViewLive())
2580 continue;
2581 DictionaryValue* item = new DictionaryValue;
2582 item->SetString("name", ex_host->extension()->name());
2583 item->SetInteger(
2584 "pid",
2585 base::GetProcId(ex_host->render_process_host()->GetHandle()));
2586 extension_processes->Append(item);
2587 }
2588 }
2589 return_value->Set("extension_processes", extension_processes);
2590 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
2591 }
2592
2593 // Sample json input: { "command": "GetNavigationInfo" }
2594 // Refer to GetNavigationInfo() in chrome/test/pyautolib/pyauto.py for
2595 // sample json output.
GetNavigationInfo(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)2596 void TestingAutomationProvider::GetNavigationInfo(
2597 Browser* browser,
2598 DictionaryValue* args,
2599 IPC::Message* reply_message) {
2600 AutomationJSONReply reply(this, reply_message);
2601 int tab_index;
2602 TabContents* tab_contents = NULL;
2603 if (!args->GetInteger("tab_index", &tab_index) ||
2604 !(tab_contents = browser->GetTabContentsAt(tab_index))) {
2605 reply.SendError("tab_index missing or invalid.");
2606 return;
2607 }
2608 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2609 const NavigationController& controller = tab_contents->controller();
2610 NavigationEntry* nav_entry = controller.GetActiveEntry();
2611 DCHECK(nav_entry);
2612
2613 // Security info.
2614 DictionaryValue* ssl = new DictionaryValue;
2615 std::map<SecurityStyle, std::string> style_to_string;
2616 style_to_string[SECURITY_STYLE_UNKNOWN] = "SECURITY_STYLE_UNKNOWN";
2617 style_to_string[SECURITY_STYLE_UNAUTHENTICATED] =
2618 "SECURITY_STYLE_UNAUTHENTICATED";
2619 style_to_string[SECURITY_STYLE_AUTHENTICATION_BROKEN] =
2620 "SECURITY_STYLE_AUTHENTICATION_BROKEN";
2621 style_to_string[SECURITY_STYLE_AUTHENTICATED] =
2622 "SECURITY_STYLE_AUTHENTICATED";
2623
2624 NavigationEntry::SSLStatus ssl_status = nav_entry->ssl();
2625 ssl->SetString("security_style",
2626 style_to_string[ssl_status.security_style()]);
2627 ssl->SetBoolean("ran_insecure_content", ssl_status.ran_insecure_content());
2628 ssl->SetBoolean("displayed_insecure_content",
2629 ssl_status.displayed_insecure_content());
2630 return_value->Set("ssl", ssl);
2631
2632 // Page type.
2633 std::map<PageType, std::string> pagetype_to_string;
2634 pagetype_to_string[NORMAL_PAGE] = "NORMAL_PAGE";
2635 pagetype_to_string[ERROR_PAGE] = "ERROR_PAGE";
2636 pagetype_to_string[INTERSTITIAL_PAGE] = "INTERSTITIAL_PAGE";
2637 return_value->SetString("page_type",
2638 pagetype_to_string[nav_entry->page_type()]);
2639
2640 return_value->SetString("favicon_url", nav_entry->favicon().url().spec());
2641 reply.SendSuccess(return_value.get());
2642 }
2643
2644 // Sample json input: { "command": "GetHistoryInfo",
2645 // "search_text": "some text" }
2646 // Refer chrome/test/pyautolib/history_info.py for sample json output.
GetHistoryInfo(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)2647 void TestingAutomationProvider::GetHistoryInfo(Browser* browser,
2648 DictionaryValue* args,
2649 IPC::Message* reply_message) {
2650 consumer_.CancelAllRequests();
2651
2652 string16 search_text;
2653 args->GetString("search_text", &search_text);
2654
2655 // Fetch history.
2656 HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
2657 history::QueryOptions options;
2658 // The observer owns itself. It deletes itself after it fetches history.
2659 AutomationProviderHistoryObserver* history_observer =
2660 new AutomationProviderHistoryObserver(this, reply_message);
2661 hs->QueryHistory(
2662 search_text,
2663 options,
2664 &consumer_,
2665 NewCallback(history_observer,
2666 &AutomationProviderHistoryObserver::HistoryQueryComplete));
2667 }
2668
2669 // Sample json input: { "command": "AddHistoryItem",
2670 // "item": { "URL": "http://www.google.com",
2671 // "title": "Google", # optional
2672 // "time": 12345 # optional (time_t)
2673 // } }
2674 // Refer chrome/test/pyautolib/pyauto.py for details on input.
AddHistoryItem(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)2675 void TestingAutomationProvider::AddHistoryItem(Browser* browser,
2676 DictionaryValue* args,
2677 IPC::Message* reply_message) {
2678 DictionaryValue* item = NULL;
2679 args->GetDictionary("item", &item);
2680 string16 url_text;
2681 string16 title;
2682 base::Time time = base::Time::Now();
2683 AutomationJSONReply reply(this, reply_message);
2684
2685 if (!item->GetString("url", &url_text)) {
2686 reply.SendError("bad args (no URL in dict?)");
2687 return;
2688 }
2689 GURL gurl(url_text);
2690 item->GetString("title", &title); // Don't care if it fails.
2691 int it;
2692 double dt;
2693 if (item->GetInteger("time", &it))
2694 time = base::Time::FromTimeT(it);
2695 else if (item->GetDouble("time", &dt))
2696 time = base::Time::FromDoubleT(dt);
2697
2698 // Ideas for "dummy" values (e.g. id_scope) came from
2699 // chrome/browser/autocomplete/history_contents_provider_unittest.cc
2700 HistoryService* hs = profile_->GetHistoryService(Profile::EXPLICIT_ACCESS);
2701 const void* id_scope = reinterpret_cast<void*>(1);
2702 hs->AddPage(gurl, time,
2703 id_scope,
2704 0,
2705 GURL(),
2706 PageTransition::LINK,
2707 history::RedirectList(),
2708 history::SOURCE_BROWSED,
2709 false);
2710 if (title.length())
2711 hs->SetPageTitle(gurl, title);
2712 reply.SendSuccess(NULL);
2713 }
2714
2715 // Sample json input: { "command": "GetDownloadsInfo" }
2716 // Refer chrome/test/pyautolib/download_info.py for sample json output.
GetDownloadsInfo(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)2717 void TestingAutomationProvider::GetDownloadsInfo(Browser* browser,
2718 DictionaryValue* args,
2719 IPC::Message* reply_message) {
2720 AutomationJSONReply reply(this, reply_message);
2721 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2722 ListValue* list_of_downloads = new ListValue;
2723
2724 if (browser->profile()->HasCreatedDownloadManager()) {
2725 std::vector<DownloadItem*> downloads;
2726 browser->profile()->GetDownloadManager()->
2727 GetAllDownloads(FilePath(), &downloads);
2728
2729 for (std::vector<DownloadItem*>::iterator it = downloads.begin();
2730 it != downloads.end();
2731 it++) { // Fill info about each download item.
2732 list_of_downloads->Append(GetDictionaryFromDownloadItem(*it));
2733 }
2734 }
2735 return_value->Set("downloads", list_of_downloads);
2736 reply.SendSuccess(return_value.get());
2737 }
2738
WaitForDownloadsToComplete(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)2739 void TestingAutomationProvider::WaitForDownloadsToComplete(
2740 Browser* browser,
2741 DictionaryValue* args,
2742 IPC::Message* reply_message) {
2743
2744 // Look for a quick return.
2745 if (!browser->profile()->HasCreatedDownloadManager()) {
2746 // No download manager.
2747 AutomationJSONReply(this, reply_message).SendSuccess(NULL);
2748 return;
2749 }
2750 std::vector<DownloadItem*> downloads;
2751 browser->profile()->GetDownloadManager()->
2752 GetCurrentDownloads(FilePath(), &downloads);
2753 if (downloads.empty()) {
2754 AutomationJSONReply(this, reply_message).SendSuccess(NULL);
2755 return;
2756 }
2757 // The observer owns itself. When the last observed item pings, it
2758 // deletes itself.
2759 AutomationProviderDownloadItemObserver* item_observer =
2760 new AutomationProviderDownloadItemObserver(
2761 this, reply_message, downloads.size());
2762 for (std::vector<DownloadItem*>::iterator i = downloads.begin();
2763 i != downloads.end();
2764 i++) {
2765 (*i)->AddObserver(item_observer);
2766 }
2767 }
2768
2769 namespace {
2770
GetDownloadItemFromId(int id,DownloadManager * download_manager)2771 DownloadItem* GetDownloadItemFromId(int id, DownloadManager* download_manager) {
2772 std::vector<DownloadItem*> downloads;
2773 download_manager->GetAllDownloads(FilePath(), &downloads);
2774 DownloadItem* selected_item = NULL;
2775
2776 for (std::vector<DownloadItem*>::iterator it = downloads.begin();
2777 it != downloads.end();
2778 it++) {
2779 DownloadItem* curr_item = *it;
2780 if (curr_item->id() == id) {
2781 selected_item = curr_item;
2782 break;
2783 }
2784 }
2785 return selected_item;
2786 }
2787
2788 } // namespace
2789
2790 // See PerformActionOnDownload() in chrome/test/pyautolib/pyauto.py for sample
2791 // json input and output.
PerformActionOnDownload(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)2792 void TestingAutomationProvider::PerformActionOnDownload(
2793 Browser* browser,
2794 DictionaryValue* args,
2795 IPC::Message* reply_message) {
2796 int id;
2797 std::string action;
2798
2799 if (!browser->profile()->HasCreatedDownloadManager()) {
2800 AutomationJSONReply(this, reply_message).SendError("No download manager.");
2801 return;
2802 }
2803 if (!args->GetInteger("id", &id) || !args->GetString("action", &action)) {
2804 AutomationJSONReply(this, reply_message)
2805 .SendError("Must include int id and string action.");
2806 return;
2807 }
2808
2809 DownloadManager* download_manager = browser->profile()->GetDownloadManager();
2810 DownloadItem* selected_item = GetDownloadItemFromId(id, download_manager);
2811 if (!selected_item) {
2812 AutomationJSONReply(this, reply_message)
2813 .SendError(StringPrintf("No download with an id of %d\n", id));
2814 return;
2815 }
2816
2817 if (action == "open") {
2818 selected_item->AddObserver(
2819 new AutomationProviderDownloadUpdatedObserver(
2820 this, reply_message, true));
2821 selected_item->OpenDownload();
2822 } else if (action == "toggle_open_files_like_this") {
2823 selected_item->OpenFilesBasedOnExtension(
2824 !selected_item->ShouldOpenFileBasedOnExtension());
2825 AutomationJSONReply(this, reply_message).SendSuccess(NULL);
2826 } else if (action == "remove") {
2827 download_manager->AddObserver(
2828 new AutomationProviderDownloadModelChangedObserver(
2829 this, reply_message, download_manager));
2830 selected_item->Remove();
2831 } else if (action == "decline_dangerous_download") {
2832 download_manager->AddObserver(
2833 new AutomationProviderDownloadModelChangedObserver(
2834 this, reply_message, download_manager));
2835 selected_item->Delete(DownloadItem::DELETE_DUE_TO_USER_DISCARD);
2836 } else if (action == "save_dangerous_download") {
2837 selected_item->AddObserver(new AutomationProviderDownloadUpdatedObserver(
2838 this, reply_message, false));
2839 selected_item->DangerousDownloadValidated();
2840 } else if (action == "toggle_pause") {
2841 selected_item->AddObserver(new AutomationProviderDownloadUpdatedObserver(
2842 this, reply_message, false));
2843 // This will still return if download has already completed.
2844 selected_item->TogglePause();
2845 } else if (action == "cancel") {
2846 selected_item->AddObserver(new AutomationProviderDownloadUpdatedObserver(
2847 this, reply_message, false));
2848 selected_item->Cancel(true);
2849 } else {
2850 AutomationJSONReply(this, reply_message)
2851 .SendError(StringPrintf("Invalid action '%s' given.", action.c_str()));
2852 }
2853 }
2854
2855 // Sample JSON input { "command": "LoadSearchEngineInfo" }
LoadSearchEngineInfo(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)2856 void TestingAutomationProvider::LoadSearchEngineInfo(
2857 Browser* browser,
2858 DictionaryValue* args,
2859 IPC::Message* reply_message) {
2860 TemplateURLModel* url_model(profile_->GetTemplateURLModel());
2861 if (url_model->loaded()) {
2862 AutomationJSONReply(this, reply_message).SendSuccess(NULL);
2863 return;
2864 }
2865 url_model->AddObserver(new AutomationProviderSearchEngineObserver(
2866 this, reply_message));
2867 url_model->Load();
2868 }
2869
2870 // Sample JSON input { "command": "GetSearchEngineInfo" }
2871 // Refer to pyauto.py for sample output.
GetSearchEngineInfo(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)2872 void TestingAutomationProvider::GetSearchEngineInfo(
2873 Browser* browser,
2874 DictionaryValue* args,
2875 IPC::Message* reply_message) {
2876 TemplateURLModel* url_model(profile_->GetTemplateURLModel());
2877 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2878 ListValue* search_engines = new ListValue;
2879 std::vector<const TemplateURL*> template_urls = url_model->GetTemplateURLs();
2880 for (std::vector<const TemplateURL*>::const_iterator it =
2881 template_urls.begin(); it != template_urls.end(); ++it) {
2882 DictionaryValue* search_engine = new DictionaryValue;
2883 search_engine->SetString("short_name", UTF16ToUTF8((*it)->short_name()));
2884 search_engine->SetString("description", UTF16ToUTF8((*it)->description()));
2885 search_engine->SetString("keyword", UTF16ToUTF8((*it)->keyword()));
2886 search_engine->SetBoolean("in_default_list", (*it)->ShowInDefaultList());
2887 search_engine->SetBoolean("is_default",
2888 (*it) == url_model->GetDefaultSearchProvider());
2889 search_engine->SetBoolean("is_valid", (*it)->url()->IsValid());
2890 search_engine->SetBoolean("supports_replacement",
2891 (*it)->url()->SupportsReplacement());
2892 search_engine->SetString("url", (*it)->url()->url());
2893 search_engine->SetString("host", (*it)->url()->GetHost());
2894 search_engine->SetString("path", (*it)->url()->GetPath());
2895 search_engine->SetString("display_url",
2896 UTF16ToUTF8((*it)->url()->DisplayURL()));
2897 search_engines->Append(search_engine);
2898 }
2899 return_value->Set("search_engines", search_engines);
2900 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
2901 }
2902
2903 // Refer to pyauto.py for sample JSON input.
AddOrEditSearchEngine(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)2904 void TestingAutomationProvider::AddOrEditSearchEngine(
2905 Browser* browser,
2906 DictionaryValue* args,
2907 IPC::Message* reply_message) {
2908 TemplateURLModel* url_model(profile_->GetTemplateURLModel());
2909 const TemplateURL* template_url;
2910 string16 new_title;
2911 string16 new_keyword;
2912 std::string new_url;
2913 std::string keyword;
2914 if (!args->GetString("new_title", &new_title) ||
2915 !args->GetString("new_keyword", &new_keyword) ||
2916 !args->GetString("new_url", &new_url)) {
2917 AutomationJSONReply(this, reply_message)
2918 .SendError("One or more inputs invalid");
2919 return;
2920 }
2921 std::string new_ref_url = TemplateURLRef::DisplayURLToURLRef(
2922 UTF8ToUTF16(new_url));
2923 scoped_ptr<KeywordEditorController> controller(
2924 new KeywordEditorController(profile_));
2925 if (args->GetString("keyword", &keyword)) {
2926 template_url = url_model->GetTemplateURLForKeyword(UTF8ToUTF16(keyword));
2927 if (template_url == NULL) {
2928 AutomationJSONReply(this, reply_message)
2929 .SendError(StringPrintf("No match for keyword: %s", keyword.c_str()));
2930 return;
2931 }
2932 url_model->AddObserver(new AutomationProviderSearchEngineObserver(
2933 this, reply_message));
2934 controller->ModifyTemplateURL(template_url, new_title, new_keyword,
2935 new_ref_url);
2936 } else {
2937 url_model->AddObserver(new AutomationProviderSearchEngineObserver(
2938 this, reply_message));
2939 controller->AddTemplateURL(new_title, new_keyword, new_ref_url);
2940 }
2941 }
2942
2943 // Sample json input: { "command": "PerformActionOnSearchEngine",
2944 // "keyword": keyword, "action": action }
PerformActionOnSearchEngine(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)2945 void TestingAutomationProvider::PerformActionOnSearchEngine(
2946 Browser* browser,
2947 DictionaryValue* args,
2948 IPC::Message* reply_message) {
2949 TemplateURLModel* url_model(profile_->GetTemplateURLModel());
2950 std::string keyword;
2951 std::string action;
2952 if (!args->GetString("keyword", &keyword) ||
2953 !args->GetString("action", &action)) {
2954 AutomationJSONReply(this, reply_message).SendError(
2955 "One or more inputs invalid");
2956 return;
2957 }
2958 const TemplateURL* template_url(
2959 url_model->GetTemplateURLForKeyword(UTF8ToUTF16(keyword)));
2960 if (template_url == NULL) {
2961 AutomationJSONReply(this, reply_message)
2962 .SendError(StringPrintf("No match for keyword: %s", keyword.c_str()));
2963 return;
2964 }
2965 if (action == "delete") {
2966 url_model->AddObserver(new AutomationProviderSearchEngineObserver(
2967 this, reply_message));
2968 url_model->Remove(template_url);
2969 } else if (action == "default") {
2970 url_model->AddObserver(new AutomationProviderSearchEngineObserver(
2971 this, reply_message));
2972 url_model->SetDefaultSearchProvider(template_url);
2973 } else {
2974 AutomationJSONReply(this, reply_message)
2975 .SendError(StringPrintf("Invalid action: %s", action.c_str()));
2976 }
2977 }
2978
2979 // Sample json input: { "command": "GetPrefsInfo" }
2980 // Refer chrome/test/pyautolib/prefs_info.py for sample json output.
GetPrefsInfo(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)2981 void TestingAutomationProvider::GetPrefsInfo(Browser* browser,
2982 DictionaryValue* args,
2983 IPC::Message* reply_message) {
2984 DictionaryValue* items = profile_->GetPrefs()->GetPreferenceValues();
2985
2986 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
2987 return_value->Set("prefs", items); // return_value owns items.
2988 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
2989 }
2990
2991 // Sample json input: { "command": "SetPrefs", "path": path, "value": value }
SetPrefs(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)2992 void TestingAutomationProvider::SetPrefs(Browser* browser,
2993 DictionaryValue* args,
2994 IPC::Message* reply_message) {
2995 std::string path;
2996 Value* val;
2997 AutomationJSONReply reply(this, reply_message);
2998 if (args->GetString("path", &path) && args->Get("value", &val)) {
2999 PrefService* pref_service = profile_->GetPrefs();
3000 const PrefService::Preference* pref =
3001 pref_service->FindPreference(path.c_str());
3002 if (!pref) { // Not a registered pref.
3003 reply.SendError("pref not registered.");
3004 return;
3005 } else if (pref->IsManaged()) { // Do not attempt to change a managed pref.
3006 reply.SendError("pref is managed. cannot be changed.");
3007 return;
3008 } else { // Set the pref.
3009 pref_service->Set(path.c_str(), *val);
3010 }
3011 } else {
3012 reply.SendError("no pref path or value given.");
3013 return;
3014 }
3015
3016 reply.SendSuccess(NULL);
3017 }
3018
3019 // Sample json input: { "command": "GetOmniboxInfo" }
3020 // Refer chrome/test/pyautolib/omnibox_info.py for sample json output.
GetOmniboxInfo(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)3021 void TestingAutomationProvider::GetOmniboxInfo(Browser* browser,
3022 DictionaryValue* args,
3023 IPC::Message* reply_message) {
3024 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
3025
3026 LocationBar* loc_bar = browser->window()->GetLocationBar();
3027 AutocompleteEditView* edit_view = loc_bar->location_entry();
3028 AutocompleteEditModel* model = edit_view->model();
3029
3030 // Fill up matches.
3031 ListValue* matches = new ListValue;
3032 const AutocompleteResult& result = model->result();
3033 for (AutocompleteResult::const_iterator i = result.begin();
3034 i != result.end(); ++i) {
3035 const AutocompleteMatch& match = *i;
3036 DictionaryValue* item = new DictionaryValue; // owned by return_value
3037 item->SetString("type", AutocompleteMatch::TypeToString(match.type));
3038 item->SetBoolean("starred", match.starred);
3039 item->SetString("destination_url", match.destination_url.spec());
3040 item->SetString("contents", match.contents);
3041 item->SetString("description", match.description);
3042 matches->Append(item);
3043 }
3044 return_value->Set("matches", matches);
3045
3046 // Fill up other properties.
3047 DictionaryValue* properties = new DictionaryValue; // owned by return_value
3048 properties->SetBoolean("has_focus", model->has_focus());
3049 properties->SetBoolean("query_in_progress",
3050 !model->autocomplete_controller()->done());
3051 properties->SetString("keyword", model->keyword());
3052 properties->SetString("text", edit_view->GetText());
3053 return_value->Set("properties", properties);
3054
3055 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
3056 }
3057
3058 // Sample json input: { "command": "SetOmniboxText",
3059 // "text": "goog" }
SetOmniboxText(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)3060 void TestingAutomationProvider::SetOmniboxText(Browser* browser,
3061 DictionaryValue* args,
3062 IPC::Message* reply_message) {
3063 string16 text;
3064 AutomationJSONReply reply(this, reply_message);
3065 if (!args->GetString("text", &text)) {
3066 reply.SendError("text missing");
3067 return;
3068 }
3069 browser->FocusLocationBar();
3070 LocationBar* loc_bar = browser->window()->GetLocationBar();
3071 AutocompleteEditView* edit_view = loc_bar->location_entry();
3072 edit_view->model()->OnSetFocus(false);
3073 edit_view->SetUserText(text);
3074 reply.SendSuccess(NULL);
3075 }
3076
3077 // Sample json input: { "command": "OmniboxMovePopupSelection",
3078 // "count": 1 }
3079 // Negative count implies up, positive implies down. Count values will be
3080 // capped by the size of the popup list.
OmniboxMovePopupSelection(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)3081 void TestingAutomationProvider::OmniboxMovePopupSelection(
3082 Browser* browser,
3083 DictionaryValue* args,
3084 IPC::Message* reply_message) {
3085 int count;
3086 AutomationJSONReply reply(this, reply_message);
3087 if (!args->GetInteger("count", &count)) {
3088 reply.SendError("count missing");
3089 return;
3090 }
3091 LocationBar* loc_bar = browser->window()->GetLocationBar();
3092 AutocompleteEditModel* model = loc_bar->location_entry()->model();
3093 model->OnUpOrDownKeyPressed(count);
3094 reply.SendSuccess(NULL);
3095 }
3096
3097 // Sample json input: { "command": "OmniboxAcceptInput" }
OmniboxAcceptInput(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)3098 void TestingAutomationProvider::OmniboxAcceptInput(
3099 Browser* browser,
3100 DictionaryValue* args,
3101 IPC::Message* reply_message) {
3102 NavigationController& controller =
3103 browser->GetSelectedTabContents()->controller();
3104 new OmniboxAcceptNotificationObserver(&controller, this, reply_message);
3105 browser->window()->GetLocationBar()->AcceptInput();
3106 }
3107
3108 // Sample json input: { "command": "GetInstantInfo" }
GetInstantInfo(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)3109 void TestingAutomationProvider::GetInstantInfo(Browser* browser,
3110 DictionaryValue* args,
3111 IPC::Message* reply_message) {
3112 DictionaryValue* info = new DictionaryValue;
3113 if (browser->instant()) {
3114 InstantController* instant = browser->instant();
3115 info->SetBoolean("enabled", true);
3116 info->SetBoolean("showing", instant->IsShowingInstant());
3117 info->SetBoolean("active", instant->is_active());
3118 info->SetBoolean("current", instant->IsCurrent());
3119 if (instant->GetPreviewContents() &&
3120 instant->GetPreviewContents()->tab_contents()) {
3121 TabContents* contents = instant->GetPreviewContents()->tab_contents();
3122 info->SetBoolean("loading", contents->is_loading());
3123 info->SetString("location", contents->GetURL().spec());
3124 info->SetString("title", contents->GetTitle());
3125 }
3126 } else {
3127 info->SetBoolean("enabled", false);
3128 }
3129 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
3130 return_value->Set("instant", info);
3131 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
3132 }
3133
3134 // Sample json input: { "command": "GetInitialLoadTimes" }
3135 // Refer to InitialLoadObserver::GetTimingInformation() for sample output.
GetInitialLoadTimes(Browser *,DictionaryValue *,IPC::Message * reply_message)3136 void TestingAutomationProvider::GetInitialLoadTimes(
3137 Browser*,
3138 DictionaryValue*,
3139 IPC::Message* reply_message) {
3140 scoped_ptr<DictionaryValue> return_value(
3141 initial_load_observer_->GetTimingInformation());
3142
3143 std::string json_return;
3144 base::JSONWriter::Write(return_value.get(), false, &json_return);
3145 AutomationMsg_SendJSONRequest::WriteReplyParams(
3146 reply_message, json_return, true);
3147 Send(reply_message);
3148 }
3149
3150 // Sample json input: { "command": "GetPluginsInfo" }
3151 // Refer chrome/test/pyautolib/plugins_info.py for sample json output.
GetPluginsInfo(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)3152 void TestingAutomationProvider::GetPluginsInfo(
3153 Browser* browser,
3154 DictionaryValue* args,
3155 IPC::Message* reply_message) {
3156 std::vector<webkit::npapi::WebPluginInfo> plugins;
3157 webkit::npapi::PluginList::Singleton()->GetPlugins(false, &plugins);
3158 ListValue* items = new ListValue;
3159 for (std::vector<webkit::npapi::WebPluginInfo>::const_iterator it =
3160 plugins.begin();
3161 it != plugins.end();
3162 ++it) {
3163 DictionaryValue* item = new DictionaryValue;
3164 item->SetString("name", it->name);
3165 item->SetString("path", it->path.value());
3166 item->SetString("version", it->version);
3167 item->SetString("desc", it->desc);
3168 item->SetBoolean("enabled", webkit::npapi::IsPluginEnabled(*it));
3169 // Add info about mime types.
3170 ListValue* mime_types = new ListValue();
3171 for (std::vector<webkit::npapi::WebPluginMimeType>::const_iterator type_it =
3172 it->mime_types.begin();
3173 type_it != it->mime_types.end();
3174 ++type_it) {
3175 DictionaryValue* mime_type = new DictionaryValue();
3176 mime_type->SetString("mimeType", type_it->mime_type);
3177 mime_type->SetString("description", type_it->description);
3178
3179 ListValue* file_extensions = new ListValue();
3180 for (std::vector<std::string>::const_iterator ext_it =
3181 type_it->file_extensions.begin();
3182 ext_it != type_it->file_extensions.end();
3183 ++ext_it) {
3184 file_extensions->Append(new StringValue(*ext_it));
3185 }
3186 mime_type->Set("fileExtensions", file_extensions);
3187
3188 mime_types->Append(mime_type);
3189 }
3190 item->Set("mimeTypes", mime_types);
3191 items->Append(item);
3192 }
3193 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
3194 return_value->Set("plugins", items); // return_value owns items.
3195
3196 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
3197 }
3198
3199 // Sample json input:
3200 // { "command": "EnablePlugin",
3201 // "path": "/Library/Internet Plug-Ins/Flash Player.plugin" }
EnablePlugin(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)3202 void TestingAutomationProvider::EnablePlugin(Browser* browser,
3203 DictionaryValue* args,
3204 IPC::Message* reply_message) {
3205 FilePath::StringType path;
3206 AutomationJSONReply reply(this, reply_message);
3207 if (!args->GetString("path", &path)) {
3208 reply.SendError("path not specified.");
3209 return;
3210 } else if (!webkit::npapi::PluginList::Singleton()->EnablePlugin(
3211 FilePath(path))) {
3212 reply.SendError(StringPrintf("Could not enable plugin for path %s.",
3213 path.c_str()));
3214 return;
3215 }
3216 reply.SendSuccess(NULL);
3217 }
3218
3219 // Sample json input:
3220 // { "command": "DisablePlugin",
3221 // "path": "/Library/Internet Plug-Ins/Flash Player.plugin" }
DisablePlugin(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)3222 void TestingAutomationProvider::DisablePlugin(Browser* browser,
3223 DictionaryValue* args,
3224 IPC::Message* reply_message) {
3225 FilePath::StringType path;
3226 AutomationJSONReply reply(this, reply_message);
3227 if (!args->GetString("path", &path)) {
3228 reply.SendError("path not specified.");
3229 return;
3230 } else if (!webkit::npapi::PluginList::Singleton()->DisablePlugin(
3231 FilePath(path))) {
3232 reply.SendError(StringPrintf("Could not disable plugin for path %s.",
3233 path.c_str()));
3234 return;
3235 }
3236 reply.SendSuccess(NULL);
3237 }
3238
3239 // Sample json input:
3240 // { "command": "SaveTabContents",
3241 // "tab_index": 0,
3242 // "filename": <a full pathname> }
3243 // Sample json output:
3244 // {}
SaveTabContents(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)3245 void TestingAutomationProvider::SaveTabContents(
3246 Browser* browser,
3247 DictionaryValue* args,
3248 IPC::Message* reply_message) {
3249 int tab_index = 0;
3250 FilePath::StringType filename;
3251 FilePath::StringType parent_directory;
3252 TabContentsWrapper* tab_contents = NULL;
3253
3254 if (!args->GetInteger("tab_index", &tab_index) ||
3255 !args->GetString("filename", &filename)) {
3256 AutomationJSONReply(this, reply_message)
3257 .SendError("tab_index or filename param missing");
3258 return;
3259 } else {
3260 tab_contents = browser->GetTabContentsWrapperAt(tab_index);
3261 if (!tab_contents) {
3262 AutomationJSONReply(this, reply_message).SendError("no tab at tab_index");
3263 return;
3264 }
3265 }
3266 // We're doing a SAVE_AS_ONLY_HTML so the the directory path isn't
3267 // used. Nevertheless, SavePackage requires it be valid. Sigh.
3268 parent_directory = FilePath(filename).DirName().value();
3269 if (!tab_contents->download_tab_helper()->SavePage(
3270 FilePath(filename),
3271 FilePath(parent_directory),
3272 SavePackage::SAVE_AS_ONLY_HTML)) {
3273 AutomationJSONReply(this, reply_message).SendError(
3274 "Could not initiate SavePage");
3275 return;
3276 }
3277 // The observer will delete itself when done.
3278 new SavePackageNotificationObserver(
3279 tab_contents->download_tab_helper()->save_package(), this, reply_message);
3280 }
3281
3282 // Refer to ImportSettings() in chrome/test/pyautolib/pyauto.py for sample
3283 // json input.
3284 // Sample json output: "{}"
ImportSettings(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)3285 void TestingAutomationProvider::ImportSettings(Browser* browser,
3286 DictionaryValue* args,
3287 IPC::Message* reply_message) {
3288 // Map from the json string passed over to the import item masks.
3289 std::map<std::string, importer::ImportItem> string_to_import_item;
3290 string_to_import_item["HISTORY"] = importer::HISTORY;
3291 string_to_import_item["FAVORITES"] = importer::FAVORITES;
3292 string_to_import_item["COOKIES"] = importer::COOKIES;
3293 string_to_import_item["PASSWORDS"] = importer::PASSWORDS;
3294 string_to_import_item["SEARCH_ENGINES"] = importer::SEARCH_ENGINES;
3295 string_to_import_item["HOME_PAGE"] = importer::HOME_PAGE;
3296 string_to_import_item["ALL"] = importer::ALL;
3297
3298 ListValue* import_items_list = NULL;
3299 if (!args->GetString("import_from", &import_settings_data_.browser_name) ||
3300 !args->GetBoolean("first_run", &import_settings_data_.first_run) ||
3301 !args->GetList("import_items", &import_items_list)) {
3302 AutomationJSONReply(this, reply_message)
3303 .SendError("Incorrect type for one or more of the arguments.");
3304 return;
3305 }
3306
3307 import_settings_data_.import_items = 0;
3308 int num_items = import_items_list->GetSize();
3309 for (int i = 0; i < num_items; i++) {
3310 std::string item;
3311 import_items_list->GetString(i, &item);
3312 // If the provided string is not part of the map, error out.
3313 if (!ContainsKey(string_to_import_item, item)) {
3314 AutomationJSONReply(this, reply_message)
3315 .SendError("Invalid item string found in import_items.");
3316 return;
3317 }
3318 import_settings_data_.import_items |= string_to_import_item[item];
3319 }
3320
3321 import_settings_data_.browser = browser;
3322 import_settings_data_.reply_message = reply_message;
3323
3324 importer_list_ = new ImporterList;
3325 importer_list_->DetectSourceProfiles(this);
3326 }
3327
3328 namespace {
3329
3330 // Translates a dictionary password to a PasswordForm struct.
GetPasswordFormFromDict(const DictionaryValue & password_dict)3331 webkit_glue::PasswordForm GetPasswordFormFromDict(
3332 const DictionaryValue& password_dict) {
3333
3334 // If the time is specified, change time to the specified time.
3335 base::Time time = base::Time::Now();
3336 int it;
3337 double dt;
3338 if (password_dict.GetInteger("time", &it))
3339 time = base::Time::FromTimeT(it);
3340 else if (password_dict.GetDouble("time", &dt))
3341 time = base::Time::FromDoubleT(dt);
3342
3343 std::string signon_realm;
3344 string16 username_value;
3345 string16 password_value;
3346 string16 origin_url_text;
3347 string16 username_element;
3348 string16 password_element;
3349 string16 submit_element;
3350 string16 action_target_text;
3351 bool blacklist = false;
3352 string16 old_password_element;
3353 string16 old_password_value;
3354
3355 // We don't care if any of these fail - they are either optional or checked
3356 // before this function is called.
3357 password_dict.GetString("signon_realm", &signon_realm);
3358 password_dict.GetString("username_value", &username_value);
3359 password_dict.GetString("password_value", &password_value);
3360 password_dict.GetString("origin_url", &origin_url_text);
3361 password_dict.GetString("username_element", &username_element);
3362 password_dict.GetString("password_element", &password_element);
3363 password_dict.GetString("submit_element", &submit_element);
3364 password_dict.GetString("action_target", &action_target_text);
3365 password_dict.GetBoolean("blacklist", &blacklist);
3366
3367 GURL origin_gurl(origin_url_text);
3368 GURL action_target(action_target_text);
3369
3370 webkit_glue::PasswordForm password_form;
3371 password_form.signon_realm = signon_realm;
3372 password_form.username_value = username_value;
3373 password_form.password_value = password_value;
3374 password_form.origin = origin_gurl;
3375 password_form.username_element = username_element;
3376 password_form.password_element = password_element;
3377 password_form.submit_element = submit_element;
3378 password_form.action = action_target;
3379 password_form.blacklisted_by_user = blacklist;
3380 password_form.date_created = time;
3381
3382 return password_form;
3383 }
3384
3385 } // namespace
3386
3387 // See AddSavedPassword() in chrome/test/functional/pyauto.py for sample json
3388 // input.
3389 // Sample json output: { "password_added": true }
AddSavedPassword(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)3390 void TestingAutomationProvider::AddSavedPassword(
3391 Browser* browser,
3392 DictionaryValue* args,
3393 IPC::Message* reply_message) {
3394 AutomationJSONReply reply(this, reply_message);
3395 DictionaryValue* password_dict = NULL;
3396
3397 if (!args->GetDictionary("password", &password_dict)) {
3398 reply.SendError("Password must be a dictionary.");
3399 return;
3400 }
3401
3402 // The signon realm is effectively the primary key and must be included.
3403 // Check here before calling GetPasswordFormFromDict.
3404 if (!password_dict->HasKey("signon_realm")) {
3405 reply.SendError("Password must include signon_realm.");
3406 return;
3407 }
3408 webkit_glue::PasswordForm new_password =
3409 GetPasswordFormFromDict(*password_dict);
3410
3411 Profile* profile = browser->profile();
3412 // Use IMPLICIT_ACCESS since new passwords aren't added in incognito mode.
3413 PasswordStore* password_store =
3414 profile->GetPasswordStore(Profile::IMPLICIT_ACCESS);
3415
3416 // Set the return based on whether setting the password succeeded.
3417 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
3418
3419 // It will be null if it's accessed in an incognito window.
3420 if (password_store != NULL) {
3421 password_store->AddLogin(new_password);
3422 return_value->SetBoolean("password_added", true);
3423 } else {
3424 return_value->SetBoolean("password_added", false);
3425 }
3426
3427 reply.SendSuccess(return_value.get());
3428 }
3429
3430 // See RemoveSavedPassword() in chrome/test/functional/pyauto.py for sample
3431 // json input.
3432 // Sample json output: {}
RemoveSavedPassword(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)3433 void TestingAutomationProvider::RemoveSavedPassword(
3434 Browser* browser,
3435 DictionaryValue* args,
3436 IPC::Message* reply_message) {
3437 AutomationJSONReply reply(this, reply_message);
3438 DictionaryValue* password_dict = NULL;
3439
3440 if (!args->GetDictionary("password", &password_dict)) {
3441 reply.SendError("Password must be a dictionary.");
3442 return;
3443 }
3444
3445 // The signon realm is effectively the primary key and must be included.
3446 // Check here before calling GetPasswordFormFromDict.
3447 if (!password_dict->HasKey("signon_realm")) {
3448 reply.SendError("Password must include signon_realm.");
3449 return;
3450 }
3451 webkit_glue::PasswordForm to_remove =
3452 GetPasswordFormFromDict(*password_dict);
3453
3454 Profile* profile = browser->profile();
3455 // Use EXPLICIT_ACCESS since passwords can be removed in incognito mode.
3456 PasswordStore* password_store =
3457 profile->GetPasswordStore(Profile::EXPLICIT_ACCESS);
3458
3459 password_store->RemoveLogin(to_remove);
3460 reply.SendSuccess(NULL);
3461 }
3462
3463 // Sample json input: { "command": "GetSavedPasswords" }
3464 // Refer to GetSavedPasswords() in chrome/test/pyautolib/pyauto.py for sample
3465 // json output.
GetSavedPasswords(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)3466 void TestingAutomationProvider::GetSavedPasswords(
3467 Browser* browser,
3468 DictionaryValue* args,
3469 IPC::Message* reply_message) {
3470 Profile* profile = browser->profile();
3471 // Use EXPLICIT_ACCESS since saved passwords can be retrieved in
3472 // incognito mode.
3473 PasswordStore* password_store =
3474 profile->GetPasswordStore(Profile::EXPLICIT_ACCESS);
3475 password_store->GetAutofillableLogins(
3476 new AutomationProviderGetPasswordsObserver(this, reply_message));
3477 // Observer deletes itself after returning.
3478 }
3479
3480 // Refer to ClearBrowsingData() in chrome/test/pyautolib/pyauto.py for sample
3481 // json input.
3482 // Sample json output: {}
ClearBrowsingData(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)3483 void TestingAutomationProvider::ClearBrowsingData(
3484 Browser* browser,
3485 DictionaryValue* args,
3486 IPC::Message* reply_message) {
3487 std::map<std::string, BrowsingDataRemover::TimePeriod> string_to_time_period;
3488 string_to_time_period["LAST_HOUR"] = BrowsingDataRemover::LAST_HOUR;
3489 string_to_time_period["LAST_DAY"] = BrowsingDataRemover::LAST_DAY;
3490 string_to_time_period["LAST_WEEK"] = BrowsingDataRemover::LAST_WEEK;
3491 string_to_time_period["FOUR_WEEKS"] = BrowsingDataRemover::FOUR_WEEKS;
3492 string_to_time_period["EVERYTHING"] = BrowsingDataRemover::EVERYTHING;
3493
3494 std::map<std::string, int> string_to_mask_value;
3495 string_to_mask_value["HISTORY"] = BrowsingDataRemover::REMOVE_HISTORY;
3496 string_to_mask_value["DOWNLOADS"] = BrowsingDataRemover::REMOVE_DOWNLOADS;
3497 string_to_mask_value["COOKIES"] = BrowsingDataRemover::REMOVE_COOKIES;
3498 string_to_mask_value["PASSWORDS"] = BrowsingDataRemover::REMOVE_PASSWORDS;
3499 string_to_mask_value["FORM_DATA"] = BrowsingDataRemover::REMOVE_FORM_DATA;
3500 string_to_mask_value["CACHE"] = BrowsingDataRemover::REMOVE_CACHE;
3501
3502 std::string time_period;
3503 ListValue* to_remove;
3504 if (!args->GetString("time_period", &time_period) ||
3505 !args->GetList("to_remove", &to_remove)) {
3506 AutomationJSONReply(this, reply_message)
3507 .SendError("time_period must be a string and to_remove a list.");
3508 return;
3509 }
3510
3511 int remove_mask = 0;
3512 int num_removals = to_remove->GetSize();
3513 for (int i = 0; i < num_removals; i++) {
3514 std::string removal;
3515 to_remove->GetString(i, &removal);
3516 // If the provided string is not part of the map, then error out.
3517 if (!ContainsKey(string_to_mask_value, removal)) {
3518 AutomationJSONReply(this, reply_message)
3519 .SendError("Invalid browsing data string found in to_remove.");
3520 return;
3521 }
3522 remove_mask |= string_to_mask_value[removal];
3523 }
3524
3525 if (!ContainsKey(string_to_time_period, time_period)) {
3526 AutomationJSONReply(this, reply_message)
3527 .SendError("Invalid string for time_period.");
3528 return;
3529 }
3530
3531 BrowsingDataRemover* remover = new BrowsingDataRemover(
3532 profile(), string_to_time_period[time_period], base::Time());
3533
3534 remover->AddObserver(
3535 new AutomationProviderBrowsingDataObserver(this, reply_message));
3536 remover->Remove(remove_mask);
3537 // BrowsingDataRemover deletes itself using DeleteTask.
3538 // The observer also deletes itself after sending the reply.
3539 }
3540
3541 namespace {
3542
3543 // Get the TabContents from a dictionary of arguments.
GetTabContentsFromDict(const Browser * browser,const DictionaryValue * args,std::string * error_message)3544 TabContents* GetTabContentsFromDict(const Browser* browser,
3545 const DictionaryValue* args,
3546 std::string* error_message) {
3547 int tab_index;
3548 if (!args->GetInteger("tab_index", &tab_index)) {
3549 *error_message = "Must include tab_index.";
3550 return NULL;
3551 }
3552
3553 TabContents* tab_contents = browser->GetTabContentsAt(tab_index);
3554 if (!tab_contents) {
3555 *error_message = StringPrintf("No tab at index %d.", tab_index);
3556 return NULL;
3557 }
3558 return tab_contents;
3559 }
3560
3561 // Get the TranslateInfoBarDelegate from TabContents.
GetTranslateInfoBarDelegate(TabContents * tab_contents)3562 TranslateInfoBarDelegate* GetTranslateInfoBarDelegate(
3563 TabContents* tab_contents) {
3564 for (size_t i = 0; i < tab_contents->infobar_count(); i++) {
3565 InfoBarDelegate* infobar = tab_contents->GetInfoBarDelegateAt(i);
3566 if (infobar->AsTranslateInfoBarDelegate())
3567 return infobar->AsTranslateInfoBarDelegate();
3568 }
3569 // No translate infobar.
3570 return NULL;
3571 }
3572 } // namespace
3573
FindInPage(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)3574 void TestingAutomationProvider::FindInPage(
3575 Browser* browser,
3576 DictionaryValue* args,
3577 IPC::Message* reply_message) {
3578 std::string error_message;
3579 TabContents* tab_contents = GetTabContentsFromDict(browser, args,
3580 &error_message);
3581 if (!tab_contents) {
3582 AutomationJSONReply(this, reply_message).SendError(error_message);
3583 return;
3584 }
3585 string16 search_string;
3586 bool forward;
3587 bool match_case;
3588 bool find_next;
3589 if (!args->GetString("search_string", &search_string)) {
3590 AutomationJSONReply(this, reply_message).
3591 SendError("Must include search_string string.");
3592 return;
3593 }
3594 if (!args->GetBoolean("forward", &forward)) {
3595 AutomationJSONReply(this, reply_message).
3596 SendError("Must include forward boolean.");
3597 return;
3598 }
3599 if (!args->GetBoolean("match_case", &match_case)) {
3600 AutomationJSONReply(this, reply_message).
3601 SendError("Must include match_case boolean.");
3602 return;
3603 }
3604 if (!args->GetBoolean("find_next", &find_next)) {
3605 AutomationJSONReply(this, reply_message).
3606 SendError("Must include find_next boolean.");
3607 return;
3608 }
3609 SendFindRequest(tab_contents,
3610 true,
3611 search_string,
3612 forward,
3613 match_case,
3614 find_next,
3615 reply_message);
3616 }
3617
3618 // See GetTranslateInfo() in chrome/test/pyautolib/pyauto.py for sample json
3619 // input and output.
GetTranslateInfo(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)3620 void TestingAutomationProvider::GetTranslateInfo(
3621 Browser* browser,
3622 DictionaryValue* args,
3623 IPC::Message* reply_message) {
3624 std::string error_message;
3625 TabContents* tab_contents = GetTabContentsFromDict(browser, args,
3626 &error_message);
3627 if (!tab_contents) {
3628 AutomationJSONReply(this, reply_message).SendError(error_message);
3629 return;
3630 }
3631
3632 // Get the translate bar if there is one and pass it to the observer.
3633 // The observer will check for null and populate the information accordingly.
3634 TranslateInfoBarDelegate* translate_bar =
3635 GetTranslateInfoBarDelegate(tab_contents);
3636
3637 TabLanguageDeterminedObserver* observer = new TabLanguageDeterminedObserver(
3638 this, reply_message, tab_contents, translate_bar);
3639 // If the language for the page hasn't been loaded yet, then just make
3640 // the observer, otherwise call observe directly.
3641 TranslateTabHelper* helper = TabContentsWrapper::GetCurrentWrapperForContents(
3642 tab_contents)->translate_tab_helper();
3643 std::string language = helper->language_state().original_language();
3644 if (!language.empty()) {
3645 observer->Observe(NotificationType::TAB_LANGUAGE_DETERMINED,
3646 Source<TabContents>(tab_contents),
3647 Details<std::string>(&language));
3648 }
3649 }
3650
3651 // See SelectTranslateOption() in chrome/test/pyautolib/pyauto.py for sample
3652 // json input.
3653 // Sample json output: {}
SelectTranslateOption(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)3654 void TestingAutomationProvider::SelectTranslateOption(
3655 Browser* browser,
3656 DictionaryValue* args,
3657 IPC::Message* reply_message) {
3658 std::string option;
3659 std::string error_message;
3660 TabContents* tab_contents = GetTabContentsFromDict(browser, args,
3661 &error_message);
3662 if (!tab_contents) {
3663 AutomationJSONReply(this, reply_message).SendError(error_message);
3664 return;
3665 }
3666
3667 TranslateInfoBarDelegate* translate_bar =
3668 GetTranslateInfoBarDelegate(tab_contents);
3669 if (!translate_bar) {
3670 AutomationJSONReply(this, reply_message)
3671 .SendError("There is no translate bar open.");
3672 return;
3673 }
3674
3675 if (!args->GetString("option", &option)) {
3676 AutomationJSONReply(this, reply_message).SendError("Must include option");
3677 return;
3678 }
3679
3680 if (option == "translate_page") {
3681 // Make a new notification observer which will send the reply.
3682 new PageTranslatedObserver(this, reply_message, tab_contents);
3683 translate_bar->Translate();
3684 return;
3685 } else if (option == "set_target_language") {
3686 string16 target_language;
3687 if (!args->GetString("target_language", &target_language)) {
3688 AutomationJSONReply(this, reply_message)
3689 .SendError("Must include target_language string.");
3690 return;
3691 }
3692 // Get the target language index based off of the language name.
3693 size_t target_language_index = TranslateInfoBarDelegate::kNoIndex;
3694 for (size_t i = 0; i < translate_bar->GetLanguageCount(); i++) {
3695 if (translate_bar->GetLanguageDisplayableNameAt(i) == target_language) {
3696 target_language_index = i;
3697 break;
3698 }
3699 }
3700 if (target_language_index == TranslateInfoBarDelegate::kNoIndex) {
3701 AutomationJSONReply(this, reply_message)
3702 .SendError("Invalid target language string.");
3703 return;
3704 }
3705 // If the page has already been translated it will be translated again to
3706 // the new language. The observer will wait until the page has been
3707 // translated to reply.
3708 if (translate_bar->type() == TranslateInfoBarDelegate::AFTER_TRANSLATE) {
3709 new PageTranslatedObserver(this, reply_message, tab_contents);
3710 translate_bar->SetTargetLanguage(target_language_index);
3711 return;
3712 }
3713 // Otherwise just send the reply back immediately.
3714 translate_bar->SetTargetLanguage(target_language_index);
3715 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
3716 return_value->SetBoolean("translation_success", true);
3717 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
3718 return;
3719 } else if (option == "click_always_translate_lang_button") {
3720 if (!translate_bar->ShouldShowAlwaysTranslateButton()) {
3721 AutomationJSONReply(this, reply_message)
3722 .SendError("Always translate button not showing.");
3723 return;
3724 }
3725 // Clicking 'Always Translate' triggers a translation. The observer will
3726 // wait until the translation is complete before sending the reply.
3727 new PageTranslatedObserver(this, reply_message, tab_contents);
3728 translate_bar->AlwaysTranslatePageLanguage();
3729 return;
3730 }
3731
3732 AutomationJSONReply reply(this, reply_message);
3733 if (option == "never_translate_language") {
3734 if (translate_bar->IsLanguageBlacklisted()) {
3735 reply.SendError("The language was already blacklisted.");
3736 return;
3737 }
3738 translate_bar->ToggleLanguageBlacklist();
3739 reply.SendSuccess(NULL);
3740 } else if (option == "never_translate_site") {
3741 if (translate_bar->IsSiteBlacklisted()) {
3742 reply.SendError("The site was already blacklisted.");
3743 return;
3744 }
3745 translate_bar->ToggleSiteBlacklist();
3746 reply.SendSuccess(NULL);
3747 } else if (option == "toggle_always_translate") {
3748 translate_bar->ToggleAlwaysTranslate();
3749 reply.SendSuccess(NULL);
3750 } else if (option == "revert_translation") {
3751 translate_bar->RevertTranslation();
3752 reply.SendSuccess(NULL);
3753 } else if (option == "click_never_translate_lang_button") {
3754 if (!translate_bar->ShouldShowNeverTranslateButton()) {
3755 reply.SendError("Always translate button not showing.");
3756 return;
3757 }
3758 translate_bar->NeverTranslatePageLanguage();
3759 reply.SendSuccess(NULL);
3760 } else if (option == "decline_translation") {
3761 // This is the function called when an infobar is dismissed or when the
3762 // user clicks the 'Nope' translate button.
3763 translate_bar->TranslationDeclined();
3764 tab_contents->RemoveInfoBar(translate_bar);
3765 reply.SendSuccess(NULL);
3766 } else {
3767 reply.SendError("Invalid string found for option.");
3768 }
3769 }
3770
3771 // Sample json input: { "command": "GetBlockedPopupsInfo",
3772 // "tab_index": 1 }
3773 // Refer GetBlockedPopupsInfo() in pyauto.py for sample output.
GetBlockedPopupsInfo(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)3774 void TestingAutomationProvider::GetBlockedPopupsInfo(
3775 Browser* browser,
3776 DictionaryValue* args,
3777 IPC::Message* reply_message) {
3778 AutomationJSONReply reply(this, reply_message);
3779 std::string error_message;
3780 TabContents* tab_contents = GetTabContentsFromDict(
3781 browser, args, &error_message);
3782 if (!tab_contents) {
3783 reply.SendError(error_message);
3784 return;
3785 }
3786 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
3787 BlockedContentContainer* popup_container =
3788 tab_contents->blocked_content_container();
3789 ListValue* blocked_popups_list = new ListValue;
3790 if (popup_container) {
3791 std::vector<TabContents*> blocked_contents;
3792 popup_container->GetBlockedContents(&blocked_contents);
3793 for (std::vector<TabContents*>::const_iterator it =
3794 blocked_contents.begin(); it != blocked_contents.end(); ++it) {
3795 DictionaryValue* item = new DictionaryValue;
3796 item->SetString("url", (*it)->GetURL().spec());
3797 item->SetString("title", (*it)->GetTitle());
3798 blocked_popups_list->Append(item);
3799 }
3800 }
3801 return_value->Set("blocked_popups", blocked_popups_list);
3802 reply.SendSuccess(return_value.get());
3803 }
3804
3805 // Refer UnblockAndLaunchBlockedPopup() in pyauto.py for sample input.
UnblockAndLaunchBlockedPopup(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)3806 void TestingAutomationProvider::UnblockAndLaunchBlockedPopup(
3807 Browser* browser,
3808 DictionaryValue* args,
3809 IPC::Message* reply_message) {
3810 AutomationJSONReply reply(this, reply_message);
3811 std::string error_message;
3812 TabContents* tab_contents = GetTabContentsFromDict(
3813 browser, args, &error_message);
3814 if (!tab_contents) {
3815 reply.SendError(error_message);
3816 return;
3817 }
3818 int popup_index;
3819 if (!args->GetInteger("popup_index", &popup_index)) {
3820 reply.SendError("Need popup_index arg");
3821 return;
3822 }
3823 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
3824 BlockedContentContainer* content_container =
3825 tab_contents->blocked_content_container();
3826 if (!content_container ||
3827 popup_index >= (int)content_container->GetBlockedContentsCount()) {
3828 reply.SendError(StringPrintf("No popup at index %d", popup_index));
3829 return;
3830 }
3831 std::vector<TabContents*> blocked_contents;
3832 content_container->GetBlockedContents(&blocked_contents);
3833 content_container->LaunchForContents(blocked_contents[popup_index]);
3834 reply.SendSuccess(NULL);
3835 }
3836
3837 // Sample json input: { "command": "GetThemeInfo" }
3838 // Refer GetThemeInfo() in chrome/test/pyautolib/pyauto.py for sample output.
GetThemeInfo(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)3839 void TestingAutomationProvider::GetThemeInfo(
3840 Browser* browser,
3841 DictionaryValue* args,
3842 IPC::Message* reply_message) {
3843 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
3844 const Extension* theme = ThemeServiceFactory::GetThemeForProfile(profile());
3845 if (theme) {
3846 return_value->SetString("name", theme->name());
3847 return_value->Set("images", theme->GetThemeImages()->DeepCopy());
3848 return_value->Set("colors", theme->GetThemeColors()->DeepCopy());
3849 return_value->Set("tints", theme->GetThemeTints()->DeepCopy());
3850 }
3851 AutomationJSONReply(this, reply_message).SendSuccess(return_value.get());
3852 }
3853
3854 namespace {
3855
GetHostPermissions(const Extension * ext)3856 ListValue* GetHostPermissions(const Extension* ext) {
3857 ListValue* permissions = new ListValue;
3858 const URLPatternList pattern_list =
3859 ext->GetEffectiveHostPermissions().patterns();
3860 for (URLPatternList::const_iterator perm = pattern_list.begin();
3861 perm != pattern_list.end(); ++perm) {
3862 permissions->Append(new StringValue(perm->GetAsString()));
3863 }
3864 return permissions;
3865 }
3866
GetAPIPermissions(const Extension * ext)3867 ListValue* GetAPIPermissions(const Extension* ext) {
3868 ListValue* permissions = new ListValue;
3869 std::set<std::string> perm_list = ext->api_permissions();
3870 for (std::set<std::string>::const_iterator perm = perm_list.begin();
3871 perm != perm_list.end(); ++perm) {
3872 permissions->Append(new StringValue(perm->c_str()));
3873 }
3874 return permissions;
3875 }
3876
3877 } // namespace
3878
3879 // Sample json input: { "command": "GetExtensionsInfo" }
3880 // See GetExtensionsInfo() in chrome/test/pyautolib/pyauto.py for sample json
3881 // output.
GetExtensionsInfo(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)3882 void TestingAutomationProvider::GetExtensionsInfo(
3883 Browser* browser,
3884 DictionaryValue* args,
3885 IPC::Message* reply_message) {
3886 AutomationJSONReply reply(this, reply_message);
3887 ExtensionService* service = profile()->GetExtensionService();
3888 if (!service) {
3889 reply.SendError("No extensions service.");
3890 }
3891 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
3892 ListValue* extensions_values = new ListValue;
3893 const ExtensionList* extensions = service->extensions();
3894 for (ExtensionList::const_iterator it = extensions->begin();
3895 it != extensions->end(); ++it) {
3896 const Extension* extension = *it;
3897 DictionaryValue* extension_value = new DictionaryValue;
3898 extension_value->SetString("id", extension->id());
3899 extension_value->SetString("version", extension->VersionString());
3900 extension_value->SetString("name", extension->name());
3901 extension_value->SetString("public_key", extension->public_key());
3902 extension_value->SetString("description", extension->description());
3903 extension_value->SetString("background_url",
3904 extension->background_url().spec());
3905 extension_value->SetString("options_url",
3906 extension->options_url().spec());
3907 extension_value->Set("host_permissions", GetHostPermissions(extension));
3908 extension_value->Set("api_permissions", GetAPIPermissions(extension));
3909 extensions_values->Append(extension_value);
3910 }
3911 return_value->Set("extensions", extensions_values);
3912 reply.SendSuccess(return_value.get());
3913 }
3914
3915 // See UninstallExtensionById() in chrome/test/pyautolib/pyauto.py for sample
3916 // json input.
3917 // Sample json output: {}
UninstallExtensionById(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)3918 void TestingAutomationProvider::UninstallExtensionById(
3919 Browser* browser,
3920 DictionaryValue* args,
3921 IPC::Message* reply_message) {
3922 std::string id;
3923 if (!args->GetString("id", &id)) {
3924 AutomationJSONReply(this, reply_message).SendError(
3925 "Must include string id.");
3926 return;
3927 }
3928 ExtensionService* service = profile()->GetExtensionService();
3929 if (!service) {
3930 AutomationJSONReply(this, reply_message).SendError(
3931 "No extensions service.");
3932 return;
3933 }
3934
3935 if (!service->GetExtensionById(id, true) &&
3936 !service->GetTerminatedExtension(id)) {
3937 // The extension ID does not correspond to any extension, whether crashed
3938 // or not.
3939 AutomationJSONReply(this, reply_message).SendError(base::StringPrintf(
3940 "Extension does not exist: %s.", id.c_str()));
3941 return;
3942 }
3943
3944 // Wait for a notification indicating that the extension with the given ID
3945 // has been uninstalled. This observer will delete itself.
3946 new ExtensionUninstallObserver(this, reply_message, id);
3947 service->UninstallExtension(id, false, NULL);
3948 }
3949
3950 // Sample json input:
3951 // { "command": "GetAutofillProfile" }
3952 // Refer to GetAutofillProfile() in chrome/test/pyautolib/pyauto.py for sample
3953 // json output.
GetAutofillProfile(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)3954 void TestingAutomationProvider::GetAutofillProfile(
3955 Browser* browser,
3956 DictionaryValue* args,
3957 IPC::Message* reply_message) {
3958 AutomationJSONReply reply(this, reply_message);
3959 // Get the AutofillProfiles currently in the database.
3960 int tab_index = 0;
3961 if (!args->GetInteger("tab_index", &tab_index)) {
3962 reply.SendError("Invalid or missing tab_index integer value.");
3963 return;
3964 }
3965
3966 TabContents* tab_contents = browser->GetTabContentsAt(tab_index);
3967 if (tab_contents) {
3968 PersonalDataManager* pdm = tab_contents->profile()->GetOriginalProfile()
3969 ->GetPersonalDataManager();
3970 if (pdm) {
3971 std::vector<AutofillProfile*> autofill_profiles = pdm->profiles();
3972 std::vector<CreditCard*> credit_cards = pdm->credit_cards();
3973
3974 ListValue* profiles = GetListFromAutofillProfiles(autofill_profiles);
3975 ListValue* cards = GetListFromCreditCards(credit_cards);
3976
3977 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
3978
3979 return_value->Set("profiles", profiles);
3980 return_value->Set("credit_cards", cards);
3981 reply.SendSuccess(return_value.get());
3982 } else {
3983 reply.SendError("No PersonalDataManager.");
3984 return;
3985 }
3986 } else {
3987 reply.SendError("No tab at that index.");
3988 return;
3989 }
3990 }
3991
3992 // Refer to FillAutofillProfile() in chrome/test/pyautolib/pyauto.py for sample
3993 // json input.
3994 // Sample json output: {}
FillAutofillProfile(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)3995 void TestingAutomationProvider::FillAutofillProfile(
3996 Browser* browser,
3997 DictionaryValue* args,
3998 IPC::Message* reply_message) {
3999 AutomationJSONReply reply(this, reply_message);
4000 ListValue* profiles = NULL;
4001 ListValue* cards = NULL;
4002
4003 // It's ok for profiles/credit_cards elements to be missing.
4004 args->GetList("profiles", &profiles);
4005 args->GetList("credit_cards", &cards);
4006
4007 std::string error_mesg;
4008
4009 std::vector<AutofillProfile> autofill_profiles;
4010 std::vector<CreditCard> credit_cards;
4011 // Create an AutofillProfile for each of the dictionary profiles.
4012 if (profiles) {
4013 autofill_profiles = GetAutofillProfilesFromList(*profiles, &error_mesg);
4014 }
4015 // Create a CreditCard for each of the dictionary values.
4016 if (cards) {
4017 credit_cards = GetCreditCardsFromList(*cards, &error_mesg);
4018 }
4019 if (!error_mesg.empty()) {
4020 reply.SendError(error_mesg);
4021 return;
4022 }
4023
4024 // Save the AutofillProfiles.
4025 int tab_index = 0;
4026 if (!args->GetInteger("tab_index", &tab_index)) {
4027 reply.SendError("Invalid or missing tab_index integer");
4028 return;
4029 }
4030
4031 TabContents* tab_contents = browser->GetTabContentsAt(tab_index);
4032
4033 if (tab_contents) {
4034 PersonalDataManager* pdm = tab_contents->profile()
4035 ->GetPersonalDataManager();
4036 if (pdm) {
4037 if (profiles)
4038 pdm->SetProfiles(&autofill_profiles);
4039 if (cards)
4040 pdm->SetCreditCards(&credit_cards);
4041 } else {
4042 reply.SendError("No PersonalDataManager.");
4043 return;
4044 }
4045 } else {
4046 reply.SendError("No tab at that index.");
4047 return;
4048 }
4049 reply.SendSuccess(NULL);
4050 }
4051
4052 // Sample json output: { "success": true }
SignInToSync(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)4053 void TestingAutomationProvider::SignInToSync(Browser* browser,
4054 DictionaryValue* args,
4055 IPC::Message* reply_message) {
4056 AutomationJSONReply reply(this, reply_message);
4057 std::string username;
4058 std::string password;
4059 if (!args->GetString("username", &username) ||
4060 !args->GetString("password", &password)) {
4061 reply.SendError("Invalid or missing args");
4062 return;
4063 }
4064 if (sync_waiter_.get() == NULL) {
4065 sync_waiter_.reset(new ProfileSyncServiceHarness(
4066 browser->profile(), username, password, 0));
4067 } else {
4068 sync_waiter_->SetCredentials(username, password);
4069 }
4070 if (sync_waiter_->SetupSync()) {
4071 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
4072 return_value->SetBoolean("success", true);
4073 reply.SendSuccess(return_value.get());
4074 } else {
4075 reply.SendError("Signing in to sync was unsuccessful");
4076 }
4077 }
4078
4079 // Sample json output:
4080 // {u'summary': u'SYNC DISABLED'}
4081 //
4082 // { u'authenticated': True,
4083 // u'last synced': u'Just now',
4084 // u'summary': u'READY',
4085 // u'sync url': u'clients4.google.com',
4086 // u'updates received': 42,
4087 // u'synced datatypes': [ u'Bookmarks',
4088 // u'Preferences',
4089 // u'Passwords',
4090 // u'Autofill',
4091 // u'Themes',
4092 // u'Extensions',
4093 // u'Apps']}
GetSyncInfo(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)4094 void TestingAutomationProvider::GetSyncInfo(Browser* browser,
4095 DictionaryValue* args,
4096 IPC::Message* reply_message) {
4097 AutomationJSONReply reply(this, reply_message);
4098 DictionaryValue* sync_info = new DictionaryValue;
4099 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
4100 if (sync_waiter_.get() == NULL) {
4101 sync_waiter_.reset(
4102 ProfileSyncServiceHarness::CreateAndAttach(browser->profile()));
4103 }
4104 if (!sync_waiter_->IsSyncAlreadySetup()) {
4105 sync_info->SetString("summary", "SYNC DISABLED");
4106 } else {
4107 ProfileSyncService* service = sync_waiter_->service();
4108 ProfileSyncService::Status status = sync_waiter_->GetStatus();
4109 sync_info->SetString("summary",
4110 ProfileSyncService::BuildSyncStatusSummaryText(status.summary));
4111 sync_info->SetString("sync url", service->sync_service_url().host());
4112 sync_info->SetBoolean("authenticated", status.authenticated);
4113 sync_info->SetString("last synced", service->GetLastSyncedTimeString());
4114 sync_info->SetInteger("updates received", status.updates_received);
4115 ListValue* synced_datatype_list = new ListValue;
4116 syncable::ModelTypeSet synced_datatypes;
4117 service->GetPreferredDataTypes(&synced_datatypes);
4118 for (syncable::ModelTypeSet::iterator it = synced_datatypes.begin();
4119 it != synced_datatypes.end(); ++it) {
4120 synced_datatype_list->Append(
4121 new StringValue(syncable::ModelTypeToString(*it)));
4122 }
4123 sync_info->Set("synced datatypes", synced_datatype_list);
4124 }
4125 return_value->Set("sync_info", sync_info);
4126 reply.SendSuccess(return_value.get());
4127 }
4128
4129 // Sample json output: { "success": true }
AwaitSyncCycleCompletion(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)4130 void TestingAutomationProvider::AwaitSyncCycleCompletion(
4131 Browser* browser,
4132 DictionaryValue* args,
4133 IPC::Message* reply_message) {
4134 AutomationJSONReply reply(this, reply_message);
4135 if (sync_waiter_.get() == NULL) {
4136 sync_waiter_.reset(
4137 ProfileSyncServiceHarness::CreateAndAttach(browser->profile()));
4138 }
4139 if (!sync_waiter_->IsSyncAlreadySetup()) {
4140 reply.SendError("Not signed in to sync");
4141 return;
4142 }
4143 // Ensure that the profile sync service is initialized before waiting for sync
4144 // to complete. In cases where the browser is restarted with sync enabled,
4145 // the sync service may take a while to get reinitialized.
4146 if (!browser->profile()->GetProfileSyncService()) {
4147 reply.SendError("ProfileSyncService not initialized.");
4148 return;
4149 }
4150 sync_waiter_->AwaitSyncCycleCompletion("Waiting for sync cycle");
4151 ProfileSyncService::Status status = sync_waiter_->GetStatus();
4152 if (status.summary == ProfileSyncService::Status::READY) {
4153 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
4154 return_value->SetBoolean("success", true);
4155 reply.SendSuccess(return_value.get());
4156 } else {
4157 std::string error_msg = "Wait for sync cycle was unsuccessful. "
4158 "Sync status: ";
4159 error_msg.append(
4160 ProfileSyncService::BuildSyncStatusSummaryText(status.summary));
4161 reply.SendError(error_msg);
4162 }
4163 }
4164
4165 // Refer to EnableSyncForDatatypes() in chrome/test/pyautolib/pyauto.py for
4166 // sample json input. Sample json output: { "success": true }
EnableSyncForDatatypes(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)4167 void TestingAutomationProvider::EnableSyncForDatatypes(
4168 Browser* browser,
4169 DictionaryValue* args,
4170 IPC::Message* reply_message) {
4171 AutomationJSONReply reply(this, reply_message);
4172 if (sync_waiter_.get() == NULL) {
4173 sync_waiter_.reset(
4174 ProfileSyncServiceHarness::CreateAndAttach(browser->profile()));
4175 }
4176 if (!sync_waiter_->IsSyncAlreadySetup()) {
4177 reply.SendError("Not signed in to sync");
4178 return;
4179 }
4180 ListValue* datatypes = NULL;
4181 if (!args->GetList("datatypes", &datatypes)) {
4182 reply.SendError("Invalid or missing args");
4183 return;
4184 }
4185 std::string first_datatype;
4186 datatypes->GetString(0, &first_datatype);
4187 if (first_datatype == "All") {
4188 sync_waiter_->EnableSyncForAllDatatypes();
4189 } else {
4190 int num_datatypes = datatypes->GetSize();
4191 for (int i = 0; i < num_datatypes; ++i) {
4192 std::string datatype_string;
4193 datatypes->GetString(i, &datatype_string);
4194 syncable::ModelType datatype =
4195 syncable::ModelTypeFromString(datatype_string);
4196 if (datatype == syncable::UNSPECIFIED) {
4197 AutomationJSONReply(this, reply_message).SendError(StringPrintf(
4198 "Invalid datatype string: %s.", datatype_string.c_str()));
4199 return;
4200 }
4201 sync_waiter_->EnableSyncForDatatype(datatype);
4202 sync_waiter_->AwaitSyncCycleCompletion(StringPrintf(
4203 "Enabling datatype: %s", datatype_string.c_str()));
4204 }
4205 }
4206 ProfileSyncService::Status status = sync_waiter_->GetStatus();
4207 if (status.summary == ProfileSyncService::Status::READY ||
4208 status.summary == ProfileSyncService::Status::SYNCING) {
4209 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
4210 return_value->SetBoolean("success", true);
4211 reply.SendSuccess(return_value.get());
4212 } else {
4213 reply.SendError("Enabling sync for given datatypes was unsuccessful");
4214 }
4215 }
4216
4217 // Refer to DisableSyncForDatatypes() in chrome/test/pyautolib/pyauto.py for
4218 // sample json input. Sample json output: { "success": true }
DisableSyncForDatatypes(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)4219 void TestingAutomationProvider::DisableSyncForDatatypes(
4220 Browser* browser,
4221 DictionaryValue* args,
4222 IPC::Message* reply_message) {
4223 AutomationJSONReply reply(this, reply_message);
4224 if (sync_waiter_.get() == NULL) {
4225 sync_waiter_.reset(
4226 ProfileSyncServiceHarness::CreateAndAttach(browser->profile()));
4227 }
4228 if (!sync_waiter_->IsSyncAlreadySetup()) {
4229 reply.SendError("Not signed in to sync");
4230 return;
4231 }
4232 ListValue* datatypes = NULL;
4233 if (!args->GetList("datatypes", &datatypes)) {
4234 reply.SendError("Invalid or missing args");
4235 return;
4236 }
4237 std::string first_datatype;
4238 if (!datatypes->GetString(0, &first_datatype)) {
4239 reply.SendError("Invalid or missing string");
4240 return;
4241 }
4242 if (first_datatype == "All") {
4243 sync_waiter_->DisableSyncForAllDatatypes();
4244 ProfileSyncService::Status status = sync_waiter_->GetStatus();
4245 if (status.summary != ProfileSyncService::Status::READY &&
4246 status.summary != ProfileSyncService::Status::SYNCING) {
4247 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
4248 return_value->SetBoolean("success", true);
4249 reply.SendSuccess(return_value.get());
4250 } else {
4251 reply.SendError("Disabling all sync datatypes was unsuccessful");
4252 }
4253 } else {
4254 int num_datatypes = datatypes->GetSize();
4255 for (int i = 0; i < num_datatypes; i++) {
4256 std::string datatype_string;
4257 datatypes->GetString(i, &datatype_string);
4258 syncable::ModelType datatype =
4259 syncable::ModelTypeFromString(datatype_string);
4260 if (datatype == syncable::UNSPECIFIED) {
4261 AutomationJSONReply(this, reply_message).SendError(StringPrintf(
4262 "Invalid datatype string: %s.", datatype_string.c_str()));
4263 return;
4264 }
4265 sync_waiter_->DisableSyncForDatatype(datatype);
4266 sync_waiter_->AwaitSyncCycleCompletion(StringPrintf(
4267 "Disabling datatype: %s", datatype_string.c_str()));
4268 }
4269 ProfileSyncService::Status status = sync_waiter_->GetStatus();
4270 if (status.summary == ProfileSyncService::Status::READY ||
4271 status.summary == ProfileSyncService::Status::SYNCING) {
4272 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
4273 return_value->SetBoolean("success", true);
4274 reply.SendSuccess(return_value.get());
4275 } else {
4276 reply.SendError("Disabling sync for given datatypes was unsuccessful");
4277 }
4278 }
4279 }
4280
4281 /* static */
GetListFromAutofillProfiles(const std::vector<AutofillProfile * > & autofill_profiles)4282 ListValue* TestingAutomationProvider::GetListFromAutofillProfiles(
4283 const std::vector<AutofillProfile*>& autofill_profiles) {
4284 ListValue* profiles = new ListValue;
4285
4286 std::map<AutofillFieldType, std::string> autofill_type_to_string
4287 = GetAutofillFieldToStringMap();
4288
4289 // For each AutofillProfile, transform it to a dictionary object to return.
4290 for (std::vector<AutofillProfile*>::const_iterator it =
4291 autofill_profiles.begin();
4292 it != autofill_profiles.end(); ++it) {
4293 AutofillProfile* profile = *it;
4294 DictionaryValue* profile_info = new DictionaryValue;
4295 // For each of the types, if it has a value, add it to the dictionary.
4296 for (std::map<AutofillFieldType, std::string>::iterator
4297 type_it = autofill_type_to_string.begin();
4298 type_it != autofill_type_to_string.end(); ++type_it) {
4299 string16 value = profile->GetInfo(type_it->first);
4300 if (value.length()) { // If there was something stored for that value.
4301 profile_info->SetString(type_it->second, value);
4302 }
4303 }
4304 profiles->Append(profile_info);
4305 }
4306 return profiles;
4307 }
4308
4309 /* static */
GetListFromCreditCards(const std::vector<CreditCard * > & credit_cards)4310 ListValue* TestingAutomationProvider::GetListFromCreditCards(
4311 const std::vector<CreditCard*>& credit_cards) {
4312 ListValue* cards = new ListValue;
4313
4314 std::map<AutofillFieldType, std::string> credit_card_type_to_string =
4315 GetCreditCardFieldToStringMap();
4316
4317 // For each AutofillProfile, transform it to a dictionary object to return.
4318 for (std::vector<CreditCard*>::const_iterator it =
4319 credit_cards.begin();
4320 it != credit_cards.end(); ++it) {
4321 CreditCard* card = *it;
4322 DictionaryValue* card_info = new DictionaryValue;
4323 // For each of the types, if it has a value, add it to the dictionary.
4324 for (std::map<AutofillFieldType, std::string>::iterator type_it =
4325 credit_card_type_to_string.begin();
4326 type_it != credit_card_type_to_string.end(); ++type_it) {
4327 string16 value = card->GetInfo(type_it->first);
4328 // If there was something stored for that value.
4329 if (value.length()) {
4330 card_info->SetString(type_it->second, value);
4331 }
4332 }
4333 cards->Append(card_info);
4334 }
4335 return cards;
4336 }
4337
4338 /* static */
4339 std::vector<AutofillProfile>
GetAutofillProfilesFromList(const ListValue & profiles,std::string * error_message)4340 TestingAutomationProvider::GetAutofillProfilesFromList(
4341 const ListValue& profiles, std::string* error_message) {
4342 std::vector<AutofillProfile> autofill_profiles;
4343 DictionaryValue* profile_info = NULL;
4344 string16 current_value;
4345
4346 std::map<AutofillFieldType, std::string> autofill_type_to_string =
4347 GetAutofillFieldToStringMap();
4348
4349 int num_profiles = profiles.GetSize();
4350 for (int i = 0; i < num_profiles; i++) {
4351 profiles.GetDictionary(i, &profile_info);
4352 AutofillProfile profile;
4353 // Loop through the possible profile types and add those provided.
4354 for (std::map<AutofillFieldType, std::string>::iterator type_it =
4355 autofill_type_to_string.begin();
4356 type_it != autofill_type_to_string.end(); ++type_it) {
4357 if (profile_info->HasKey(type_it->second)) {
4358 if (profile_info->GetString(type_it->second,
4359 ¤t_value)) {
4360 profile.SetInfo(type_it->first, current_value);
4361 } else {
4362 *error_message= "All values must be strings";
4363 break;
4364 }
4365 }
4366 }
4367 autofill_profiles.push_back(profile);
4368 }
4369 return autofill_profiles;
4370 }
4371
4372 /* static */
GetCreditCardsFromList(const ListValue & cards,std::string * error_message)4373 std::vector<CreditCard> TestingAutomationProvider::GetCreditCardsFromList(
4374 const ListValue& cards, std::string* error_message) {
4375 std::vector<CreditCard> credit_cards;
4376 DictionaryValue* card_info = NULL;
4377 string16 current_value;
4378
4379 std::map<AutofillFieldType, std::string> credit_card_type_to_string =
4380 GetCreditCardFieldToStringMap();
4381
4382 int num_credit_cards = cards.GetSize();
4383 for (int i = 0; i < num_credit_cards; i++) {
4384 cards.GetDictionary(i, &card_info);
4385 CreditCard card;
4386 // Loop through the possible credit card fields and add those provided.
4387 for (std::map<AutofillFieldType, std::string>::iterator type_it =
4388 credit_card_type_to_string.begin();
4389 type_it != credit_card_type_to_string.end(); ++type_it) {
4390 if (card_info->HasKey(type_it->second)) {
4391 if (card_info->GetString(type_it->second, ¤t_value)) {
4392 card.SetInfo(type_it->first, current_value);
4393 } else {
4394 *error_message= "All values must be strings";
4395 break;
4396 }
4397 }
4398 }
4399 credit_cards.push_back(card);
4400 }
4401 return credit_cards;
4402 }
4403
4404 /* static */
4405 std::map<AutofillFieldType, std::string>
GetAutofillFieldToStringMap()4406 TestingAutomationProvider::GetAutofillFieldToStringMap() {
4407 std::map<AutofillFieldType, std::string> autofill_type_to_string;
4408 // Strings ordered by order of fields when adding a profile in Autofill prefs.
4409 autofill_type_to_string[NAME_FIRST] = "NAME_FIRST";
4410 autofill_type_to_string[NAME_MIDDLE] = "NAME_MIDDLE";
4411 autofill_type_to_string[NAME_LAST] = "NAME_LAST";
4412 autofill_type_to_string[COMPANY_NAME] = "COMPANY_NAME";
4413 autofill_type_to_string[EMAIL_ADDRESS] = "EMAIL_ADDRESS";
4414 autofill_type_to_string[ADDRESS_HOME_LINE1] = "ADDRESS_HOME_LINE1";
4415 autofill_type_to_string[ADDRESS_HOME_LINE2] = "ADDRESS_HOME_LINE2";
4416 autofill_type_to_string[ADDRESS_HOME_CITY] = "ADDRESS_HOME_CITY";
4417 autofill_type_to_string[ADDRESS_HOME_STATE] = "ADDRESS_HOME_STATE";
4418 autofill_type_to_string[ADDRESS_HOME_ZIP] = "ADDRESS_HOME_ZIP";
4419 autofill_type_to_string[ADDRESS_HOME_COUNTRY] = "ADDRESS_HOME_COUNTRY";
4420 autofill_type_to_string[PHONE_HOME_COUNTRY_CODE] =
4421 "PHONE_HOME_COUNTRY_CODE";
4422 autofill_type_to_string[PHONE_HOME_CITY_CODE] = "PHONE_HOME_CITY_CODE";
4423 autofill_type_to_string[PHONE_HOME_WHOLE_NUMBER] =
4424 "PHONE_HOME_WHOLE_NUMBER";
4425 autofill_type_to_string[PHONE_FAX_COUNTRY_CODE] = "PHONE_FAX_COUNTRY_CODE";
4426 autofill_type_to_string[PHONE_FAX_CITY_CODE] = "PHONE_FAX_CITY_CODE";
4427 autofill_type_to_string[PHONE_FAX_WHOLE_NUMBER] = "PHONE_FAX_WHOLE_NUMBER";
4428 return autofill_type_to_string;
4429 }
4430
4431 /* static */
4432 std::map<AutofillFieldType, std::string>
GetCreditCardFieldToStringMap()4433 TestingAutomationProvider::GetCreditCardFieldToStringMap() {
4434 std::map<AutofillFieldType, std::string> credit_card_type_to_string;
4435 credit_card_type_to_string[CREDIT_CARD_NAME] = "CREDIT_CARD_NAME";
4436 credit_card_type_to_string[CREDIT_CARD_NUMBER] = "CREDIT_CARD_NUMBER";
4437 credit_card_type_to_string[CREDIT_CARD_EXP_MONTH] = "CREDIT_CARD_EXP_MONTH";
4438 credit_card_type_to_string[CREDIT_CARD_EXP_4_DIGIT_YEAR] =
4439 "CREDIT_CARD_EXP_4_DIGIT_YEAR";
4440 return credit_card_type_to_string;
4441 }
4442
4443 // Refer to GetActiveNotifications() in chrome/test/pyautolib/pyauto.py for
4444 // sample json input/output.
GetActiveNotifications(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)4445 void TestingAutomationProvider::GetActiveNotifications(
4446 Browser* browser,
4447 DictionaryValue* args,
4448 IPC::Message* reply_message) {
4449 new GetActiveNotificationsObserver(this, reply_message);
4450 }
4451
4452 // Refer to CloseNotification() in chrome/test/pyautolib/pyauto.py for
4453 // sample json input.
4454 // Returns empty json message.
CloseNotification(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)4455 void TestingAutomationProvider::CloseNotification(
4456 Browser* browser,
4457 DictionaryValue* args,
4458 IPC::Message* reply_message) {
4459 int index;
4460 if (!args->GetInteger("index", &index)) {
4461 AutomationJSONReply(this, reply_message)
4462 .SendError("'index' missing or invalid.");
4463 return;
4464 }
4465 NotificationUIManager* manager = g_browser_process->notification_ui_manager();
4466 BalloonCollection* collection = manager->balloon_collection();
4467 const BalloonCollection::Balloons& balloons = collection->GetActiveBalloons();
4468 int balloon_count = static_cast<int>(balloons.size());
4469 if (index < 0 || index >= balloon_count) {
4470 AutomationJSONReply(this, reply_message)
4471 .SendError(StringPrintf("No notification at index %d", index));
4472 return;
4473 }
4474 // This will delete itself when finished.
4475 new OnNotificationBalloonCountObserver(
4476 this, reply_message, collection, balloon_count - 1);
4477 manager->CancelById(balloons[index]->notification().notification_id());
4478 }
4479
4480 // Refer to WaitForNotificationCount() in chrome/test/pyautolib/pyauto.py for
4481 // sample json input.
4482 // Returns empty json message.
WaitForNotificationCount(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)4483 void TestingAutomationProvider::WaitForNotificationCount(
4484 Browser* browser,
4485 DictionaryValue* args,
4486 IPC::Message* reply_message) {
4487 int count;
4488 if (!args->GetInteger("count", &count)) {
4489 AutomationJSONReply(this, reply_message)
4490 .SendError("'count' missing or invalid.");
4491 return;
4492 }
4493 NotificationUIManager* manager = g_browser_process->notification_ui_manager();
4494 BalloonCollection* collection = manager->balloon_collection();
4495 const BalloonCollection::Balloons& balloons = collection->GetActiveBalloons();
4496 if (static_cast<int>(balloons.size()) == count) {
4497 AutomationJSONReply(this, reply_message).SendSuccess(NULL);
4498 return;
4499 }
4500 // This will delete itself when finished.
4501 new OnNotificationBalloonCountObserver(
4502 this, reply_message, collection, count);
4503 }
4504
4505 // Sample JSON input: { "command": "GetNTPInfo" }
4506 // For output, refer to chrome/test/pyautolib/ntp_model.py.
GetNTPInfo(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)4507 void TestingAutomationProvider::GetNTPInfo(
4508 Browser* browser,
4509 DictionaryValue* args,
4510 IPC::Message* reply_message) {
4511 // This observer will delete itself.
4512 new NTPInfoObserver(this, reply_message, &consumer_);
4513 }
4514
MoveNTPMostVisitedThumbnail(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)4515 void TestingAutomationProvider::MoveNTPMostVisitedThumbnail(
4516 Browser* browser,
4517 DictionaryValue* args,
4518 IPC::Message* reply_message) {
4519 AutomationJSONReply reply(this, reply_message);
4520 std::string url, error;
4521 int index, old_index;
4522 if (!args->GetString("url", &url)) {
4523 reply.SendError("Missing or invalid 'url' key.");
4524 return;
4525 }
4526 if (!args->GetInteger("index", &index)) {
4527 reply.SendError("Missing or invalid 'index' key.");
4528 return;
4529 }
4530 if (!args->GetInteger("old_index", &old_index)) {
4531 reply.SendError("Missing or invalid 'old_index' key");
4532 return;
4533 }
4534 history::TopSites* top_sites = browser->profile()->GetTopSites();
4535 if (!top_sites) {
4536 reply.SendError("TopSites service is not initialized.");
4537 return;
4538 }
4539 GURL swapped;
4540 // If thumbnail A is switching positions with a pinned thumbnail B, B
4541 // should be pinned in the old index of A.
4542 if (top_sites->GetPinnedURLAtIndex(index, &swapped)) {
4543 top_sites->AddPinnedURL(swapped, old_index);
4544 }
4545 top_sites->AddPinnedURL(GURL(url), index);
4546 reply.SendSuccess(NULL);
4547 }
4548
RemoveNTPMostVisitedThumbnail(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)4549 void TestingAutomationProvider::RemoveNTPMostVisitedThumbnail(
4550 Browser* browser,
4551 DictionaryValue* args,
4552 IPC::Message* reply_message) {
4553 AutomationJSONReply reply(this, reply_message);
4554 std::string url;
4555 if (!args->GetString("url", &url)) {
4556 reply.SendError("Missing or invalid 'url' key.");
4557 return;
4558 }
4559 history::TopSites* top_sites = browser->profile()->GetTopSites();
4560 if (!top_sites) {
4561 reply.SendError("TopSites service is not initialized.");
4562 return;
4563 }
4564 top_sites->AddBlacklistedURL(GURL(url));
4565 reply.SendSuccess(NULL);
4566 }
4567
UnpinNTPMostVisitedThumbnail(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)4568 void TestingAutomationProvider::UnpinNTPMostVisitedThumbnail(
4569 Browser* browser,
4570 DictionaryValue* args,
4571 IPC::Message* reply_message) {
4572 AutomationJSONReply reply(this, reply_message);
4573 std::string url;
4574 if (!args->GetString("url", &url)) {
4575 reply.SendError("Missing or invalid 'url' key.");
4576 return;
4577 }
4578 history::TopSites* top_sites = browser->profile()->GetTopSites();
4579 if (!top_sites) {
4580 reply.SendError("TopSites service is not initialized.");
4581 return;
4582 }
4583 top_sites->RemovePinnedURL(GURL(url));
4584 reply.SendSuccess(NULL);
4585 }
4586
RestoreAllNTPMostVisitedThumbnails(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)4587 void TestingAutomationProvider::RestoreAllNTPMostVisitedThumbnails(
4588 Browser* browser,
4589 DictionaryValue* args,
4590 IPC::Message* reply_message) {
4591 AutomationJSONReply reply(this, reply_message);
4592 history::TopSites* top_sites = browser->profile()->GetTopSites();
4593 if (!top_sites) {
4594 reply.SendError("TopSites service is not initialized.");
4595 return;
4596 }
4597 top_sites->ClearBlacklistedURLs();
4598 reply.SendSuccess(NULL);
4599 }
4600
KillRendererProcess(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)4601 void TestingAutomationProvider::KillRendererProcess(
4602 Browser* browser,
4603 DictionaryValue* args,
4604 IPC::Message* reply_message) {
4605 int pid;
4606 if (!args->GetInteger("pid", &pid)) {
4607 AutomationJSONReply(this, reply_message)
4608 .SendError("'pid' key missing or invalid.");
4609 return;
4610 }
4611 base::ProcessHandle process;
4612 if (!base::OpenProcessHandle(static_cast<base::ProcessId>(pid), &process)) {
4613 AutomationJSONReply(this, reply_message).SendError(base::StringPrintf(
4614 "Failed to open process handle for pid %d", pid));
4615 return;
4616 }
4617 new RendererProcessClosedObserver(this, reply_message);
4618 base::KillProcess(process, 0, false);
4619 base::CloseProcessHandle(process);
4620 }
4621
BuildWebKeyEventFromArgs(DictionaryValue * args,std::string * error,NativeWebKeyboardEvent * event)4622 bool TestingAutomationProvider::BuildWebKeyEventFromArgs(
4623 DictionaryValue* args,
4624 std::string* error,
4625 NativeWebKeyboardEvent* event) {
4626 int type, modifiers;
4627 bool is_system_key;
4628 string16 unmodified_text, text;
4629 std::string key_identifier;
4630 if (!args->GetInteger("type", &type)) {
4631 *error = "'type' missing or invalid.";
4632 return false;
4633 }
4634 if (!args->GetBoolean("isSystemKey", &is_system_key)) {
4635 *error = "'isSystemKey' missing or invalid.";
4636 return false;
4637 }
4638 if (!args->GetString("unmodifiedText", &unmodified_text)) {
4639 *error = "'unmodifiedText' missing or invalid.";
4640 return false;
4641 }
4642 if (!args->GetString("text", &text)) {
4643 *error = "'text' missing or invalid.";
4644 return false;
4645 }
4646 if (!args->GetInteger("nativeKeyCode", &event->nativeKeyCode)) {
4647 *error = "'nativeKeyCode' missing or invalid.";
4648 return false;
4649 }
4650 if (!args->GetInteger("windowsKeyCode", &event->windowsKeyCode)) {
4651 *error = "'windowsKeyCode' missing or invalid.";
4652 return false;
4653 }
4654 if (!args->GetInteger("modifiers", &modifiers)) {
4655 *error = "'modifiers' missing or invalid.";
4656 return false;
4657 }
4658 if (args->GetString("keyIdentifier", &key_identifier)) {
4659 base::strlcpy(event->keyIdentifier,
4660 key_identifier.c_str(),
4661 WebKit::WebKeyboardEvent::keyIdentifierLengthCap);
4662 } else {
4663 event->setKeyIdentifierFromWindowsKeyCode();
4664 }
4665
4666 if (type == automation::kRawKeyDownType) {
4667 event->type = WebKit::WebInputEvent::RawKeyDown;
4668 } else if (type == automation::kKeyDownType) {
4669 event->type = WebKit::WebInputEvent::KeyDown;
4670 } else if (type == automation::kKeyUpType) {
4671 event->type = WebKit::WebInputEvent::KeyUp;
4672 } else if (type == automation::kCharType) {
4673 event->type = WebKit::WebInputEvent::Char;
4674 } else {
4675 *error = "'type' refers to an unrecognized keyboard event type";
4676 return false;
4677 }
4678
4679 string16 unmodified_text_truncated = unmodified_text.substr(
4680 0, WebKit::WebKeyboardEvent::textLengthCap - 1);
4681 memcpy(event->unmodifiedText,
4682 unmodified_text_truncated.c_str(),
4683 unmodified_text_truncated.length() + 1);
4684 string16 text_truncated = text.substr(
4685 0, WebKit::WebKeyboardEvent::textLengthCap - 1);
4686 memcpy(event->text, text_truncated.c_str(), text_truncated.length() + 1);
4687
4688 event->modifiers = 0;
4689 if (modifiers & automation::kShiftKeyMask)
4690 event->modifiers |= WebKit::WebInputEvent::ShiftKey;
4691 if (modifiers & automation::kControlKeyMask)
4692 event->modifiers |= WebKit::WebInputEvent::ControlKey;
4693 if (modifiers & automation::kAltKeyMask)
4694 event->modifiers |= WebKit::WebInputEvent::AltKey;
4695 if (modifiers & automation::kMetaKeyMask)
4696 event->modifiers |= WebKit::WebInputEvent::MetaKey;
4697
4698 event->isSystemKey = is_system_key;
4699 event->timeStampSeconds = base::Time::Now().ToDoubleT();
4700 event->skip_in_browser = true;
4701 return true;
4702 }
4703
SendWebkitKeyEvent(DictionaryValue * args,IPC::Message * reply_message)4704 void TestingAutomationProvider::SendWebkitKeyEvent(
4705 DictionaryValue* args,
4706 IPC::Message* reply_message) {
4707 NativeWebKeyboardEvent event;
4708 // BuildWebKeyEventFromArgs handles telling what when wrong and sending
4709 // the reply message, if it failed we just have to stop here.
4710 std::string error;
4711 if (!BuildWebKeyEventFromArgs(args, &error, &event)) {
4712 AutomationJSONReply(this, reply_message).SendError(error);
4713 return;
4714 }
4715
4716 TabContents* tab_contents;
4717 if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
4718 AutomationJSONReply(this, reply_message).SendError(error);
4719 return;
4720 }
4721 new InputEventAckNotificationObserver(this, reply_message, event.type);
4722 tab_contents->render_view_host()->ForwardKeyboardEvent(event);
4723 }
4724
SendOSLevelKeyEventToTab(DictionaryValue * args,IPC::Message * reply_message)4725 void TestingAutomationProvider::SendOSLevelKeyEventToTab(
4726 DictionaryValue* args,
4727 IPC::Message* reply_message) {
4728 int modifiers, keycode;
4729 if (!args->GetInteger("keyCode", &keycode)) {
4730 AutomationJSONReply(this, reply_message)
4731 .SendError("'keyCode' missing or invalid.");
4732 return;
4733 }
4734 if (!args->GetInteger("modifiers", &modifiers)) {
4735 AutomationJSONReply(this, reply_message)
4736 .SendError("'modifiers' missing or invalid.");
4737 return;
4738 }
4739
4740 std::string error;
4741 Browser* browser;
4742 TabContents* tab_contents;
4743 if (!GetBrowserAndTabFromJSONArgs(args, &browser, &tab_contents, &error)) {
4744 AutomationJSONReply(this, reply_message).SendError(error);
4745 return;
4746 }
4747 // The key events will be sent to the browser window, we need the current tab
4748 // containing the element we send the text in to be shown.
4749 browser->ActivateTabAt(
4750 browser->GetIndexOfController(&tab_contents->controller()), true);
4751
4752 BrowserWindow* browser_window = browser->window();
4753 if (!browser_window) {
4754 AutomationJSONReply(this, reply_message)
4755 .SendError("Could not get the browser window");
4756 return;
4757 }
4758 gfx::NativeWindow window = browser_window->GetNativeHandle();
4759 if (!window) {
4760 AutomationJSONReply(this, reply_message)
4761 .SendError("Could not get the browser window handle");
4762 return;
4763 }
4764
4765 bool control = !!(modifiers & automation::kControlKeyMask);
4766 bool shift = !!(modifiers & automation::kShiftKeyMask);
4767 bool alt = !!(modifiers & automation::kAltKeyMask);
4768 bool meta = !!(modifiers & automation::kMetaKeyMask);
4769 if (!ui_controls::SendKeyPressNotifyWhenDone(
4770 window, static_cast<ui::KeyboardCode>(keycode),
4771 control, shift, alt, meta,
4772 NewRunnableMethod(this,
4773 &TestingAutomationProvider::SendSuccessReply, reply_message))) {
4774 AutomationJSONReply(this, reply_message)
4775 .SendError("Could not send the native key event");
4776 }
4777 }
4778
SendSuccessReply(IPC::Message * reply_message)4779 void TestingAutomationProvider::SendSuccessReply(IPC::Message* reply_message) {
4780 AutomationJSONReply(this, reply_message).SendSuccess(NULL);
4781 }
4782
4783 // Sample JSON input: { "command": "GetNTPThumbnailMode" }
4784 // For output, refer to GetNTPThumbnailMode() in
4785 // chrome/test/pyautolib/pyauto.py.
GetNTPThumbnailMode(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)4786 void TestingAutomationProvider::GetNTPThumbnailMode(
4787 Browser* browser,
4788 DictionaryValue* args,
4789 IPC::Message* reply_message) {
4790 const int shown_sections = ShownSectionsHandler::GetShownSections(
4791 browser->profile()->GetPrefs());
4792
4793 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
4794 return_value->SetBoolean("apps", shown_sections & APPS ? true : false);
4795 return_value->SetBoolean("most_visited",
4796 shown_sections & THUMB ? true : false);
4797
4798 AutomationJSONReply reply(this, reply_message);
4799 reply.SendSuccess(return_value.get());
4800 }
4801
4802 // Sample JSON input: { "command": "SetNTPThumbnailMode", "section": "apps",
4803 // "turn_on": true }
4804 // Refer to SetNTPThumbnailMode() in chrome/test/pyautolib/pyauto.py for
4805 // all possible input values.
4806 // Sample JSON output: {}
SetNTPThumbnailMode(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)4807 void TestingAutomationProvider::SetNTPThumbnailMode(
4808 Browser* browser,
4809 DictionaryValue* args,
4810 IPC::Message* reply_message) {
4811 AutomationJSONReply reply(this, reply_message);
4812 std::string section_name;
4813 bool turn_on;
4814 if (!args->GetString("section", §ion_name) ||
4815 !args->GetBoolean("turn_on", &turn_on)) {
4816 reply.SendError("Invalid or missing args");
4817 return;
4818 }
4819
4820 PrefService* prefs = browser->profile()->GetPrefs();
4821 Section section;
4822 if (section_name.compare("apps") == 0) {
4823 section = APPS;
4824 } else if (section_name.compare("most_visited") == 0) {
4825 section = THUMB;
4826 } else if (section_name.compare("recently_closed") == 0) {
4827 reply.SendError("Thumbnail mode does not apply to the recently closed "
4828 "section.");
4829 return;
4830 } else {
4831 reply.SendError(StringPrintf("Unexpected section name: '%s'",
4832 section_name.c_str()));
4833 return;
4834 }
4835
4836 if (turn_on) {
4837 ShownSectionsHandler::SetShownSection(prefs, section);
4838 } else {
4839 int shown_sections = ShownSectionsHandler::GetShownSections(prefs);
4840 // Change the bit for the relevant section in the bitmask to 0.
4841 shown_sections &= ~(0xFFFFFFFF & section);
4842 prefs->SetInteger(prefs::kNTPShownSections, shown_sections);
4843 }
4844
4845 reply.SendSuccess(NULL);
4846 }
4847
4848 // Sample JSON input: { "command": "GetNTPMenuMode" }
4849 // For output, refer to GetNTPMenuMode() in
4850 // chrome/test/pyautolib/pyauto.py.
GetNTPMenuMode(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)4851 void TestingAutomationProvider::GetNTPMenuMode(
4852 Browser* browser,
4853 DictionaryValue* args,
4854 IPC::Message* reply_message) {
4855 const int shown_sections = ShownSectionsHandler::GetShownSections(
4856 browser->profile()->GetPrefs());
4857
4858 scoped_ptr<DictionaryValue> return_value(new DictionaryValue);
4859 return_value->SetBoolean("apps", shown_sections & MENU_APPS ? true : false);
4860 return_value->SetBoolean("most_visited",
4861 shown_sections & MENU_THUMB ? true : false);
4862 return_value->SetBoolean("recently_closed",
4863 shown_sections & MENU_RECENT ? true : false);
4864
4865 AutomationJSONReply reply(this, reply_message);
4866 reply.SendSuccess(return_value.get());
4867 }
4868
4869 // Sample JSON input: { "command": "SetNTPMenuMode", "section": "apps",
4870 // "turn_on": false }
4871 // Refer to SetNTPMenuMode() in chrome/test/pyautolib/pyauto.py for all possible
4872 // input values.
4873 // Sample JSON output: {}
SetNTPMenuMode(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)4874 void TestingAutomationProvider::SetNTPMenuMode(
4875 Browser* browser,
4876 DictionaryValue* args,
4877 IPC::Message* reply_message) {
4878 AutomationJSONReply reply(this, reply_message);
4879 std::string section_name;
4880 bool turn_on;
4881 if (!args->GetString("section", §ion_name) ||
4882 !args->GetBoolean("turn_on", &turn_on)) {
4883 reply.SendError("Invalid or missing args");
4884 return;
4885 }
4886
4887 PrefService* prefs = browser->profile()->GetPrefs();
4888 Section section;
4889 if (section_name.compare("apps") == 0) {
4890 section = MENU_APPS;
4891 } else if (section_name.compare("most_visited") == 0) {
4892 section = MENU_THUMB;
4893 } else if (section_name.compare("recently_closed") == 0) {
4894 section = MENU_RECENT;
4895 } else {
4896 reply.SendError(StringPrintf("Unexpected section name: '%s'",
4897 section_name.c_str()));
4898 return;
4899 }
4900
4901 int shown_sections = ShownSectionsHandler::GetShownSections(prefs);
4902 if (turn_on) {
4903 // Change the bit for the relevant section in the bitmask to 1.
4904 shown_sections |= section;
4905 } else {
4906 // Change the bit for the relevant section in the bitmask to 0.
4907 shown_sections &= ~(0xFFFFFFFF & section);
4908 }
4909 prefs->SetInteger(prefs::kNTPShownSections, shown_sections);
4910
4911 reply.SendSuccess(NULL);
4912 }
4913
4914 // Sample JSON input: { "command": "LaunchApp",
4915 // "id": "ahfgeienlihckogmohjhadlkjgocpleb" }
4916 // Sample JSON output: {}
LaunchApp(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)4917 void TestingAutomationProvider::LaunchApp(
4918 Browser* browser,
4919 DictionaryValue* args,
4920 IPC::Message* reply_message) {
4921 std::string id;
4922 if (!args->GetString("id", &id)) {
4923 AutomationJSONReply(this, reply_message).SendError(
4924 "Must include string id.");
4925 return;
4926 }
4927
4928 ExtensionService* service = browser->profile()->GetExtensionService();
4929 if (!service) {
4930 AutomationJSONReply(this, reply_message).SendError(
4931 "No extensions service.");
4932 return;
4933 }
4934
4935 const Extension* extension = service->GetExtensionById(
4936 id, false /* do not include disabled extensions */);
4937 if (!extension) {
4938 AutomationJSONReply(this, reply_message).SendError(
4939 StringPrintf("Extension with ID '%s' doesn't exist or is disabled.",
4940 id.c_str()));
4941 return;
4942 }
4943
4944 // Look at preferences to find the right launch container. If no preference
4945 // is set, launch as a regular tab.
4946 extension_misc::LaunchContainer launch_container =
4947 service->extension_prefs()->GetLaunchContainer(
4948 extension, ExtensionPrefs::LAUNCH_REGULAR);
4949
4950 TabContents* old_contents = browser->GetSelectedTabContents();
4951 if (!old_contents) {
4952 AutomationJSONReply(this, reply_message).SendError(
4953 "Cannot identify selected tab contents.");
4954 return;
4955 }
4956
4957 // This observer will delete itself.
4958 new AppLaunchObserver(&old_contents->controller(), this, reply_message,
4959 launch_container);
4960 Browser::OpenApplication(profile(), extension, launch_container,
4961 old_contents);
4962 }
4963
4964 // Sample JSON input: { "command": "SetAppLaunchType",
4965 // "id": "ahfgeienlihckogmohjhadlkjgocpleb",
4966 // "launch_type": "pinned" }
4967 // Sample JSON output: {}
SetAppLaunchType(Browser * browser,DictionaryValue * args,IPC::Message * reply_message)4968 void TestingAutomationProvider::SetAppLaunchType(
4969 Browser* browser,
4970 DictionaryValue* args,
4971 IPC::Message* reply_message) {
4972 AutomationJSONReply reply(this, reply_message);
4973
4974 std::string id;
4975 if (!args->GetString("id", &id)) {
4976 reply.SendError("Must include string id.");
4977 return;
4978 }
4979
4980 std::string launch_type_str;
4981 if (!args->GetString("launch_type", &launch_type_str)) {
4982 reply.SendError("Must specify app launch type.");
4983 return;
4984 }
4985
4986 ExtensionService* service = browser->profile()->GetExtensionService();
4987 if (!service) {
4988 reply.SendError("No extensions service.");
4989 return;
4990 }
4991
4992 const Extension* extension = service->GetExtensionById(
4993 id, true /* include disabled extensions */);
4994 if (!extension) {
4995 reply.SendError(
4996 StringPrintf("Extension with ID '%s' doesn't exist.", id.c_str()));
4997 return;
4998 }
4999
5000 ExtensionPrefs::LaunchType launch_type;
5001 if (launch_type_str == "pinned") {
5002 launch_type = ExtensionPrefs::LAUNCH_PINNED;
5003 } else if (launch_type_str == "regular") {
5004 launch_type = ExtensionPrefs::LAUNCH_REGULAR;
5005 } else if (launch_type_str == "fullscreen") {
5006 launch_type = ExtensionPrefs::LAUNCH_FULLSCREEN;
5007 } else if (launch_type_str == "window") {
5008 launch_type = ExtensionPrefs::LAUNCH_WINDOW;
5009 } else {
5010 reply.SendError(
5011 StringPrintf("Unexpected launch type '%s'.", launch_type_str.c_str()));
5012 return;
5013 }
5014
5015 service->extension_prefs()->SetLaunchType(extension->id(), launch_type);
5016 reply.SendSuccess(NULL);
5017 }
5018
WaitForAllTabsToStopLoading(DictionaryValue * args,IPC::Message * reply_message)5019 void TestingAutomationProvider::WaitForAllTabsToStopLoading(
5020 DictionaryValue* args,
5021 IPC::Message* reply_message) {
5022 // This class will send the message immediately if no tab is loading.
5023 new AllTabsStoppedLoadingObserver(this, reply_message);
5024 }
5025
GetIndicesFromTab(DictionaryValue * args,IPC::Message * reply_message)5026 void TestingAutomationProvider::GetIndicesFromTab(
5027 DictionaryValue* args,
5028 IPC::Message* reply_message) {
5029 AutomationJSONReply reply(this, reply_message);
5030 int id_or_handle = 0;
5031 bool has_id = args->HasKey("tab_id");
5032 bool has_handle = args->HasKey("tab_handle");
5033 if (has_id && has_handle) {
5034 reply.SendError(
5035 "Both 'tab_id' and 'tab_handle' were specified. Only one is allowed");
5036 return;
5037 } else if (!has_id && !has_handle) {
5038 reply.SendError("Either 'tab_id' or 'tab_handle' must be specified");
5039 return;
5040 }
5041 if (has_id && !args->GetInteger("tab_id", &id_or_handle)) {
5042 reply.SendError("'tab_id' is invalid");
5043 return;
5044 }
5045 if (has_handle && (!args->GetInteger("tab_handle", &id_or_handle) ||
5046 !tab_tracker_->ContainsHandle(id_or_handle))) {
5047 reply.SendError("'tab_handle' is invalid");
5048 return;
5049 }
5050 int id = id_or_handle;
5051 if (has_handle)
5052 id = tab_tracker_->GetResource(id_or_handle)->session_id().id();
5053 BrowserList::const_iterator iter = BrowserList::begin();
5054 int browser_index = 0;
5055 for (; iter != BrowserList::end(); ++iter, ++browser_index) {
5056 Browser* browser = *iter;
5057 for (int tab_index = 0; tab_index < browser->tab_count(); ++tab_index) {
5058 TabContents* tab = browser->GetTabContentsAt(tab_index);
5059 if (tab->controller().session_id().id() == id) {
5060 DictionaryValue dict;
5061 dict.SetInteger("windex", browser_index);
5062 dict.SetInteger("tab_index", tab_index);
5063 reply.SendSuccess(&dict);
5064 return;
5065 }
5066 }
5067 }
5068 reply.SendError("Could not find tab among current browser windows");
5069 }
5070
NavigateToURL(DictionaryValue * args,IPC::Message * reply_message)5071 void TestingAutomationProvider::NavigateToURL(
5072 DictionaryValue* args,
5073 IPC::Message* reply_message) {
5074 int navigation_count;
5075 std::string url, error;
5076 Browser* browser;
5077 TabContents* tab_contents;
5078 if (!GetBrowserAndTabFromJSONArgs(args, &browser, &tab_contents, &error)) {
5079 AutomationJSONReply(this, reply_message).SendError(error);
5080 return;
5081 }
5082 if (!args->GetString("url", &url)) {
5083 AutomationJSONReply(this, reply_message)
5084 .SendError("'url' missing or invalid");
5085 return;
5086 }
5087 if (!args->GetInteger("navigation_count", &navigation_count)) {
5088 AutomationJSONReply(this, reply_message)
5089 .SendError("'navigation_count' missing or invalid");
5090 return;
5091 }
5092 new NavigationNotificationObserver(
5093 &tab_contents->controller(), this, reply_message,
5094 navigation_count, false, true);
5095 browser->OpenURLFromTab(
5096 tab_contents, GURL(url), GURL(), CURRENT_TAB, PageTransition::TYPED);
5097 }
5098
ExecuteJavascriptJSON(DictionaryValue * args,IPC::Message * reply_message)5099 void TestingAutomationProvider::ExecuteJavascriptJSON(
5100 DictionaryValue* args,
5101 IPC::Message* reply_message) {
5102 string16 frame_xpath, javascript;
5103 std::string error;
5104 TabContents* tab_contents;
5105 if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
5106 AutomationJSONReply(this, reply_message).SendError(error);
5107 return;
5108 }
5109 if (!args->GetString("frame_xpath", &frame_xpath)) {
5110 AutomationJSONReply(this, reply_message)
5111 .SendError("'frame_xpath' missing or invalid");
5112 return;
5113 }
5114 if (!args->GetString("javascript", &javascript)) {
5115 AutomationJSONReply(this, reply_message)
5116 .SendError("'javascript' missing or invalid");
5117 return;
5118 }
5119
5120 // Set the routing id of this message with the controller.
5121 // This routing id needs to be remembered for the reverse
5122 // communication while sending back the response of
5123 // this javascript execution.
5124 std::string set_automation_id;
5125 base::SStringPrintf(&set_automation_id,
5126 "window.domAutomationController.setAutomationId(%d);",
5127 reply_message->routing_id());
5128
5129 new DomOperationMessageSender(this, reply_message, true);
5130 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
5131 frame_xpath, UTF8ToUTF16(set_automation_id));
5132 tab_contents->render_view_host()->ExecuteJavascriptInWebFrame(
5133 frame_xpath, javascript);
5134 }
5135
GoForward(DictionaryValue * args,IPC::Message * reply_message)5136 void TestingAutomationProvider::GoForward(
5137 DictionaryValue* args,
5138 IPC::Message* reply_message) {
5139 TabContents* tab_contents;
5140 std::string error;
5141 if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
5142 AutomationJSONReply(this, reply_message).SendError(error);
5143 return;
5144 }
5145 NavigationController& controller = tab_contents->controller();
5146 if (!controller.CanGoForward()) {
5147 DictionaryValue dict;
5148 dict.SetBoolean("did_go_forward", false);
5149 AutomationJSONReply(this, reply_message).SendSuccess(&dict);
5150 return;
5151 }
5152 new NavigationNotificationObserver(&controller, this, reply_message,
5153 1, false, true);
5154 controller.GoForward();
5155 }
5156
GoBack(DictionaryValue * args,IPC::Message * reply_message)5157 void TestingAutomationProvider::GoBack(
5158 DictionaryValue* args,
5159 IPC::Message* reply_message) {
5160 TabContents* tab_contents;
5161 std::string error;
5162 if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
5163 AutomationJSONReply(this, reply_message).SendError(error);
5164 return;
5165 }
5166 NavigationController& controller = tab_contents->controller();
5167 if (!controller.CanGoBack()) {
5168 DictionaryValue dict;
5169 dict.SetBoolean("did_go_back", false);
5170 AutomationJSONReply(this, reply_message).SendSuccess(&dict);
5171 return;
5172 }
5173 new NavigationNotificationObserver(&controller, this, reply_message,
5174 1, false, true);
5175 controller.GoBack();
5176 }
5177
ReloadJSON(DictionaryValue * args,IPC::Message * reply_message)5178 void TestingAutomationProvider::ReloadJSON(
5179 DictionaryValue* args,
5180 IPC::Message* reply_message) {
5181 TabContents* tab_contents;
5182 std::string error;
5183 if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
5184 AutomationJSONReply(this, reply_message).SendError(error);
5185 return;
5186 }
5187 NavigationController& controller = tab_contents->controller();
5188 new NavigationNotificationObserver(&controller, this, reply_message,
5189 1, false, true);
5190 controller.Reload(false);
5191 }
5192
GetTabURLJSON(DictionaryValue * args,IPC::Message * reply_message)5193 void TestingAutomationProvider::GetTabURLJSON(
5194 DictionaryValue* args,
5195 IPC::Message* reply_message) {
5196 AutomationJSONReply reply(this, reply_message);
5197 TabContents* tab_contents;
5198 std::string error;
5199 if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
5200 reply.SendError(error);
5201 return;
5202 }
5203 DictionaryValue dict;
5204 dict.SetString("url", tab_contents->GetURL().possibly_invalid_spec());
5205 reply.SendSuccess(&dict);
5206 }
5207
GetTabTitleJSON(DictionaryValue * args,IPC::Message * reply_message)5208 void TestingAutomationProvider::GetTabTitleJSON(
5209 DictionaryValue* args,
5210 IPC::Message* reply_message) {
5211 AutomationJSONReply reply(this, reply_message);
5212 TabContents* tab_contents;
5213 std::string error;
5214 if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
5215 reply.SendError(error);
5216 return;
5217 }
5218 DictionaryValue dict;
5219 dict.SetString("title", tab_contents->GetTitle());
5220 reply.SendSuccess(&dict);
5221 }
5222
CaptureEntirePageJSON(DictionaryValue * args,IPC::Message * reply_message)5223 void TestingAutomationProvider::CaptureEntirePageJSON(
5224 DictionaryValue* args,
5225 IPC::Message* reply_message) {
5226 TabContents* tab_contents;
5227 std::string error;
5228
5229 if (!GetTabFromJSONArgs(args, &tab_contents, &error)) {
5230 AutomationJSONReply(this, reply_message).SendError(error);
5231 return;
5232 }
5233
5234 FilePath::StringType path_str;
5235 if (!args->GetString("path", &path_str)) {
5236 AutomationJSONReply(this, reply_message)
5237 .SendError("'path' missing or invalid");
5238 return;
5239 }
5240
5241 RenderViewHost* render_view = tab_contents->render_view_host();
5242 if (render_view) {
5243 FilePath path(path_str);
5244 // This will delete itself when finished.
5245 PageSnapshotTaker* snapshot_taker = new PageSnapshotTaker(
5246 this, reply_message, render_view, path);
5247 snapshot_taker->Start();
5248 } else {
5249 AutomationJSONReply(this, reply_message)
5250 .SendError("Tab has no associated RenderViewHost");
5251 }
5252 }
5253
GetCookiesJSON(DictionaryValue * args,IPC::Message * reply_message)5254 void TestingAutomationProvider::GetCookiesJSON(
5255 DictionaryValue* args, IPC::Message* reply_message) {
5256 automation_util::GetCookiesJSON(this, args, reply_message);
5257 }
5258
DeleteCookieJSON(DictionaryValue * args,IPC::Message * reply_message)5259 void TestingAutomationProvider::DeleteCookieJSON(
5260 DictionaryValue* args, IPC::Message* reply_message) {
5261 automation_util::DeleteCookieJSON(this, args, reply_message);
5262 }
5263
SetCookieJSON(DictionaryValue * args,IPC::Message * reply_message)5264 void TestingAutomationProvider::SetCookieJSON(
5265 DictionaryValue* args, IPC::Message* reply_message) {
5266 automation_util::SetCookieJSON(this, args, reply_message);
5267 }
5268
GetTabIds(DictionaryValue * args,IPC::Message * reply_message)5269 void TestingAutomationProvider::GetTabIds(
5270 DictionaryValue* args, IPC::Message* reply_message) {
5271 ListValue* id_list = new ListValue();
5272 BrowserList::const_iterator iter = BrowserList::begin();
5273 for (; iter != BrowserList::end(); ++iter) {
5274 Browser* browser = *iter;
5275 for (int i = 0; i < browser->tab_count(); ++i) {
5276 int id = browser->GetTabContentsAt(i)->controller().session_id().id();
5277 id_list->Append(Value::CreateIntegerValue(id));
5278 }
5279 }
5280 DictionaryValue dict;
5281 dict.Set("ids", id_list);
5282 AutomationJSONReply(this, reply_message).SendSuccess(&dict);
5283 }
5284
IsTabIdValid(DictionaryValue * args,IPC::Message * reply_message)5285 void TestingAutomationProvider::IsTabIdValid(
5286 DictionaryValue* args, IPC::Message* reply_message) {
5287 AutomationJSONReply reply(this, reply_message);
5288 int id;
5289 if (!args->GetInteger("id", &id)) {
5290 reply.SendError("'id' missing or invalid");
5291 return;
5292 }
5293 bool is_valid = false;
5294 BrowserList::const_iterator iter = BrowserList::begin();
5295 for (; iter != BrowserList::end(); ++iter) {
5296 Browser* browser = *iter;
5297 for (int i = 0; i < browser->tab_count(); ++i) {
5298 TabContents* tab = browser->GetTabContentsAt(i);
5299 if (tab->controller().session_id().id() == id) {
5300 is_valid = true;
5301 break;
5302 }
5303 }
5304 }
5305 DictionaryValue dict;
5306 dict.SetBoolean("is_valid", is_valid);
5307 reply.SendSuccess(&dict);
5308 }
5309
CloseTabJSON(DictionaryValue * args,IPC::Message * reply_message)5310 void TestingAutomationProvider::CloseTabJSON(
5311 DictionaryValue* args, IPC::Message* reply_message) {
5312 AutomationJSONReply reply(this, reply_message);
5313 Browser* browser;
5314 TabContents* tab_contents;
5315 std::string error;
5316 if (!GetBrowserAndTabFromJSONArgs(args, &browser, &tab_contents, &error)) {
5317 reply.SendError(error);
5318 return;
5319 }
5320 browser->CloseTabContents(tab_contents);
5321 reply.SendSuccess(NULL);
5322 }
5323
ActivateTabJSON(DictionaryValue * args,IPC::Message * reply_message)5324 void TestingAutomationProvider::ActivateTabJSON(
5325 DictionaryValue* args,
5326 IPC::Message* reply_message) {
5327 AutomationJSONReply reply(this, reply_message);
5328 Browser* browser;
5329 TabContents* tab_contents;
5330 std::string error;
5331 if (!GetBrowserAndTabFromJSONArgs(args, &browser, &tab_contents, &error)) {
5332 reply.SendError(error);
5333 return;
5334 }
5335 browser->ActivateTabAt(
5336 browser->GetIndexOfController(&tab_contents->controller()), true);
5337 reply.SendSuccess(NULL);
5338 }
5339
5340 // Sample json input: { "command": "UpdateExtensionsNow" }
5341 // Sample json output: {}
UpdateExtensionsNow(DictionaryValue * args,IPC::Message * reply_message)5342 void TestingAutomationProvider::UpdateExtensionsNow(
5343 DictionaryValue* args,
5344 IPC::Message* reply_message) {
5345 ExtensionService* service = profile()->GetExtensionService();
5346 if (!service) {
5347 AutomationJSONReply(this, reply_message).SendError(
5348 "No extensions service.");
5349 return;
5350 }
5351
5352 ExtensionUpdater* updater = service->updater();
5353 if (!updater) {
5354 AutomationJSONReply(this, reply_message).SendError(
5355 "No updater for extensions service.");
5356 return;
5357 }
5358
5359 ExtensionProcessManager* manager = profile()->GetExtensionProcessManager();
5360 if (!manager) {
5361 AutomationJSONReply(this, reply_message).SendError(
5362 "No extension process manager.");
5363 return;
5364 }
5365
5366 // Create a new observer that waits until the extensions have been fully
5367 // updated (we should not send the reply until after all extensions have
5368 // been updated). This observer will delete itself.
5369 new ExtensionsUpdatedObserver(manager, this, reply_message);
5370 updater->CheckNow();
5371 }
5372
GetChromeDriverAutomationVersion(DictionaryValue * args,IPC::Message * reply_message)5373 void TestingAutomationProvider::GetChromeDriverAutomationVersion(
5374 DictionaryValue* args,
5375 IPC::Message* reply_message) {
5376 DictionaryValue reply_dict;
5377 reply_dict.SetInteger("version", automation::kChromeDriverAutomationVersion);
5378 AutomationJSONReply(this, reply_message).SendSuccess(&reply_dict);
5379 }
5380
WaitForTabCountToBecome(int browser_handle,int target_tab_count,IPC::Message * reply_message)5381 void TestingAutomationProvider::WaitForTabCountToBecome(
5382 int browser_handle,
5383 int target_tab_count,
5384 IPC::Message* reply_message) {
5385 if (!browser_tracker_->ContainsHandle(browser_handle)) {
5386 AutomationMsg_WaitForTabCountToBecome::WriteReplyParams(reply_message,
5387 false);
5388 Send(reply_message);
5389 return;
5390 }
5391
5392 Browser* browser = browser_tracker_->GetResource(browser_handle);
5393
5394 // The observer will delete itself.
5395 new TabCountChangeObserver(this, browser, reply_message, target_tab_count);
5396 }
5397
WaitForInfoBarCount(int tab_handle,size_t target_count,IPC::Message * reply_message)5398 void TestingAutomationProvider::WaitForInfoBarCount(
5399 int tab_handle,
5400 size_t target_count,
5401 IPC::Message* reply_message) {
5402 if (!tab_tracker_->ContainsHandle(tab_handle)) {
5403 AutomationMsg_WaitForInfoBarCount::WriteReplyParams(reply_message_, false);
5404 Send(reply_message_);
5405 return;
5406 }
5407
5408 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
5409 if (!controller) {
5410 AutomationMsg_WaitForInfoBarCount::WriteReplyParams(reply_message_, false);
5411 Send(reply_message_);
5412 return;
5413 }
5414
5415 // The delegate will delete itself.
5416 new InfoBarCountObserver(this, reply_message, controller->tab_contents(),
5417 target_count);
5418 }
5419
5420 // Gets the current used encoding name of the page in the specified tab.
GetPageCurrentEncoding(int tab_handle,std::string * current_encoding)5421 void TestingAutomationProvider::GetPageCurrentEncoding(
5422 int tab_handle, std::string* current_encoding) {
5423 if (tab_tracker_->ContainsHandle(tab_handle)) {
5424 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
5425 Browser* browser = FindAndActivateTab(nav);
5426 DCHECK(browser);
5427
5428 if (browser->command_updater()->IsCommandEnabled(IDC_ENCODING_MENU))
5429 *current_encoding = nav->tab_contents()->encoding();
5430 }
5431 }
5432
ShutdownSessionService(int handle,bool * result)5433 void TestingAutomationProvider::ShutdownSessionService(int handle,
5434 bool* result) {
5435 if (browser_tracker_->ContainsHandle(handle)) {
5436 Browser* browser = browser_tracker_->GetResource(handle);
5437 browser->profile()->ShutdownSessionService();
5438 *result = true;
5439 } else {
5440 *result = false;
5441 }
5442 }
5443
SetContentSetting(int handle,const std::string & host,ContentSettingsType content_type,ContentSetting setting,bool * success)5444 void TestingAutomationProvider::SetContentSetting(
5445 int handle,
5446 const std::string& host,
5447 ContentSettingsType content_type,
5448 ContentSetting setting,
5449 bool* success) {
5450 *success = false;
5451 if (browser_tracker_->ContainsHandle(handle)) {
5452 Browser* browser = browser_tracker_->GetResource(handle);
5453 HostContentSettingsMap* map =
5454 browser->profile()->GetHostContentSettingsMap();
5455 if (host.empty()) {
5456 map->SetDefaultContentSetting(content_type, setting);
5457 } else {
5458 map->SetContentSetting(ContentSettingsPattern(host),
5459 content_type, "", setting);
5460 }
5461 *success = true;
5462 }
5463 }
5464
LoadBlockedPlugins(int tab_handle,bool * success)5465 void TestingAutomationProvider::LoadBlockedPlugins(int tab_handle,
5466 bool* success) {
5467 *success = false;
5468 if (tab_tracker_->ContainsHandle(tab_handle)) {
5469 NavigationController* nav = tab_tracker_->GetResource(tab_handle);
5470 if (!nav)
5471 return;
5472 TabContents* contents = nav->tab_contents();
5473 if (!contents)
5474 return;
5475 contents->render_view_host()->LoadBlockedPlugins();
5476 *success = true;
5477 }
5478 }
5479
ResetToDefaultTheme()5480 void TestingAutomationProvider::ResetToDefaultTheme() {
5481 ThemeServiceFactory::GetForProfile(profile_)->UseDefaultTheme();
5482 }
5483
WaitForProcessLauncherThreadToGoIdle(IPC::Message * reply_message)5484 void TestingAutomationProvider::WaitForProcessLauncherThreadToGoIdle(
5485 IPC::Message* reply_message) {
5486 new WaitForProcessLauncherThreadToGoIdleObserver(this, reply_message);
5487 }
5488
GetParentBrowserOfTab(int tab_handle,int * browser_handle,bool * success)5489 void TestingAutomationProvider::GetParentBrowserOfTab(int tab_handle,
5490 int* browser_handle,
5491 bool* success) {
5492 *success = false;
5493 if (tab_tracker_->ContainsHandle(tab_handle)) {
5494 NavigationController* controller = tab_tracker_->GetResource(tab_handle);
5495 int index;
5496 Browser* browser = Browser::GetBrowserForController(controller, &index);
5497 if (browser) {
5498 *browser_handle = browser_tracker_->Add(browser);
5499 *success = true;
5500 }
5501 }
5502 }
5503
5504 // TODO(brettw) change this to accept GURLs when history supports it
OnRedirectQueryComplete(HistoryService::Handle request_handle,GURL from_url,bool success,history::RedirectList * redirects)5505 void TestingAutomationProvider::OnRedirectQueryComplete(
5506 HistoryService::Handle request_handle,
5507 GURL from_url,
5508 bool success,
5509 history::RedirectList* redirects) {
5510 DCHECK_EQ(redirect_query_, request_handle);
5511 DCHECK(reply_message_ != NULL);
5512
5513 std::vector<GURL> redirects_gurl;
5514 reply_message_->WriteBool(success);
5515 if (success) {
5516 for (size_t i = 0; i < redirects->size(); i++)
5517 redirects_gurl.push_back(redirects->at(i));
5518 }
5519
5520 IPC::ParamTraits<std::vector<GURL> >::Write(reply_message_, redirects_gurl);
5521
5522 Send(reply_message_);
5523 redirect_query_ = 0;
5524 reply_message_ = NULL;
5525 }
5526
OnRemoveProvider()5527 void TestingAutomationProvider::OnRemoveProvider() {
5528 AutomationProviderList::GetInstance()->RemoveProvider(this);
5529 }
5530