// This file is generated by TypeBuilder_cpp.template.

// Copyright 2016 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/devtools/protocol/emulation.h"

#include "content/browser/devtools/protocol/protocol.h"

#include "third_party/inspector_protocol/crdtp/cbor.h"
#include "third_party/inspector_protocol/crdtp/find_by_first.h"
#include "third_party/inspector_protocol/crdtp/span.h"

namespace content {
namespace protocol {
namespace Emulation {

using crdtp::DeserializerState;
using crdtp::FallthroughCallback;
using crdtp::ProtocolTypeTraits;

// ------------- Enum values from types.

const char Metainfo::domainName[] = "Emulation";
const char Metainfo::commandPrefix[] = "Emulation.";
const char Metainfo::version[] = "1.3";


const char* ScreenOrientation::TypeEnum::PortraitPrimary = "portraitPrimary";
const char* ScreenOrientation::TypeEnum::PortraitSecondary = "portraitSecondary";
const char* ScreenOrientation::TypeEnum::LandscapePrimary = "landscapePrimary";
const char* ScreenOrientation::TypeEnum::LandscapeSecondary = "landscapeSecondary";
CRDTP_BEGIN_DESERIALIZER(ScreenOrientation)
    CRDTP_DESERIALIZE_FIELD("angle", m_angle),
    CRDTP_DESERIALIZE_FIELD("type", m_type),
CRDTP_END_DESERIALIZER()

CRDTP_BEGIN_SERIALIZER(ScreenOrientation)
    CRDTP_SERIALIZE_FIELD("type", m_type);
    CRDTP_SERIALIZE_FIELD("angle", m_angle);
CRDTP_END_SERIALIZER();



const char* DisplayFeature::OrientationEnum::Vertical = "vertical";
const char* DisplayFeature::OrientationEnum::Horizontal = "horizontal";
CRDTP_BEGIN_DESERIALIZER(DisplayFeature)
    CRDTP_DESERIALIZE_FIELD("maskLength", m_maskLength),
    CRDTP_DESERIALIZE_FIELD("offset", m_offset),
    CRDTP_DESERIALIZE_FIELD("orientation", m_orientation),
CRDTP_END_DESERIALIZER()

CRDTP_BEGIN_SERIALIZER(DisplayFeature)
    CRDTP_SERIALIZE_FIELD("orientation", m_orientation);
    CRDTP_SERIALIZE_FIELD("offset", m_offset);
    CRDTP_SERIALIZE_FIELD("maskLength", m_maskLength);
CRDTP_END_SERIALIZER();



const char* DevicePosture::TypeEnum::Continuous = "continuous";
const char* DevicePosture::TypeEnum::Folded = "folded";
CRDTP_BEGIN_DESERIALIZER(DevicePosture)
    CRDTP_DESERIALIZE_FIELD("type", m_type),
CRDTP_END_DESERIALIZER()

CRDTP_BEGIN_SERIALIZER(DevicePosture)
    CRDTP_SERIALIZE_FIELD("type", m_type);
CRDTP_END_SERIALIZER();


CRDTP_BEGIN_DESERIALIZER(MediaFeature)
    CRDTP_DESERIALIZE_FIELD("name", m_name),
    CRDTP_DESERIALIZE_FIELD("value", m_value),
CRDTP_END_DESERIALIZER()

CRDTP_BEGIN_SERIALIZER(MediaFeature)
    CRDTP_SERIALIZE_FIELD("name", m_name);
    CRDTP_SERIALIZE_FIELD("value", m_value);
CRDTP_END_SERIALIZER();


CRDTP_BEGIN_DESERIALIZER(UserAgentBrandVersion)
    CRDTP_DESERIALIZE_FIELD("brand", m_brand),
    CRDTP_DESERIALIZE_FIELD("version", m_version),
CRDTP_END_DESERIALIZER()

CRDTP_BEGIN_SERIALIZER(UserAgentBrandVersion)
    CRDTP_SERIALIZE_FIELD("brand", m_brand);
    CRDTP_SERIALIZE_FIELD("version", m_version);
CRDTP_END_SERIALIZER();


CRDTP_BEGIN_DESERIALIZER(UserAgentMetadata)
    CRDTP_DESERIALIZE_FIELD("architecture", m_architecture),
    CRDTP_DESERIALIZE_FIELD_OPT("bitness", m_bitness),
    CRDTP_DESERIALIZE_FIELD_OPT("brands", m_brands),
    CRDTP_DESERIALIZE_FIELD_OPT("formFactors", m_formFactors),
    CRDTP_DESERIALIZE_FIELD_OPT("fullVersion", m_fullVersion),
    CRDTP_DESERIALIZE_FIELD_OPT("fullVersionList", m_fullVersionList),
    CRDTP_DESERIALIZE_FIELD("mobile", m_mobile),
    CRDTP_DESERIALIZE_FIELD("model", m_model),
    CRDTP_DESERIALIZE_FIELD("platform", m_platform),
    CRDTP_DESERIALIZE_FIELD("platformVersion", m_platformVersion),
    CRDTP_DESERIALIZE_FIELD_OPT("wow64", m_wow64),
CRDTP_END_DESERIALIZER()

CRDTP_BEGIN_SERIALIZER(UserAgentMetadata)
    CRDTP_SERIALIZE_FIELD("brands", m_brands);
    CRDTP_SERIALIZE_FIELD("fullVersionList", m_fullVersionList);
    CRDTP_SERIALIZE_FIELD("fullVersion", m_fullVersion);
    CRDTP_SERIALIZE_FIELD("platform", m_platform);
    CRDTP_SERIALIZE_FIELD("platformVersion", m_platformVersion);
    CRDTP_SERIALIZE_FIELD("architecture", m_architecture);
    CRDTP_SERIALIZE_FIELD("model", m_model);
    CRDTP_SERIALIZE_FIELD("mobile", m_mobile);
    CRDTP_SERIALIZE_FIELD("bitness", m_bitness);
    CRDTP_SERIALIZE_FIELD("wow64", m_wow64);
    CRDTP_SERIALIZE_FIELD("formFactors", m_formFactors);
CRDTP_END_SERIALIZER();



CRDTP_BEGIN_DESERIALIZER(SensorMetadata)
    CRDTP_DESERIALIZE_FIELD_OPT("available", m_available),
    CRDTP_DESERIALIZE_FIELD_OPT("maximumFrequency", m_maximumFrequency),
    CRDTP_DESERIALIZE_FIELD_OPT("minimumFrequency", m_minimumFrequency),
CRDTP_END_DESERIALIZER()

CRDTP_BEGIN_SERIALIZER(SensorMetadata)
    CRDTP_SERIALIZE_FIELD("available", m_available);
    CRDTP_SERIALIZE_FIELD("minimumFrequency", m_minimumFrequency);
    CRDTP_SERIALIZE_FIELD("maximumFrequency", m_maximumFrequency);
CRDTP_END_SERIALIZER();


CRDTP_BEGIN_DESERIALIZER(SensorReadingSingle)
    CRDTP_DESERIALIZE_FIELD("value", m_value),
CRDTP_END_DESERIALIZER()

CRDTP_BEGIN_SERIALIZER(SensorReadingSingle)
    CRDTP_SERIALIZE_FIELD("value", m_value);
CRDTP_END_SERIALIZER();


CRDTP_BEGIN_DESERIALIZER(SensorReadingXYZ)
    CRDTP_DESERIALIZE_FIELD("x", m_x),
    CRDTP_DESERIALIZE_FIELD("y", m_y),
    CRDTP_DESERIALIZE_FIELD("z", m_z),
CRDTP_END_DESERIALIZER()

CRDTP_BEGIN_SERIALIZER(SensorReadingXYZ)
    CRDTP_SERIALIZE_FIELD("x", m_x);
    CRDTP_SERIALIZE_FIELD("y", m_y);
    CRDTP_SERIALIZE_FIELD("z", m_z);
CRDTP_END_SERIALIZER();


CRDTP_BEGIN_DESERIALIZER(SensorReadingQuaternion)
    CRDTP_DESERIALIZE_FIELD("w", m_w),
    CRDTP_DESERIALIZE_FIELD("x", m_x),
    CRDTP_DESERIALIZE_FIELD("y", m_y),
    CRDTP_DESERIALIZE_FIELD("z", m_z),
CRDTP_END_DESERIALIZER()

CRDTP_BEGIN_SERIALIZER(SensorReadingQuaternion)
    CRDTP_SERIALIZE_FIELD("x", m_x);
    CRDTP_SERIALIZE_FIELD("y", m_y);
    CRDTP_SERIALIZE_FIELD("z", m_z);
    CRDTP_SERIALIZE_FIELD("w", m_w);
CRDTP_END_SERIALIZER();


CRDTP_BEGIN_DESERIALIZER(SensorReading)
    CRDTP_DESERIALIZE_FIELD_OPT("quaternion", m_quaternion),
    CRDTP_DESERIALIZE_FIELD_OPT("single", m_single),
    CRDTP_DESERIALIZE_FIELD_OPT("xyz", m_xyz),
CRDTP_END_DESERIALIZER()

CRDTP_BEGIN_SERIALIZER(SensorReading)
    CRDTP_SERIALIZE_FIELD("single", m_single);
    CRDTP_SERIALIZE_FIELD("xyz", m_xyz);
    CRDTP_SERIALIZE_FIELD("quaternion", m_quaternion);
CRDTP_END_SERIALIZER();




CRDTP_BEGIN_DESERIALIZER(PressureMetadata)
    CRDTP_DESERIALIZE_FIELD_OPT("available", m_available),
CRDTP_END_DESERIALIZER()

CRDTP_BEGIN_SERIALIZER(PressureMetadata)
    CRDTP_SERIALIZE_FIELD("available", m_available);
CRDTP_END_SERIALIZER();


// ------------- Enum values from params.


// ------------- Frontend notifications.

void Frontend::VirtualTimeBudgetExpired()
{
    if (!frontend_channel_)
        return;
    frontend_channel_->SendProtocolNotification(crdtp::CreateNotification("Emulation.virtualTimeBudgetExpired"));
}

void Frontend::ScreenOrientationLockChanged(bool locked, std::unique_ptr<protocol::Emulation::ScreenOrientation> orientation)
{
    if (!frontend_channel_)
        return;
    crdtp::ObjectSerializer serializer;
    serializer.AddField(crdtp::MakeSpan("locked"), locked);
    serializer.AddField(crdtp::MakeSpan("orientation"), orientation);
    frontend_channel_->SendProtocolNotification(crdtp::CreateNotification("Emulation.screenOrientationLockChanged", serializer.Finish()));
}

void Frontend::flush()
{
    frontend_channel_->FlushProtocolNotifications();
}

void Frontend::sendRawNotification(std::unique_ptr<Serializable> notification)
{
    frontend_channel_->SendProtocolNotification(std::move(notification));
}

// --------------------- Dispatcher.

class DomainDispatcherImpl : public protocol::DomainDispatcher {
public:
    DomainDispatcherImpl(FrontendChannel* frontendChannel, Backend* backend)
        : DomainDispatcher(frontendChannel)
        , m_backend(backend) {}
    ~DomainDispatcherImpl() override { }

