chromiumoxide/handler/
emulation.rs1use chromiumoxide_cdp::cdp::browser_protocol::emulation::{
2 ScreenOrientation, ScreenOrientationType, SetDeviceMetricsOverrideParams,
3 SetTouchEmulationEnabledParams,
4};
5use chromiumoxide_types::Method;
6
7use crate::cmd::CommandChain;
8use crate::handler::viewport::Viewport;
9use std::time::Duration;
10
11#[derive(Default, Debug, Clone, Copy, PartialEq)]
12pub struct EmulationManager {
14 pub emulating_mobile: bool,
16 pub has_touch: bool,
18 pub needs_reload: bool,
20 pub request_timeout: Duration,
22}
23
24impl EmulationManager {
25 pub fn new(request_timeout: Duration) -> Self {
27 Self {
28 emulating_mobile: false,
29 has_touch: false,
30 needs_reload: false,
31 request_timeout,
32 }
33 }
34 pub fn init_commands(&mut self, viewport: &Viewport) -> CommandChain {
39 let mut chains = Vec::with_capacity(2);
40 let set_touch = SetTouchEmulationEnabledParams::new(viewport.emulating_mobile);
41 let orientation = if viewport.is_landscape {
42 ScreenOrientation::new(ScreenOrientationType::LandscapePrimary, 90)
43 } else {
44 ScreenOrientation::new(ScreenOrientationType::PortraitPrimary, 0)
45 };
46
47 if let Ok(set_device) = SetDeviceMetricsOverrideParams::builder()
48 .mobile(viewport.emulating_mobile)
49 .width(viewport.width)
50 .height(viewport.height)
51 .device_scale_factor(viewport.device_scale_factor.unwrap_or(1.))
52 .screen_orientation(orientation)
53 .build()
54 {
55 if let Ok(set_device_value) = serde_json::to_value(&set_device) {
56 chains.push((set_device.identifier(), set_device_value));
57 }
58 }
59
60 if let Ok(set_touch_value) = serde_json::to_value(&set_touch) {
61 chains.push((set_touch.identifier(), set_touch_value));
62 }
63
64 let chain = CommandChain::new(chains, self.request_timeout);
65
66 self.needs_reload = self.emulating_mobile != viewport.emulating_mobile
67 || self.has_touch != viewport.has_touch;
68 chain
69 }
70}