Beispiel #1
0
    def test_find_best_ambiguous(self):
        """
        Test matching for similarly scored profiles
        """
        edid = "office"
        edidhash = profile.md5(edid)

        connected_outputs = [
            XrandrConnection("LVDS1", Display()),
            XrandrConnection("DP1", Display(["1920x1080"], edid=edid))
        ]

        profile_outputs = [
            Output("LVDS1", Viewport('1366x768'), True),
            Output("DP1", Viewport('1920x1080'))
        ]

        p1 = Profile("p1", profile_outputs, {
            "LVDS1": Rule(),
            "DP1": Rule(edidhash)
        })
        p2 = Profile("p2", profile_outputs, {
            "LVDS1": Rule(),
            "DP1": Rule(edidhash)
        })

        best = self.matcher.find_best([p1, p2], connected_outputs)
        self.assertEqual(p1, best)
Beispiel #2
0
    def test_compose_mode_args(self):
        xrandr = Xrandr()
        xrandr.EXECUTABLE = "stub"

        outputs = [
            Output("LVDS1", Geometry(1366, 768), primary=True),
            Output("DP1", Geometry(1920, 1080, 1366, 0)),
            Output("VGA1", Geometry(800, 600, 0, 768))
        ]

        p = Profile("default", outputs)

        xrandr_connections = [XrandrOutput("HDMI1"), XrandrOutput("HDMI2")]

        command = xrandr.__compose_mode_args__(p, xrandr_connections)

        num_of_outputs = len(outputs) + len(xrandr_connections)

        self.assertEqual(num_of_outputs, command.count(xrandr.OUTPUT_KEY))
        self.assertEqual(len(outputs), command.count(xrandr.POS_KEY))
        self.assertEqual(len(outputs), command.count(xrandr.MODE_KEY))
        self.assertEqual(len(xrandr_connections),
                         command.count(xrandr.OFF_KEY))
        self.assertEqual(1, command.count(xrandr.PRIMARY_KEY))
        self.assertEqual(1, command.count("LVDS1"))
        self.assertEqual(1, command.count("DP1"))
        self.assertEqual(1, command.count("VGA1"))
        self.assertEqual(1, command.count("HDMI1"))
        self.assertEqual(1, command.count("HDMI2"))
Beispiel #3
0
    def read_file(self, profile_file_descriptor):
        try:
            result = json.load(profile_file_descriptor)

            rules = result.get('match')
            priority = int(result.get('priority', 100))

            if rules:
                for k, v in rules.items():
                    # backward compatibility for match.mode
                    if v.get('mode'):
                        logger.warn(
                            "%s\n\tmatch.mode is deprecated"
                            "\n\tConsider changing to 'supports' or 'prefers'",
                            profile_file_descriptor.name)
                        v['supports'] = v['mode']
                        del v['mode']
                    rules[k] = Rule(**v)
            else:
                rules = {}

            primary = result['primary']
            outputs_raw = result['outputs']
            outputs = []
            for name, mode_raw in outputs_raw.items():
                output = Output(name, **mode_raw)
                outputs.append(output)

            name = os.path.basename(profile_file_descriptor.name)

            return Profile(name, outputs, rules, primary, priority)
        except (KeyError, ValueError):
            raise InvalidProfileException(profile_file_descriptor.name)
Beispiel #4
0
 def test_priority(self):
     outputs_default = [
         XrandrConnection("LVDS1", Display()),
     ]
     outputs_office = [
         XrandrConnection("LVDS1", Display()),
         XrandrConnection("HDMI1", Display(["1920x1080"], edid="office"))
     ]
     profiles = [
         Profile("default", [Output("LVDS1", "1366x768")],
                 {"LVDS1": Rule()},
                 priority=50),
         Profile("office", [Output("HDMI1", "1920x1080")],
                 {"HDMI1": Rule()},
                 priority=100)  # default priority
     ]
     best_default = self.matcher.find_best(profiles, outputs_default)
     best_office = self.matcher.find_best(profiles, outputs_office)
     self.assertEqual(profiles[0], best_default)
     self.assertEqual(profiles[1], best_office)
Beispiel #5
0
    def profile_from_xrandr(self, xrandr_connections: list, name: str='profile'):
        outputs = []
        rules = {}
        for c in xrandr_connections:
            if not c.connected or not c.is_active():
                continue
            output = Output(c.name, c.current_geometry, c.primary)
            outputs.append(output)
            rule = Rule(md5(c.edid), c.preferred_mode, c.current_geometry.mode)
            rules[c.name] = rule

        logger.debug("Extracted %d outputs from %d xrandr connections", len(outputs), len(xrandr_connections))

        return Profile(name, outputs, rules)
