debug-server-next
Version:
Dev server for hippy-core.
724 lines (723 loc) • 31.8 kB
JavaScript
// 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.
/* eslint-disable rulesdir/no_underscored_properties */
import * as Common from '../../core/common/common.js';
import * as Host from '../../core/host/host.js';
import * as i18n from '../../core/i18n/i18n.js';
import * as Root from '../../core/root/root.js';
import * as SDK from '../../core/sdk/sdk.js';
import * as UI from '../../ui/legacy/legacy.js';
import { Horizontal, HorizontalSpanned, Vertical, VerticalSpanned } from './EmulatedDevices.js';
const UIStrings = {
/**
* @description Error message shown in the Devices settings pane when the user enters an invalid
* width for a custom device.
*/
widthMustBeANumber: 'Width must be a number.',
/**
* @description Error message shown in the Devices settings pane when the user has entered a width
* for a custom device that is too large.
* @example {9999} PH1
*/
widthMustBeLessThanOrEqualToS: 'Width must be less than or equal to {PH1}.',
/**
* @description Error message shown in the Devices settings pane when the user has entered a width
* for a custom device that is too small.
* @example {50} PH1
*/
widthMustBeGreaterThanOrEqualToS: 'Width must be greater than or equal to {PH1}.',
/**
* @description Error message shown in the Devices settings pane when the user enters an invalid
* height for a custom device.
*/
heightMustBeANumber: 'Height must be a number.',
/**
* @description Error message shown in the Devices settings pane when the user has entered a height
* for a custom device that is too large.
* @example {9999} PH1
*/
heightMustBeLessThanOrEqualToS: 'Height must be less than or equal to {PH1}.',
/**
* @description Error message shown in the Devices settings pane when the user has entered a height
* for a custom device that is too small.
* @example {50} PH1
*/
heightMustBeGreaterThanOrEqualTo: 'Height must be greater than or equal to {PH1}.',
/**
* @description Error message shown in the Devices settings pane when the user enters an invalid
* device pixel ratio for a custom device.
*/
devicePixelRatioMustBeANumberOr: 'Device pixel ratio must be a number or blank.',
/**
* @description Error message shown in the Devices settings pane when the user enters a device
* pixel ratio for a custom device that is too large.
* @example {10} PH1
*/
devicePixelRatioMustBeLessThanOr: 'Device pixel ratio must be less than or equal to {PH1}.',
/**
* @description Error message shown in the Devices settings pane when the user enters a device
* pixel ratio for a custom device that is too small.
* @example {0} PH1
*/
devicePixelRatioMustBeGreater: 'Device pixel ratio must be greater than or equal to {PH1}.',
};
const str_ = i18n.i18n.registerUIStrings('panels/emulation/DeviceModeModel.ts', UIStrings);
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
let deviceModeModelInstance;
export class DeviceModeModel extends Common.ObjectWrapper.ObjectWrapper {
_screenRect;
_visiblePageRect;
_availableSize;
_preferredSize;
_initialized;
_appliedDeviceSize;
_appliedDeviceScaleFactor;
_appliedUserAgentType;
_experimentDualScreenSupport;
_webPlatformExperimentalFeaturesEnabled;
_scaleSetting;
_scale;
_widthSetting;
_heightSetting;
_uaSetting;
_deviceScaleFactorSetting;
_deviceOutlineSetting;
_toolbarControlsEnabledSetting;
_type;
_device;
_mode;
_fitScale;
_touchEnabled;
_touchMobile;
_emulationModel;
_onModelAvailable;
_emulatedPageSize;
_outlineRect;
constructor() {
super();
this._screenRect = new UI.Geometry.Rect(0, 0, 1, 1);
this._visiblePageRect = new UI.Geometry.Rect(0, 0, 1, 1);
this._availableSize = new UI.Geometry.Size(1, 1);
this._preferredSize = new UI.Geometry.Size(1, 1);
this._initialized = false;
this._appliedDeviceSize = new UI.Geometry.Size(1, 1);
this._appliedDeviceScaleFactor = window.devicePixelRatio;
this._appliedUserAgentType = UA.Desktop;
this._experimentDualScreenSupport = Root.Runtime.experiments.isEnabled('dualScreenSupport');
this._webPlatformExperimentalFeaturesEnabled = Boolean(eval('window.getWindowSegments'));
this._scaleSetting = Common.Settings.Settings.instance().createSetting('emulation.deviceScale', 1);
// We've used to allow zero before.
if (!this._scaleSetting.get()) {
this._scaleSetting.set(1);
}
this._scaleSetting.addChangeListener(this._scaleSettingChanged, this);
this._scale = 1;
this._widthSetting = Common.Settings.Settings.instance().createSetting('emulation.deviceWidth', 400);
if (this._widthSetting.get() < MinDeviceSize) {
this._widthSetting.set(MinDeviceSize);
}
if (this._widthSetting.get() > MaxDeviceSize) {
this._widthSetting.set(MaxDeviceSize);
}
this._widthSetting.addChangeListener(this._widthSettingChanged, this);
this._heightSetting = Common.Settings.Settings.instance().createSetting('emulation.deviceHeight', 0);
if (this._heightSetting.get() && this._heightSetting.get() < MinDeviceSize) {
this._heightSetting.set(MinDeviceSize);
}
if (this._heightSetting.get() > MaxDeviceSize) {
this._heightSetting.set(MaxDeviceSize);
}
this._heightSetting.addChangeListener(this._heightSettingChanged, this);
this._uaSetting = Common.Settings.Settings.instance().createSetting('emulation.deviceUA', UA.Mobile);
this._uaSetting.addChangeListener(this._uaSettingChanged, this);
this._deviceScaleFactorSetting =
Common.Settings.Settings.instance().createSetting('emulation.deviceScaleFactor', 0);
this._deviceScaleFactorSetting.addChangeListener(this._deviceScaleFactorSettingChanged, this);
this._deviceOutlineSetting = Common.Settings.Settings.instance().moduleSetting('emulation.showDeviceOutline');
this._deviceOutlineSetting.addChangeListener(this._deviceOutlineSettingChanged, this);
this._toolbarControlsEnabledSetting = Common.Settings.Settings.instance().createSetting('emulation.toolbarControlsEnabled', true, Common.Settings.SettingStorageType.Session);
this._type = Type.None;
this._device = null;
this._mode = null;
this._fitScale = 1;
this._touchEnabled = false;
this._touchMobile = false;
this._emulationModel = null;
this._onModelAvailable = null;
SDK.TargetManager.TargetManager.instance().observeModels(SDK.EmulationModel.EmulationModel, this);
}
static instance(opts = { forceNew: null }) {
if (!deviceModeModelInstance || opts.forceNew) {
deviceModeModelInstance = new DeviceModeModel();
}
return deviceModeModelInstance;
}
static widthValidator(value) {
let valid = false;
let errorMessage;
if (!/^[\d]+$/.test(value)) {
errorMessage = i18nString(UIStrings.widthMustBeANumber);
}
else if (Number(value) > MaxDeviceSize) {
errorMessage = i18nString(UIStrings.widthMustBeLessThanOrEqualToS, { PH1: MaxDeviceSize });
}
else if (Number(value) < MinDeviceSize) {
errorMessage = i18nString(UIStrings.widthMustBeGreaterThanOrEqualToS, { PH1: MinDeviceSize });
}
else {
valid = true;
}
return { valid, errorMessage };
}
static heightValidator(value) {
let valid = false;
let errorMessage;
if (!/^[\d]+$/.test(value)) {
errorMessage = i18nString(UIStrings.heightMustBeANumber);
}
else if (Number(value) > MaxDeviceSize) {
errorMessage = i18nString(UIStrings.heightMustBeLessThanOrEqualToS, { PH1: MaxDeviceSize });
}
else if (Number(value) < MinDeviceSize) {
errorMessage = i18nString(UIStrings.heightMustBeGreaterThanOrEqualTo, { PH1: MinDeviceSize });
}
else {
valid = true;
}
return { valid, errorMessage };
}
static scaleValidator(value) {
let valid = false;
let errorMessage;
const parsedValue = Number(value.trim());
if (!value) {
valid = true;
}
else if (Number.isNaN(parsedValue)) {
errorMessage = i18nString(UIStrings.devicePixelRatioMustBeANumberOr);
}
else if (Number(value) > MaxDeviceScaleFactor) {
errorMessage = i18nString(UIStrings.devicePixelRatioMustBeLessThanOr, { PH1: MaxDeviceScaleFactor });
}
else if (Number(value) < MinDeviceScaleFactor) {
errorMessage = i18nString(UIStrings.devicePixelRatioMustBeGreater, { PH1: MinDeviceScaleFactor });
}
else {
valid = true;
}
return { valid, errorMessage };
}
setAvailableSize(availableSize, preferredSize) {
this._availableSize = availableSize;
this._preferredSize = preferredSize;
this._initialized = true;
this._calculateAndEmulate(false);
}
emulate(type, device, mode, scale) {
const resetPageScaleFactor = this._type !== type || this._device !== device || this._mode !== mode;
this._type = type;
if (type === Type.Device && device && mode) {
console.assert(Boolean(device) && Boolean(mode), 'Must pass device and mode for device emulation');
this._mode = mode;
this._device = device;
if (this._initialized) {
const orientation = device.orientationByName(mode.orientation);
this._scaleSetting.set(scale ||
this._calculateFitScale(orientation.width, orientation.height, this._currentOutline(), this._currentInsets()));
}
}
else {
this._device = null;
this._mode = null;
}
if (type !== Type.None) {
Host.userMetrics.actionTaken(Host.UserMetrics.Action.DeviceModeEnabled);
}
this._calculateAndEmulate(resetPageScaleFactor);
}
setWidth(width) {
const max = Math.min(MaxDeviceSize, this._preferredScaledWidth());
width = Math.max(Math.min(width, max), 1);
this._widthSetting.set(width);
}
setWidthAndScaleToFit(width) {
width = Math.max(Math.min(width, MaxDeviceSize), 1);
this._scaleSetting.set(this._calculateFitScale(width, this._heightSetting.get()));
this._widthSetting.set(width);
}
setHeight(height) {
const max = Math.min(MaxDeviceSize, this._preferredScaledHeight());
height = Math.max(Math.min(height, max), 0);
if (height === this._preferredScaledHeight()) {
height = 0;
}
this._heightSetting.set(height);
}
setHeightAndScaleToFit(height) {
height = Math.max(Math.min(height, MaxDeviceSize), 0);
this._scaleSetting.set(this._calculateFitScale(this._widthSetting.get(), height));
this._heightSetting.set(height);
}
setScale(scale) {
this._scaleSetting.set(scale);
}
device() {
return this._device;
}
mode() {
return this._mode;
}
type() {
return this._type;
}
screenImage() {
return (this._device && this._mode) ? this._device.modeImage(this._mode) : '';
}
outlineImage() {
return (this._device && this._mode && this._deviceOutlineSetting.get()) ? this._device.outlineImage(this._mode) :
'';
}
outlineRect() {
return this._outlineRect || null;
}
screenRect() {
return this._screenRect;
}
visiblePageRect() {
return this._visiblePageRect;
}
scale() {
return this._scale;
}
fitScale() {
return this._fitScale;
}
appliedDeviceSize() {
return this._appliedDeviceSize;
}
appliedDeviceScaleFactor() {
return this._appliedDeviceScaleFactor;
}
appliedUserAgentType() {
return this._appliedUserAgentType;
}
isFullHeight() {
return !this._heightSetting.get();
}
_isMobile() {
switch (this._type) {
case Type.Device:
return this._device ? this._device.mobile() : false;
case Type.None:
return false;
case Type.Responsive:
return this._uaSetting.get() === UA.Mobile || this._uaSetting.get() === UA.MobileNoTouch;
}
return false;
}
enabledSetting() {
return Common.Settings.Settings.instance().createSetting('emulation.showDeviceMode', false);
}
scaleSetting() {
return this._scaleSetting;
}
uaSetting() {
return this._uaSetting;
}
deviceScaleFactorSetting() {
return this._deviceScaleFactorSetting;
}
deviceOutlineSetting() {
return this._deviceOutlineSetting;
}
toolbarControlsEnabledSetting() {
return this._toolbarControlsEnabledSetting;
}
reset() {
this._deviceScaleFactorSetting.set(0);
this._scaleSetting.set(1);
this.setWidth(400);
this.setHeight(0);
this._uaSetting.set(UA.Mobile);
}
modelAdded(emulationModel) {
if (!this._emulationModel && emulationModel.supportsDeviceEmulation()) {
this._emulationModel = emulationModel;
if (this._onModelAvailable) {
const callback = this._onModelAvailable;
this._onModelAvailable = null;
callback();
}
const resourceTreeModel = emulationModel.target().model(SDK.ResourceTreeModel.ResourceTreeModel);
if (resourceTreeModel) {
resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.FrameResized, this._onFrameChange, this);
resourceTreeModel.addEventListener(SDK.ResourceTreeModel.Events.FrameNavigated, this._onFrameChange, this);
}
}
else {
emulationModel.emulateTouch(this._touchEnabled, this._touchMobile);
}
}
modelRemoved(emulationModel) {
if (this._emulationModel === emulationModel) {
this._emulationModel = null;
}
}
inspectedURL() {
return this._emulationModel ? this._emulationModel.target().inspectedURL() : null;
}
_onFrameChange() {
const overlayModel = this._emulationModel ? this._emulationModel.overlayModel() : null;
if (!overlayModel) {
return;
}
this._showHingeIfApplicable(overlayModel);
}
_scaleSettingChanged() {
this._calculateAndEmulate(false);
}
_widthSettingChanged() {
this._calculateAndEmulate(false);
}
_heightSettingChanged() {
this._calculateAndEmulate(false);
}
_uaSettingChanged() {
this._calculateAndEmulate(true);
}
_deviceScaleFactorSettingChanged() {
this._calculateAndEmulate(false);
}
_deviceOutlineSettingChanged() {
this._calculateAndEmulate(false);
}
_preferredScaledWidth() {
return Math.floor(this._preferredSize.width / (this._scaleSetting.get() || 1));
}
_preferredScaledHeight() {
return Math.floor(this._preferredSize.height / (this._scaleSetting.get() || 1));
}
_currentOutline() {
let outline = new UI.Geometry.Insets(0, 0, 0, 0);
if (this._type !== Type.Device || !this._device || !this._mode) {
return outline;
}
const orientation = this._device.orientationByName(this._mode.orientation);
if (this._deviceOutlineSetting.get()) {
outline = orientation.outlineInsets || outline;
}
return outline;
}
_currentInsets() {
if (this._type !== Type.Device || !this._mode) {
return new UI.Geometry.Insets(0, 0, 0, 0);
}
return this._mode.insets;
}
_getScreenOrientationType() {
if (!this._mode) {
throw new Error('Mode required to get orientation type.');
}
switch (this._mode.orientation) {
case VerticalSpanned:
case Vertical:
return "portraitPrimary" /* PortraitPrimary */;
case HorizontalSpanned:
case Horizontal:
default:
return "landscapePrimary" /* LandscapePrimary */;
}
}
_calculateAndEmulate(resetPageScaleFactor) {
if (!this._emulationModel) {
this._onModelAvailable = this._calculateAndEmulate.bind(this, resetPageScaleFactor);
}
const mobile = this._isMobile();
const overlayModel = this._emulationModel ? this._emulationModel.overlayModel() : null;
if (overlayModel) {
this._showHingeIfApplicable(overlayModel);
}
if (this._type === Type.Device && this._device && this._mode) {
const orientation = this._device.orientationByName(this._mode.orientation);
const outline = this._currentOutline();
const insets = this._currentInsets();
this._fitScale = this._calculateFitScale(orientation.width, orientation.height, outline, insets);
if (mobile) {
this._appliedUserAgentType = this._device.touch() ? UA.Mobile : UA.MobileNoTouch;
}
else {
this._appliedUserAgentType = this._device.touch() ? UA.DesktopTouch : UA.Desktop;
}
this._applyDeviceMetrics(new UI.Geometry.Size(orientation.width, orientation.height), insets, outline, this._scaleSetting.get(), this._device.deviceScaleFactor, mobile, this._getScreenOrientationType(), resetPageScaleFactor, this._webPlatformExperimentalFeaturesEnabled);
this._applyUserAgent(this._device.userAgent, this._device.userAgentMetadata);
this._applyTouch(this._device.touch(), mobile);
}
else if (this._type === Type.None) {
this._fitScale = this._calculateFitScale(this._availableSize.width, this._availableSize.height);
this._appliedUserAgentType = UA.Desktop;
this._applyDeviceMetrics(this._availableSize, new UI.Geometry.Insets(0, 0, 0, 0), new UI.Geometry.Insets(0, 0, 0, 0), 1, 0, mobile, null, resetPageScaleFactor);
this._applyUserAgent('', null);
this._applyTouch(false, false);
}
else if (this._type === Type.Responsive) {
let screenWidth = this._widthSetting.get();
if (!screenWidth || screenWidth > this._preferredScaledWidth()) {
screenWidth = this._preferredScaledWidth();
}
let screenHeight = this._heightSetting.get();
if (!screenHeight || screenHeight > this._preferredScaledHeight()) {
screenHeight = this._preferredScaledHeight();
}
const defaultDeviceScaleFactor = mobile ? defaultMobileScaleFactor : 0;
this._fitScale = this._calculateFitScale(this._widthSetting.get(), this._heightSetting.get());
this._appliedUserAgentType = this._uaSetting.get();
this._applyDeviceMetrics(new UI.Geometry.Size(screenWidth, screenHeight), new UI.Geometry.Insets(0, 0, 0, 0), new UI.Geometry.Insets(0, 0, 0, 0), this._scaleSetting.get(), this._deviceScaleFactorSetting.get() || defaultDeviceScaleFactor, mobile, screenHeight >= screenWidth ? "portraitPrimary" /* PortraitPrimary */ :
"landscapePrimary" /* LandscapePrimary */, resetPageScaleFactor);
this._applyUserAgent(mobile ? defaultMobileUserAgent : '', mobile ? defaultMobileUserAgentMetadata : null);
this._applyTouch(this._uaSetting.get() === UA.DesktopTouch || this._uaSetting.get() === UA.Mobile, this._uaSetting.get() === UA.Mobile);
}
if (overlayModel) {
overlayModel.setShowViewportSizeOnResize(this._type === Type.None);
}
this.dispatchEventToListeners("Updated" /* Updated */);
}
_calculateFitScale(screenWidth, screenHeight, outline, insets) {
const outlineWidth = outline ? outline.left + outline.right : 0;
const outlineHeight = outline ? outline.top + outline.bottom : 0;
const insetsWidth = insets ? insets.left + insets.right : 0;
const insetsHeight = insets ? insets.top + insets.bottom : 0;
let scale = Math.min(screenWidth ? this._preferredSize.width / (screenWidth + outlineWidth) : 1, screenHeight ? this._preferredSize.height / (screenHeight + outlineHeight) : 1);
scale = Math.min(Math.floor(scale * 100), 100);
let sharpScale = scale;
while (sharpScale > scale * 0.7) {
let sharp = true;
if (screenWidth) {
sharp = sharp && Number.isInteger((screenWidth - insetsWidth) * sharpScale / 100);
}
if (screenHeight) {
sharp = sharp && Number.isInteger((screenHeight - insetsHeight) * sharpScale / 100);
}
if (sharp) {
return sharpScale / 100;
}
sharpScale -= 1;
}
return scale / 100;
}
setSizeAndScaleToFit(width, height) {
this._scaleSetting.set(this._calculateFitScale(width, height));
this.setWidth(width);
this.setHeight(height);
}
_applyUserAgent(userAgent, userAgentMetadata) {
SDK.NetworkManager.MultitargetNetworkManager.instance().setUserAgentOverride(userAgent, userAgentMetadata);
}
_applyDeviceMetrics(screenSize, insets, outline, scale, deviceScaleFactor, mobile, screenOrientation, resetPageScaleFactor, forceMetricsOverride = false) {
screenSize.width = Math.max(1, Math.floor(screenSize.width));
screenSize.height = Math.max(1, Math.floor(screenSize.height));
let pageWidth = screenSize.width - insets.left - insets.right;
let pageHeight = screenSize.height - insets.top - insets.bottom;
this._emulatedPageSize = new UI.Geometry.Size(pageWidth, pageHeight);
const positionX = insets.left;
const positionY = insets.top;
const screenOrientationAngle = screenOrientation === "landscapePrimary" /* LandscapePrimary */ ? 90 : 0;
this._appliedDeviceSize = screenSize;
this._appliedDeviceScaleFactor = deviceScaleFactor || window.devicePixelRatio;
this._screenRect = new UI.Geometry.Rect(Math.max(0, (this._availableSize.width - screenSize.width * scale) / 2), outline.top * scale, screenSize.width * scale, screenSize.height * scale);
this._outlineRect = new UI.Geometry.Rect(this._screenRect.left - outline.left * scale, 0, (outline.left + screenSize.width + outline.right) * scale, (outline.top + screenSize.height + outline.bottom) * scale);
this._visiblePageRect = new UI.Geometry.Rect(positionX * scale, positionY * scale, Math.min(pageWidth * scale, this._availableSize.width - this._screenRect.left - positionX * scale), Math.min(pageHeight * scale, this._availableSize.height - this._screenRect.top - positionY * scale));
this._scale = scale;
if (!forceMetricsOverride) {
// When sending displayFeature, we cannot use the optimization below due to backend restrictions.
if (scale === 1 && this._availableSize.width >= screenSize.width &&
this._availableSize.height >= screenSize.height) {
// When we have enough space, no page size override is required. This will speed things up and remove lag.
pageWidth = 0;
pageHeight = 0;
}
if (this._visiblePageRect.width === pageWidth * scale && this._visiblePageRect.height === pageHeight * scale &&
Number.isInteger(pageWidth * scale) && Number.isInteger(pageHeight * scale)) {
// When we only have to apply scale, do not resize the page. This will speed things up and remove lag.
pageWidth = 0;
pageHeight = 0;
}
}
if (!this._emulationModel) {
return;
}
if (resetPageScaleFactor) {
this._emulationModel.resetPageScaleFactor();
}
if (pageWidth || pageHeight || mobile || deviceScaleFactor || scale !== 1 || screenOrientation ||
forceMetricsOverride) {
const metrics = {
width: pageWidth,
height: pageHeight,
deviceScaleFactor: deviceScaleFactor,
mobile: mobile,
scale: scale,
screenWidth: screenSize.width,
screenHeight: screenSize.height,
positionX: positionX,
positionY: positionY,
dontSetVisibleSize: true,
displayFeature: undefined,
screenOrientation: undefined,
};
const displayFeature = this._getDisplayFeature();
if (displayFeature) {
metrics.displayFeature = displayFeature;
}
if (screenOrientation) {
metrics.screenOrientation = { type: screenOrientation, angle: screenOrientationAngle };
}
this._emulationModel.emulateDevice(metrics);
}
else {
this._emulationModel.emulateDevice(null);
}
}
exitHingeMode() {
const overlayModel = this._emulationModel ? this._emulationModel.overlayModel() : null;
if (overlayModel) {
overlayModel.showHingeForDualScreen(null);
}
}
webPlatformExperimentalFeaturesEnabled() {
return this._webPlatformExperimentalFeaturesEnabled;
}
shouldReportDisplayFeature() {
return this._webPlatformExperimentalFeaturesEnabled && this._experimentDualScreenSupport;
}
async captureScreenshot(fullSize, clip) {
const screenCaptureModel = this._emulationModel ? this._emulationModel.target().model(SDK.ScreenCaptureModel.ScreenCaptureModel) : null;
if (!screenCaptureModel) {
return null;
}
const overlayModel = this._emulationModel ? this._emulationModel.overlayModel() : null;
if (overlayModel) {
overlayModel.setShowViewportSizeOnResize(false);
}
// Define the right clipping area for fullsize screenshots.
if (fullSize) {
const metrics = await screenCaptureModel.fetchLayoutMetrics();
if (!metrics) {
return null;
}
// Cap the height to not hit the GPU limit.
const contentHeight = Math.min((1 << 14), metrics.contentHeight);
clip = { x: 0, y: 0, width: Math.floor(metrics.contentWidth), height: Math.floor(contentHeight), scale: 1 };
}
const screenshot = await screenCaptureModel.captureScreenshot("png" /* Png */, 100, clip);
const deviceMetrics = {
width: 0,
height: 0,
deviceScaleFactor: 0,
mobile: false,
};
if (fullSize && this._emulationModel) {
if (this._device && this._mode) {
const orientation = this._device.orientationByName(this._mode.orientation);
deviceMetrics.width = orientation.width;
deviceMetrics.height = orientation.height;
const dispFeature = this._getDisplayFeature();
if (dispFeature) {
// @ts-ignore: displayFeature isn't in protocol.d.ts but is an
// experimental flag:
// https://chromedevtools.github.io/devtools-protocol/tot/Emulation/#method-setDeviceMetricsOverride
deviceMetrics.displayFeature = dispFeature;
}
}
else {
deviceMetrics.width = 0;
deviceMetrics.height = 0;
}
await this._emulationModel.emulateDevice(deviceMetrics);
}
this._calculateAndEmulate(false);
return screenshot;
}
_applyTouch(touchEnabled, mobile) {
this._touchEnabled = touchEnabled;
this._touchMobile = mobile;
for (const emulationModel of SDK.TargetManager.TargetManager.instance().models(SDK.EmulationModel.EmulationModel)) {
emulationModel.emulateTouch(touchEnabled, mobile);
}
}
_showHingeIfApplicable(overlayModel) {
const orientation = (this._device && this._mode) ? this._device.orientationByName(this._mode.orientation) : null;
if (this._experimentDualScreenSupport && orientation && orientation.hinge) {
overlayModel.showHingeForDualScreen(orientation.hinge);
return;
}
overlayModel.showHingeForDualScreen(null);
}
_getDisplayFeatureOrientation() {
if (!this._mode) {
throw new Error('Mode required to get display feature orientation.');
}
switch (this._mode.orientation) {
case VerticalSpanned:
case Vertical:
return "vertical" /* Vertical */;
case HorizontalSpanned:
case Horizontal:
default:
return "horizontal" /* Horizontal */;
}
}
_getDisplayFeature() {
if (!this.shouldReportDisplayFeature()) {
return null;
}
if (!this._device || !this._mode ||
(this._mode.orientation !== VerticalSpanned && this._mode.orientation !== HorizontalSpanned)) {
return null;
}
const orientation = this._device.orientationByName(this._mode.orientation);
if (!orientation || !orientation.hinge) {
return null;
}
const hinge = orientation.hinge;
return {
orientation: this._getDisplayFeatureOrientation(),
offset: (this._mode.orientation === VerticalSpanned) ? hinge.x : hinge.y,
maskLength: (this._mode.orientation === VerticalSpanned) ? hinge.width : hinge.height,
};
}
}
// TODO(crbug.com/1167717): Make this a const enum again
// eslint-disable-next-line rulesdir/const_enum
export var Type;
(function (Type) {
Type["None"] = "None";
Type["Responsive"] = "Responsive";
Type["Device"] = "Device";
})(Type || (Type = {}));
// TODO(crbug.com/1167717): Make this a const enum again
// eslint-disable-next-line rulesdir/const_enum
export var UA;
(function (UA) {
// TODO(crbug.com/1136655): This enum is used for both display and code functionality.
// we should refactor this so localization of these strings only happens for user display.
UA["Mobile"] = "Mobile";
UA["MobileNoTouch"] = "Mobile (no touch)";
UA["Desktop"] = "Desktop";
UA["DesktopTouch"] = "Desktop (touch)";
})(UA || (UA = {}));
export const MinDeviceSize = 50;
export const MaxDeviceSize = 9999;
export const MinDeviceScaleFactor = 0;
export const MaxDeviceScaleFactor = 10;
export const MaxDeviceNameLength = 50;
const mobileUserAgent = 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36';
const defaultMobileUserAgent = SDK.NetworkManager.MultitargetNetworkManager.patchUserAgentWithChromeVersion(mobileUserAgent);
const defaultMobileUserAgentMetadata = {
platform: 'Android',
platformVersion: '6.0',
architecture: '',
model: 'Nexus 5',
mobile: true,
};
export const defaultMobileScaleFactor = 2;