[mutter] monitor-config-store: Allow changing D-Bus configuration policy



commit b49421d8e8c73447872de571620649309e774708
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Thu Sep 30 21:06:38 2021 +0200

    monitor-config-store: Allow changing D-Bus configuration policy
    
    Adding a <dbus/> element containing a boolean (yes/no) determines
    whether org.gnome.Mutter.DisplayConfig ApplyMonitorsConfig will be
    callable. The state is also introspectable via the
    ApplyMonitorsConfigAllowed property on the same interface.
    
    For example
    
        <monitors version="2">
          <policy>
            <dbus>no</dbus>
          </policy>
        </monitors>
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2030>

 .../org.gnome.Mutter.DisplayConfig.xml             |  7 +++
 src/backends/meta-monitor-config-store.c           | 68 ++++++++++++++++++++++
 src/backends/meta-monitor-config-store.h           |  8 +++
 src/backends/meta-monitor-manager.c                | 24 ++++++++
 src/tests/monitor-configs/policy-dbus-invalid.xml  |  6 ++
 src/tests/monitor-configs/policy-dbus.xml          |  5 ++
 src/tests/monitor-store-unit-tests.c               | 50 ++++++++++++++++
 7 files changed, 168 insertions(+)
---
diff --git a/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml 
b/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml
index 2a7c5bb1ec..af7cd6472b 100644
--- a/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml
+++ b/data/dbus-interfaces/org.gnome.Mutter.DisplayConfig.xml
@@ -290,6 +290,13 @@
     -->
     <property name="PanelOrientationManaged" type="b" access="read" />
 
+    <!--
+        ApplyMonitorsConfigAllowed:
+
+        Whether calling the ApplyMonitorsConfig method is allowed.
+    -->
+    <property name="ApplyMonitorsConfigAllowed" type="b" access="read" />
+
     <!--
         MonitorsChanged:
 
diff --git a/src/backends/meta-monitor-config-store.c b/src/backends/meta-monitor-config-store.c
index 93a494c79b..5d48ec2ea5 100644
--- a/src/backends/meta-monitor-config-store.c
+++ b/src/backends/meta-monitor-config-store.c
@@ -123,6 +123,9 @@ struct _MetaMonitorConfigStore
 
   gboolean has_stores_policy;
   GList *stores_policy;
+
+  gboolean has_dbus_policy;
+  MetaMonitorConfigPolicy policy;
 };
 
 #define META_MONITOR_CONFIG_STORE_ERROR (meta_monitor_config_store_error_quark ())
@@ -168,6 +171,7 @@ typedef enum
   STATE_POLICY,
   STATE_STORES,
   STATE_STORE,
+  STATE_DBUS,
 } ParserState;
 
 typedef struct
@@ -191,9 +195,13 @@ typedef struct
   GList *current_disabled_monitor_specs;
   gboolean seen_policy;
   gboolean seen_stores;
+  gboolean seen_dbus;
   MetaConfigStore pending_store;
   GList *stores;
 
+  gboolean enable_dbus_set;
+  gboolean enable_dbus;
+
   ParserState unknown_state_root;
   int unknown_level;
 
@@ -574,6 +582,19 @@ handle_start_element (GMarkupParseContext  *context,
             parser->seen_stores = TRUE;
             parser->state = STATE_STORES;
           }
+        else if (g_str_equal (element_name, "dbus"))
+          {
+            if (parser->seen_dbus)
+              {
+                g_set_error (error,
+                             G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+                             "Multiple dbus elements under policy");
+                return;
+              }
+
+            parser->seen_dbus = TRUE;
+            parser->state = STATE_DBUS;
+          }
         else
           {
             enter_unknown_element (parser, element_name,
@@ -604,6 +625,13 @@ handle_start_element (GMarkupParseContext  *context,
                      "Invalid store sub element '%s'", element_name);
         return;
       }
+
+    case STATE_DBUS:
+      {
+        g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+                     "Invalid dbus sub element '%s'", element_name);
+        return;
+      }
     }
 }
 
@@ -953,6 +981,23 @@ handle_end_element (GMarkupParseContext  *context,
         parser->state = STATE_POLICY;
         return;
 
+    case STATE_DBUS:
+        if (!parser->config_store->has_dbus_policy)
+          {
+            parser->config_store->has_dbus_policy = TRUE;
+            parser->config_store->policy.enable_dbus = parser->enable_dbus;
+            parser->enable_dbus_set = FALSE;
+          }
+        else
+          {
+            g_warning ("Policy for monitor configuration via D-Bus "
+                       "has already been set, ignoring policy from '%s'",
+                       g_file_get_path (parser->file));
+          }
+        parser->state = STATE_POLICY;
+
+        return;
+
     case STATE_POLICY:
         g_assert (g_str_equal (element_name, "policy"));
 
@@ -1285,6 +1330,15 @@ handle_text (GMarkupParseContext *context,
         parser->pending_store = store;
         return;
       }
+
+    case STATE_DBUS:
+      {
+        parser->enable_dbus_set = TRUE;
+        read_bool (text, text_len,
+                   &parser->enable_dbus,
+                   error);
+        return;
+      }
     }
 }
 
