1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "chrome/test/chromedriver/chrome/chrome_impl.h" 6 7#include "chrome/test/chromedriver/chrome/devtools_client.h" 8#include "chrome/test/chromedriver/chrome/devtools_event_listener.h" 9#include "chrome/test/chromedriver/chrome/devtools_http_client.h" 10#include "chrome/test/chromedriver/chrome/status.h" 11#include "chrome/test/chromedriver/chrome/web_view_impl.h" 12#include "chrome/test/chromedriver/net/port_server.h" 13 14ChromeImpl::~ChromeImpl() { 15 if (!quit_) 16 port_reservation_->Leak(); 17} 18 19ChromeDesktopImpl* ChromeImpl::GetAsDesktop() { 20 return NULL; 21} 22 23const BrowserInfo* ChromeImpl::GetBrowserInfo() { 24 return devtools_http_client_->browser_info(); 25} 26 27bool ChromeImpl::HasCrashedWebView() { 28 for (WebViewList::iterator it = web_views_.begin(); 29 it != web_views_.end(); ++it) { 30 if ((*it)->WasCrashed()) 31 return true; 32 } 33 return false; 34} 35 36Status ChromeImpl::GetWebViewIds(std::list<std::string>* web_view_ids) { 37 WebViewsInfo views_info; 38 Status status = devtools_http_client_->GetWebViewsInfo(&views_info); 39 if (status.IsError()) 40 return status; 41 42 // Check if some web views are closed. 43 WebViewList::iterator it = web_views_.begin(); 44 while (it != web_views_.end()) { 45 if (!views_info.GetForId((*it)->GetId())) { 46 it = web_views_.erase(it); 47 } else { 48 ++it; 49 } 50 } 51 52 // Check for newly-opened web views. 53 for (size_t i = 0; i < views_info.GetSize(); ++i) { 54 const WebViewInfo& view = views_info.Get(i); 55 if (view.type != WebViewInfo::kPage && view.type != WebViewInfo::kApp) 56 continue; 57 58 // Workaround to ignore generated background pages that are 59 // being returned as active windows for some builds of Chrome. 60 // TODO(bustamante): Once Chrome builds < 1755 are no longer 61 // supported this check can be removed. 62 int kBuildNumber = devtools_http_client_->browser_info()->build_no; 63 if (kBuildNumber < 1755 && view.type == WebViewInfo::kApp && 64 view.url.find("_generated_background") != std::string::npos) 65 continue; 66 67 bool found = false; 68 for (WebViewList::const_iterator web_view_iter = web_views_.begin(); 69 web_view_iter != web_views_.end(); ++web_view_iter) { 70 if ((*web_view_iter)->GetId() == view.id) { 71 found = true; 72 break; 73 } 74 } 75 if (!found) { 76 scoped_ptr<DevToolsClient> client( 77 devtools_http_client_->CreateClient(view.id)); 78 for (ScopedVector<DevToolsEventListener>::const_iterator listener = 79 devtools_event_listeners_.begin(); 80 listener != devtools_event_listeners_.end(); ++listener) { 81 client->AddListener(*listener); 82 // OnConnected will fire when DevToolsClient connects later. 83 } 84 web_views_.push_back(make_linked_ptr(new WebViewImpl( 85 view.id, 86 devtools_http_client_->browser_info(), 87 client.Pass(), 88 devtools_http_client_->device_metrics()))); 89 } 90 } 91 92 std::list<std::string> web_view_ids_tmp; 93 for (WebViewList::const_iterator web_view_iter = web_views_.begin(); 94 web_view_iter != web_views_.end(); ++web_view_iter) { 95 web_view_ids_tmp.push_back((*web_view_iter)->GetId()); 96 } 97 web_view_ids->swap(web_view_ids_tmp); 98 return Status(kOk); 99} 100 101Status ChromeImpl::GetWebViewById(const std::string& id, WebView** web_view) { 102 for (WebViewList::iterator it = web_views_.begin(); 103 it != web_views_.end(); ++it) { 104 if ((*it)->GetId() == id) { 105 *web_view = (*it).get(); 106 return Status(kOk); 107 } 108 } 109 return Status(kUnknownError, "web view not found"); 110} 111 112Status ChromeImpl::CloseWebView(const std::string& id) { 113 Status status = devtools_http_client_->CloseWebView(id); 114 if (status.IsError()) 115 return status; 116 for (WebViewList::iterator iter = web_views_.begin(); 117 iter != web_views_.end(); ++iter) { 118 if ((*iter)->GetId() == id) { 119 web_views_.erase(iter); 120 break; 121 } 122 } 123 return Status(kOk); 124} 125 126Status ChromeImpl::ActivateWebView(const std::string& id) { 127 return devtools_http_client_->ActivateWebView(id); 128} 129 130bool ChromeImpl::IsMobileEmulationEnabled() const { 131 return false; 132} 133 134Status ChromeImpl::Quit() { 135 Status status = QuitImpl(); 136 if (status.IsOk()) 137 quit_ = true; 138 return status; 139} 140 141ChromeImpl::ChromeImpl( 142 scoped_ptr<DevToolsHttpClient> http_client, 143 scoped_ptr<DevToolsClient> websocket_client, 144 ScopedVector<DevToolsEventListener>& devtools_event_listeners, 145 scoped_ptr<PortReservation> port_reservation) 146 : quit_(false), 147 devtools_http_client_(http_client.Pass()), 148 devtools_websocket_client_(websocket_client.Pass()), 149 port_reservation_(port_reservation.Pass()) { 150 devtools_event_listeners_.swap(devtools_event_listeners); 151} 152