| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/devtools/protocol/emulation_handler.h" | 5 #include "content/browser/devtools/protocol/emulation_handler.h" |
| 6 | 6 |
| 7 #include "base/strings/string_number_conversions.h" |
| 8 #include "content/browser/geolocation/geolocation_service_context.h" |
| 9 #include "content/browser/renderer_host/render_view_host_impl.h" |
| 10 #include "content/browser/web_contents/web_contents_impl.h" |
| 11 #include "content/common/view_messages.h" |
| 12 #include "content/public/common/url_constants.h" |
| 13 |
| 7 namespace content { | 14 namespace content { |
| 8 namespace devtools { | 15 namespace devtools { |
| 9 namespace emulation { | 16 namespace emulation { |
| 10 | 17 |
| 11 using Response = DevToolsProtocolClient::Response; | 18 using Response = DevToolsProtocolClient::Response; |
| 12 | 19 |
| 13 EmulationHandler::EmulationHandler() { | 20 namespace { |
| 21 |
| 22 ui::GestureProviderConfigType TouchEmulationConfigurationToType( |
| 23 const std::string& protocol_value) { |
| 24 ui::GestureProviderConfigType result = |
| 25 ui::GestureProviderConfigType::CURRENT_PLATFORM; |
| 26 if (protocol_value == |
| 27 set_touch_emulation_enabled::kConfigurationMobile) { |
| 28 result = ui::GestureProviderConfigType::GENERIC_MOBILE; |
| 29 } |
| 30 if (protocol_value == |
| 31 set_touch_emulation_enabled::kConfigurationDesktop) { |
| 32 result = ui::GestureProviderConfigType::GENERIC_DESKTOP; |
| 33 } |
| 34 return result; |
| 35 } |
| 36 |
| 37 } // namespace |
| 38 |
| 39 EmulationHandler::EmulationHandler(page::PageHandler* page_handler) |
| 40 : touch_emulation_enabled_(false), |
| 41 device_emulation_enabled_(false), |
| 42 page_handler_(page_handler), |
| 43 host_(nullptr) |
| 44 { |
| 45 page_handler->SetScreencastListener(this); |
| 14 } | 46 } |
| 15 | 47 |
| 16 EmulationHandler::~EmulationHandler() { | 48 EmulationHandler::~EmulationHandler() { |
| 17 } | 49 } |
| 18 | 50 |
| 19 void EmulationHandler::SetClient(scoped_ptr<DevToolsProtocolClient> client) { | 51 void EmulationHandler::ScreencastEnabledChanged() { |
| 52 UpdateTouchEventEmulationState(); |
| 53 } |
| 54 |
| 55 void EmulationHandler::SetRenderViewHost(RenderViewHostImpl* host) { |
| 56 if (host_ == host) |
| 57 return; |
| 58 |
| 59 host_ = host; |
| 60 UpdateTouchEventEmulationState(); |
| 61 UpdateDeviceEmulationState(); |
| 62 } |
| 63 |
| 64 void EmulationHandler::Detached() { |
| 65 touch_emulation_enabled_ = false; |
| 66 device_emulation_enabled_ = false; |
| 67 UpdateTouchEventEmulationState(); |
| 68 UpdateDeviceEmulationState(); |
| 20 } | 69 } |
| 21 | 70 |
| 22 Response EmulationHandler::SetGeolocationOverride( | 71 Response EmulationHandler::SetGeolocationOverride( |
| 23 double* latitude, double* longitude, double* accuracy) { | 72 double* latitude, double* longitude, double* accuracy) { |
| 24 return Response::InternalError("Not implemented"); | 73 if (!host_) |
| 74 return Response::InternalError("Could not connect to view"); |
| 75 |
| 76 WebContentsImpl* web_contents = static_cast<WebContentsImpl*>( |
| 77 WebContents::FromRenderViewHost(host_)); |
| 78 if (!web_contents) |
| 79 return Response::InternalError("No WebContents to override"); |
| 80 |
| 81 GeolocationServiceContext* geolocation_context = |
| 82 web_contents->GetGeolocationServiceContext(); |
| 83 scoped_ptr<Geoposition> geoposition(new Geoposition()); |
| 84 if (latitude && longitude && accuracy) { |
| 85 geoposition->latitude = *latitude; |
| 86 geoposition->longitude = *longitude; |
| 87 geoposition->accuracy = *accuracy; |
| 88 geoposition->timestamp = base::Time::Now(); |
| 89 if (!geoposition->Validate()) { |
| 90 return Response::InternalError("Invalid geolocation"); |
| 91 } |
| 92 } else { |
| 93 geoposition->error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE; |
| 94 } |
| 95 geolocation_context->SetOverride(geoposition.Pass()); |
| 96 return Response::OK(); |
| 25 } | 97 } |
| 26 | 98 |
| 27 Response EmulationHandler::ClearGeolocationOverride() { | 99 Response EmulationHandler::ClearGeolocationOverride() { |
| 28 return Response::InternalError("Not implemented"); | 100 if (!host_) |
| 101 return Response::InternalError("Could not connect to view"); |
| 102 |
| 103 WebContentsImpl* web_contents = static_cast<WebContentsImpl*>( |
| 104 WebContents::FromRenderViewHost(host_)); |
| 105 if (!web_contents) |
| 106 return Response::InternalError("No WebContents to override"); |
| 107 |
| 108 GeolocationServiceContext* geolocation_context = |
| 109 web_contents->GetGeolocationServiceContext(); |
| 110 geolocation_context->ClearOverride(); |
| 111 return Response::OK(); |
| 29 } | 112 } |
| 30 | 113 |
| 31 Response EmulationHandler::SetTouchEmulationEnabled( | 114 Response EmulationHandler::SetTouchEmulationEnabled( |
| 32 bool enabled, const std::string* configuration) { | 115 bool enabled, const std::string* configuration) { |
| 33 return Response::InternalError("Not implemented"); | 116 touch_emulation_enabled_ = enabled; |
| 117 touch_emulation_configuration_ = |
| 118 configuration ? *configuration : std::string(); |
| 119 UpdateTouchEventEmulationState(); |
| 120 return Response::FallThrough(); |
| 34 } | 121 } |
| 35 | 122 |
| 36 Response EmulationHandler::CanEmulate(bool* result) { | 123 Response EmulationHandler::CanEmulate(bool* result) { |
| 37 return Response::InternalError("Not implemented"); | 124 #if defined(OS_ANDROID) |
| 125 *result = false; |
| 126 #else |
| 127 if (host_) { |
| 128 if (WebContents* web_contents = WebContents::FromRenderViewHost(host_)) { |
| 129 *result = web_contents->GetMainFrame()->GetRenderViewHost() == host_; |
| 130 #if defined(DEBUG_DEVTOOLS) |
| 131 *result &= !web_contents->GetVisibleURL().SchemeIs(kChromeDevToolsScheme); |
| 132 #endif // defined(DEBUG_DEVTOOLS) |
| 133 } else { |
| 134 *result = true; |
| 135 } |
| 136 } else { |
| 137 *result = true; |
| 138 } |
| 139 #endif // defined(OS_ANDROID) |
| 140 return Response::OK(); |
| 38 } | 141 } |
| 39 | 142 |
| 40 Response EmulationHandler::SetDeviceMetricsOverride( | 143 Response EmulationHandler::SetDeviceMetricsOverride( |
| 41 int width, int height, double device_scale_factor, bool mobile, | 144 int width, int height, double device_scale_factor, bool mobile, |
| 42 bool fit_window, const double* optional_scale, | 145 bool fit_window, const double* optional_scale, |
| 43 const double* optional_offset_x, const double* optional_offset_y) { | 146 const double* optional_offset_x, const double* optional_offset_y) { |
| 44 return Response::InternalError("Not implemented"); | 147 const static int max_size = 10000000; |
| 148 const static double max_scale = 10; |
| 149 |
| 150 if (!host_) |
| 151 return Response::InternalError("Could not connect to view"); |
| 152 |
| 153 if (width < 0 || height < 0 || width > max_size || height > max_size) { |
| 154 return Response::InvalidParams( |
| 155 "Width and height values must be positive, not greater than " + |
| 156 base::IntToString(max_size)); |
| 157 } |
| 158 |
| 159 if (device_scale_factor < 0) |
| 160 return Response::InvalidParams("deviceScaleFactor must be non-negative"); |
| 161 |
| 162 if (optional_scale && (*optional_scale <= 0 || *optional_scale > max_scale)) { |
| 163 return Response::InvalidParams( |
| 164 "scale must be positive, not greater than " + |
| 165 base::IntToString(max_scale)); |
| 166 } |
| 167 |
| 168 blink::WebDeviceEmulationParams params; |
| 169 params.screenPosition = mobile ? blink::WebDeviceEmulationParams::Mobile : |
| 170 blink::WebDeviceEmulationParams::Desktop; |
| 171 params.deviceScaleFactor = device_scale_factor; |
| 172 params.viewSize = blink::WebSize(width, height); |
| 173 params.fitToView = fit_window; |
| 174 params.scale = optional_scale ? *optional_scale : 1; |
| 175 params.offset = blink::WebFloatPoint( |
| 176 optional_offset_x ? *optional_offset_x : 0.f, |
| 177 optional_offset_y ? *optional_offset_y : 0.f); |
| 178 |
| 179 if (device_emulation_enabled_ && params == device_emulation_params_) |
| 180 return Response::OK(); |
| 181 |
| 182 device_emulation_enabled_ = true; |
| 183 device_emulation_params_ = params; |
| 184 UpdateDeviceEmulationState(); |
| 185 return Response::OK(); |
| 45 } | 186 } |
| 46 | 187 |
| 47 Response EmulationHandler::ClearDeviceMetricsOverride() { | 188 Response EmulationHandler::ClearDeviceMetricsOverride() { |
| 48 return Response::InternalError("Not implemented"); | 189 if (!device_emulation_enabled_) |
| 190 return Response::OK(); |
| 191 |
| 192 device_emulation_enabled_ = false; |
| 193 UpdateDeviceEmulationState(); |
| 194 return Response::OK(); |
| 195 } |
| 196 |
| 197 void EmulationHandler::UpdateTouchEventEmulationState() { |
| 198 if (!host_) |
| 199 return; |
| 200 bool enabled = touch_emulation_enabled_ || |
| 201 page_handler_->screencast_enabled(); |
| 202 ui::GestureProviderConfigType config_type = |
| 203 TouchEmulationConfigurationToType(touch_emulation_configuration_); |
| 204 host_->SetTouchEventEmulationEnabled(enabled, config_type); |
| 205 WebContentsImpl* web_contents = static_cast<WebContentsImpl*>( |
| 206 WebContents::FromRenderViewHost(host_)); |
| 207 if (web_contents) |
| 208 web_contents->SetForceDisableOverscrollContent(enabled); |
| 209 } |
| 210 |
| 211 void EmulationHandler::UpdateDeviceEmulationState() { |
| 212 if (!host_) |
| 213 return; |
| 214 if (device_emulation_enabled_) { |
| 215 host_->Send(new ViewMsg_EnableDeviceEmulation( |
| 216 host_->GetRoutingID(), device_emulation_params_)); |
| 217 } else { |
| 218 host_->Send(new ViewMsg_DisableDeviceEmulation(host_->GetRoutingID())); |
| 219 } |
| 49 } | 220 } |
| 50 | 221 |
| 51 } // namespace emulation | 222 } // namespace emulation |
| 52 } // namespace devtools | 223 } // namespace devtools |
| 53 } // namespace content | 224 } // namespace content |
| OLD | NEW |