Beispiel #6
0
 def write(self, p: Profile, yaml_flow_style: bool = False):
     """
     Write profile to file into configured profile directory.
     Profile name becomes the name of the file. If name contains illegal characters, only safe part is used.
     For example, if name is my_home_vga/../../passwd, then file will be written as passwd under profile dir
     """
     os.makedirs(self.write_location, exist_ok=True)
     dict = p.to_dict()
     safename = os.path.basename(p.name)
     fullname = os.path.join(self.write_location, safename)
     if safename != p.name:
         logger.warning("Illegal name provided. Writing as %s", fullname)
     with open(fullname, 'w+') as fp:
         yaml.dump(dict, fp, default_flow_style=yaml_flow_style)
Beispiel #7
0
 def write(self, p: Profile, yaml_flow_style: bool=False):
     """
     Write profile to file into configured profile directory.
     Profile name becomes the name of the file. If name contains illegal characters, only safe part is used.
     For example, if name is my_home_vga/../../passwd, then file will be written as passwd under profile dir
     """
     os.makedirs(self.write_location, exist_ok=True)
     dict = p.to_dict()
     safename = os.path.basename(p.name)
     fullname = os.path.join(self.write_location, safename)
     if safename != p.name:
         logger.warning("Illegal name provided. Writing as %s", fullname)
     with open(fullname, 'w+') as fp:
         yaml.dump(dict, fp, default_flow_style=yaml_flow_style)
Beispiel #8
0
    def profile_from_xrandr(self, xrandr_connections: list, name: str='profile'):
        outputs = []
        rules = {}
        primary = None
        for c in xrandr_connections:
            display = c.display
            if not display or not c.is_active():
                continue
            output = Output.fromconnection(c)
            if c.primary:
                primary = c.name
            outputs.append(output)
            rule = Rule(md5(display.edid), display.preferred_mode, display.mode)
            rules[c.name] = rule

        logger.debug("Extracted %d outputs from %d xrandr connections", len(outputs), len(xrandr_connections))

        return Profile(name, outputs, rules, primary)
Beispiel #9
0
    def test_compose_mode_args_exact_line(self):
        xrandr = Xrandr()
        xrandr.EXECUTABLE = "stub"

        outputs = [Output("LVDS1", mode='1366x768')]

        p = Profile("default", outputs, primary="LVDS1")

        xrandr_connections = [
            XrandrConnection("LVDS1"),
            XrandrConnection("HDMI1")
        ]

        command = xrandr._compose_mode_args(p, xrandr_connections)
        self.assertListEqual([
            '--output', 'LVDS1', '--mode', '1366x768', '--pos', '0x0',
            '--rotate', 'normal', '--panning', '0x0', '--scale', '1x1',
            '--primary', '--output', 'HDMI1', '--off'
        ], command)
Beispiel #10
0
    def test_compose_mode_args(self):
        xrandr = Xrandr(":0", None)
        xrandr.EXECUTABLE = "stub"

        outputs = {
            "LVDS1":
            Output(mode='1366x768'),
            "DP1":
            Output(mode='1920x1080',
                   pos='1366x0',
                   scale='1.5x1.5',
                   panning='1920x1080'),
            "VGA1":
            Output(mode='800x600', pos='0x768')
        }

        p = Profile("default", outputs, primary="LVDS1")

        xrandr_connections = [
            XrandrConnection("HDMI1"),
            XrandrConnection("HDMI2")
        ]

        command = xrandr._compose_mode_args(p, xrandr_connections)

        num_of_outputs = len(outputs) + len(xrandr_connections)

        self.assertEqual(num_of_outputs, command.count(xrandr.OUTPUT_KEY))
        self.assertEqual(len(outputs), command.count(xrandr.POS_KEY))
        self.assertEqual(len(outputs), command.count(xrandr.MODE_KEY))
        self.assertEqual(len(outputs), command.count(xrandr.PANNING_KEY))
        self.assertEqual(len(outputs), command.count(xrandr.ROTATE_KEY))
        self.assertEqual(len(outputs), command.count(xrandr.SCALE_KEY))
        self.assertEqual(len(xrandr_connections),
                         command.count(xrandr.OFF_KEY))
        self.assertEqual(1, command.count(xrandr.PRIMARY_KEY))
        self.assertEqual(1, command.count("LVDS1"))
        self.assertEqual(1, command.count("DP1"))
        self.assertEqual(1, command.count("VGA1"))
        self.assertEqual(1, command.count("HDMI1"))
        self.assertEqual(1, command.count("HDMI2"))