@@ -1643,6 +1697,11 @@ meta_monitor_config_store_save (MetaMonitorConfigStore *config_store)
       return;
     }
 
+  if (config_store->has_stores_policy &&
+      !g_list_find (config_store->stores_policy,
+                    GINT_TO_POINTER (META_CONFIG_STORE_USER)))
+    return;
+
   config_store->save_cancellable = g_cancellable_new ();
 
   buffer = generate_config_xml (config_store);
@@ -1719,6 +1778,8 @@ meta_monitor_config_store_set_custom (MetaMonitorConfigStore  *config_store,
 
   g_clear_pointer (&config_store->stores_policy, g_list_free);
   config_store->has_stores_policy = FALSE;
+  config_store->policy.enable_dbus = TRUE;
+  config_store->has_dbus_policy = FALSE;
 
   if (!read_config_file (config_store,
                          config_store->custom_read_file,
@@ -1834,6 +1895,7 @@ meta_monitor_config_store_init (MetaMonitorConfigStore *config_store)
                                                  meta_monitors_config_key_equal,
                                                  NULL,
                                                  g_object_unref);
+  config_store->policy.enable_dbus = TRUE;
 }
 
 static void
@@ -1987,3 +2049,9 @@ meta_monitor_config_store_reset (MetaMonitorConfigStore *config_store)
 
   g_free (user_file_path);
 }
+
+const MetaMonitorConfigPolicy *
+meta_monitor_config_store_get_policy (MetaMonitorConfigStore *config_store)
+{
+  return &config_store->policy;
+}
diff --git a/src/backends/meta-monitor-config-store.h b/src/backends/meta-monitor-config-store.h
index cb6759dca0..a255e370ba 100644
--- a/src/backends/meta-monitor-config-store.h
+++ b/src/backends/meta-monitor-config-store.h
@@ -32,6 +32,11 @@ typedef enum _MetaConfigStore
   META_CONFIG_STORE_USER,
 } MetaConfigStore;
 
+typedef struct _MetaMonitorConfigPolicy
+{
+  gboolean enable_dbus;
+} MetaMonitorConfigPolicy;
+
 #define META_TYPE_MONITOR_CONFIG_STORE (meta_monitor_config_store_get_type ())
 G_DECLARE_FINAL_TYPE (MetaMonitorConfigStore, meta_monitor_config_store,
                       META, MONITOR_CONFIG_STORE, GObject)