    using CallHandler = void (DomainDispatcherImpl::*)(crdtp::Dispatchable& dispatchable);

    bool Dispatch(crdtp::span<uint8_t> command_name, crdtp::Dispatchable& dispatchable) override;

    void canEmulate(crdtp::Dispatchable& dispatchable);
    void clearDeviceMetricsOverride(crdtp::Dispatchable& dispatchable);
    void clearGeolocationOverride(crdtp::Dispatchable& dispatchable);
    void setFocusEmulationEnabled(crdtp::Dispatchable& dispatchable);
    void setDeviceMetricsOverride(crdtp::Dispatchable& dispatchable);
    void setDevicePostureOverride(crdtp::Dispatchable& dispatchable);
    void clearDevicePostureOverride(crdtp::Dispatchable& dispatchable);
    void setDisplayFeaturesOverride(crdtp::Dispatchable& dispatchable);
    void clearDisplayFeaturesOverride(crdtp::Dispatchable& dispatchable);
    void setEmitTouchEventsForMouse(crdtp::Dispatchable& dispatchable);
    void setEmulatedMedia(crdtp::Dispatchable& dispatchable);
    void setGeolocationOverride(crdtp::Dispatchable& dispatchable);
    void getOverriddenSensorInformation(crdtp::Dispatchable& dispatchable);
    void setSensorOverrideEnabled(crdtp::Dispatchable& dispatchable);
    void setSensorOverrideReadings(crdtp::Dispatchable& dispatchable);
    void setPressureSourceOverrideEnabled(crdtp::Dispatchable& dispatchable);
    void setPressureStateOverride(crdtp::Dispatchable& dispatchable);
    void setIdleOverride(crdtp::Dispatchable& dispatchable);
    void clearIdleOverride(crdtp::Dispatchable& dispatchable);
    void setVisibleSize(crdtp::Dispatchable& dispatchable);
    void setUserAgentOverride(crdtp::Dispatchable& dispatchable);
 protected:
    Backend* m_backend;
};

namespace {
// This helper method with a static map of command methods (instance methods
// of DomainDispatcherImpl declared just above) by their name is used immediately below,
// in the DomainDispatcherImpl::Dispatch method.
DomainDispatcherImpl::CallHandler CommandByName(crdtp::span<uint8_t> command_name) {
  static auto* commands = [](){
    auto* commands = new std::vector<std::pair<crdtp::span<uint8_t>,
                              DomainDispatcherImpl::CallHandler>>{
    {
          crdtp::SpanFrom("canEmulate"),
          &DomainDispatcherImpl::canEmulate
    },
    {
          crdtp::SpanFrom("clearDeviceMetricsOverride"),
          &DomainDispatcherImpl::clearDeviceMetricsOverride
    },
    {
          crdtp::SpanFrom("clearDevicePostureOverride"),
          &DomainDispatcherImpl::clearDevicePostureOverride
    },
    {
          crdtp::SpanFrom("clearDisplayFeaturesOverride"),
          &DomainDispatcherImpl::clearDisplayFeaturesOverride
    },
    {
          crdtp::SpanFrom("clearGeolocationOverride"),
          &DomainDispatcherImpl::clearGeolocationOverride
    },
    {
          crdtp::SpanFrom("clearIdleOverride"),
          &DomainDispatcherImpl::clearIdleOverride
    },
    {
          crdtp::SpanFrom("getOverriddenSensorInformation"),
          &DomainDispatcherImpl::getOverriddenSensorInformation
    },
    {
          crdtp::SpanFrom("setDeviceMetricsOverride"),
          &DomainDispatcherImpl::setDeviceMetricsOverride
    },
    {
          crdtp::SpanFrom("setDevicePostureOverride"),
          &DomainDispatcherImpl::setDevicePostureOverride
    },
    {
          crdtp::SpanFrom("setDisplayFeaturesOverride"),
          &DomainDispatcherImpl::setDisplayFeaturesOverride
    },
    {
          crdtp::SpanFrom("setEmitTouchEventsForMouse"),
          &DomainDispatcherImpl::setEmitTouchEventsForMouse
    },
    {
          crdtp::SpanFrom("setEmulatedMedia"),
          &DomainDispatcherImpl::setEmulatedMedia
    },
    {
          crdtp::SpanFrom("setFocusEmulationEnabled"),
          &DomainDispatcherImpl::setFocusEmulationEnabled
    },
    {
          crdtp::SpanFrom("setGeolocationOverride"),
          &DomainDispatcherImpl::setGeolocationOverride
    },
    {
          crdtp::SpanFrom("setIdleOverride"),
          &DomainDispatcherImpl::setIdleOverride
    },
    {
          crdtp::SpanFrom("setPressureSourceOverrideEnabled"),
          &DomainDispatcherImpl::setPressureSourceOverrideEnabled
    },
    {
          crdtp::SpanFrom("setPressureStateOverride"),
          &DomainDispatcherImpl::setPressureStateOverride
    },
    {
          crdtp::SpanFrom("setSensorOverrideEnabled"),
          &DomainDispatcherImpl::setSensorOverrideEnabled
    },
    {
          crdtp::SpanFrom("setSensorOverrideReadings"),
          &DomainDispatcherImpl::setSensorOverrideReadings
    },
    {
          crdtp::SpanFrom("setUserAgentOverride"),
          &DomainDispatcherImpl::setUserAgentOverride
    },
    {
          crdtp::SpanFrom("setVisibleSize"),
          &DomainDispatcherImpl::setVisibleSize
    },
    };
    return commands;
  }();
  return crdtp::FindByFirst<DomainDispatcherImpl::CallHandler>(*commands, command_name, nullptr);
}
}  // namespace

bool DomainDispatcherImpl::Dispatch(crdtp::span<uint8_t> command_name, crdtp::Dispatchable& dispatchable) {
  CallHandler handler = CommandByName(command_name);
  if (!handler) return false;

  (this->*handler)(dispatchable);
  return true;
}


namespace {


}  // namespace

void DomainDispatcherImpl::canEmulate(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.
    // Declare output parameters.
    bool out_result;

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->CanEmulate(&out_result);
    if (response.IsFallThrough()) {
        dispatchable.DispatchFallThrough(response.Message());
        return;
    }
      if (weak->get()) {
        std::unique_ptr<crdtp::Serializable> result;
        if (response.IsSuccess()) {
          crdtp::ObjectSerializer serializer;
          serializer.AddField(crdtp::MakeSpan("result"), out_result);
          result = serializer.Finish();
        } else {
          result = Serializable::From({});
        }
        weak->get()->sendResponse(dispatchable.CallId(), response, std::move(result));
      }
    return;
}

namespace {


}  // namespace

void DomainDispatcherImpl::clearDeviceMetricsOverride(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->ClearDeviceMetricsOverride();
    if (response.IsFallThrough()) {
        dispatchable.DispatchFallThrough(response.Message());
        return;
    }
    if (weak->get())
        weak->get()->sendResponse(dispatchable.CallId(), response);
    return;
}

namespace {


}  // namespace

void DomainDispatcherImpl::clearGeolocationOverride(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->ClearGeolocationOverride();
    if (response.IsFallThrough()) {
        dispatchable.DispatchFallThrough(response.Message());
        return;
    }
    if (weak->get())
        weak->get()->sendResponse(dispatchable.CallId(), response);
    return;
}

namespace {

struct setFocusEmulationEnabledParams : public crdtp::DeserializableProtocolObject<setFocusEmulationEnabledParams> {
    bool enabled;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(setFocusEmulationEnabledParams)
    CRDTP_DESERIALIZE_FIELD("enabled", enabled),
CRDTP_END_DESERIALIZER()

}  // namespace

void DomainDispatcherImpl::setFocusEmulationEnabled(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.
    auto deserializer = crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer();
    setFocusEmulationEnabledParams params;
    if (!setFocusEmulationEnabledParams::Deserialize(&deserializer, &params)) {
      ReportInvalidParams(dispatchable, deserializer);
      return;
    }

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->SetFocusEmulationEnabled(params.enabled);
    if (response.IsFallThrough()) {
        dispatchable.DispatchFallThrough(response.Message());
        return;
    }
    if (weak->get())
        weak->get()->sendResponse(dispatchable.CallId(), response);
    return;
}

namespace {

struct setDeviceMetricsOverrideParams : public crdtp::DeserializableProtocolObject<setDeviceMetricsOverrideParams> {
    int width;
    int height;
    double deviceScaleFactor;
    bool mobile;
    std::optional<double> scale;
    std::optional<int> screenWidth;
    std::optional<int> screenHeight;
    std::optional<int> positionX;
    std::optional<int> positionY;
    std::optional<bool> dontSetVisibleSize;
    std::unique_ptr<protocol::Emulation::ScreenOrientation> screenOrientation;
    std::unique_ptr<protocol::Page::Viewport> viewport;
    std::unique_ptr<protocol::Emulation::DisplayFeature> displayFeature;
    std::unique_ptr<protocol::Emulation::DevicePosture> devicePosture;
    std::optional<String> scrollbarType;
    std::optional<bool> screenOrientationLockEmulation;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(setDeviceMetricsOverrideParams)
    CRDTP_DESERIALIZE_FIELD_OPT("devicePosture", devicePosture),
    CRDTP_DESERIALIZE_FIELD("deviceScaleFactor", deviceScaleFactor),
    CRDTP_DESERIALIZE_FIELD_OPT("displayFeature", displayFeature),
    CRDTP_DESERIALIZE_FIELD_OPT("dontSetVisibleSize", dontSetVisibleSize),
    CRDTP_DESERIALIZE_FIELD("height", height),
    CRDTP_DESERIALIZE_FIELD("mobile", mobile),
    CRDTP_DESERIALIZE_FIELD_OPT("positionX", positionX),
    CRDTP_DESERIALIZE_FIELD_OPT("positionY", positionY),
    CRDTP_DESERIALIZE_FIELD_OPT("scale", scale),
    CRDTP_DESERIALIZE_FIELD_OPT("screenHeight", screenHeight),
    CRDTP_DESERIALIZE_FIELD_OPT("screenOrientation", screenOrientation),
    CRDTP_DESERIALIZE_FIELD_OPT("screenOrientationLockEmulation", screenOrientationLockEmulation),
    CRDTP_DESERIALIZE_FIELD_OPT("screenWidth", screenWidth),
    CRDTP_DESERIALIZE_FIELD_OPT("scrollbarType", scrollbarType),
    CRDTP_DESERIALIZE_FIELD_OPT("viewport", viewport),
    CRDTP_DESERIALIZE_FIELD("width", width),
CRDTP_END_DESERIALIZER()

}  // namespace

void DomainDispatcherImpl::setDeviceMetricsOverride(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.
    auto deserializer = crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer();
    setDeviceMetricsOverrideParams params;
    if (!setDeviceMetricsOverrideParams::Deserialize(&deserializer, &params)) {
      ReportInvalidParams(dispatchable, deserializer);
      return;
    }

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->SetDeviceMetricsOverride(params.width, params.height, params.deviceScaleFactor, params.mobile, std::move(params.scale), std::move(params.screenWidth), std::move(params.screenHeight), std::move(params.positionX), std::move(params.positionY), std::move(params.dontSetVisibleSize), std::move(params.screenOrientation), std::move(params.viewport), std::move(params.displayFeature), std::move(params.devicePosture), std::move(params.scrollbarType), std::move(params.screenOrientationLockEmulation));
    if (response.IsFallThrough()) {
        dispatchable.DispatchFallThrough(response.Message());
        return;
    }
    if (weak->get())
        weak->get()->sendResponse(dispatchable.CallId(), response);
    return;
}

namespace {

struct setDevicePostureOverrideParams : public crdtp::DeserializableProtocolObject<setDevicePostureOverrideParams> {
    std::unique_ptr<protocol::Emulation::DevicePosture> posture;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(setDevicePostureOverrideParams)
    CRDTP_DESERIALIZE_FIELD("posture", posture),
CRDTP_END_DESERIALIZER()

}  // namespace

void DomainDispatcherImpl::setDevicePostureOverride(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.
    auto deserializer = crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer();
    setDevicePostureOverrideParams params;
    if (!setDevicePostureOverrideParams::Deserialize(&deserializer, &params)) {
      ReportInvalidParams(dispatchable, deserializer);
      return;
    }

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->SetDevicePostureOverride(std::move(params.posture));
    if (response.IsFallThrough()) {
        dispatchable.DispatchFallThrough(response.Message());
        return;
    }
    if (weak->get())
        weak->get()->sendResponse(dispatchable.CallId(), response);
    return;
}

namespace {


}  // namespace

void DomainDispatcherImpl::clearDevicePostureOverride(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->ClearDevicePostureOverride();
    if (response.IsFallThrough()) {
        dispatchable.DispatchFallThrough(response.Message());
        return;
    }
    if (weak->get())
        weak->get()->sendResponse(dispatchable.CallId(), response);
    return;
}

namespace {

struct setDisplayFeaturesOverrideParams : public crdtp::DeserializableProtocolObject<setDisplayFeaturesOverrideParams> {
    std::unique_ptr<protocol::Array<protocol::Emulation::DisplayFeature>> features;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(setDisplayFeaturesOverrideParams)
    CRDTP_DESERIALIZE_FIELD("features", features),
CRDTP_END_DESERIALIZER()

}  // namespace

void DomainDispatcherImpl::setDisplayFeaturesOverride(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.
    auto deserializer = crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer();
    setDisplayFeaturesOverrideParams params;
    if (!setDisplayFeaturesOverrideParams::Deserialize(&deserializer, &params)) {
      ReportInvalidParams(dispatchable, deserializer);
      return;
    }

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->SetDisplayFeaturesOverride(std::move(params.features));
    if (response.IsFallThrough()) {
        dispatchable.DispatchFallThrough(response.Message());
        return;
    }
    if (weak->get())
        weak->get()->sendResponse(dispatchable.CallId(), response);
    return;
}

namespace {


}  // namespace

void DomainDispatcherImpl::clearDisplayFeaturesOverride(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->ClearDisplayFeaturesOverride();
    if (response.IsFallThrough()) {
        dispatchable.DispatchFallThrough(response.Message());
        return;
    }
    if (weak->get())
        weak->get()->sendResponse(dispatchable.CallId(), response);
    return;
}

namespace {

struct setEmitTouchEventsForMouseParams : public crdtp::DeserializableProtocolObject<setEmitTouchEventsForMouseParams> {
    bool enabled;
    std::optional<String> configuration;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(setEmitTouchEventsForMouseParams)
    CRDTP_DESERIALIZE_FIELD_OPT("configuration", configuration),
    CRDTP_DESERIALIZE_FIELD("enabled", enabled),
CRDTP_END_DESERIALIZER()

}  // namespace

void DomainDispatcherImpl::setEmitTouchEventsForMouse(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.
    auto deserializer = crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer();
    setEmitTouchEventsForMouseParams params;
    if (!setEmitTouchEventsForMouseParams::Deserialize(&deserializer, &params)) {
      ReportInvalidParams(dispatchable, deserializer);
      return;
    }

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->SetEmitTouchEventsForMouse(params.enabled, std::move(params.configuration));
    if (response.IsFallThrough()) {
        dispatchable.DispatchFallThrough(response.Message());
        return;
    }
    if (weak->get())
        weak->get()->sendResponse(dispatchable.CallId(), response);
    return;
}

namespace {

struct setEmulatedMediaParams : public crdtp::DeserializableProtocolObject<setEmulatedMediaParams> {
    std::optional<String> media;
    std::unique_ptr<protocol::Array<protocol::Emulation::MediaFeature>> features;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(setEmulatedMediaParams)
    CRDTP_DESERIALIZE_FIELD_OPT("features", features),
    CRDTP_DESERIALIZE_FIELD_OPT("media", media),
CRDTP_END_DESERIALIZER()

}  // namespace

void DomainDispatcherImpl::setEmulatedMedia(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.
    auto deserializer = crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer();
    setEmulatedMediaParams params;
    if (!setEmulatedMediaParams::Deserialize(&deserializer, &params)) {
      ReportInvalidParams(dispatchable, deserializer);
      return;
    }

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->SetEmulatedMedia(std::move(params.media), std::move(params.features));
    if (response.IsFallThrough()) {
        dispatchable.DispatchFallThrough(response.Message());
        return;
    }
    if (weak->get())
        weak->get()->sendResponse(dispatchable.CallId(), response);
    return;
}

namespace {

struct setGeolocationOverrideParams : public crdtp::DeserializableProtocolObject<setGeolocationOverrideParams> {
    std::optional<double> latitude;
    std::optional<double> longitude;
    std::optional<double> accuracy;
    std::optional<double> altitude;
    std::optional<double> altitudeAccuracy;
    std::optional<double> heading;
    std::optional<double> speed;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(setGeolocationOverrideParams)
    CRDTP_DESERIALIZE_FIELD_OPT("accuracy", accuracy),
    CRDTP_DESERIALIZE_FIELD_OPT("altitude", altitude),
    CRDTP_DESERIALIZE_FIELD_OPT("altitudeAccuracy", altitudeAccuracy),
    CRDTP_DESERIALIZE_FIELD_OPT("heading", heading),
    CRDTP_DESERIALIZE_FIELD_OPT("latitude", latitude),
    CRDTP_DESERIALIZE_FIELD_OPT("longitude", longitude),
    CRDTP_DESERIALIZE_FIELD_OPT("speed", speed),
CRDTP_END_DESERIALIZER()

}  // namespace

void DomainDispatcherImpl::setGeolocationOverride(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.
    auto deserializer = crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer();
    setGeolocationOverrideParams params;
    if (!setGeolocationOverrideParams::Deserialize(&deserializer, &params)) {
      ReportInvalidParams(dispatchable, deserializer);
      return;
    }

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->SetGeolocationOverride(std::move(params.latitude), std::move(params.longitude), std::move(params.accuracy), std::move(params.altitude), std::move(params.altitudeAccuracy), std::move(params.heading), std::move(params.speed));
    if (response.IsFallThrough()) {
        dispatchable.DispatchFallThrough(response.Message());
        return;
    }
    if (weak->get())
        weak->get()->sendResponse(dispatchable.CallId(), response);
    return;
}

class GetOverriddenSensorInformationCallbackImpl : public Backend::GetOverriddenSensorInformationCallback, public DomainDispatcher::Callback {
public:
    GetOverriddenSensorInformationCallbackImpl(std::unique_ptr<DomainDispatcher::WeakPtr> backendImpl, crdtp::Dispatchable& dispatchable)
        : DomainDispatcher::Callback(std::move(backendImpl), dispatchable, crdtp::SpanFrom("Emulation.getOverriddenSensorInformation")) { }

