blob: 5d142caf01b1d82e4e9b03e2c53b34e83c0cb051 [file] [log] [blame]
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "web/InspectorEmulationAgent.h"
#include "core/frame/FrameView.h"
#include "core/frame/Settings.h"
#include "core/inspector/protocol/DOM.h"
#include "core/page/Page.h"
#include "platform/geometry/DoubleRect.h"
#include "platform/graphics/Color.h"
#include "public/platform/Platform.h"
#include "public/platform/WebFloatPoint.h"
#include "public/platform/WebThread.h"
#include "public/platform/WebViewScheduler.h"
#include "web/DevToolsEmulator.h"
#include "web/WebLocalFrameImpl.h"
#include "web/WebViewImpl.h"
namespace blink {
using protocol::Maybe;
using protocol::Response;
namespace EmulationAgentState {
static const char kScriptExecutionDisabled[] = "scriptExecutionDisabled";
static const char kTouchEventEmulationEnabled[] = "touchEventEmulationEnabled";
static const char kEmulatedMedia[] = "emulatedMedia";
static const char kForcedViewportEnabled[] = "forcedViewportEnabled";
static const char kForcedViewportX[] = "forcedViewportX";
static const char kForcedViewportY[] = "forcedViewportY";
static const char kForcedViewportScale[] = "forcedViewportScale";
static const char kDefaultBackgroundColorOverrideRGBA[] =
"defaultBackgroundColorOverrideRGBA";
}
InspectorEmulationAgent* InspectorEmulationAgent::Create(
WebLocalFrameImpl* web_local_frame_impl,
Client* client) {
return new InspectorEmulationAgent(web_local_frame_impl, client);
}
InspectorEmulationAgent::InspectorEmulationAgent(
WebLocalFrameImpl* web_local_frame_impl,
Client* client)
: web_local_frame_impl_(web_local_frame_impl), client_(client) {}
InspectorEmulationAgent::~InspectorEmulationAgent() {}
WebViewImpl* InspectorEmulationAgent::GetWebViewImpl() {
return web_local_frame_impl_->ViewImpl();
}
void InspectorEmulationAgent::Restore() {
setScriptExecutionDisabled(state_->booleanProperty(
EmulationAgentState::kScriptExecutionDisabled, false));
setTouchEmulationEnabled(
state_->booleanProperty(EmulationAgentState::kTouchEventEmulationEnabled,
false),
protocol::Maybe<String>());
String emulated_media;
state_->getString(EmulationAgentState::kEmulatedMedia, &emulated_media);
setEmulatedMedia(emulated_media);
if (state_->booleanProperty(EmulationAgentState::kForcedViewportEnabled,
false)) {
forceViewport(
state_->doubleProperty(EmulationAgentState::kForcedViewportX, 0),
state_->doubleProperty(EmulationAgentState::kForcedViewportY, 0),
state_->doubleProperty(EmulationAgentState::kForcedViewportScale, 1));
}
auto rgba_value =
state_->get(EmulationAgentState::kDefaultBackgroundColorOverrideRGBA);
if (rgba_value) {
blink::protocol::ErrorSupport errors;
auto rgba = protocol::DOM::RGBA::fromValue(rgba_value, &errors);
if (!errors.hasErrors()) {
setDefaultBackgroundColorOverride(
Maybe<protocol::DOM::RGBA>(std::move(rgba)));
}
}
}
Response InspectorEmulationAgent::disable() {
setScriptExecutionDisabled(false);
setTouchEmulationEnabled(false, Maybe<String>());
setEmulatedMedia(String());
setCPUThrottlingRate(1);
resetViewport();
setDefaultBackgroundColorOverride(Maybe<protocol::DOM::RGBA>());
return Response::OK();
}
Response InspectorEmulationAgent::forceViewport(double x,
double y,
double scale) {
if (x < 0 || y < 0)
return Response::Error("Coordinates must be non-negative");
if (scale <= 0)
return Response::Error("Scale must be positive");
state_->setBoolean(EmulationAgentState::kForcedViewportEnabled, true);
state_->setDouble(EmulationAgentState::kForcedViewportX, x);
state_->setDouble(EmulationAgentState::kForcedViewportY, y);
state_->setDouble(EmulationAgentState::kForcedViewportScale, scale);
GetWebViewImpl()->GetDevToolsEmulator()->ForceViewport(WebFloatPoint(x, y),
scale);
return Response::OK();
}
Response InspectorEmulationAgent::resetViewport() {
state_->setBoolean(EmulationAgentState::kForcedViewportEnabled, false);
GetWebViewImpl()->GetDevToolsEmulator()->ResetViewport();
return Response::OK();
}
Response InspectorEmulationAgent::resetPageScaleFactor() {
GetWebViewImpl()->ResetScaleStateImmediately();
return Response::OK();
}
Response InspectorEmulationAgent::setPageScaleFactor(double page_scale_factor) {
GetWebViewImpl()->SetPageScaleFactor(static_cast<float>(page_scale_factor));
return Response::OK();
}
Response InspectorEmulationAgent::setScriptExecutionDisabled(bool value) {
state_->setBoolean(EmulationAgentState::kScriptExecutionDisabled, value);
GetWebViewImpl()->GetDevToolsEmulator()->SetScriptExecutionDisabled(value);
return Response::OK();
}
Response InspectorEmulationAgent::setTouchEmulationEnabled(
bool enabled,
Maybe<String> configuration) {
state_->setBoolean(EmulationAgentState::kTouchEventEmulationEnabled, enabled);
GetWebViewImpl()->GetDevToolsEmulator()->SetTouchEventEmulationEnabled(
enabled);
return Response::OK();
}
Response InspectorEmulationAgent::setEmulatedMedia(const String& media) {
state_->setString(EmulationAgentState::kEmulatedMedia, media);
GetWebViewImpl()->GetPage()->GetSettings().SetMediaTypeOverride(media);
return Response::OK();
}
Response InspectorEmulationAgent::setCPUThrottlingRate(double throttling_rate) {
client_->SetCPUThrottlingRate(throttling_rate);
return Response::OK();
}
Response InspectorEmulationAgent::setVirtualTimePolicy(const String& policy,
Maybe<int> budget) {
if (protocol::Emulation::VirtualTimePolicyEnum::Advance == policy) {
web_local_frame_impl_->View()->Scheduler()->SetVirtualTimePolicy(
WebViewScheduler::VirtualTimePolicy::ADVANCE);
} else if (protocol::Emulation::VirtualTimePolicyEnum::Pause == policy) {
web_local_frame_impl_->View()->Scheduler()->SetVirtualTimePolicy(
WebViewScheduler::VirtualTimePolicy::PAUSE);
} else if (protocol::Emulation::VirtualTimePolicyEnum::
PauseIfNetworkFetchesPending == policy) {
web_local_frame_impl_->View()->Scheduler()->SetVirtualTimePolicy(
WebViewScheduler::VirtualTimePolicy::DETERMINISTIC_LOADING);
}
web_local_frame_impl_->View()->Scheduler()->EnableVirtualTime();
if (budget.isJust()) {
RefPtr<WebTaskRunner> task_runner =
Platform::Current()->CurrentThread()->GetWebTaskRunner();
long long delay_millis = static_cast<long long>(budget.fromJust());
virtual_time_budget_expired_task_handle_ =
task_runner->PostDelayedCancellableTask(
BLINK_FROM_HERE,
WTF::Bind(&InspectorEmulationAgent::VirtualTimeBudgetExpired,
WrapWeakPersistent(this)),
delay_millis);
}
return Response::OK();
}
void InspectorEmulationAgent::VirtualTimeBudgetExpired() {
web_local_frame_impl_->View()->Scheduler()->SetVirtualTimePolicy(
WebViewScheduler::VirtualTimePolicy::PAUSE);
GetFrontend()->virtualTimeBudgetExpired();
}
Response InspectorEmulationAgent::setDefaultBackgroundColorOverride(
Maybe<protocol::DOM::RGBA> color) {
if (!color.isJust()) {
// Clear the override and state.
GetWebViewImpl()->ClearBaseBackgroundColorOverride();
state_->remove(EmulationAgentState::kDefaultBackgroundColorOverrideRGBA);
return Response::OK();
}
blink::protocol::DOM::RGBA* rgba = color.fromJust();
state_->setValue(EmulationAgentState::kDefaultBackgroundColorOverrideRGBA,
rgba->toValue());
// Clamping of values is done by Color() constructor.
int alpha = lroundf(255.0f * rgba->getA(1.0f));
GetWebViewImpl()->SetBaseBackgroundColorOverride(
Color(rgba->getR(), rgba->getG(), rgba->getB(), alpha).Rgb());
return Response::OK();
}
DEFINE_TRACE(InspectorEmulationAgent) {
visitor->Trace(web_local_frame_impl_);
InspectorBaseAgent::Trace(visitor);
}
} // namespace blink