From cb46051005d5d9d1f21d7cb82b9fffd21f88c4c9 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 20 Apr 2016 17:09:14 -0500 Subject: watch for the Greeter to appear on the bus --- src/greeter.cpp | 144 ++++++++++++++++++++++++++++++++------------------------ src/greeter.h | 4 +- src/main.cpp | 12 ++++- 3 files changed, 96 insertions(+), 64 deletions(-) diff --git a/src/greeter.cpp b/src/greeter.cpp index d2e34a0..9d331d7 100644 --- a/src/greeter.cpp +++ b/src/greeter.cpp @@ -26,21 +26,40 @@ class UnityGreeter::Impl { public: - Impl(): + explicit Impl(GDBusConnection* connection): + m_bus(G_DBUS_CONNECTION(g_object_ref(connection))), m_cancellable{g_cancellable_new()} { - g_message("%s getting bus", G_STRLOC); - g_bus_get(G_BUS_TYPE_SESSION, m_cancellable, on_bus_ready_static, this); +g_message("%s %s", G_STRLOC, G_STRFUNC); + + m_watcher_id = g_bus_watch_name_on_connection( + m_bus, + DBusNames::UnityGreeter::NAME, + G_BUS_NAME_WATCHER_FLAGS_AUTO_START, + on_greeter_appeared, + on_greeter_vanished, + this, + nullptr); + + m_subscription_id = g_dbus_connection_signal_subscribe( + m_bus, + DBusNames::UnityGreeter::NAME, + DBusNames::Properties::INTERFACE, + DBusNames::Properties::PropertiesChanged::NAME, + DBusNames::UnityGreeter::PATH, + DBusNames::UnityGreeter::INTERFACE, + G_DBUS_SIGNAL_FLAGS_NONE, + on_properties_changed_signal, + this, + nullptr); } ~Impl() { g_cancellable_cancel(m_cancellable); g_clear_object(&m_cancellable); - - if (m_subscription_id != 0) - g_dbus_connection_signal_unsubscribe (m_bus, m_subscription_id); - + g_bus_unwatch_name(m_watcher_id); + g_dbus_connection_signal_unsubscribe(m_bus, m_subscription_id); g_clear_object(&m_bus); } @@ -51,60 +70,55 @@ public: private: - static void on_bus_ready_static(GObject* /*source*/, GAsyncResult* res, gpointer gself) + static void on_greeter_appeared( + GDBusConnection* /*session_bus*/, + const char* /*name*/, + const char* name_owner, + gpointer gself) { g_message("%s %s", G_STRLOC, G_STRFUNC); - GError* error {}; - auto bus = g_bus_get_finish (res, &error); - if (error != nullptr) { - if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning("UsbSnap: Error getting session bus: %s", error->message); - g_clear_error(&error); - } else { - static_cast(gself)->on_bus_ready(bus); - } - g_clear_object(&bus); + auto self = static_cast(gself); + + self->m_owner = name_owner; + + g_dbus_connection_call( + self->m_bus, + DBusNames::UnityGreeter::NAME, + DBusNames::UnityGreeter::PATH, + DBusNames::Properties::INTERFACE, + "Get", + g_variant_new("(ss)", DBusNames::UnityGreeter::INTERFACE, "IsActive"), + G_VARIANT_TYPE("(v)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + self->m_cancellable, + on_get_is_active_ready, + gself); } - void on_bus_ready(GDBusConnection* bus) + static void on_greeter_vanished( + GDBusConnection* /*session_bus*/, + const char* /*name*/, + gpointer gself) { - g_message("%s bus is ready", G_STRLOC); - - m_bus = G_DBUS_CONNECTION(g_object_ref(G_OBJECT(bus))); - - g_dbus_connection_call(m_bus, - DBusNames::UnityGreeter::NAME, - DBusNames::UnityGreeter::PATH, - DBusNames::Properties::INTERFACE, - "Get", - g_variant_new("(ss)", DBusNames::UnityGreeter::INTERFACE, "IsActive"), - G_VARIANT_TYPE("(v)"), - G_DBUS_CALL_FLAGS_NONE, - -1, - m_cancellable, - on_get_is_active_ready, - this); - - m_subscription_id = g_dbus_connection_signal_subscribe(m_bus, - DBusNames::UnityGreeter::NAME, - DBusNames::Properties::INTERFACE, - DBusNames::Properties::PropertiesChanged::NAME, - DBusNames::UnityGreeter::PATH, - DBusNames::UnityGreeter::INTERFACE, - G_DBUS_SIGNAL_FLAGS_NONE, - on_properties_changed_signal, - this, - nullptr); + g_message("%s %s", G_STRLOC, G_STRFUNC); + auto self = static_cast(gself); + + self->m_owner.clear(); + self->m_is_active.set(false); } - static void on_get_is_active_ready(GObject* source, GAsyncResult* res, gpointer gself) + static void on_get_is_active_ready( + GObject* source, + GAsyncResult* res, + gpointer gself) { g_message("%s", G_STRLOC); GError* error {}; auto v = g_dbus_connection_call_finish(G_DBUS_CONNECTION(source), res, &error); if (error != nullptr) { if (!g_error_matches(error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning("UsbSnap: Error getting session bus: %s", error->message); + g_warning("Greeter: Error getting IsActive property: %s", error->message); g_clear_error(&error); } else { g_message("%s v is %s", G_STRLOC, g_variant_print(v, true)); @@ -116,22 +130,24 @@ private: g_clear_pointer(&v, g_variant_unref); } - static void on_properties_changed_signal(GDBusConnection* /*connection*/, - const gchar* /*sender_name*/, - const gchar* object_path, - const gchar* interface_name, - const gchar* signal_name, - GVariant* parameters, - gpointer gself) + static void on_properties_changed_signal( + GDBusConnection* /*connection*/, + const gchar* sender_name, + const gchar* object_path, + const gchar* interface_name, + const gchar* signal_name, + GVariant* parameters, + gpointer gself) { - g_message("%s", G_STRLOC); + auto self = static_cast(gself); + g_return_if_fail(!g_strcmp0(sender_name, self->m_owner.c_str())); g_return_if_fail(!g_strcmp0(object_path, DBusNames::UnityGreeter::PATH)); g_return_if_fail(!g_strcmp0(interface_name, DBusNames::Properties::INTERFACE)); g_return_if_fail(!g_strcmp0(signal_name, DBusNames::Properties::PropertiesChanged::NAME)); g_return_if_fail(g_variant_is_of_type(parameters, G_VARIANT_TYPE(DBusNames::Properties::PropertiesChanged::ARGS_VARIANT_TYPE))); - auto v = g_variant_get_child_value (parameters, 1); + auto v = g_variant_get_child_value(parameters, 1); if (v != nullptr) g_message("%s v is %s", G_STRLOC, g_variant_print(v, true)); @@ -139,15 +155,19 @@ private: if (g_variant_lookup(v, "IsActive", "b", &is_active)) { g_message("%s is_active changed to %d", G_STRLOC, int(is_active)); - static_cast(gself)->m_is_active.set(is_active); + self->m_is_active.set(is_active); } g_clear_pointer(&v, g_variant_unref); + } - core::Property m_is_active; - GCancellable* m_cancellable {}; + core::Property m_is_active {false}; + GDBusConnection* m_bus {}; + GCancellable* m_cancellable {}; + guint m_watcher_id {}; unsigned int m_subscription_id {}; + std::string m_owner; }; /*** @@ -158,8 +178,8 @@ Greeter::Greeter() =default; Greeter::~Greeter() =default; -UnityGreeter::UnityGreeter(): - impl{new Impl{}} +UnityGreeter::UnityGreeter(GDBusConnection* connection): + impl{new Impl{connection}} { } diff --git a/src/greeter.h b/src/greeter.h index e084d25..6707c4f 100644 --- a/src/greeter.h +++ b/src/greeter.h @@ -21,6 +21,8 @@ #include +#include + #include #include @@ -36,7 +38,7 @@ public: class UnityGreeter: public Greeter { public: - UnityGreeter(); + explicit UnityGreeter(GDBusConnection* connection); virtual ~UnityGreeter(); core::Property& is_active() override; diff --git a/src/main.cpp b/src/main.cpp index 52cdd58..ee05f52 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -47,6 +47,15 @@ main(int /*argc*/, char** /*argv*/) g_main_loop_quit(loop); }; + // get the session bus + GError* error {}; + auto session_bus = g_bus_get_sync(G_BUS_TYPE_SESSION, nullptr, &error); + if (error != nullptr) { + g_critical("Unable to get session bus: %s", error->message); + g_clear_error(&error); + return 0; + } + // build all our indicators. // Right now we've only got one -- rotation lock -- but hey, we can dream. std::vector> indicators; @@ -63,7 +72,7 @@ main(int /*argc*/, char** /*argv*/) static constexpr char const * ADB_SOCKET_PATH {"/dev/socket/adbd"}; static constexpr char const * PUBLIC_KEYS_FILENAME {"/data/misc/adb/adb_keys"}; auto usb_monitor = std::make_shared(); - auto greeter = std::make_shared(); + auto greeter = std::make_shared(session_bus); UsbManager usb_manager {ADB_SOCKET_PATH, PUBLIC_KEYS_FILENAME, usb_monitor, greeter}; // let's go! @@ -71,5 +80,6 @@ main(int /*argc*/, char** /*argv*/) // cleanup g_main_loop_unref(loop); + g_clear_object(&session_bus); return 0; } -- cgit v1.2.3