    void sendSuccess(double requestedSamplingFrequency) override
    {
        crdtp::ObjectSerializer serializer;
        serializer.AddField(crdtp::MakeSpan("requestedSamplingFrequency"), requestedSamplingFrequency);
        sendIfActive(serializer.Finish(), DispatchResponse::Success());
    }

    void fallThrough() override
    {
        fallThroughIfActive();
    }

    void sendFailure(const DispatchResponse& response) override
    {
        DCHECK(response.IsError());
        sendIfActive(nullptr, response);
    }
};

namespace {

struct getOverriddenSensorInformationParams : public crdtp::DeserializableProtocolObject<getOverriddenSensorInformationParams> {
    String type;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(getOverriddenSensorInformationParams)
    CRDTP_DESERIALIZE_FIELD("type", type),
CRDTP_END_DESERIALIZER()

}  // namespace

void DomainDispatcherImpl::getOverriddenSensorInformation(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.
    auto deserializer = crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer();
    getOverriddenSensorInformationParams params;
    if (!getOverriddenSensorInformationParams::Deserialize(&deserializer, &params)) {
      ReportInvalidParams(dispatchable, deserializer);
      return;
    }

    m_backend->GetOverriddenSensorInformation(params.type, std::make_unique<GetOverriddenSensorInformationCallbackImpl>(weakPtr(), dispatchable));
}

namespace {

struct setSensorOverrideEnabledParams : public crdtp::DeserializableProtocolObject<setSensorOverrideEnabledParams> {
    bool enabled;
    String type;
    std::unique_ptr<protocol::Emulation::SensorMetadata> metadata;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(setSensorOverrideEnabledParams)
    CRDTP_DESERIALIZE_FIELD("enabled", enabled),
    CRDTP_DESERIALIZE_FIELD_OPT("metadata", metadata),
    CRDTP_DESERIALIZE_FIELD("type", type),
CRDTP_END_DESERIALIZER()

}  // namespace

void DomainDispatcherImpl::setSensorOverrideEnabled(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.
    auto deserializer = crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer();
    setSensorOverrideEnabledParams params;
    if (!setSensorOverrideEnabledParams::Deserialize(&deserializer, &params)) {
      ReportInvalidParams(dispatchable, deserializer);
      return;
    }

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->SetSensorOverrideEnabled(params.enabled, params.type, std::move(params.metadata));
    if (response.IsFallThrough()) {
        dispatchable.DispatchFallThrough(response.Message());
        return;
    }
    if (weak->get())
        weak->get()->sendResponse(dispatchable.CallId(), response);
    return;
}

class SetSensorOverrideReadingsCallbackImpl : public Backend::SetSensorOverrideReadingsCallback, public DomainDispatcher::Callback {
public:
    SetSensorOverrideReadingsCallbackImpl(std::unique_ptr<DomainDispatcher::WeakPtr> backendImpl, crdtp::Dispatchable& dispatchable)
        : DomainDispatcher::Callback(std::move(backendImpl), dispatchable, crdtp::SpanFrom("Emulation.setSensorOverrideReadings")) { }

