summaryrefslogtreecommitdiff
diff options
authorUbuntu <ubuntu@cert-jenkins-slave-1-201406-15260.maas>2022-06-15 17:25:47 +0000
committerUbuntu <ubuntu@cert-jenkins-slave-1-201406-15260.maas>2022-06-15 17:25:47 +0000
commit91478e881f1672cb9c9a3f68fd7b2d31b6602b07 (patch)
tree04070515cb7f058368e84209477f85fb73a62be8
parente25b1973fc78bb10c8a709362ae7d5932769a1d0 (diff)
parenta028a44bb18f0f2e9e26c91c3e7f216c70911509 (diff)
Merge #424146 from ~pieq/plainbox-provider-checkbox:1968943-rework-max-resolution-job
-rwxr-xr-xbin/graphics_max_resolution.py148
-rwxr-xr-xbin/graphics_modes_info.py74
-rw-r--r--units/graphics/jobs.pxu18
-rw-r--r--units/graphics/legacy.pxu8
4 files changed, 149 insertions, 99 deletions
diff --git a/bin/graphics_max_resolution.py b/bin/graphics_max_resolution.py
new file mode 100755
index 0000000..56628a4
--- /dev/null
+++ b/bin/graphics_max_resolution.py
@@ -0,0 +1,148 @@
+#!/usr/bin/env python3
+#
+# This file is part of Checkbox.
+#
+# Copyright 2022 Canonical Ltd.
+#
+# Authors:
+# Pierre Equoy <pierre.equoy@canonical.com>
+#
+# Checkbox is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 3,
+# as published by the Free Software Foundation.
+#
+# Checkbox is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with Checkbox. If not, see <http://www.gnu.org/licenses/>.
+
+import gi
+from glob import glob
+import os
+import sys
+from pathlib import Path
+
+gi.require_versions({"Gtk": "3.0", "Gdk": "3.0"})
+from gi.repository import Gdk, Gtk # noqa: E402
+
+
+def get_sysfs_info():
+ """
+ Go through each graphics cards sysfs entries to find max resolution if
+ connected to a monitor.
+ Return a list of ports with information about them.
+ """
+ ports = glob("/sys/class/drm/card*-*")
+ entries = []
+ for p in ports:
+ with open(Path(p) / "modes") as f:
+ # Topmost line in the modes file is the max resolution
+ max_resolution = f.readline().strip()
+ if max_resolution:
+ # e.g. "/sys/class/drm/card0-HDMI-A-1"
+ port = p.split("/")[-1]
+ width, height = max_resolution.split("x")
+ with open(Path(p) / "enabled") as f:
+ enabled = f.readline().strip()
+ with open(Path(p) / "dpms") as f:
+ dpms = f.readline().strip()
+ with open(Path(p) / "status") as f:
+ status = f.readline().strip()
+ port_info = {
+ "port": port,
+ "width": int(width),
+ "height": int(height),
+ "enabled": enabled, # "enabled" or "disabled"
+ "status": status, # "connected" or "disconnected"
+ "dpms": dpms, # "On" or "Off"
+ }
+ entries.append(port_info)
+ return entries
+
+
+def get_monitors_info():
+ """
+ Get information (model, manufacturer, resolution) from each connected
+ monitors using Gtk.
+ Return a list of monitors with their information.
+ """
+ Gtk.init()
+ display = Gdk.Display.get_default()
+ monitors = []
+ for i in range(display.get_n_monitors()):
+ mon = display.get_monitor(i)
+ monitor = {
+ "model": mon.get_model(),
+ "manufacturer": mon.get_manufacturer(),
+ "width": mon.get_geometry().width,
+ "height": mon.get_geometry().height,
+ "scale_factor": mon.get_scale_factor(),
+ }
+ monitors.append(monitor)
+ return monitors
+
+
+if __name__ == "__main__":
+ sysfs_entries = get_sysfs_info()
+ mons_entries = get_monitors_info()
+ total_sysfs_res = 0
+ total_mons_res = 0
+ compositor = os.environ.get("XDG_SESSION_TYPE")
+ print("Current compositor: {}".format(compositor))
+ print()
+ print("Maximum resolution found for each connected monitors:")
+ for p in sysfs_entries:
+ port = p["port"]
+ width = p["width"]
+ height = p["height"]
+ enabled = p["enabled"]
+ status = p["status"]
+ dpms = p["dpms"].lower()
+ print(
+ "\t{}: {}x{} ({}, {}, {})".format(
+ port, width, height, dpms, status, enabled
+ )
+ )
+ # If the monitor is disabled (e.g. "Single Display" mode), don't take
+ # its surface into account.
+ if enabled == "enabled":
+ total_sysfs_res += width * height
+ print()
+ print("Current resolution found for each connected monitors:")
+ for m in mons_entries:
+ model = m["model"]
+ manufacturer = m["manufacturer"]
+ scale = m["scale_factor"]
+ # Under X11, the returned width and height are in "application pixels",
+ # not "device pixels", so it has to be multiplied by the scale factor.
+ # However, Wayland always returns the "device pixels" width and height.
+ #
+ # Example: a 3840x2160 screen set to 200% scale will have
+ # width = 1920, height = 1080, scale_factor = 2 on X11
+ # width = 3840, height = 2160, scale_factor = 2 on Wayland
+ if compositor == "x11":
+ width = m["width"] * m["scale_factor"]
+ height = m["height"] * m["scale_factor"]
+ else:
+ width = m["width"]
+ height = m["height"]
+ print(
+ "\t{} ({}): {}x{} @{}%".format(
+ model, manufacturer, width, height, scale * 100
+ )
+ )
+ total_mons_res += width * height
+ print()
+ if total_sysfs_res == total_mons_res:
+ print("The displays are configured at their maximum resolution.")
+ else:
+ sys.exit(
+ (
+ "The displays do not seem to be configured at their maximum "
+ "resolution.\nPlease switch to the maximum resolution before "
+ "continuing."
+ )
+ )
diff --git a/bin/graphics_modes_info.py b/bin/graphics_modes_info.py
deleted file mode 100755
index f92cd76..0000000
--- a/bin/graphics_modes_info.py
+++ /dev/null
@@ -1,74 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-#
-# graphics_modes_info.py
-#
-# This file is part of Checkbox.
-#
-# Copyright 2012 Canonical Ltd.
-#
-# Authors: Alberto Milone <alberto.milone@canonical.com>
-#
-# Checkbox is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License version 3,
-# as published by the Free Software Foundation.
-
-#
-# Checkbox is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with Checkbox. If not, see <http://www.gnu.org/licenses/>.
-
-from __future__ import print_function
-from __future__ import unicode_literals
-import sys
-
-from checkbox_support.contrib import xrandr
-
-
-def print_modes_info(screen):
- """Print some information about the detected screen and its outputs"""
- xrandr._check_required_version((1, 0))
- print("Screen %s: minimum %s x %s, current %s x %s, maximum %s x %s" %
- (screen._screen,
- screen._width_min, screen._height_min,
- screen._width, screen._height,
- screen._width_max, screen._height_max))
- print(" %smm x %smm" % (screen._width_mm, screen._height_mm))
- print("Outputs:")
- for o in list(screen.outputs.keys()):
- output = screen.outputs[o]
- print(" %s" % o, end=' ')
- if output.is_connected():
- print("(%smm x %smm)" % (output.get_physical_width(),
- output.get_physical_height()))
- modes = output.get_available_modes()
- print(" Modes:")
- for m in range(len(modes)):
- mode = modes[m]
- refresh = mode.dotClock / (mode.hTotal * mode.vTotal)
- print(
- " [%s] %s x %s @ %s Hz" %
- (m, mode.width, mode.height, refresh), end=' ')
- if mode.id == output._mode:
- print("(current)", end=' ')
- if m == output.get_preferred_mode():
- print("(preferred)", end=' ')
- print("")
- else:
- print("(not connected)")
-
-
-def main():
- screen = xrandr.get_current_screen()
- try:
- print_modes_info(screen)
- except(xrandr.UnsupportedRRError):
- print('Error: RandR version lower than 1.0', file=sys.stderr)
-
-
-if __name__ == '__main__':
- main()
diff --git a/units/graphics/jobs.pxu b/units/graphics/jobs.pxu
index 4dde304..8206f1a 100644
--- a/units/graphics/jobs.pxu
+++ b/units/graphics/jobs.pxu
@@ -133,13 +133,7 @@ category_id: com.canonical.plainbox::graphics
requires:
device.category == 'VIDEO'
command:
- # shellcheck disable=SC1091
- source graphics_env.sh {driver} {index}
- maxi="$(xrandr -q |grep -A 1 "connected\( primary\)* [0-9]" |tail -1 |awk '{{print $1}}')"
- now="$(python3 -c 'from gi.repository import Gdk; screen=Gdk.Screen.get_default(); geo = screen.get_monitor_geometry(screen.get_primary_monitor()); print(geo.width, "x", geo.height, sep="")')"
- test "$maxi" != "$now" && notify="\nPlease switch to the maximum resolution \nfor every graphic tests"
- echo "Maximum resolution: $maxi"
- echo "Current resolution: $now $notify"
+ graphics_max_resolution.py
estimated_duration: 10.0
_summary: Test maximum supported resolution for {vendor} {product}
_description:
@@ -154,16 +148,6 @@ _description:
unit: template
template-resource: graphics_card
-id: graphics/{index}_modes_{product_slug}
-plugin: shell
-category_id: com.canonical.plainbox::graphics
-command: graphics_modes_info.py
-estimated_duration: 0.250
-_description: Collect info on graphics modes (screen resolution and refresh rate) for {vendor} {product}
-_summary: Test graphic modes info for {vendor} {product}
-
-unit: template
-template-resource: graphics_card
id: graphics/{index}_color_depth_{product_slug}
plugin: shell
category_id: com.canonical.plainbox::graphics
diff --git a/units/graphics/legacy.pxu b/units/graphics/legacy.pxu
index 14969b0..2b9545d 100644
--- a/units/graphics/legacy.pxu
+++ b/units/graphics/legacy.pxu
@@ -96,14 +96,6 @@ _description:
VERIFICATION:
Is this the display's maximum resolution?
-id: graphics/modes
-plugin: shell
-category_id: com.canonical.plainbox::graphics
-command: graphics_modes_info.py
-estimated_duration: 0.250
-_description: Collect info on graphics modes (screen resolution and refresh rate)
-_summary: Collect info on graphics modes
-
id: graphics/color_depth
plugin: shell
category_id: com.canonical.plainbox::graphics