Beispiel #11
0
    def profile_from_xrandr(self,
                            xrandr_connections: list,
                            profile_name: str = 'profile'):
        outputs = {}
        rules = {}
        primary = None
        for connection in xrandr_connections:
            output_name = connection.name
            display = connection.display
            if not display or not connection.is_active():
                continue
            output = Output.fromconnection(connection)
            if connection.primary:
                primary = output_name
            outputs[output_name] = output
            rule = Rule(hash(display.edid), display.preferred_mode,
                        display.mode)
            rules[output_name] = rule

        logger.debug("Extracted %d outputs from %d xrandr connections",
                     len(outputs), len(xrandr_connections))

        return Profile(profile_name, outputs, rules, primary)
Beispiel #12
0
def profile(name: str, match: dict = None, prio: int = 100):
    # we do not care about actual outputs in these tests, only rules matters
    return Profile(name, {}, match, priority=prio)
Beispiel #13
0
 def print(self, p: Profile, yaml_flow_style: bool=False):
     print(yaml.dump(p.to_dict(), default_flow_style=yaml_flow_style))
Beispiel #14
0
 def print(self, p: Profile, yaml_flow_style: bool = False):
     print(yaml.dump(p.to_dict(), default_flow_style=yaml_flow_style))
Beispiel #15
0
    def test_profile_from_dict(self):
        # given
        data = [
            (
                Profile("no_rules", {"lvds1": Output("800x600")}, priority=100),
                {
                    'name': 'no_rules',
                    'outputs': {
                        'lvds1': {
                            'mode': '800x600',
                            'pos': '0x0',
                            'rotate': 'normal',
                            'panning': '0x0',
                            'scale': '1x1',
                        }
                    },
                    'priority': 100
                }
            ),
            (
                Profile(
                    name="with_rules",
                    outputs={
                        "lvds1": Output("800x600", rate="60"),
                        "vga1": Output("1024x768", pos="800x0", rate="75")
                    },
                    match={
                        "lvds1": Rule("edid", "800x600", "800x600")
                    },
                    primary="lvds1",
                    priority=100
                ),
                {
                    'name': 'with_rules',
                    'match': {
                        'lvds1': {
                            'edid': 'edid',
                            'supports': '800x600',
                            'prefers': '800x600'
                        }
                    },
                    'outputs': {
                        'lvds1': {
                            'mode': '800x600',
                            'pos': '0x0',
                            'rotate': 'normal',
                            'panning': '0x0',
                            'scale': '1x1',
                            'rate': '60'
                        },
                        'vga1': {
                            'mode': '1024x768',
                            'pos': '800x0',
                            'rotate': 'normal',
                            'panning': '0x0',
                            'scale': '1x1',
                            'rate': 75
                        }
                    },
                    'primary': 'lvds1',
                    'priority': 100
                }
            )
        ]

        for expected_profile, dict in data:
            # when
            p = Profile.from_dict(dict)

            # then
            self.assertEqual(expected_profile, p)
            self.assertDictEqual(dict, p.to_dict())