    void sendSuccess() override
    {
        crdtp::ObjectSerializer serializer;
        sendIfActive(serializer.Finish(), DispatchResponse::Success());
    }

    void fallThrough() override
    {
        fallThroughIfActive();
    }

    void sendFailure(const DispatchResponse& response) override
    {
        DCHECK(response.IsError());
        sendIfActive(nullptr, response);
    }
};

namespace {

struct setSensorOverrideReadingsParams : public crdtp::DeserializableProtocolObject<setSensorOverrideReadingsParams> {
    String type;
    std::unique_ptr<protocol::Emulation::SensorReading> reading;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(setSensorOverrideReadingsParams)
    CRDTP_DESERIALIZE_FIELD("reading", reading),
    CRDTP_DESERIALIZE_FIELD("type", type),
CRDTP_END_DESERIALIZER()

}  // namespace

void DomainDispatcherImpl::setSensorOverrideReadings(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.
    auto deserializer = crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer();
    setSensorOverrideReadingsParams params;
    if (!setSensorOverrideReadingsParams::Deserialize(&deserializer, &params)) {
      ReportInvalidParams(dispatchable, deserializer);
      return;
    }

    m_backend->SetSensorOverrideReadings(params.type, std::move(params.reading), std::make_unique<SetSensorOverrideReadingsCallbackImpl>(weakPtr(), dispatchable));
}

namespace {

struct setPressureSourceOverrideEnabledParams : public crdtp::DeserializableProtocolObject<setPressureSourceOverrideEnabledParams> {
    bool enabled;
    String source;
    std::unique_ptr<protocol::Emulation::PressureMetadata> metadata;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(setPressureSourceOverrideEnabledParams)
    CRDTP_DESERIALIZE_FIELD("enabled", enabled),
    CRDTP_DESERIALIZE_FIELD_OPT("metadata", metadata),
    CRDTP_DESERIALIZE_FIELD("source", source),
CRDTP_END_DESERIALIZER()

}  // namespace

void DomainDispatcherImpl::setPressureSourceOverrideEnabled(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.
    auto deserializer = crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer();
    setPressureSourceOverrideEnabledParams params;
    if (!setPressureSourceOverrideEnabledParams::Deserialize(&deserializer, &params)) {
      ReportInvalidParams(dispatchable, deserializer);
      return;
    }

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->SetPressureSourceOverrideEnabled(params.enabled, params.source, std::move(params.metadata));
    if (response.IsFallThrough()) {
        dispatchable.DispatchFallThrough(response.Message());
        return;
    }
    if (weak->get())
        weak->get()->sendResponse(dispatchable.CallId(), response);
    return;
}

class SetPressureStateOverrideCallbackImpl : public Backend::SetPressureStateOverrideCallback, public DomainDispatcher::Callback {
public:
    SetPressureStateOverrideCallbackImpl(std::unique_ptr<DomainDispatcher::WeakPtr> backendImpl, crdtp::Dispatchable& dispatchable)
        : DomainDispatcher::Callback(std::move(backendImpl), dispatchable, crdtp::SpanFrom("Emulation.setPressureStateOverride")) { }

