Skip to content

Commit

Permalink
Automatic device screen dimensions (#124)
Browse files Browse the repository at this point in the history
* Try to automatically add device screen dimensions if they are not provided in the device configuration via the UI
* Change placement of device buttons in control screen
  • Loading branch information
shamanec authored Oct 1, 2024
1 parent 21b9fcc commit 903a119
Show file tree
Hide file tree
Showing 10 changed files with 798 additions and 59 deletions.
673 changes: 673 additions & 0 deletions common/constants/constants.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion common/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ func GetDBDeviceNew() []models.Device {
return dbDevices
}

func UpsertDeviceDB(device models.Device) error {
func UpsertDeviceDB(device *models.Device) error {
update := bson.M{
"$set": device,
}
Expand Down
6 changes: 6 additions & 0 deletions common/models/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,9 @@ type LocalHubDevice struct {
IsAvailableForAutomation bool `json:"is_available_for_automation"`
Available bool `json:"available" bson:"-"` // if device is currently available - not only connected, but setup completed
}

type IOSModelData struct {
Width string
Height string
Model string
}
Original file line number Diff line number Diff line change
Expand Up @@ -234,25 +234,23 @@ function NewDevice({ providers, handleGetDeviceData }) {
/>
</Tooltip>
<Tooltip
title={<div>Device screen width<br />For Android - go to `https://whatismyandroidversion.com` and use the displayed `Screen size`, not `Viewport size`<br />For iOS - you can get it on https://whatismyviewport.com (ScreenSize: at the bottom)</div>}
title={<div>Device screen width - Optional. Set manually if you find a problem with the automatic values.<br />For Android - go to `https://whatismyandroidversion.com` and use the displayed `Screen size`, not `Viewport size`<br />For iOS - you can get it on https://whatismyviewport.com (ScreenSize: at the bottom)</div>}
arrow
placement='top'
>
<TextField
required
label="Screen width"
value={screenWidth}
autoComplete="off"
onChange={(event) => setScreenWidth(event.target.value)}
/>
</Tooltip>
<Tooltip
title={<div>Device screen height<br />For Android - go to `https://whatismyandroidversion.com` and use the displayed `Screen size`, not `Viewport size`<br />For iOS - you can get it on https://whatismyviewport.com (ScreenSize: at the bottom)</div>}
title={<div>Device screen height - Optional. Set manually if you find a problem with the automatic values.<br />For Android - go to `https://whatismyandroidversion.com` and use the displayed `Screen size`, not `Viewport size`<br />For iOS - you can get it on https://whatismyviewport.com (ScreenSize: at the bottom)</div>}
arrow
placement='top'
>
<TextField
required
label="Screen height"
value={screenHeight}
autoComplete="off"
Expand Down Expand Up @@ -539,7 +537,6 @@ function ExistingDevice({ deviceData, providersData, handleGetDeviceData }) {
placement='top'
>
<TextField
required
label="Screen width"
defaultValue={screenWidth}
autoComplete="off"
Expand All @@ -552,7 +549,6 @@ function ExistingDevice({ deviceData, providersData, handleGetDeviceData }) {
placement='top'
>
<TextField
required
label="Screen height"
defaultValue={screenHeight}
autoComplete="off"
Expand Down
6 changes: 0 additions & 6 deletions hub/gads-ui/src/components/DeviceControl/StreamCanvas.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,4 @@
#phone-imitation {
background-color: #9ba984;
border-radius: 30px;
}

.canvas-buttons {
width: 33.33%;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
110 changes: 68 additions & 42 deletions hub/gads-ui/src/components/DeviceControl/StreamCanvas.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Auth } from "../../contexts/Auth"
import { useContext, useEffect, useState } from "react"
import './StreamCanvas.css'
import { Button, Divider, Grid, Stack, Tooltip } from "@mui/material"
import { Box, Button, Divider, Grid, Stack, Tooltip } from "@mui/material"
import HomeIcon from '@mui/icons-material/Home';
import LockOpenIcon from '@mui/icons-material/LockOpen';
import LockIcon from '@mui/icons-material/Lock';
Expand Down Expand Up @@ -83,7 +83,14 @@ export default function StreamCanvas({ deviceData }) {
}, [isPortrait]);

return (
<Grid>
<Grid
spacing={1}
direction="row"
display="flex"
justifyContent='center'
alignItems='flex-start'
>

<div
id='phone-imitation'
>
Expand Down Expand Up @@ -116,15 +123,59 @@ export default function StreamCanvas({ deviceData }) {
streamUrl={streamUrl}
></Stream>
</div>
<Divider></Divider>
<Grid
height='50px'
height='30px'
display='flex'
justifyContent='center'
style={{
marginTop: '10px'
}}
>
</Grid>
</div >

<Grid
direction="column"
width="150px"
marginLeft="10px"
spacing={1}
container
>
<Grid item>
<Tooltip
title="This does not change the orientation of the device itself, just updates the UI if the device orientation is already changed"
arrow
placement='top'
>
<Button
variant={"contained"}
color={"secondary"}
onClick={() => handleOrientationButtonClick(true)}
disabled={isPortrait}
sx={{ width: '100%' }}
>
Portrait
</Button>
</Tooltip>
</Grid>
<Grid item>
<Tooltip
title="This does not change the orientation of the device itself, just updates the UI if the device orientation is already changed"
arrow
placement='top'
>
<Button
variant={"contained"}
color={"secondary"}
onClick={() => handleOrientationButtonClick(false)}
disabled={!isPortrait}
sx={{ width: '100%' }}
>
Landscape
</Button>
</Tooltip>
</Grid>
<Grid item>
<Divider></Divider>
</Grid>
<Grid item>
<Button
onClick={() => homeButton(authToken, deviceData, setDialog)}
className='canvas-buttons'
Expand All @@ -134,9 +185,11 @@ export default function StreamCanvas({ deviceData }) {
fontWeight: "bold",
color: "#9ba984",
backgroundColor: "#2f3b26",
borderBottomLeftRadius: '25px',
width: '100%'
}}
>Home</Button>
</Grid>
<Grid item>
<Button
onClick={() => lockButton(authToken, deviceData, setDialog)}
className='canvas-buttons'
Expand All @@ -145,9 +198,12 @@ export default function StreamCanvas({ deviceData }) {
style={{
fontWeight: "bold",
color: "#9ba984",
backgroundColor: "#2f3b26"
backgroundColor: "#2f3b26",
width: '100%'
}}
>Lock</Button>
</Grid>
<Grid item>
<Button
onClick={() => unlockButton(authToken, deviceData, setDialog)}
className='canvas-buttons'
Expand All @@ -157,42 +213,12 @@ export default function StreamCanvas({ deviceData }) {
fontWeight: "bold",
color: "#9ba984",
backgroundColor: "#2f3b26",
borderBottomRightRadius: '25px'
width: '100%'
}}
>Unlock</Button>
</Grid>
</div >
<Tooltip
title="This does not change the orientation of the device itself, just updates the UI if the device orientation is already changed"
arrow
placement='bottom'
>
<Grid
display='flex'
justifyContent='center'
style={{
marginTop: '10px'
}}
>
<Button
variant={"contained"}
color={"secondary"}
onClick={() => handleOrientationButtonClick(true)}
disabled={isPortrait}
>
Portrait
</Button>
<Button
variant={"contained"}
color={"secondary"}
onClick={() => handleOrientationButtonClick(false)}
disabled={!isPortrait}
>
Landscape
</Button>
</Grid>
</Tooltip>
</Grid>
</Grid>
</Grid >
)
}

Expand Down
9 changes: 5 additions & 4 deletions hub/router/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -587,7 +587,7 @@ func AddDevice(c *gin.Context) {
}
}

err = db.UpsertDeviceDB(device)
err = db.UpsertDeviceDB(&device)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to upsert device in DB"})
return
Expand Down Expand Up @@ -621,10 +621,11 @@ func UpdateDevice(c *gin.Context) {
if reqDevice.OS != "" && dbDevice.OS != reqDevice.OS {
dbDevice.OS = reqDevice.OS
}
if reqDevice.ScreenHeight != "" && dbDevice.ScreenHeight != reqDevice.ScreenHeight {
if dbDevice.ScreenHeight != reqDevice.ScreenHeight {
dbDevice.ScreenHeight = reqDevice.ScreenHeight
}
if reqDevice.ScreenWidth != "" && dbDevice.ScreenWidth != reqDevice.ScreenWidth {

if dbDevice.ScreenWidth != reqDevice.ScreenWidth {
dbDevice.ScreenWidth = reqDevice.ScreenWidth
}
if reqDevice.OSVersion != "" && dbDevice.OSVersion != reqDevice.OSVersion {
Expand All @@ -637,7 +638,7 @@ func UpdateDevice(c *gin.Context) {
if reqDevice.Usage != "" && reqDevice.Usage != dbDevice.Usage {
dbDevice.Usage = reqDevice.Usage
}
err = db.UpsertDeviceDB(dbDevice)
err = db.UpsertDeviceDB(&dbDevice)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to upsert device in DB"})
return
Expand Down
6 changes: 6 additions & 0 deletions provider/devices/android.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package devices

import (
"GADS/common/db"
"GADS/common/models"
"GADS/provider/config"
"GADS/provider/logger"
Expand Down Expand Up @@ -146,6 +147,11 @@ func updateAndroidScreenSizeADB(device *models.Device) error {
device.ScreenHeight = strings.TrimSpace(screenDimensions[1])
}

err := db.UpsertDeviceDB(device)
if err != nil {
return fmt.Errorf("Failed to uspert new device screen dimensions to DB - %s", err)
}

return nil
}

Expand Down
18 changes: 18 additions & 0 deletions provider/devices/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,15 @@ func setupAndroidDevice(device *models.Device) {
}
getAndroidDeviceHardwareModel(device)

if device.ScreenHeight == "" || device.ScreenWidth == "" {
err := updateAndroidScreenSizeADB(device)
if err != nil {
logger.ProviderLogger.LogError("android_device_setup", fmt.Sprintf("Failed to update screen dimensions with adb for device `%v` - %v", device.UDID, err))
resetLocalDevice(device)
return
}
}

streamPort, err := providerutil.GetFreePort()
if err != nil {
logger.ProviderLogger.LogError("android_device_setup", fmt.Sprintf("Could not allocate free host port for GADS-stream for device `%v` - %v", device.UDID, err))
Expand Down Expand Up @@ -391,6 +400,15 @@ func setupIOSDevice(device *models.Device) {
// Update hardware model got from plist
device.HardwareModel = plistValues["HardwareModel"].(string)

if device.ScreenHeight == "" || device.ScreenWidth == "" {
err = updateIOSScreenSize(device, plistValues["ProductType"].(string))
if err != nil {
logger.ProviderLogger.LogError("ios_device_setup", fmt.Sprintf("Failed to update screen dimensions for device `%s` - %s", device.UDID, err))
resetLocalDevice(device)
return
}
}

// If Selenium Grid is used attempt to create a TOML file for the grid connection
if config.ProviderConfig.UseSeleniumGrid {
err := createGridTOML(device)
Expand Down
19 changes: 19 additions & 0 deletions provider/devices/ios.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"strings"
"time"

"GADS/common/constants"
"GADS/common/db"
"GADS/common/models"
"GADS/provider/config"
"GADS/provider/logger"
Expand Down Expand Up @@ -334,3 +336,20 @@ func runWDAGoIOS(device *models.Device) {
resetLocalDevice(device)
}
}

func updateIOSScreenSize(device *models.Device, deviceMachineCode string) error {
if dimensions, ok := constants.IOSDeviceInfoMap[deviceMachineCode]; ok {
device.ScreenHeight = dimensions.Height
device.ScreenWidth = dimensions.Width
} else {
return fmt.Errorf("Could not find `%s` device machine code in the IOSDeviceInfoMap map, please update the map", deviceMachineCode)
}

// Update the device with the new dimensions in the DB
err := db.UpsertDeviceDB(device)
if err != nil {
return fmt.Errorf("Failed to update DB with new device dimensions - %s", err)
}

return nil
}

0 comments on commit 903a119

Please sign in to comment.