12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/chrome_impl.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/devtools_client.h" 890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/devtools_event_listener.h" 9c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/devtools_http_client.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/status.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/chromedriver/chrome/web_view_impl.h" 1268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "chrome/test/chromedriver/net/port_server.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)ChromeImpl::~ChromeImpl() { 1568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!quit_) 1668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) port_reservation_->Leak(); 1768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 191e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)ChromeDesktopImpl* ChromeImpl::GetAsDesktop() { 201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return NULL; 211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 230529e5d033099cbfc42635f6f6183833b09dff6eBen Murdochconst BrowserInfo* ChromeImpl::GetBrowserInfo() { 240529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch return devtools_http_client_->browser_info(); 25c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch} 26c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 2768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool ChromeImpl::HasCrashedWebView() { 2868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (WebViewList::iterator it = web_views_.begin(); 2968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) it != web_views_.end(); ++it) { 3068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if ((*it)->WasCrashed()) 3168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return true; 3268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 3368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return false; 3468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 3568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ChromeImpl::GetWebViewIds(std::list<std::string>* web_view_ids) { 37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) WebViewsInfo views_info; 38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Status status = devtools_http_client_->GetWebViewsInfo(&views_info); 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (status.IsError()) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return status; 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check if some web views are closed. 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WebViewList::iterator it = web_views_.begin(); 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (it != web_views_.end()) { 45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!views_info.GetForId((*it)->GetId())) { 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it = web_views_.erase(it); 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++it; 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Check for newly-opened web views. 53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < views_info.GetSize(); ++i) { 54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const WebViewInfo& view = views_info.Get(i); 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (view.type != WebViewInfo::kPage && view.type != WebViewInfo::kApp) 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue; 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Workaround to ignore generated background pages that are 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // being returned as active windows for some builds of Chrome. 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(bustamante): Once Chrome builds < 1755 are no longer 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // supported this check can be removed. 620529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch int kBuildNumber = devtools_http_client_->browser_info()->build_no; 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (kBuildNumber < 1755 && view.type == WebViewInfo::kApp && 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) view.url.find("_generated_background") != std::string::npos) 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool found = false; 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (WebViewList::const_iterator web_view_iter = web_views_.begin(); 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) web_view_iter != web_views_.end(); ++web_view_iter) { 70c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if ((*web_view_iter)->GetId() == view.id) { 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) found = true; 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!found) { 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<DevToolsClient> client( 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) devtools_http_client_->CreateClient(view.id)); 78b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) for (ScopedVector<DevToolsEventListener>::const_iterator listener = 79b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) devtools_event_listeners_.begin(); 80b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) listener != devtools_event_listeners_.end(); ++listener) { 81b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) client->AddListener(*listener); 82b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) // OnConnected will fire when DevToolsClient connects later. 83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) web_views_.push_back(make_linked_ptr(new WebViewImpl( 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) view.id, 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) devtools_http_client_->browser_info(), 87cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) client.Pass(), 88cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) devtools_http_client_->device_metrics()))); 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::list<std::string> web_view_ids_tmp; 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (WebViewList::const_iterator web_view_iter = web_views_.begin(); 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) web_view_iter != web_views_.end(); ++web_view_iter) { 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) web_view_ids_tmp.push_back((*web_view_iter)->GetId()); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) web_view_ids->swap(web_view_ids_tmp); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Status ChromeImpl::GetWebViewById(const std::string& id, WebView** web_view) { 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (WebViewList::iterator it = web_views_.begin(); 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) it != web_views_.end(); ++it) { 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((*it)->GetId() == id) { 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *web_view = (*it).get(); 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kOk); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Status(kUnknownError, "web view not found"); 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)Status ChromeImpl::CloseWebView(const std::string& id) { 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Status status = devtools_http_client_->CloseWebView(id); 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (status.IsError()) 115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return status; 116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (WebViewList::iterator iter = web_views_.begin(); 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) iter != web_views_.end(); ++iter) { 118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if ((*iter)->GetId() == id) { 119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) web_views_.erase(iter); 120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) break; 121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return Status(kOk); 124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 126424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)Status ChromeImpl::ActivateWebView(const std::string& id) { 127424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return devtools_http_client_->ActivateWebView(id); 128424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 129424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 130cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)bool ChromeImpl::IsMobileEmulationEnabled() const { 131cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return false; 132cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 133cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 13468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)Status ChromeImpl::Quit() { 13568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Status status = QuitImpl(); 13668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (status.IsOk()) 13768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) quit_ = true; 13868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return status; 13968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 14068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)ChromeImpl::ChromeImpl( 1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<DevToolsHttpClient> http_client, 1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) scoped_ptr<DevToolsClient> websocket_client, 14468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ScopedVector<DevToolsEventListener>& devtools_event_listeners, 14568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scoped_ptr<PortReservation> port_reservation) 14668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) : quit_(false), 1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) devtools_http_client_(http_client.Pass()), 1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) devtools_websocket_client_(websocket_client.Pass()), 14968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) port_reservation_(port_reservation.Pass()) { 150b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) devtools_event_listeners_.swap(devtools_event_listeners); 151b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)} 152