    void sendSuccess() override
    {
        crdtp::ObjectSerializer serializer;
        sendIfActive(serializer.Finish(), DispatchResponse::Success());
    }

    void fallThrough() override
    {
        fallThroughIfActive();
    }

    void sendFailure(const DispatchResponse& response) override
    {
        DCHECK(response.IsError());
        sendIfActive(nullptr, response);
    }
};

namespace {

struct setPressureStateOverrideParams : public crdtp::DeserializableProtocolObject<setPressureStateOverrideParams> {
    String source;
    String state;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(setPressureStateOverrideParams)
    CRDTP_DESERIALIZE_FIELD("source", source),
    CRDTP_DESERIALIZE_FIELD("state", state),
CRDTP_END_DESERIALIZER()

}  // namespace

void DomainDispatcherImpl::setPressureStateOverride(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.
    auto deserializer = crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer();
    setPressureStateOverrideParams params;
    if (!setPressureStateOverrideParams::Deserialize(&deserializer, &params)) {
      ReportInvalidParams(dispatchable, deserializer);
      return;
    }

    m_backend->SetPressureStateOverride(params.source, params.state, std::make_unique<SetPressureStateOverrideCallbackImpl>(weakPtr(), dispatchable));
}

namespace {

struct setIdleOverrideParams : public crdtp::DeserializableProtocolObject<setIdleOverrideParams> {
    bool isUserActive;
    bool isScreenUnlocked;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(setIdleOverrideParams)
    CRDTP_DESERIALIZE_FIELD("isScreenUnlocked", isScreenUnlocked),
    CRDTP_DESERIALIZE_FIELD("isUserActive", isUserActive),
CRDTP_END_DESERIALIZER()

}  // namespace

void DomainDispatcherImpl::setIdleOverride(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.
    auto deserializer = crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer();
    setIdleOverrideParams params;
    if (!setIdleOverrideParams::Deserialize(&deserializer, &params)) {
      ReportInvalidParams(dispatchable, deserializer);
      return;
    }

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->SetIdleOverride(params.isUserActive, params.isScreenUnlocked);
    if (response.IsFallThrough()) {
        dispatchable.DispatchFallThrough(response.Message());
        return;
    }
    if (weak->get())
        weak->get()->sendResponse(dispatchable.CallId(), response);
    return;
}

namespace {


}  // namespace

void DomainDispatcherImpl::clearIdleOverride(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->ClearIdleOverride();
    if (response.IsFallThrough()) {
        dispatchable.DispatchFallThrough(response.Message());
        return;
    }
    if (weak->get())
        weak->get()->sendResponse(dispatchable.CallId(), response);
    return;
}

namespace {

struct setVisibleSizeParams : public crdtp::DeserializableProtocolObject<setVisibleSizeParams> {
    int width;
    int height;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(setVisibleSizeParams)
    CRDTP_DESERIALIZE_FIELD("height", height),
    CRDTP_DESERIALIZE_FIELD("width", width),
CRDTP_END_DESERIALIZER()

}  // namespace

void DomainDispatcherImpl::setVisibleSize(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.
    auto deserializer = crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer();
    setVisibleSizeParams params;
    if (!setVisibleSizeParams::Deserialize(&deserializer, &params)) {
      ReportInvalidParams(dispatchable, deserializer);
      return;
    }

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->SetVisibleSize(params.width, params.height);
    if (response.IsFallThrough()) {
        dispatchable.DispatchFallThrough(response.Message());
        return;
    }
    if (weak->get())
        weak->get()->sendResponse(dispatchable.CallId(), response);
    return;
}

namespace {

struct setUserAgentOverrideParams : public crdtp::DeserializableProtocolObject<setUserAgentOverrideParams> {
    String userAgent;
    std::optional<String> acceptLanguage;
    std::optional<String> platform;
    std::unique_ptr<protocol::Emulation::UserAgentMetadata> userAgentMetadata;
    DECLARE_DESERIALIZATION_SUPPORT();
};

CRDTP_BEGIN_DESERIALIZER(setUserAgentOverrideParams)
    CRDTP_DESERIALIZE_FIELD_OPT("acceptLanguage", acceptLanguage),
    CRDTP_DESERIALIZE_FIELD_OPT("platform", platform),
    CRDTP_DESERIALIZE_FIELD("userAgent", userAgent),
    CRDTP_DESERIALIZE_FIELD_OPT("userAgentMetadata", userAgentMetadata),
CRDTP_END_DESERIALIZER()

}  // namespace

void DomainDispatcherImpl::setUserAgentOverride(crdtp::Dispatchable& dispatchable)
{
    // Prepare input parameters.
    auto deserializer = crdtp::DeferredMessage::FromSpan(dispatchable.Params())->MakeDeserializer();
    setUserAgentOverrideParams params;
    if (!setUserAgentOverrideParams::Deserialize(&deserializer, &params)) {
      ReportInvalidParams(dispatchable, deserializer);
      return;
    }

    std::unique_ptr<DomainDispatcher::WeakPtr> weak = weakPtr();
    DispatchResponse response = m_backend->SetUserAgentOverride(params.userAgent, std::move(params.acceptLanguage), std::move(params.platform), std::move(params.userAgentMetadata));
    if (response.IsFallThrough()) {
        dispatchable.DispatchFallThrough(response.Message());
        return;
    }
    if (weak->get())
        weak->get()->sendResponse(dispatchable.CallId(), response);
    return;
}

namespace {
// This helper method (with a static map of redirects) is used from Dispatcher::wire
// immediately below.
const std::vector<std::pair<crdtp::span<uint8_t>, crdtp::span<uint8_t>>>& SortedRedirects() {
  static auto* redirects = [](){
    auto* redirects = new std::vector<std::pair<crdtp::span<uint8_t>, crdtp::span<uint8_t>>>{
    };
    return redirects;
  }();
  return *redirects;
}
}  // namespace

// static
void Dispatcher::wire(UberDispatcher* uber, Backend* backend)
{
    auto dispatcher = std::make_unique<DomainDispatcherImpl>(uber->channel(), backend);
    uber->WireBackend(crdtp::SpanFrom("Emulation"), SortedRedirects(), std::move(dispatcher));
}

} // Emulation
} // namespace content
} // namespace protocol