@@ -70,4 +75,7 @@ MetaMonitorManager * meta_monitor_config_store_get_monitor_manager (MetaMonitorC
 META_EXPORT_TEST
 void meta_monitor_config_store_reset (MetaMonitorConfigStore *config_store);
 
+META_EXPORT_TEST
+const MetaMonitorConfigPolicy * meta_monitor_config_store_get_policy (MetaMonitorConfigStore *config_store);
+
 #endif /* META_MONITOR_CONFIG_STORE_H */
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index 3b650c62c0..6c4684f418 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -51,6 +51,7 @@
 #include "backends/meta-logical-monitor.h"
 #include "backends/meta-monitor.h"
 #include "backends/meta-monitor-config-manager.h"
+#include "backends/meta-monitor-config-store.h"
 #include "backends/meta-orientation-manager.h"
 #include "backends/meta-output.h"
 #include "backends/meta-virtual-monitor.h"
@@ -1163,9 +1164,18 @@ update_has_builtin_panel (MetaMonitorManager *manager)
 void
 meta_monitor_manager_setup (MetaMonitorManager *manager)
 {
+  MetaMonitorConfigStore *config_store;
+  const MetaMonitorConfigPolicy *policy;
+
   manager->in_init = TRUE;
 
   manager->config_manager = meta_monitor_config_manager_new (manager);
+  config_store =
+    meta_monitor_config_manager_get_store (manager->config_manager);
+  policy = meta_monitor_config_store_get_policy (config_store);
+  meta_dbus_display_config_set_apply_monitors_config_allowed (manager->display_config,
+                                                              policy->enable_dbus);
+
 
   meta_monitor_manager_read_current_state (manager);
 
@@ -2545,6 +2555,8 @@ meta_monitor_manager_handle_apply_monitors_config (MetaDBusDisplayConfig *skelet
                                                    GVariant              *properties_variant,
                                                    MetaMonitorManager    *manager)
 {
+  MetaMonitorConfigStore *config_store;
+  const MetaMonitorConfigPolicy *policy;
   MetaMonitorManagerCapability capabilities;
   GVariant *layout_mode_variant = NULL;
   MetaLogicalMonitorLayoutMode layout_mode;
@@ -2561,6 +2573,18 @@ meta_monitor_manager_handle_apply_monitors_config (MetaDBusDisplayConfig *skelet
       return TRUE;
     }
 
+  config_store =
+    meta_monitor_config_manager_get_store (manager->config_manager);
+  policy = meta_monitor_config_store_get_policy (config_store);
+
+  if (!policy->enable_dbus)
+    {
+      g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR,
+                                             G_DBUS_ERROR_ACCESS_DENIED,
+                                             "Monitor configuration via D-Bus is disabled");
+      return TRUE;
+    }
+
   capabilities = meta_monitor_manager_get_capabilities (manager);
 
   if (properties_variant)
diff --git a/src/tests/monitor-configs/policy-dbus-invalid.xml 
b/src/tests/monitor-configs/policy-dbus-invalid.xml
new file mode 100644
index 0000000000..67fa6045ff
--- /dev/null
+++ b/src/tests/monitor-configs/policy-dbus-invalid.xml
@@ -0,0 +1,6 @@
+<monitors version="2">
+  <policy>
+    <dbus>no</dbus>
+    <dbus>yes</dbus>
+  </policy>
+</monitors>
diff --git a/src/tests/monitor-configs/policy-dbus.xml b/src/tests/monitor-configs/policy-dbus.xml
new file mode 100644
index 0000000000..c407e1f021
--- /dev/null
+++ b/src/tests/monitor-configs/policy-dbus.xml
@@ -0,0 +1,5 @@
+<monitors version="2">
+  <policy>
+    <dbus>no</dbus>
+  </policy>
+</monitors>
diff --git a/src/tests/monitor-store-unit-tests.c b/src/tests/monitor-store-unit-tests.c
index 37b0675d0b..9ccf101ea1 100644
--- a/src/tests/monitor-store-unit-tests.c
+++ b/src/tests/monitor-store-unit-tests.c
@@ -26,6 +26,7 @@
 #include "backends/meta-monitor-config-manager.h"
 #include "backends/meta-monitor-manager-private.h"
 #include "tests/monitor-test-utils.h"
+#include "tests/unit-tests.h"
 
 #define MAX_N_MONITORS 10
 #define MAX_N_LOGICAL_MONITORS 10
@@ -955,6 +956,51 @@ meta_test_monitor_store_policy_multiple (void)
   g_test_assert_expected_messages ();
 }
 
+static void
+meta_test_monitor_store_policy_dbus (void)
+{
+  MetaBackend *backend = meta_context_get_backend (test_context);
+  MetaMonitorManager *monitor_manager =
+    meta_backend_get_monitor_manager (backend);
+  MetaMonitorConfigManager *config_manager =
+    meta_monitor_manager_get_config_manager (monitor_manager);
+  MetaMonitorConfigStore *config_store =
+    meta_monitor_config_manager_get_store (config_manager);
+  const MetaMonitorConfigPolicy *policy;
+
+  policy = meta_monitor_config_store_get_policy (config_store);
+  g_assert_nonnull (policy);
+  g_assert_cmpint (policy->enable_dbus, ==, TRUE);
+
+  set_custom_monitor_system_config ("policy-dbus.xml");
+
+  policy = meta_monitor_config_store_get_policy (config_store);
+  g_assert_nonnull (policy);
+  g_assert_cmpint (policy->enable_dbus, ==, FALSE);
+}
+
+static void
+meta_test_monitor_store_policy_dbus_invalid (void)
+{
+  MetaBackend *backend = meta_context_get_backend (test_context);
+  MetaMonitorManager *monitor_manager =
+    meta_backend_get_monitor_manager (backend);
+  MetaMonitorConfigManager *config_manager =
+    meta_monitor_manager_get_config_manager (monitor_manager);
+  MetaMonitorConfigStore *config_store =
+    meta_monitor_config_manager_get_store (config_manager);
+  const MetaMonitorConfigPolicy *policy;
+
+  g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
+                         "*Multiple dbus elements under policy*");
+  set_custom_monitor_system_config ("policy-dbus-invalid.xml");
+  g_test_assert_expected_messages ();
+
+  policy = meta_monitor_config_store_get_policy (config_store);
+  g_assert_nonnull (policy);
+  g_assert_cmpint (policy->enable_dbus, ==, FALSE);
+}
+
 void
 init_monitor_store_tests (void)
 {
@@ -994,4 +1040,8 @@ init_monitor_store_tests (void)
                    meta_test_monitor_store_policy_invalid);
   g_test_add_func ("/backends/monitor-store/policy-multiple",
                    meta_test_monitor_store_policy_multiple);
+  g_test_add_func ("/backends/monitor-store/dbus",
+                   meta_test_monitor_store_policy_dbus);
+  g_test_add_func ("/backends/monitor-store/dbus-invalid",
+                   meta_test_monitor_store_policy_dbus_invalid);
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]