Beispiel #16
0
class Test_ProfileMatcher(TestCase):
    logging.basicConfig()

    matcher = ProfileMatcher()

    HOME_MD5 = hashlib.md5("home".encode()).hexdigest()
    OFFICE_MD5 = hashlib.md5("office".encode()).hexdigest()

    profiles = [
        Profile("default", [Output("LVDS1", "1366x768")], {"LVDS1": Rule()}),
        Profile("DP1_1920x1080",
                [Output("LVDS1", "1366x768"),
                 Output("DP1", "1920x1080")], {
                     "LVDS1": Rule(),
                     "DP1": Rule(None, None, "1920x1080")
                 }),
        Profile("DP1_1920x1200",
                [Output("LVDS1", "1366x768"),
                 Output("DP1", "1920x1200")], {
                     "LVDS1": Rule(),
                     "DP1": Rule(None, "1920x1200", None)
                 }),
        Profile("home",
                [Output("LVDS1", "1366x768"),
                 Output("DP1", "1920x1080")], {
                     "LVDS1": Rule(),
                     "DP1": Rule(HOME_MD5)
                 }),
        Profile("no_rule", [Output("LVDS1", "800x600")]),
        Profile("office",
                [Output("LVDS1", "1366x768"),
                 Output("HDMI1", "1920x1080")], {
                     "LVDS1": Rule(),
                     "HDMI1": Rule(OFFICE_MD5)
                 })
    ]

    def test_find_best_default(self):
        outputs = [XrandrConnection("LVDS1", Display())]
        best = self.matcher.find_best(self.profiles, outputs)
        self.assertEqual(self.profiles[0], best)

    def test_find_best_no_match(self):
        outputs = [
            XrandrConnection("LVDS1", Display()),
            XrandrConnection("DP1", Display(["1280x1024"], edid="guest"))
        ]
        best = self.matcher.find_best(self.profiles, outputs)
        self.assertIsNone(best)

    def test_find_best_edid_over_mode(self):
        outputs = [
            XrandrConnection("LVDS1", Display()),
            XrandrConnection("DP1", Display(["1920x1080"], edid="home"))
        ]
        best = self.matcher.find_best(self.profiles, outputs)
        self.assertEqual(self.profiles[3], best)

    def test_find_best_prefers_over_supports(self):
        outputs = [
            XrandrConnection("LVDS1", Display()),
            XrandrConnection(
                "DP1",
                Display(["1920x1080", "1920x1200"], "1920x1200",
                        edid="office"))
        ]
        best = self.matcher.find_best(self.profiles, outputs)
        self.assertEqual(self.profiles[2], best)

    def test_find_best_mode(self):
        outputs = [
            XrandrConnection("LVDS1", Display()),
            XrandrConnection("DP1", Display(["1920x1080"], edid="office"))
        ]
        best = self.matcher.find_best(self.profiles, outputs)
        self.assertEqual(self.profiles[1], best)

    def test_find_best_ambiguous(self):
        """
        Test matching for similarly scored profiles
        """
        edid = "office"
        edidhash = profile.md5(edid)

        connected_outputs = [
            XrandrConnection("LVDS1", Display()),
            XrandrConnection("DP1", Display(["1920x1080"], edid=edid))
        ]

        profile_outputs = [
            Output("LVDS1", Viewport('1366x768'), True),
            Output("DP1", Viewport('1920x1080'))
        ]

        p1 = Profile("p1", profile_outputs, {
            "LVDS1": Rule(),
            "DP1": Rule(edidhash)
        })
        p2 = Profile("p2", profile_outputs, {
            "LVDS1": Rule(),
            "DP1": Rule(edidhash)
        })

        best = self.matcher.find_best([p1, p2], connected_outputs)
        self.assertEqual(p1, best)
Beispiel #17
0
    def test_profile_from_dict(self):
        # given
        data = [(Profile("no_rules", {"lvds1": Output("800x600")},
                         priority=100), {
                             'name': 'no_rules',
                             'outputs': {
                                 'lvds1': {
                                     'mode': '800x600',
                                     'pos': '0x0',
                                     'rotate': 'normal',
                                     'panning': '0x0',
                                     'scale': '1x1',
                                 }
                             },
                             'priority': 100
                         }),
                (Profile(name="with_rules",
                         outputs={
                             "lvds1": Output("800x600", rate="60"),
                             "vga1": Output("1024x768", pos="800x0", rate="75")
                         },
                         match={"lvds1": Rule("edid", "800x600", "800x600")},
                         primary="lvds1",
                         priority=100), {
                             'name': 'with_rules',
                             'match': {
                                 'lvds1': {
                                     'edid': 'edid',
                                     'supports': '800x600',
                                     'prefers': '800x600'
                                 }
                             },
                             'outputs': {
                                 'lvds1': {
                                     'mode': '800x600',
                                     'pos': '0x0',
                                     'rotate': 'normal',
                                     'panning': '0x0',
                                     'scale': '1x1',
                                     'rate': '60'
                                 },
                                 'vga1': {
                                     'mode': '1024x768',
                                     'pos': '800x0',
                                     'rotate': 'normal',
                                     'panning': '0x0',
                                     'scale': '1x1',
                                     'rate': 75
                                 }
                             },
                             'primary': 'lvds1',
                             'priority': 100
                         })]

        for expected_profile, dict in data:
            # when
            p = Profile.from_dict(dict)

            # then
            self.assertEqual(expected_profile, p)
            self.assertDictEqual(dict, p.to_dict())