From ae39f7001e5603010afc02de29787ade6d48ef14 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 22 Mar 2013 16:34:34 -0500 Subject: port indicator-session to GMenu/cmake. Code coverage increased from 0% to 95.4%. --- AUTHORS | 2 - ChangeLog | 2 - INSTALL | 72 ++ Makefile.am | 43 - Makefile.am.coverage | 48 - README | 47 + autogen.sh | 11 - configure.ac | 231 ---- m4/gcov.m4 | 86 -- m4/gtest.m4 | 63 - src/CMakeLists.txt | 19 + src/Makefile.am | 207 ---- src/actions.c | 383 ++++++ src/actions.h | 129 ++ src/backend-dbus/CMakeLists.txt | 86 ++ src/backend-dbus/actions.c | 730 ++++++++++++ src/backend-dbus/actions.h | 73 ++ src/backend-dbus/backend-dbus.c | 117 ++ src/backend-dbus/backend-dbus.h | 38 + .../com.canonical.indicators.webcredentials.xml | 82 ++ src/backend-dbus/display-manager.xml | 30 + src/backend-dbus/guest.c | 570 +++++++++ src/backend-dbus/guest.h | 72 ++ src/backend-dbus/org.freedesktop.Accounts.User.xml | 744 ++++++++++++ src/backend-dbus/org.freedesktop.Accounts.xml | 194 ++++ .../org.freedesktop.ConsoleKit.Manager.xml | 353 ++++++ .../org.freedesktop.ConsoleKit.Seat.xml | 164 +++ .../org.freedesktop.ConsoleKit.Session.xml | 435 +++++++ src/backend-dbus/org.gnome.ScreenSaver.xml | 16 + .../org.gnome.SessionManager.EndSessionDialog.xml | 53 + src/backend-dbus/org.gnome.SessionManager.xml | 451 +++++++ src/backend-dbus/session-dbus.xml | 20 + src/backend-dbus/upower.xml | 309 +++++ src/backend-dbus/users.c | 810 +++++++++++++ src/backend-dbus/users.h | 71 ++ src/backend-dbus/utils.c | 399 +++++++ src/backend-dbus/utils.h | 53 + src/backend.h | 47 + src/dialog.c | 248 ---- src/dialog.h | 64 - src/display-manager.xml | 30 - src/gtk-logout-helper.c | 266 ----- src/guest.c | 190 +++ src/guest.h | 82 ++ src/indicator-session.c | 495 -------- src/main.c | 87 ++ src/online-accounts-mgr.c | 166 --- src/online-accounts-mgr.h | 50 - src/org.freedesktop.Accounts.User.xml | 744 ------------ src/org.freedesktop.Accounts.xml | 194 ---- src/org.freedesktop.ConsoleKit.Manager.xml | 353 ------ src/org.freedesktop.ConsoleKit.Seat.xml | 164 --- src/org.freedesktop.ConsoleKit.Session.xml | 435 ------- src/service.c | 1192 +++++++++++++++++++ src/service.h | 64 + src/session-dbus.c | 282 ----- src/session-dbus.h | 56 - src/session-dbus.xml | 20 - src/session-menu-mgr.c | 1226 -------------------- src/session-menu-mgr.h | 55 - src/session-service.c | 96 -- src/shared-names.h | 52 - src/upower.xml | 309 ----- src/user-widget.c | 292 ----- src/user-widget.h | 55 - src/users-service-dbus.c | 1044 ----------------- src/users-service-dbus.h | 97 -- src/users.c | 198 ++++ src/users.h | 146 +++ tests/CMakeLists.txt | 53 + tests/Makefile.am | 51 - tests/Makefile.am.strings | 38 - tests/backend-dbus/CMakeLists.txt | 62 + tests/backend-dbus/gtest-mock-dbus-fixture.h | 130 +++ tests/backend-dbus/mock-accounts.cc | 156 +++ tests/backend-dbus/mock-accounts.h | 74 ++ tests/backend-dbus/mock-consolekit-manager.cc | 156 +++ tests/backend-dbus/mock-consolekit-manager.h | 77 ++ tests/backend-dbus/mock-consolekit-seat.cc | 220 ++++ tests/backend-dbus/mock-consolekit-seat.h | 75 ++ tests/backend-dbus/mock-consolekit-session.cc | 113 ++ tests/backend-dbus/mock-consolekit-session.h | 65 ++ tests/backend-dbus/mock-display-manager-seat.cc | 140 +++ tests/backend-dbus/mock-display-manager-seat.h | 72 ++ tests/backend-dbus/mock-end-session-dialog.cc | 89 ++ tests/backend-dbus/mock-end-session-dialog.h | 67 ++ tests/backend-dbus/mock-object.cc | 122 ++ tests/backend-dbus/mock-object.h | 62 + tests/backend-dbus/mock-screen-saver.cc | 71 ++ tests/backend-dbus/mock-screen-saver.h | 53 + tests/backend-dbus/mock-session-manager.cc | 66 ++ tests/backend-dbus/mock-session-manager.h | 50 + tests/backend-dbus/mock-upower.cc | 103 ++ tests/backend-dbus/mock-upower.h | 72 ++ tests/backend-dbus/mock-user.cc | 131 +++ tests/backend-dbus/mock-user.h | 57 + tests/backend-dbus/mock-webcredentials.cc | 54 + tests/backend-dbus/mock-webcredentials.h | 42 + tests/backend-dbus/test-actions.cc | 454 ++++++++ tests/backend-dbus/test-guest.cc | 192 +++ tests/backend-dbus/test-users.cc | 377 ++++++ tests/backend-mock-actions.c | 229 ++++ tests/backend-mock-actions.h | 61 + tests/backend-mock-guest.c | 129 ++ tests/backend-mock-guest.h | 61 + tests/backend-mock-users.c | 189 +++ tests/backend-mock-users.h | 70 ++ tests/backend-mock.c | 44 + tests/backend-mock.h | 38 + ...nical.indicator.session.backendmock.gschema.xml | 41 + tests/com.canonical.indicator.session.gschema.xml | 32 + tests/gtest-dbus-fixture.h | 134 +++ tests/indicator-session.service.in | 4 +- tests/test-service.cc | 831 +++++++++++-- trim-lcov.py | 53 + 115 files changed, 13799 insertions(+), 7673 deletions(-) delete mode 100644 AUTHORS delete mode 100644 ChangeLog create mode 100644 INSTALL delete mode 100644 Makefile.am delete mode 100644 Makefile.am.coverage delete mode 100755 autogen.sh delete mode 100644 configure.ac delete mode 100644 m4/gcov.m4 delete mode 100644 m4/gtest.m4 create mode 100644 src/CMakeLists.txt delete mode 100644 src/Makefile.am create mode 100644 src/actions.c create mode 100644 src/actions.h create mode 100644 src/backend-dbus/CMakeLists.txt create mode 100644 src/backend-dbus/actions.c create mode 100644 src/backend-dbus/actions.h create mode 100644 src/backend-dbus/backend-dbus.c create mode 100644 src/backend-dbus/backend-dbus.h create mode 100644 src/backend-dbus/com.canonical.indicators.webcredentials.xml create mode 100644 src/backend-dbus/display-manager.xml create mode 100644 src/backend-dbus/guest.c create mode 100644 src/backend-dbus/guest.h create mode 100644 src/backend-dbus/org.freedesktop.Accounts.User.xml create mode 100644 src/backend-dbus/org.freedesktop.Accounts.xml create mode 100644 src/backend-dbus/org.freedesktop.ConsoleKit.Manager.xml create mode 100644 src/backend-dbus/org.freedesktop.ConsoleKit.Seat.xml create mode 100644 src/backend-dbus/org.freedesktop.ConsoleKit.Session.xml create mode 100644 src/backend-dbus/org.gnome.ScreenSaver.xml create mode 100644 src/backend-dbus/org.gnome.SessionManager.EndSessionDialog.xml create mode 100644 src/backend-dbus/org.gnome.SessionManager.xml create mode 100644 src/backend-dbus/session-dbus.xml create mode 100644 src/backend-dbus/upower.xml create mode 100644 src/backend-dbus/users.c create mode 100644 src/backend-dbus/users.h create mode 100644 src/backend-dbus/utils.c create mode 100644 src/backend-dbus/utils.h create mode 100644 src/backend.h delete mode 100644 src/dialog.c delete mode 100644 src/dialog.h delete mode 100644 src/display-manager.xml delete mode 100644 src/gtk-logout-helper.c create mode 100644 src/guest.c create mode 100644 src/guest.h delete mode 100644 src/indicator-session.c create mode 100644 src/main.c delete mode 100644 src/online-accounts-mgr.c delete mode 100644 src/online-accounts-mgr.h delete mode 100644 src/org.freedesktop.Accounts.User.xml delete mode 100644 src/org.freedesktop.Accounts.xml delete mode 100644 src/org.freedesktop.ConsoleKit.Manager.xml delete mode 100644 src/org.freedesktop.ConsoleKit.Seat.xml delete mode 100644 src/org.freedesktop.ConsoleKit.Session.xml create mode 100644 src/service.c create mode 100644 src/service.h delete mode 100644 src/session-dbus.c delete mode 100644 src/session-dbus.h delete mode 100644 src/session-dbus.xml delete mode 100644 src/session-menu-mgr.c delete mode 100644 src/session-menu-mgr.h delete mode 100644 src/session-service.c delete mode 100644 src/shared-names.h delete mode 100644 src/upower.xml delete mode 100644 src/user-widget.c delete mode 100644 src/user-widget.h delete mode 100644 src/users-service-dbus.c delete mode 100644 src/users-service-dbus.h create mode 100644 src/users.c create mode 100644 src/users.h create mode 100644 tests/CMakeLists.txt delete mode 100644 tests/Makefile.am delete mode 100644 tests/Makefile.am.strings create mode 100644 tests/backend-dbus/CMakeLists.txt create mode 100644 tests/backend-dbus/gtest-mock-dbus-fixture.h create mode 100644 tests/backend-dbus/mock-accounts.cc create mode 100644 tests/backend-dbus/mock-accounts.h create mode 100644 tests/backend-dbus/mock-consolekit-manager.cc create mode 100644 tests/backend-dbus/mock-consolekit-manager.h create mode 100644 tests/backend-dbus/mock-consolekit-seat.cc create mode 100644 tests/backend-dbus/mock-consolekit-seat.h create mode 100644 tests/backend-dbus/mock-consolekit-session.cc create mode 100644 tests/backend-dbus/mock-consolekit-session.h create mode 100644 tests/backend-dbus/mock-display-manager-seat.cc create mode 100644 tests/backend-dbus/mock-display-manager-seat.h create mode 100644 tests/backend-dbus/mock-end-session-dialog.cc create mode 100644 tests/backend-dbus/mock-end-session-dialog.h create mode 100644 tests/backend-dbus/mock-object.cc create mode 100644 tests/backend-dbus/mock-object.h create mode 100644 tests/backend-dbus/mock-screen-saver.cc create mode 100644 tests/backend-dbus/mock-screen-saver.h create mode 100644 tests/backend-dbus/mock-session-manager.cc create mode 100644 tests/backend-dbus/mock-session-manager.h create mode 100644 tests/backend-dbus/mock-upower.cc create mode 100644 tests/backend-dbus/mock-upower.h create mode 100644 tests/backend-dbus/mock-user.cc create mode 100644 tests/backend-dbus/mock-user.h create mode 100644 tests/backend-dbus/mock-webcredentials.cc create mode 100644 tests/backend-dbus/mock-webcredentials.h create mode 100644 tests/backend-dbus/test-actions.cc create mode 100644 tests/backend-dbus/test-guest.cc create mode 100644 tests/backend-dbus/test-users.cc create mode 100644 tests/backend-mock-actions.c create mode 100644 tests/backend-mock-actions.h create mode 100644 tests/backend-mock-guest.c create mode 100644 tests/backend-mock-guest.h create mode 100644 tests/backend-mock-users.c create mode 100644 tests/backend-mock-users.h create mode 100644 tests/backend-mock.c create mode 100644 tests/backend-mock.h create mode 100644 tests/com.canonical.indicator.session.backendmock.gschema.xml create mode 100644 tests/com.canonical.indicator.session.gschema.xml create mode 100644 tests/gtest-dbus-fixture.h create mode 100755 trim-lcov.py diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index a741f25..0000000 --- a/AUTHORS +++ /dev/null @@ -1,2 +0,0 @@ -# Generated by Makefile - diff --git a/ChangeLog b/ChangeLog deleted file mode 100644 index a741f25..0000000 --- a/ChangeLog +++ /dev/null @@ -1,2 +0,0 @@ -# Generated by Makefile - diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..ef5d8e5 --- /dev/null +++ b/INSTALL @@ -0,0 +1,72 @@ +# +# Copyright (C) 2013 Canonical Ltd +# +# This program 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. +# +# This program 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 this program. If not, see . +# + +Build dependencies +------------------ + +List of packages required to build and test the code: +- glib (libglib2.0, 2.35.4 or later) +- cmake (cmake, 2.8.9 or later) +- gcovr (gcovr, 2.4 or later) +- lcov (lcov, 1.9 or later) +- google test (libgtest-dev, 1.6.0 or later) +- cppcheck (cppcheck) + +Building the code +----------------- + +The simplest case is: + + $ cd indicator-session-X.Y.Z + $ mkdir build + $ cd build + $ cmake .. + $ make + +Running the tests +----------------- + + $ cd indicator-session-X.Y.Z + $ mkdir build + $ cd build + $ cmake .. + $ make + $ make test + $ make cppcheck + +Generating Test Coverage Reports +-------------------------------- + + $ cd indicator-session-X.Y.Z + $ mkdir build-coverage + $ cd build-coverage + $ cmake -DCMAKE_BUILD_TYPE=coverage .. + $ make + $ make coverage-html + +Installation +------------ + +FIXME: not tested +To get files that form part of an installation, run a "make install" +in the build directory. By default, this installs them in the "install" +subdirectory of the build directory. If you want to install into a +different directory, use + +$ cmake -DCMAKE_INSTALL_PREFIX=/usr/local # Or wherever... +$ make release +$ make install + diff --git a/Makefile.am b/Makefile.am deleted file mode 100644 index 8fb5d77..0000000 --- a/Makefile.am +++ /dev/null @@ -1,43 +0,0 @@ - -SUBDIRS = \ - src \ - data \ - po - -if BUILD_TESTS -SUBDIRS += tests -# build src first -tests: src -endif - -EXTRA_DIST = autogen.sh - -DISTCHECK_CONFIGURE_FLAGS = --enable-localinstall - -dist-hook: - @if test -d "$(top_srcdir)/.bzr"; \ - then \ - echo Creating ChangeLog && \ - ( cd "$(top_srcdir)" && \ - echo '# Generated by Makefile. Do not edit.'; echo; \ - $(top_srcdir)/missing --run bzr log --gnu-changelog ) > ChangeLog.tmp \ - && mv -f ChangeLog.tmp $(top_distdir)/ChangeLog \ - || (rm -f ChangeLog.tmp; \ - echo Failed to generate ChangeLog >&2 ); \ - else \ - echo Failed to generate ChangeLog: not a branch >&2; \ - fi - @if test -d "$(top_srcdir)/.bzr"; \ - then \ - echo Creating AUTHORS && \ - ( cd "$(top_srcdir)" && \ - echo '# Generated by Makefile. Do not edit.'; echo; \ - $(top_srcdir)/missing --run bzr log --long --levels=0 | grep -e "^\s*author:" -e "^\s*committer:" | cut -d ":" -f 2 | cut -d "<" -f 1 | sort -u) > AUTHORS.tmp \ - && mv -f AUTHORS.tmp $(top_distdir)/AUTHORS \ - || (rm -f AUTHORS.tmp; \ - echo Failed to generate AUTHORS >&2 ); \ - else \ - echo Failed to generate AUTHORS: not a branch >&2; \ - fi - -include $(top_srcdir)/Makefile.am.coverage diff --git a/Makefile.am.coverage b/Makefile.am.coverage deleted file mode 100644 index fb97747..0000000 --- a/Makefile.am.coverage +++ /dev/null @@ -1,48 +0,0 @@ - -# Coverage targets - -.PHONY: clean-gcno clean-gcda \ - coverage-html generate-coverage-html clean-coverage-html \ - coverage-gcovr generate-coverage-gcovr clean-coverage-gcovr - -clean-local: clean-gcno clean-coverage-html clean-coverage-gcovr - -if HAVE_GCOV - -clean-gcno: - @echo Removing old coverage instrumentation - -find -name '*.gcno' -print | xargs -r rm - -clean-gcda: - @echo Removing old coverage results - -find -name '*.gcda' -print | xargs -r rm - -coverage-html: clean-gcda - -$(MAKE) $(AM_MAKEFLAGS) -k check - $(MAKE) $(AM_MAKEFLAGS) generate-coverage-html - -generate-coverage-html: - @echo Collecting coverage data - $(LCOV) --directory $(top_builddir) --capture --output-file coverage.info --no-checksum --compat-libtool - LANG=C $(GENHTML) --prefix $(top_builddir) --output-directory coveragereport --title "Code Coverage" --legend --show-details coverage.info - -clean-coverage-html: clean-gcda - -$(LCOV) --directory $(top_builddir) -z - -rm -rf coverage.info coveragereport - -if HAVE_GCOVR - -coverage-gcovr: clean-gcda - -$(MAKE) $(AM_MAKEFLAGS) -k check - $(MAKE) $(AM_MAKEFLAGS) generate-coverage-gcovr - -generate-coverage-gcovr: - @echo Generating coverage GCOVR report - $(GCOVR) -x -r $(top_builddir) -o $(top_builddir)/coverage.xml - -clean-coverage-gcovr: clean-gcda - -rm -rf $(top_builddir)/coverage.xml - -endif # HAVE_GCOVR - -endif # HAVE_GCOV diff --git a/README b/README index e69de29..8834cc2 100644 --- a/README +++ b/README @@ -0,0 +1,47 @@ +Indicator-Session is the the session menu indicator for Unity. +Its behavior and features are listed at https://wiki.ubuntu.com/SystemMenu. + +For instructions on building and running built-in tests, see the INSTALL file. + + +Notes for Client Renderers +-------------------------- + +Indicator-Session has two custom types: the Guest menuitem and User menuitems. +Referencing the spec at ,https://wiki.ubuntu.com/SystemMenu.>, both have four +visual components: (1) an Active Session Mark and the user's (2) icon, +(3) name, and (4) Logged In Mark. + +== User menuitems can be recognized by their "indicator.switch-to-user" action. + Their four visual components are determined by: + + 1. You can test for the Action Session Mark by checking the action's state. + The state is a dicionary whose "active-user" key yields the current + session's owner's username. If it matches the username in this menuitem's + "target" attribute, show the Active Session Mark. + + 2. The icon is stored in the menuitem's "icon" attribute. If none is set, + the client should use a fallback icon such as "avatar-default." + + 3. The name is stored in the menuitem's "label" attribute. + + 4. You can test for the Logged In Mark by checking the action's state. + The state is a dictionary whose "logged-in-users" key will give + an array of usernames. If the array contains the username in this + menuitem's "target" attribute, show the Logged In Mark. + +== Guest menuitems can be recognized by their "indicator.switch-to-guest" action. + Its four visual components is determined by: + + 1. You can test for the Active Session Mark by checking the action's state. + The state is a dictionary whose "is-active" key yields a boolean. + If the booelan is true, show the Active Session Mark. + + 2. The guest user should use a fallback icon such as "avatar-default." + + 3. The name ("Guest") is stored in the menuitem's "label" attribute. + + 4. You can test for the Logged In Mark by checking the action's state. + The state is a dictionary whose "is-logged-in" key yields a boolean. + If the boolean is true, show the Logged In Mark. + diff --git a/autogen.sh b/autogen.sh deleted file mode 100755 index 7c01ea7..0000000 --- a/autogen.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -PKG_NAME="indicator-session" - -which gnome-autogen.sh || { - echo "You need gnome-common from GNOME SVN" - exit 1 -} - -USE_GNOME2_MACROS=1 \ -. gnome-autogen.sh diff --git a/configure.ac b/configure.ac deleted file mode 100644 index ee90bae..0000000 --- a/configure.ac +++ /dev/null @@ -1,231 +0,0 @@ -AC_INIT([indicator-session],[12.10.4]) -AC_CONFIG_SRCDIR([src/session-menu-mgr.c]) -AM_INIT_AUTOMAKE([check-news]) -AC_CONFIG_HEADERS([config.h]) - -AM_MAINTAINER_MODE - -GLIB_GSETTINGS - -IT_PROG_INTLTOOL([0.35.0]) - -AC_ISC_POSIX -AC_PROG_CC -AC_PROG_CXX -AM_PROG_CC_C_O -AC_HEADER_STDC -LT_INIT - -AC_SUBST(VERSION) -AC_CONFIG_MACRO_DIR([m4]) - -m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])]) - -########################### -# Dependencies -########################### - -GIO_REQUIRED_VERSION=2.33 -GLIB_REQUIRED_VERSION=2.35.4 -GTK_REQUIRED_VERSION=3.0 -INDICATOR_REQUIRED_VERSION=0.3.19 -DBUSMENUGTK_REQUIRED_VERSION=0.5.90 -DBUSTEST_REQUIRED_VERSION=0.0.5 -DBUSMENUGLIB_REQUIRED_VERSION=0.1.1 - - -PKG_CHECK_MODULES(APPLET, glib-2.0 >= $GLIB_REQUIRED_VERSION - gtk+-3.0 >= $GTK_REQUIRED_VERSION - indicator3-0.4 >= $INDICATOR_REQUIRED_VERSION - dbusmenu-gtk3-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION) -AC_SUBST(APPLET_CFLAGS) -AC_SUBST(APPLET_LIBS) - - -PKG_CHECK_MODULES(SESSIONSERVICE, glib-2.0 >= $GLIB_REQUIRED_VERSION - dbusmenu-glib-0.4 >= $DBUSMENUGLIB_REQUIRED_VERSION - dbusmenu-gtk3-0.4 >= $DBUSMENUGTK_REQUIRED_VERSION - gio-unix-2.0 - indicator3-0.4 >= $INDICATOR_REQUIRED_VERSION) -AC_SUBST(SESSIONERVICE_CFLAGS) -AC_SUBST(SESSIONERVICE_LIBS) - -AC_SUBST(GUDEV_CFLAGS) -AC_SUBST(GUDEV_LIBS) - -########################### -# GTK Logout Helper -########################### - -AC_ARG_ENABLE([gtklogouthelper], - [AS_HELP_STRING([--enable-gtklogouthelper], [enable GTK Logout Helper])], - [], - [enable_gtklogouthelper=auto]) - -if test x"$enable_gtklogouthelper" != x"no" ; then - PKG_CHECK_MODULES([GTKLOGOUTHELPER], - [gtk+-3.0 >= $GTK_REQUIRED_VERSION], - [have_gtklogouthelper=yes], - [have_gtklogouthelper=no]) - if test x${have_gtklogouthelper} = xyes; then - AC_DEFINE(HAVE_GTKLOGOUTHELPER, 1, [Define to 1 to enable GTK Logout Helper]) - fi - if test x${enable_gtklogouthelper} = xyes && test x${have_gtklogouthelper} = xno; then - AC_MSG_ERROR([GTK Logout Helper configured but polkit-gobject not found]) - fi -else - have_gtklogouthelper=no -fi -AM_CONDITIONAL(BUILD_GTKLOGOUTHELPER, test x${have_gtklogouthelper} = xyes) - -AC_SUBST(GTKLOGOUTHELPER_CFLAGS) -AC_SUBST(GTKLOGOUTHELPER_LIBS) - -########################### -# Check to see if we're local -########################### - -with_localinstall="no" -AC_ARG_ENABLE(localinstall, AS_HELP_STRING([--enable-localinstall], [install all of the files localy instead of system directories (for distcheck)]), with_localinstall=$enableval, with_localinstall=no) - -########################### -# Indicator Info -########################### - -if test "x$with_localinstall" = "xyes"; then - INDICATORDIR="${libdir}/indicators/2/" - INDICATORICONSDIR="${datadir}/indicator-applet/icons/" -elif test "x$with_gtk" = x2; then - INDICATORDIR=`$PKG_CONFIG --variable=indicatordir indicator-0.4` - INDICATORICONSDIR=`$PKG_CONFIG --variable=iconsdir indicator-0.4` -else - INDICATORDIR=`$PKG_CONFIG --variable=indicatordir indicator3-0.4` - INDICATORICONSDIR=`$PKG_CONFIG --variable=iconsdir indicator3-0.4` -fi -AC_SUBST(INDICATORDIR) -AC_SUBST(INDICATORICONSDIR) - -########################### -# DBus Service Info -########################### - -if test "x$with_localinstall" = "xyes"; then - DBUSSERVICEDIR="${datadir}/dbus-1/services/" -else - DBUSSERVICEDIR=`$PKG_CONFIG --variable=session_bus_services_dir dbus-1` -fi -AC_SUBST(DBUSSERVICEDIR) - -########################### -# Google Test framework -########################### - -AC_ARG_ENABLE([tests], - [AS_HELP_STRING([--disable-tests], [Disable test scripts and tools (default=auto)])], - [enable_tests=${enableval}], - [enable_tests=auto]) -if test "x$enable_tests" != "xno"; then - m4_include([m4/gtest.m4]) - CHECK_GTEST - CHECK_XORG_GTEST - if test "x$enable_tests" = "xauto"; then - enable_tests=${have_gtest} - elif test "x$enable_tests" = "xyes" && test "x$have_gtest" != "xyes"; then - AC_MSG_ERROR([tests were requested but gtest is not installed.]) - fi - if test "x$enable_tests" = "xyes"; then - PKG_CHECK_MODULES([TEST_SERVICE],[glib-2.0 >= $GLIB_REQUIRED_VERSION - gio-2.0 >= $GIO_REQUIRED_VERSION], - [enable_tests="yes"], - [enable_tests="no"]) - fi -fi -AM_CONDITIONAL([BUILD_TESTS],[test "x$enable_tests" = "xyes"]) -AC_SUBST([TEST_SERVICE_CFLAGS]) -AC_SUBST([TEST_SERVICE_LIBS]) - -############################## -# Custom Junk -############################## - -AC_DEFUN([AC_DEFINE_PATH], [ - test "x$prefix" = xNONE && prefix="$ac_default_prefix" - test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - ac_define_path=`eval echo [$]$2` - ac_define_path=`eval echo [$]ac_define_path` - $1="$ac_define_path" - AC_SUBST($1) - ifelse($3, , - AC_DEFINE_UNQUOTED($1, "$ac_define_path"), - AC_DEFINE_UNQUOTED($1, "$ac_define_path", $3)) -]) - -########################### -# Internationalization -########################### - -GETTEXT_PACKAGE=indicator-session -AC_SUBST(GETTEXT_PACKAGE) -AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE, "$GETTEXT_PACKAGE", [Name of the default get text domain]) -AC_DEFINE_PATH(GNOMELOCALEDIR, "${datadir}/locale", [locale directory]) - -AM_GLIB_GNU_GETTEXT - -########################### -# gcov coverage reporting -########################### - -m4_include([m4/gcov.m4]) -AC_TDD_GCOV -AM_CONDITIONAL([HAVE_GCOV], [test "x$ac_cv_check_gcov" = xyes]) -AM_CONDITIONAL([HAVE_LCOV], [test "x$ac_cv_check_lcov" = xyes]) -AM_CONDITIONAL([HAVE_GCOVR], [test "x$ac_cv_check_gcovr" = xyes]) -AC_SUBST(COVERAGE_CFLAGS) -AC_SUBST(COVERAGE_LDFLAGS) - -########################### -# Files -########################### - -AC_CONFIG_FILES([ -Makefile -src/Makefile -data/Makefile -data/icons/Makefile -data/icons/16x16/Makefile -data/icons/16x16/actions/Makefile -data/icons/16x16/status/Makefile -data/icons/22x22/Makefile -data/icons/22x22/actions/Makefile -data/icons/22x22/status/Makefile -data/icons/24x24/Makefile -data/icons/24x24/actions/Makefile -data/icons/24x24/status/Makefile -data/icons/32x32/Makefile -data/icons/32x32/actions/Makefile -data/icons/32x32/status/Makefile -data/icons/scalable/Makefile -data/icons/scalable/actions/Makefile -data/icons/scalable/status/Makefile -data/extra-sessions/Makefile -tests/Makefile -tests/indicator-session.service -po/Makefile.in -]) - -AC_OUTPUT - -########################### -# Results -########################### - -AC_MSG_NOTICE([ - -SUS Indicator Configuration: - - Prefix: $prefix - Indicator Dir: $INDICATORDIR - Logout Helper: $have_gtklogouthelper - Unit Tests: $enable_tests - Coverage reporting: $use_gcov -]) diff --git a/m4/gcov.m4 b/m4/gcov.m4 deleted file mode 100644 index 3163584..0000000 --- a/m4/gcov.m4 +++ /dev/null @@ -1,86 +0,0 @@ -# Checks for existence of coverage tools: -# * gcov -# * lcov -# * genhtml -# * gcovr -# -# Sets ac_cv_check_gcov to yes if tooling is present -# and reports the executables to the variables LCOV, GCOVR and GENHTML. -AC_DEFUN([AC_TDD_GCOV], -[ - AC_ARG_ENABLE(gcov, - AS_HELP_STRING([--enable-gcov], - [enable coverage testing with gcov]), - [use_gcov=$enableval], [use_gcov=no]) - - if test "x$use_gcov" = "xyes"; then - # we need gcc: - if test "$GCC" != "yes"; then - AC_MSG_ERROR([GCC is required for --enable-gcov]) - fi - - # Check if ccache is being used - AC_CHECK_PROG(SHTOOL, shtool, shtool) - case `$SHTOOL path $CC` in - *ccache*[)] gcc_ccache=yes;; - *[)] gcc_ccache=no;; - esac - - if test "$gcc_ccache" = "yes" && (test -z "$CCACHE_DISABLE" || test "$CCACHE_DISABLE" != "1"); then - AC_MSG_ERROR([ccache must be disabled when --enable-gcov option is used. You can disable ccache by setting environment variable CCACHE_DISABLE=1.]) - fi - - lcov_version_list="1.6 1.7 1.8 1.9" - AC_CHECK_PROG(LCOV, lcov, lcov) - AC_CHECK_PROG(GENHTML, genhtml, genhtml) - - if test "$LCOV"; then - AC_CACHE_CHECK([for lcov version], glib_cv_lcov_version, [ - glib_cv_lcov_version=invalid - lcov_version=`$LCOV -v 2>/dev/null | $SED -e 's/^.* //'` - for lcov_check_version in $lcov_version_list; do - if test "$lcov_version" = "$lcov_check_version"; then - glib_cv_lcov_version="$lcov_check_version (ok)" - fi - done - ]) - else - lcov_msg="To enable code coverage reporting you must have one of the following lcov versions installed: $lcov_version_list" - AC_MSG_ERROR([$lcov_msg]) - fi - - case $glib_cv_lcov_version in - ""|invalid[)] - lcov_msg="You must have one of the following versions of lcov: $lcov_version_list (found: $lcov_version)." - AC_MSG_ERROR([$lcov_msg]) - LCOV="exit 0;" - ;; - esac - - if test -z "$GENHTML"; then - AC_MSG_ERROR([Could not find genhtml from the lcov package]) - fi - - ac_cv_check_gcov=yes - ac_cv_check_lcov=yes - - # Remove all optimization flags from CFLAGS - changequote({,}) - CFLAGS=`echo "$CFLAGS" | $SED -e 's/-O[0-9]*//g'` - changequote([,]) - - # Add the special gcc flags - COVERAGE_CFLAGS="-O0 -fprofile-arcs -ftest-coverage" - COVERAGE_CXXFLAGS="-O0 -fprofile-arcs -ftest-coverage" - COVERAGE_LDFLAGS="-lgcov" - - # Check availability of gcovr - AC_CHECK_PROG(GCOVR, gcovr, gcovr) - if test -z "$GCOVR"; then - ac_cv_check_gcovr=no - else - ac_cv_check_gcovr=yes - fi - -fi -]) # AC_TDD_GCOV diff --git a/m4/gtest.m4 b/m4/gtest.m4 deleted file mode 100644 index 2de334c..0000000 --- a/m4/gtest.m4 +++ /dev/null @@ -1,63 +0,0 @@ -# Copyright (C) 2012 Canonical, Ltd. -# -# Permission is hereby granted, free of charge, to any person obtaining a copy -# of this software and associated documentation files (the "Software"), to deal -# in the Software without restriction, including without limitation the rights -# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -# copies of the Software, and to permit persons to whom the Software is -# furnished to do so, subject to the following conditions: -# -# The above copyright notice and this permission notice (including the next -# paragraph) shall be included in all copies or substantial portions of the -# Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - -# Checks whether the gtest source is available on the system. Allows for -# adjusting the include and source path. Sets have_gtest=yes if the source is -# present. Sets GTEST_CPPFLAGS and GTEST_SOURCE to the preprocessor flags and -# source location respectively. -AC_DEFUN([CHECK_GTEST], -[ - AC_ARG_WITH([gtest-include-path], - [AS_HELP_STRING([--with-gtest-include-path], - [location of the Google test headers])], - [GTEST_CPPFLAGS="-I$withval"]) - - AC_ARG_WITH([gtest-source-path], - [AS_HELP_STRING([--with-gtest-source-path], - [location of the Google test sources, defaults to /usr/src/gtest])], - [GTEST_SOURCE="$withval"], - [GTEST_SOURCE="/usr/src/gtest"]) - - GTEST_CPPFLAGS="$GTEST_CPPFLAGS -I$GTEST_SOURCE" - - AC_LANG_PUSH([C++]) - - tmp_CPPFLAGS="$CPPFLAGS" - CPPFLAGS="$CPPFLAGS $GTEST_CPPFLAGS" - - AC_CHECK_HEADER([gtest/gtest.h]) - - CPPFLAGS="$tmp_CPPFLAGS" - - AC_LANG_POP - - AC_CHECK_FILES([$GTEST_SOURCE/src/gtest-all.cc] - [$GTEST_SOURCE/src/gtest_main.cc], - [have_gtest_source=yes], - [have_gtest_source=no]) - - AS_IF([test "x$ac_cv_header_gtest_gtest_h" = xyes -a \ - "x$have_gtest_source" = xyes], - [have_gtest=yes] - [AC_SUBST(GTEST_CPPFLAGS)] - [AC_SUBST(GTEST_SOURCE)], - [have_gtest=no]) -]) # CHECK_GTEST diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..efa704c --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,19 @@ +add_subdirectory (backend-dbus) + +add_library (libindicatorsessionservice STATIC + actions.c + actions.h + guest.c + guest.h + service.c + service.h + users.c + users.h) +set_target_properties (libindicatorsessionservice PROPERTIES COMPILE_FLAGS " -g ${CC_WARNING_ARGS} ${GCOV_FLAGS}") + +include_directories(${SERVICE_INCLUDE_DIRS}) +link_directories(${SERVICE_LIBRARY_DIRS}) + +add_executable (indicator-session-service main.c) +target_link_libraries (indicator-session-service libindicatorsessionservice backenddbus ${SERVICE_LIBRARIES} ${GCOV_LIBS}) + diff --git a/src/Makefile.am b/src/Makefile.am deleted file mode 100644 index bcc8652..0000000 --- a/src/Makefile.am +++ /dev/null @@ -1,207 +0,0 @@ -CLEANFILES = -EXTRA_DIST = - -libexec_PROGRAMS = \ - indicator-session-service - -if BUILD_GTKLOGOUTHELPER -libexec_PROGRAMS += \ - gtk-logout-helper -endif - -################### -# Indicator Stuff -################### - -CLEANFILES += .libs/*.gcda .libs/*.gcno *.gcda *.gcno - -sessionlibdir = $(INDICATORDIR) -sessionlib_LTLIBRARIES = libsession.la -libsession_la_SOURCES = \ - indicator-session.c \ - gen-session-dbus.xml.h \ - shared-names.h \ - user-widget.c \ - user-widget.h -libsession_la_CFLAGS = \ - $(APPLET_CFLAGS) \ - $(COVERAGE_CFLAGS) \ - -Wall -Wunused \ - -DG_LOG_DOMAIN=\"Indicator-Session\" -libsession_la_LIBADD = $(APPLET_LIBS) -libsession_la_LDFLAGS = \ - $(COVERAGE_LDFLAGS) \ - -module -avoid-version - -dbus_display_manager_sources = \ - dbus-display-manager.c \ - dbus-display-manager.h - -$(dbus_display_manager_sources): display-manager.xml - $(AM_V_GEN) gdbus-codegen \ - --interface-prefix org.freedesktop \ - --generate-c-code dbus-display-manager \ - $^ - -dbus_consolekit_manager_sources = \ - dbus-consolekit-manager.c \ - dbus-consolekit-manager.h - -$(dbus_consolekit_manager_sources): org.freedesktop.ConsoleKit.Manager.xml - $(AM_V_GEN) gdbus-codegen \ - --interface-prefix org.freedesktop \ - --generate-c-code dbus-consolekit-manager \ - $^ - -dbus_consolekit_seat_sources = \ - dbus-consolekit-seat.c \ - dbus-consolekit-seat.h - -$(dbus_consolekit_seat_sources): org.freedesktop.ConsoleKit.Seat.xml - $(AM_V_GEN) gdbus-codegen \ - --interface-prefix org.freedesktop \ - --generate-c-code dbus-consolekit-seat \ - $^ - -dbus_consolekit_session_sources = \ - dbus-consolekit-session.c \ - dbus-consolekit-session.h - -$(dbus_consolekit_session_sources): org.freedesktop.ConsoleKit.Session.xml - $(AM_V_GEN) gdbus-codegen \ - --interface-prefix org.freedesktop \ - --generate-c-code dbus-consolekit-session \ - $^ - -dbus_accounts_sources = \ - dbus-accounts.c \ - dbus-accounts.h - -$(dbus_accounts_sources): org.freedesktop.Accounts.xml - $(AM_V_GEN) gdbus-codegen \ - --interface-prefix org.freedesktop \ - --generate-c-code dbus-accounts \ - $^ - -dbus_user_sources = \ - dbus-user.c \ - dbus-user.h - -$(dbus_user_sources): org.freedesktop.Accounts.User.xml - $(AM_V_GEN) gdbus-codegen \ - --interface-prefix org.freedesktop \ - --generate-c-code dbus-user \ - $^ - -dbus_upower_sources = \ - dbus-upower.c \ - dbus-upower.h - -$(dbus_upower_sources): upower.xml - $(AM_V_GEN) gdbus-codegen \ - --interface-prefix org.freedesktop \ - --generate-c-code dbus-upower \ - --c-namespace DBus \ - $^ - -gen-%.xml.c: %.xml - @echo "Building $@ from $<" - @echo "const char * _$(subst -,_,$(subst .,_,$(basename $(notdir $<)))) = " > $@ - @sed -e "s:\":\\\\\":g" -e s:^:\": -e s:\$$:\\\\n\": $< >> $@ - @echo ";" >> $@ - -gen-%.xml.h: %.xml - @echo "Building $@ from $<" - @echo "extern const char * _$(subst -,_,$(subst .,_,$(basename $(notdir $<))));" > $@ - -################# -# Session Stuff -################# - -indicator_session_service_SOURCES = \ - $(dbus_accounts_sources) \ - $(dbus_consolekit_manager_sources) \ - $(dbus_consolekit_seat_sources) \ - $(dbus_consolekit_session_sources) \ - $(dbus_display_manager_sources) \ - $(dbus_upower_sources) \ - $(dbus_user_sources) \ - session-service.c \ - session-dbus.c \ - session-dbus.h \ - gen-session-dbus.xml.c \ - users-service-dbus.h \ - users-service-dbus.c \ - session-menu-mgr.h \ - session-menu-mgr.c \ - online-accounts-mgr.c \ - online-accounts-mgr.h - -indicator_session_service_CFLAGS = \ - $(SESSIONSERVICE_CFLAGS) \ - $(GCONF_CFLAGS) \ - -DLIBEXECDIR=\"$(libexecdir)\" \ - -Wall \ - -DG_LOG_DOMAIN=\"Indicator-Session\" \ - $(COVERAGE_CFLAGS) -indicator_session_service_LDADD = \ - $(SESSIONSERVICE_LIBS) \ - $(GCONF_LIBS) -indicator_session_service_LDFLAGS = \ - $(COVERAGE_LDFLAGS) - -################# -# GTK Logout Stuff -################# - -if BUILD_GTKLOGOUTHELPER -gtk_logout_helper_SOURCES = \ - $(dbus_consolekit_manager_sources) \ - gtk-logout-helper.c \ - dialog.c \ - dialog.h - -gtk_logout_helper_CFLAGS = \ - $(SESSIONSERVICE_CFLAGS) \ - $(GTKLOGOUTHELPER_CFLAGS) \ - $(GCONF_CFLAGS) \ - $(COVERAGE_CFLAGS) \ - -Wall \ - -DINDICATOR_ICONS_DIR="\"$(INDICATORICONSDIR)\"" - -gtk_logout_helper_LDADD = \ - $(SESSIONSERVICE_LIBS) \ - $(GTKLOGOUTHELPER_LIBS) \ - $(GCONF_LIBS) - -gtk_logout_helper_LDFLAGS = \ - $(COVERAGE_LDFLAGS) -endif - - -############### -# Other Stuff -############### - -BUILT_SOURCES = \ - $(dbus_accounts_sources) \ - $(dbus_consolekit_manager_sources) \ - $(dbus_consolekit_seat_sources) \ - $(dbus_consolekit_session_sources) \ - $(dbus_display_manager_sources) \ - $(dbus_upower_sources) \ - $(dbus_user_sources) \ - gen-session-dbus.xml.c \ - gen-session-dbus.xml.h - -EXTRA_DIST += \ - display-manager.xml \ - org.freedesktop.Accounts.User.xml \ - org.freedesktop.Accounts.xml \ - org.freedesktop.ConsoleKit.Manager.xml \ - org.freedesktop.ConsoleKit.Seat.xml \ - org.freedesktop.ConsoleKit.Session.xml \ - session-dbus.xml \ - upower.xml - -CLEANFILES += $(BUILT_SOURCES) diff --git a/src/actions.c b/src/actions.c new file mode 100644 index 0000000..788f418 --- /dev/null +++ b/src/actions.c @@ -0,0 +1,383 @@ + +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include "actions.h" + +/*** +**** GObject Boilerplate +***/ + +G_DEFINE_TYPE (IndicatorSessionActions, indicator_session_actions, G_TYPE_OBJECT) + +enum +{ + PROP_0, + PROP_CAN_SWITCH, + PROP_CAN_HIBERNATE, + PROP_CAN_SUSPEND, + PROP_CAN_LOCK, + PROP_CAN_LOGOUT, + PROP_CAN_PROMPT, + PROP_HAS_ONLINE_ACCOUNT_ERROR, + PROP_LAST +}; + +static GParamSpec *properties[PROP_LAST]; + +static void +my_get_property (GObject * o, + guint property_id, + GValue * value, + GParamSpec * pspec) +{ + IndicatorSessionActions * self = INDICATOR_SESSION_ACTIONS (o); + + switch (property_id) + { + case PROP_CAN_SWITCH: + g_value_set_boolean (value, indicator_session_actions_can_switch (self)); + break; + + case PROP_CAN_HIBERNATE: + g_value_set_boolean (value, indicator_session_actions_can_hibernate (self)); + break; + + case PROP_CAN_SUSPEND: + g_value_set_boolean (value, indicator_session_actions_can_suspend (self)); + break; + + case PROP_CAN_LOCK: + g_value_set_boolean (value, indicator_session_actions_can_lock (self)); + break; + + case PROP_CAN_LOGOUT: + g_value_set_boolean (value, indicator_session_actions_can_logout (self)); + break; + + case PROP_CAN_PROMPT: + g_value_set_boolean (value, indicator_session_actions_can_prompt (self)); + break; + + case PROP_HAS_ONLINE_ACCOUNT_ERROR: + g_value_set_boolean (value, indicator_session_actions_has_online_account_error (self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec); + } +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_actions_class_init (IndicatorSessionActionsClass * klass) +{ + GObjectClass * object_class; + const GParamFlags flags = G_PARAM_READABLE | G_PARAM_STATIC_STRINGS; + + object_class = G_OBJECT_CLASS (klass); + object_class->get_property = my_get_property; + + klass->can_lock = NULL; + klass->can_logout = NULL; + klass->can_switch = NULL; + klass->can_suspend = NULL; + klass->can_hibernate = NULL; + klass->has_online_account_error = NULL; + klass->logout = NULL; + klass->suspend = NULL; + klass->hibernate = NULL; + klass->restart = NULL; + klass->shutdown = NULL; + klass->switch_to_screensaver = NULL; + klass->switch_to_greeter = NULL; + klass->switch_to_guest = NULL; + klass->switch_to_username = NULL; + + /* properties */ + + properties[PROP_0] = NULL; + + properties[PROP_CAN_SWITCH] = + g_param_spec_boolean (INDICATOR_SESSION_ACTIONS_PROP_CAN_SWITCH, + "Can Switch Sessions", + "Whether or not the system services allow session switching", + TRUE, flags); + + properties[PROP_CAN_HIBERNATE] = + g_param_spec_boolean (INDICATOR_SESSION_ACTIONS_PROP_CAN_HIBERNATE, + "Can Hibernate", + "Whether or not the system services allow the user to hibernate", + TRUE, flags); + + properties[PROP_CAN_SUSPEND] = + g_param_spec_boolean (INDICATOR_SESSION_ACTIONS_PROP_CAN_SUSPEND, + "Can Suspend", + "Whether or not the system services allow the user to suspend", + TRUE, flags); + + properties[PROP_CAN_LOCK] = + g_param_spec_boolean (INDICATOR_SESSION_ACTIONS_PROP_CAN_LOCK, + "Can Lock", + "Whether or not the system services allow the user to lock the screen", + TRUE, flags); + + properties[PROP_CAN_LOGOUT] = + g_param_spec_boolean (INDICATOR_SESSION_ACTIONS_PROP_CAN_LOGOUT, + "Can Logout", + "Whether or not the system services allow the user to logout", + TRUE, flags); + + properties[PROP_CAN_PROMPT] = + g_param_spec_boolean (INDICATOR_SESSION_ACTIONS_PROP_CAN_PROMPT, + "Can Show End Session Dialog", + "Whether or not we can show an End Session dialog", + TRUE, flags); + + properties[PROP_HAS_ONLINE_ACCOUNT_ERROR] = + g_param_spec_boolean (INDICATOR_SESSION_ACTIONS_PROP_HAS_ONLINE_ACCOUNT_ERROR, + "Has Online Account Error", + "Whether or not an online account setting requires attention from the user", + FALSE, flags); + + g_object_class_install_properties (object_class, PROP_LAST, properties); +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_actions_init (IndicatorSessionActions * self G_GNUC_UNUSED) +{ +} + +/*** +**** +***/ + +gboolean +indicator_session_actions_can_lock (IndicatorSessionActions * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_ACTIONS (self), FALSE); + + return INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->can_lock (self); +} + +gboolean +indicator_session_actions_can_logout (IndicatorSessionActions * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_ACTIONS (self), FALSE); + + return INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->can_logout (self); +} + +gboolean +indicator_session_actions_can_switch (IndicatorSessionActions * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_ACTIONS (self), FALSE); + + return INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->can_switch (self); +} + +gboolean +indicator_session_actions_can_suspend (IndicatorSessionActions * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_ACTIONS (self), FALSE); + + return INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->can_suspend (self); +} + +gboolean +indicator_session_actions_can_hibernate (IndicatorSessionActions * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_ACTIONS (self), FALSE); + + return INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->can_hibernate (self); +} + +gboolean +indicator_session_actions_can_prompt (IndicatorSessionActions * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_ACTIONS (self), FALSE); + + return INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->can_prompt (self); +} + +gboolean +indicator_session_actions_has_online_account_error (IndicatorSessionActions * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_ACTIONS (self), FALSE); + + return INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->has_online_account_error (self); +} + +/*** +**** +***/ + +void +indicator_session_actions_settings (IndicatorSessionActions * self) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->settings (self); +} + +void +indicator_session_actions_logout (IndicatorSessionActions * self) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->logout (self); +} + +void +indicator_session_actions_shutdown (IndicatorSessionActions * self) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->shutdown (self); +} + +void +indicator_session_actions_help (IndicatorSessionActions * self) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->help (self); +} + +void +indicator_session_actions_about (IndicatorSessionActions * self) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->about (self); +} + +void +indicator_session_actions_restart (IndicatorSessionActions * self) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->restart (self); +} + +void +indicator_session_actions_suspend (IndicatorSessionActions * self) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->suspend (self); +} + +void +indicator_session_actions_hibernate (IndicatorSessionActions * self) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->hibernate (self); +} + +void +indicator_session_actions_switch_to_screensaver (IndicatorSessionActions * self) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->switch_to_screensaver (self); +} + +void +indicator_session_actions_switch_to_greeter (IndicatorSessionActions * self) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->switch_to_greeter (self); +} + +void +indicator_session_actions_switch_to_guest (IndicatorSessionActions * self) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->switch_to_guest (self); +} + +void +indicator_session_actions_switch_to_username (IndicatorSessionActions * self, + const gchar * username) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->switch_to_username (self, username); +} + +/*** +**** +***/ + +static void +notify_func (IndicatorSessionActions * self, int prop) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + g_debug ("%s %s emitting '%s' prop notify", G_STRLOC, G_STRFUNC, properties[prop]->name); + + g_object_notify_by_pspec (G_OBJECT(self), properties[prop]); +} + +void +indicator_session_actions_notify_can_lock (IndicatorSessionActions * self) +{ + notify_func (self, PROP_CAN_LOCK); +} + +void +indicator_session_actions_notify_can_logout (IndicatorSessionActions * self) +{ + notify_func (self, PROP_CAN_LOGOUT); +} + +void +indicator_session_actions_notify_can_switch (IndicatorSessionActions * self) +{ + notify_func (self, PROP_CAN_SWITCH); +} + +void +indicator_session_actions_notify_can_suspend (IndicatorSessionActions * self) +{ + notify_func (self, PROP_CAN_SUSPEND); +} + +void +indicator_session_actions_notify_can_hibernate (IndicatorSessionActions * self) +{ + notify_func (self, PROP_CAN_HIBERNATE); +} + +void +indicator_session_actions_notify_can_prompt (IndicatorSessionActions * self) +{ + notify_func (self, PROP_CAN_PROMPT); +} + +void +indicator_session_actions_notify_has_online_account_error (IndicatorSessionActions * self) +{ + notify_func (self, PROP_HAS_ONLINE_ACCOUNT_ERROR); +} diff --git a/src/actions.h b/src/actions.h new file mode 100644 index 0000000..e0d0ec5 --- /dev/null +++ b/src/actions.h @@ -0,0 +1,129 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef __INDICATOR_SESSION_ACTIONS_H__ +#define __INDICATOR_SESSION_ACTIONS_H__ + +#include +#include + +G_BEGIN_DECLS + +/* standard GObject macros */ +#define INDICATOR_TYPE_SESSION_ACTIONS (indicator_session_actions_get_type()) +#define INDICATOR_SESSION_ACTIONS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_SESSION_ACTIONS, IndicatorSessionActions)) +#define INDICATOR_SESSION_ACTIONS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_TYPE_SESSION_ACTIONS, IndicatorSessionActionsClass)) +#define INDICATOR_SESSION_ACTIONS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), INDICATOR_TYPE_SESSION_ACTIONS, IndicatorSessionActionsClass)) +#define INDICATOR_IS_SESSION_ACTIONS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_SESSION_ACTIONS)) + +typedef struct _IndicatorSessionActions IndicatorSessionActions; +typedef struct _IndicatorSessionActionsClass IndicatorSessionActionsClass; + +/* property keys */ +#define INDICATOR_SESSION_ACTIONS_PROP_CAN_LOCK "can-lock" +#define INDICATOR_SESSION_ACTIONS_PROP_CAN_LOGOUT "can-logout" +#define INDICATOR_SESSION_ACTIONS_PROP_CAN_SWITCH "can-switch" +#define INDICATOR_SESSION_ACTIONS_PROP_CAN_SUSPEND "can-suspend" +#define INDICATOR_SESSION_ACTIONS_PROP_CAN_HIBERNATE "can-hibernate" +#define INDICATOR_SESSION_ACTIONS_PROP_CAN_PROMPT "can-show-end-session-dialog" +#define INDICATOR_SESSION_ACTIONS_PROP_HAS_ONLINE_ACCOUNT_ERROR "has-online-account-error" + +/** + * A base class for invoking and getting state information on system actions. + * Use backend.h's get_backend() to get an instance. + */ +struct _IndicatorSessionActions +{ + /*< private >*/ + GObject parent; +}; + +struct _IndicatorSessionActionsClass +{ + GObjectClass parent_class; + + /* pure virtual functions */ + + gboolean (*can_lock) (IndicatorSessionActions * self); + gboolean (*can_logout) (IndicatorSessionActions * self); + gboolean (*can_switch) (IndicatorSessionActions * self); + gboolean (*can_suspend) (IndicatorSessionActions * self); + gboolean (*can_hibernate) (IndicatorSessionActions * self); + gboolean (*can_prompt) (IndicatorSessionActions * self); + gboolean (*has_online_account_error) (IndicatorSessionActions * self); + + void (*suspend) (IndicatorSessionActions * self); + void (*hibernate) (IndicatorSessionActions * self); + void (*logout) (IndicatorSessionActions * self); + void (*restart) (IndicatorSessionActions * self); + void (*shutdown) (IndicatorSessionActions * self); + void (*help) (IndicatorSessionActions * self); + void (*about) (IndicatorSessionActions * self); + void (*settings) (IndicatorSessionActions * self); + + void (*switch_to_greeter) (IndicatorSessionActions * self); + void (*switch_to_screensaver) (IndicatorSessionActions * self); + void (*switch_to_guest) (IndicatorSessionActions * self); + void (*switch_to_username) (IndicatorSessionActions * self, + const gchar * username); +}; + +/*** +**** +***/ + +GType indicator_session_actions_get_type (void); + +gboolean indicator_session_actions_can_lock (IndicatorSessionActions * self); +gboolean indicator_session_actions_can_logout (IndicatorSessionActions * self); +gboolean indicator_session_actions_can_switch (IndicatorSessionActions * self); +gboolean indicator_session_actions_can_suspend (IndicatorSessionActions * self); +gboolean indicator_session_actions_can_hibernate (IndicatorSessionActions * self); +gboolean indicator_session_actions_can_prompt (IndicatorSessionActions * self); +gboolean indicator_session_actions_has_online_account_error (IndicatorSessionActions * self); + + +void indicator_session_actions_notify_can_lock (IndicatorSessionActions * self); +void indicator_session_actions_notify_can_logout (IndicatorSessionActions * self); +void indicator_session_actions_notify_can_switch (IndicatorSessionActions * self); +void indicator_session_actions_notify_can_suspend (IndicatorSessionActions * self); +void indicator_session_actions_notify_can_hibernate (IndicatorSessionActions * self); +void indicator_session_actions_notify_can_prompt (IndicatorSessionActions * self); +void indicator_session_actions_notify_has_online_account_error (IndicatorSessionActions * self); + +void indicator_session_actions_lock (IndicatorSessionActions * self); +void indicator_session_actions_suspend (IndicatorSessionActions * self); +void indicator_session_actions_hibernate (IndicatorSessionActions * self); +void indicator_session_actions_logout (IndicatorSessionActions * self); +void indicator_session_actions_restart (IndicatorSessionActions * self); +void indicator_session_actions_shutdown (IndicatorSessionActions * self); + +void indicator_session_actions_help (IndicatorSessionActions * self); +void indicator_session_actions_about (IndicatorSessionActions * self); +void indicator_session_actions_settings (IndicatorSessionActions * self); + +void indicator_session_actions_switch_to_screensaver (IndicatorSessionActions * self); +void indicator_session_actions_switch_to_greeter (IndicatorSessionActions * self); +void indicator_session_actions_switch_to_guest (IndicatorSessionActions * self); +void indicator_session_actions_switch_to_username (IndicatorSessionActions * self, + const gchar * username); + +G_END_DECLS + +#endif /* __INDICATOR_SESSION_ACTIONS_H__ */ diff --git a/src/backend-dbus/CMakeLists.txt b/src/backend-dbus/CMakeLists.txt new file mode 100644 index 0000000..a477cfe --- /dev/null +++ b/src/backend-dbus/CMakeLists.txt @@ -0,0 +1,86 @@ +# autogenerate source code files for our DBus proxies +function(gdbus_codegen XML_FILE INTERFACE_PREFIX SOURCE_PREFIX) + + set (SRC_C, ${SOURCE_PREFIX}.c) + set (SRC_H, ${SOURCE_PREFIX}.h) + + # check for the app + find_program (GDBUS_CODEGEN_EXECUTABLE NAMES gdbus-codegen DOC "gdbus-codegen executable") + if(NOT GDBUS_CODEGEN_EXECUTABLE) + message(FATAL_ERROR "Executable gdbus-codegen not found") + endif() + + # generate the code + add_custom_command ( + OUTPUT ${SOURCE_PREFIX}.c ${SOURCE_PREFIX}.h + COMMAND gdbus-codegen ARGS --interface-prefix ${INTERFACE_PREFIX} --generate-c-code ${SOURCE_PREFIX} ${CMAKE_CURRENT_SOURCE_DIR}/${XML_FILE} + DEPENDS ${XML_FILE}) + + # update our variables + set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${SRC_C}) + set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${SRC_H}) + set_property (SOURCE ${SRC_C} ${SRC_H} PROPERTY GENERATED) + + # cleanup + unset (SRC_C) + unset (SRC_H) + +endfunction(gdbus_codegen) +gdbus_codegen ("display-manager.xml" "org.freedesktop" "dbus-display-manager") +gdbus_codegen ("com.canonical.indicators.webcredentials.xml" "com.canonical.indicators" "dbus-webcredentials") +gdbus_codegen ("org.freedesktop.Accounts.xml" "org.freedesktop" "dbus-accounts") +gdbus_codegen ("org.freedesktop.Accounts.User.xml" "org.freedesktop" "dbus-user") +gdbus_codegen ("org.freedesktop.ConsoleKit.Manager.xml" "org.freedesktop" "dbus-consolekit-manager") +gdbus_codegen ("org.freedesktop.ConsoleKit.Seat.xml" "org.freedesktop" "dbus-consolekit-seat") +gdbus_codegen ("org.freedesktop.ConsoleKit.Session.xml" "org.freedesktop" "dbus-consolekit-session") +gdbus_codegen ("org.gnome.ScreenSaver.xml" "org" "gnome-screen-saver") +gdbus_codegen ("org.gnome.SessionManager.xml" "org" "gnome-session-manager") +gdbus_codegen ("org.gnome.SessionManager.EndSessionDialog.xml" "org.gnome.SessionManager" "dbus-end-session-dialog") +gdbus_codegen ("upower.xml" "org.freedesktop" "dbus-upower") + +# add warnings/coverage info on handwritten files +# but not the autogenerated ones... +set_source_files_properties (actions.c + backend-dbus.c + guest.c + users.c + utils.c + PROPERTIES COMPILE_FLAGS " -g ${CC_WARNING_ARGS} ${GCOV_FLAGS}") + +# add the bin dir to our include path s.t. our code can find the autogenerated header files +include_directories (${CMAKE_CURRENT_BINARY_DIR} ${SERVICE_INCLUDE_DIRS}) + +add_library (backenddbus STATIC + gnome-screen-saver.c + gnome-screen-saver.h + gnome-session-manager.c + gnome-session-manager.h + dbus-display-manager.c + dbus-display-manager.h + dbus-consolekit-manager.c + dbus-consolekit-manager.h + dbus-consolekit-seat.c + dbus-consolekit-seat.h + dbus-consolekit-session.c + dbus-consolekit-session.h + dbus-accounts.c + dbus-accounts.h + dbus-upower.c + dbus-upower.h + dbus-user.c + dbus-user.h + dbus-webcredentials.c + dbus-webcredentials.h + dbus-end-session-dialog.c + dbus-end-session-dialog.h + actions.c + actions.h + backend-dbus.c + backend-dbus.h + guest.c + guest.h + users.c + users.h + utils.c + utils.h) + diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c new file mode 100644 index 0000000..8994710 --- /dev/null +++ b/src/backend-dbus/actions.c @@ -0,0 +1,730 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include + +#include "dbus-end-session-dialog.h" +#include "dbus-upower.h" +#include "dbus-webcredentials.h" +#include "gnome-screen-saver.h" +#include "gnome-session-manager.h" + +#include "actions.h" + +enum +{ + END_SESSION_TYPE_LOGOUT = 0, + END_SESSION_TYPE_SHUTDOWN, + END_SESSION_TYPE_REBOOT +}; + +struct _IndicatorSessionActionsDbusPriv +{ + GCancellable * cancellable; + + GSettings * lockdown_settings; + UPower * upower; + GnomeScreenSaver * screen_saver; + GnomeSessionManager * session_manager; + ConsoleKitManager * ck_manager; + ConsoleKitSeat * ck_seat; + DisplayManagerSeat * dm_seat; + Webcredentials * webcredentials; + EndSessionDialog * end_session_dialog; + + gboolean suspend_allowed; + gboolean hibernate_allowed; + gboolean seat_allows_activation; +}; + +typedef IndicatorSessionActionsDbusPriv priv_t; + +G_DEFINE_TYPE (IndicatorSessionActionsDbus, + indicator_session_actions_dbus, + INDICATOR_TYPE_SESSION_ACTIONS) + +/*** +**** +***/ + +static void +log_and_clear_error (GError ** err, const char * loc, const char * func) +{ + if (*err) + { + g_warning ("%s %s: %s", loc, func, (*err)->message); + g_clear_error (err); + } +} + +static void +on_can_activate_sessions (GObject * o, GAsyncResult * res, gpointer gself) +{ + GError * err; + gboolean can_activate_sessions; + + err = NULL; + can_activate_sessions = FALSE; + console_kit_seat_call_can_activate_sessions_finish (CONSOLE_KIT_SEAT(o), + &can_activate_sessions, + res, + &err); + if (err == NULL) + { + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; + p->seat_allows_activation = can_activate_sessions; + } + + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +set_ck_seat (IndicatorSessionActionsDbus * self, ConsoleKitSeat * seat) +{ + priv_t * p = self->priv; + + g_clear_object (&p->ck_seat); + + if (seat != NULL) + { + p->ck_seat = g_object_ref (seat); + + console_kit_seat_call_can_activate_sessions (seat, + p->cancellable, + on_can_activate_sessions, + self); + } +} + +/*** +**** +***/ + +static void +set_dm_seat (IndicatorSessionActionsDbus * self, DisplayManagerSeat * seat) +{ + priv_t * p = self->priv; + + if (p->dm_seat != NULL) + { + g_signal_handlers_disconnect_by_data (p->dm_seat, self); + g_clear_object (&p->dm_seat); + } + + if (seat != NULL) + { + p->dm_seat = g_object_ref (seat); + /*g_signal_connect (seat, "notify::has-actions-account", G_CALLBACK(on_notify_has_actions_account), self);*/ + } +} + +static void +on_screensaver_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) +{ + GError * err; + GnomeScreenSaver * ss; + + err = NULL; + ss = gnome_screen_saver_proxy_new_for_bus_finish (res, &err); + if (err == NULL) + { + INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv->screen_saver = ss; + } + + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +on_suspend_allowed_ready (GObject * o, GAsyncResult * res, gpointer gself) +{ + GError * err; + gboolean allowed = FALSE; + + err = NULL; + upower_call_suspend_allowed_finish (UPOWER(o), &allowed, res, &err); + if (err == NULL) + { + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; + + if (p->suspend_allowed != allowed) + { + p->suspend_allowed = allowed; + indicator_session_actions_notify_can_suspend (gself); + } + } + + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +on_hibernate_allowed_ready (GObject * o, GAsyncResult * res, gpointer gself) +{ + GError * err; + gboolean allowed = FALSE; + + err = NULL; + upower_call_hibernate_allowed_finish (UPOWER(o), &allowed, res, &err); + if (err == NULL) + { + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; + + if (p->hibernate_allowed != allowed) + { + p->hibernate_allowed = allowed; + indicator_session_actions_notify_can_hibernate (gself); + } + } + + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +on_upower_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) +{ + GError * err; + UPower * upower; + + err = NULL; + upower = upower_proxy_new_for_bus_finish (res, &err); + if (err == NULL) + { + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; + + p->upower = upower; + + g_signal_connect_swapped (upower, "notify::can-suspend", + G_CALLBACK(indicator_session_actions_notify_can_suspend), gself); + + g_signal_connect_swapped (upower, "notify::can-hibernate", + G_CALLBACK(indicator_session_actions_notify_can_hibernate), gself); + + upower_call_suspend_allowed (upower, p->cancellable, on_suspend_allowed_ready, gself); + + upower_call_hibernate_allowed (upower, p->cancellable, on_hibernate_allowed_ready, gself); + } + + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +on_session_manager_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) +{ + GError * err; + GnomeSessionManager * sm; + + err = NULL; + sm = gnome_session_manager_proxy_new_for_bus_finish (res, &err); + if (err == NULL) + { + INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv->session_manager = sm; + } + + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +on_webcredentials_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) +{ + GError * err; + Webcredentials * webcredentials; + + err = NULL; + webcredentials = webcredentials_proxy_new_for_bus_finish (res, &err); + if (err == NULL) + { + INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv->webcredentials = webcredentials; + + g_signal_connect_swapped (webcredentials, "notify::error-status", + G_CALLBACK(indicator_session_actions_notify_has_online_account_error), gself); + } + + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +on_end_session_dialog_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) +{ + GError * err; + EndSessionDialog * end_session_dialog; + + err = NULL; + end_session_dialog = end_session_dialog_proxy_new_for_bus_finish (res, &err); + if (err == NULL) + { + INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv->end_session_dialog = end_session_dialog; + + indicator_session_actions_notify_can_prompt (INDICATOR_SESSION_ACTIONS(gself)); + } + + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +/*** +**** Virtual Functions +***/ + +static gboolean +my_can_lock (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + return !g_settings_get_boolean (p->lockdown_settings, "disable-lock-screen"); +} + +static gboolean +my_can_logout (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + return !g_settings_get_boolean (p->lockdown_settings, "disable-log-out"); +} + +static gboolean +my_can_switch (IndicatorSessionActions * self) +{ + const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + return p->seat_allows_activation + && !g_settings_get_boolean (p->lockdown_settings, "disable-user-switching"); +} + +static gboolean +my_can_suspend (IndicatorSessionActions * self) +{ + const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + return p && p->upower && p->suspend_allowed && upower_get_can_suspend (p->upower); +} + +static gboolean +my_can_hibernate (IndicatorSessionActions * self) +{ + const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + return p && p->upower && p->hibernate_allowed && upower_get_can_hibernate (p->upower); +} + +static gboolean +my_can_prompt (IndicatorSessionActions * self) +{ + const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + return (p != NULL) + && (p->end_session_dialog != NULL) + && (g_dbus_proxy_get_name_owner (G_DBUS_PROXY(p->end_session_dialog)) != NULL); +} + +static gboolean +my_has_online_account_error (IndicatorSessionActions * self) +{ + const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + return p && (p->webcredentials) && (webcredentials_get_error_status (p->webcredentials)); +} + +static void +my_suspend (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + g_return_if_fail (p->upower != NULL); + + upower_call_suspend (p->upower, p->cancellable, NULL, NULL); +} + +static void +my_hibernate (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + g_return_if_fail (p->upower != NULL); + + upower_call_hibernate (p->upower, p->cancellable, NULL, NULL); +} + +/*** +**** End Session Dialog +***/ + +static void +logout_now (IndicatorSessionActions * self, gboolean try_to_prompt) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + const int type = try_to_prompt ? 0 : 1; + + g_return_if_fail (p->session_manager != NULL); + + gnome_session_manager_call_logout (p->session_manager, + type, + p->cancellable, + NULL, + NULL); +} + +static void +logout_now_with_prompt (IndicatorSessionActions * self) +{ + logout_now (self, TRUE); +} + +static void +logout_now_quietly (IndicatorSessionActions * self) +{ + logout_now (self, FALSE); +} + +static void +restart_now (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + g_return_if_fail (p->ck_manager != NULL); + + console_kit_manager_call_restart (p->ck_manager, p->cancellable, NULL, NULL); +} + +static void +shutdown_now (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + g_return_if_fail (p->ck_manager != NULL); + + console_kit_manager_call_stop (p->ck_manager, p->cancellable, NULL, NULL); +} + +static void +stop_listening_to_dialog (IndicatorSessionActionsDbus * self) +{ + g_signal_handlers_disconnect_by_data (self->priv->end_session_dialog, self); +} +static void +on_end_session_dialog_canceled (IndicatorSessionActionsDbus * self) +{ + stop_listening_to_dialog (self); +} +static void +on_end_session_dialog_closed (IndicatorSessionActionsDbus * self) +{ + stop_listening_to_dialog (self); +} + +static void +on_open_end_session_dialog_ready (GObject * o, + GAsyncResult * res, + gpointer gself G_GNUC_UNUSED) +{ + GError * err = NULL; + end_session_dialog_call_open_finish (END_SESSION_DIALOG(o), res, &err); + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +show_end_session_dialog (IndicatorSessionActionsDbus * self, int type) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + gpointer o = p->end_session_dialog; + const char * inhibitor_paths[] = { NULL }; + + g_assert (o != NULL); + + g_signal_connect_swapped (o, "confirmed-logout", G_CALLBACK(logout_now_quietly), self); + g_signal_connect_swapped (o, "confirmed-reboot", G_CALLBACK(restart_now), self); + g_signal_connect_swapped (o, "confirmed-shutdown", G_CALLBACK(shutdown_now), self); + g_signal_connect_swapped (o, "canceled", G_CALLBACK(on_end_session_dialog_canceled), self); + g_signal_connect_swapped (o, "closed", G_CALLBACK(on_end_session_dialog_closed), self); + + end_session_dialog_call_open (p->end_session_dialog, type, 0, 0, inhibitor_paths, + p->cancellable, + on_open_end_session_dialog_ready, + self); +} + +static void +my_logout (IndicatorSessionActions * self) +{ + if (my_can_prompt (self)) + show_end_session_dialog (INDICATOR_SESSION_ACTIONS_DBUS(self), END_SESSION_TYPE_LOGOUT); + else + logout_now_with_prompt (self); +} + + +static void +my_restart (IndicatorSessionActions * self) +{ + if (my_can_prompt (self)) + show_end_session_dialog (INDICATOR_SESSION_ACTIONS_DBUS(self), END_SESSION_TYPE_REBOOT); + else + restart_now (self); +} + +static void +my_shutdown (IndicatorSessionActions * self) +{ + /* NB: TYPE_REBOOT instead of TYPE_SHUTDOWN because + the latter adds lock & logout options in Unity... */ + if (my_can_prompt (self)) + show_end_session_dialog (INDICATOR_SESSION_ACTIONS_DBUS(self), END_SESSION_TYPE_REBOOT); + else + shutdown_now (self); +} + +/*** +**** +***/ + +static void +run_outside_app (const char * cmd) +{ + GError * err = NULL; + g_debug ("%s calling \"%s\"", G_STRFUNC, cmd); + g_spawn_command_line_async (cmd, &err); + log_and_clear_error (&err, G_STRLOC, G_STRFUNC); +} + +static void +my_help (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + run_outside_app ("yelp"); +} + +static void +my_settings (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + run_outside_app ("gnome-control-center"); +} + +static void +my_about (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + run_outside_app ("gnome-control-center info"); +} + +/*** +**** +***/ + +static void +my_switch_to_screensaver (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + g_return_if_fail (p->screen_saver != NULL); + + gnome_screen_saver_call_lock (p->screen_saver, p->cancellable, NULL, NULL); +} + +static void +my_switch_to_greeter (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + g_return_if_fail (p->dm_seat != NULL); + + display_manager_seat_call_switch_to_greeter (p->dm_seat, p->cancellable, + NULL, NULL); +} + +static void +my_switch_to_guest (IndicatorSessionActions * self) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + g_return_if_fail (p->dm_seat != NULL); + + display_manager_seat_call_switch_to_guest (p->dm_seat, "", + p->cancellable, + NULL, NULL); +} + +static void +my_switch_to_username (IndicatorSessionActions * self, const char * username) +{ + priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + + g_return_if_fail (p->dm_seat != NULL); + + display_manager_seat_call_switch_to_user (p->dm_seat, username, "", + p->cancellable, + NULL, NULL); +} + +static void +my_dispose (GObject * o) +{ + IndicatorSessionActionsDbus * self = INDICATOR_SESSION_ACTIONS_DBUS (o); + priv_t * p = self->priv; + + if (p->cancellable != NULL) + { + g_cancellable_cancel (p->cancellable); + g_clear_object (&p->cancellable); + } + + g_clear_object (&p->lockdown_settings); + g_clear_object (&p->ck_manager); + g_clear_object (&p->upower); + g_clear_object (&p->screen_saver); + g_clear_object (&p->session_manager); + g_clear_object (&p->webcredentials); + g_clear_object (&p->end_session_dialog); + set_dm_seat (self, NULL); + set_ck_seat (self, NULL); + + G_OBJECT_CLASS (indicator_session_actions_dbus_parent_class)->dispose (o); +} + +static void +my_finalize (GObject * o) +{ + /*IndicatorSessionActionsDbus * u = INDICATOR_SESSION_ACTIONS_DBUS (o);*/ + + G_OBJECT_CLASS (indicator_session_actions_dbus_parent_class)->finalize (o); +} + +/*** +**** GObject Boilerplate +***/ + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_actions_dbus_class_init (IndicatorSessionActionsDbusClass * klass) +{ + GObjectClass * object_class; + IndicatorSessionActionsClass * actions_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->dispose = my_dispose; + object_class->finalize = my_finalize; + + actions_class = INDICATOR_SESSION_ACTIONS_CLASS (klass); + actions_class->can_lock = my_can_lock; + actions_class->can_logout = my_can_logout; + actions_class->can_switch = my_can_switch; + actions_class->can_suspend = my_can_suspend; + actions_class->can_hibernate = my_can_hibernate; + actions_class->can_prompt = my_can_prompt; + actions_class->has_online_account_error = my_has_online_account_error; + actions_class->logout = my_logout; + actions_class->suspend = my_suspend; + actions_class->hibernate = my_hibernate; + actions_class->restart = my_restart; + actions_class->shutdown = my_shutdown; + actions_class->settings = my_settings; + actions_class->help = my_help; + actions_class->about = my_about; + actions_class->switch_to_screensaver = my_switch_to_screensaver; + actions_class->switch_to_greeter = my_switch_to_greeter; + actions_class->switch_to_guest = my_switch_to_guest; + actions_class->switch_to_username = my_switch_to_username; + + g_type_class_add_private (klass, sizeof (IndicatorSessionActionsDbusPriv)); +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_actions_dbus_init (IndicatorSessionActionsDbus * self) +{ + priv_t * p; + GSettings * s; + + p = G_TYPE_INSTANCE_GET_PRIVATE (self, + INDICATOR_TYPE_SESSION_ACTIONS_DBUS, + IndicatorSessionActionsDbusPriv); + p->cancellable = g_cancellable_new (); + p->seat_allows_activation = TRUE; + self->priv = p; + + s = g_settings_new ("org.gnome.desktop.lockdown"); + g_signal_connect_swapped (s, "changed::disable-lock-screen", + G_CALLBACK(indicator_session_actions_notify_can_lock), self); + g_signal_connect_swapped (s, "changed::disable-log-out", + G_CALLBACK(indicator_session_actions_notify_can_logout), self); + g_signal_connect_swapped (s, "changed::disable-user-switching", + G_CALLBACK(indicator_session_actions_notify_can_switch), self); + p->lockdown_settings = s; + + gnome_screen_saver_proxy_new_for_bus (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.ScreenSaver", + "/org/gnome/ScreenSaver", + p->cancellable, + on_screensaver_proxy_ready, + self); + + upower_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.UPower", + "/org/freedesktop/UPower", + p->cancellable, + on_upower_proxy_ready, + self); + + gnome_session_manager_proxy_new_for_bus (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + "org.gnome.SessionManager", + "/org/gnome/SessionManager", + p->cancellable, + on_session_manager_proxy_ready, + self); + + webcredentials_proxy_new_for_bus (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + "com.canonical.indicators.webcredentials", + "/com/canonical/indicators/webcredentials", + p->cancellable, + on_webcredentials_proxy_ready, + self); + + end_session_dialog_proxy_new_for_bus (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, + "com.canonical.Unity", + "/org/gnome/SessionManager/EndSessionDialog", + p->cancellable, + on_end_session_dialog_proxy_ready, + self); +} + +/*** +**** Public +***/ + +IndicatorSessionActions * +indicator_session_actions_dbus_new (void) +{ + gpointer o = g_object_new (INDICATOR_TYPE_SESSION_ACTIONS_DBUS, NULL); + + return INDICATOR_SESSION_ACTIONS (o); +} + +void +indicator_session_actions_dbus_set_proxies (IndicatorSessionActionsDbus * self, + ConsoleKitManager * ck_manager, + DisplayManagerSeat * dm_seat, + ConsoleKitSeat * ck_seat) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS_DBUS(self)); + + self->priv->ck_manager = g_object_ref (ck_manager); + + set_dm_seat (self, dm_seat); + + set_ck_seat (self, ck_seat); +} diff --git a/src/backend-dbus/actions.h b/src/backend-dbus/actions.h new file mode 100644 index 0000000..997dd73 --- /dev/null +++ b/src/backend-dbus/actions.h @@ -0,0 +1,73 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef __INDICATOR_SESSION_ACTIONS_DBUS_H__ +#define __INDICATOR_SESSION_ACTIONS_DBUS_H__ + +#include +#include + +#include "../actions.h" /* parent class */ +#include "dbus-accounts.h" +#include "dbus-consolekit-manager.h" +#include "dbus-consolekit-seat.h" +#include "dbus-consolekit-session.h" +#include "dbus-display-manager.h" + + +G_BEGIN_DECLS + +#define INDICATOR_TYPE_SESSION_ACTIONS_DBUS (indicator_session_actions_dbus_get_type()) +#define INDICATOR_SESSION_ACTIONS_DBUS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_SESSION_ACTIONS_DBUS, IndicatorSessionActionsDbus)) +#define INDICATOR_SESSION_ACTIONS_DBUS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_TYPE_SESSION_ACTIONS_DBUS, IndicatorSessionActionsDbusClass)) +#define INDICATOR_IS_SESSION_ACTIONS_DBUS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_SESSION_ACTIONS_DBUS)) + +typedef struct _IndicatorSessionActionsDbus IndicatorSessionActionsDbus; +typedef struct _IndicatorSessionActionsDbusPriv IndicatorSessionActionsDbusPriv; +typedef struct _IndicatorSessionActionsDbusClass IndicatorSessionActionsDbusClass; + +/** + * An implementation of IndicatorSessionActions that gets its user information + * from org.freedesktop.ConsoleKit and org.freedesktop.Accounts over DBus. + */ +struct _IndicatorSessionActionsDbus +{ + /*< private >*/ + IndicatorSessionActions parent; + IndicatorSessionActionsDbusPriv * priv; +}; + +struct _IndicatorSessionActionsDbusClass +{ + IndicatorSessionActionsClass parent_class; +}; + +GType indicator_session_actions_dbus_get_type (void); + +IndicatorSessionActions * indicator_session_actions_dbus_new (void); + +void indicator_session_actions_dbus_set_proxies (IndicatorSessionActionsDbus * self, + ConsoleKitManager * ck_manager, + DisplayManagerSeat * dm_seat, + ConsoleKitSeat * ck_seat); + + +G_END_DECLS + +#endif /* __INDICATOR_SESSION_ACTIONS_DBUS_H__ */ diff --git a/src/backend-dbus/backend-dbus.c b/src/backend-dbus/backend-dbus.c new file mode 100644 index 0000000..ea8f0ec --- /dev/null +++ b/src/backend-dbus/backend-dbus.c @@ -0,0 +1,117 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include "actions.h" +#include "backend-dbus.h" +#include "guest.h" +#include "users.h" +#include "utils.h" + +struct dbus_world_data +{ + GCancellable * cancellable; + IndicatorSessionActionsDbus * actions; + IndicatorSessionUsersDbus * users; + IndicatorSessionGuestDbus * guest; +}; + +static void +on_proxies_ready (ConsoleKitManager * ck_manager, + Accounts * account_manager, + DisplayManagerSeat * dm_seat, + ConsoleKitSeat * ck_seat, + ConsoleKitSession * ck_session, + AccountsUser * active_user G_GNUC_UNUSED, + const GError * error, + gpointer gdata) +{ + struct dbus_world_data * data = gdata; + + if (error == NULL) + { + if (data->actions != NULL) + indicator_session_actions_dbus_set_proxies (data->actions, + ck_manager, + dm_seat, + ck_seat); + + if (data->users != NULL) + indicator_session_users_dbus_set_proxies (data->users, + account_manager, + dm_seat, + ck_seat); + + if (data->guest != NULL) + indicator_session_guest_dbus_set_proxies (data->guest, + account_manager, + dm_seat, + ck_seat, + ck_session); + } + + g_free (data); +} + +/*** +**** +***/ + +void +backend_get (GCancellable * cancellable, + IndicatorSessionActions ** setme_actions, + IndicatorSessionUsers ** setme_users, + IndicatorSessionGuest ** setme_guest) +{ + struct dbus_world_data * data; + + data = g_new0 (struct dbus_world_data, 1); + + if (setme_actions != NULL) + { + IndicatorSessionActions * actions; + actions = indicator_session_actions_dbus_new (); + data->actions = INDICATOR_SESSION_ACTIONS_DBUS (actions); + + *setme_actions = actions; + } + + if (setme_users != NULL) + { + IndicatorSessionUsers * users; + users = indicator_session_users_dbus_new (); + data->users = INDICATOR_SESSION_USERS_DBUS (users); + + *setme_users = users; + } + + if (setme_guest != NULL) + { + IndicatorSessionGuest * guest; + guest = indicator_session_guest_dbus_new (); + data->guest = INDICATOR_SESSION_GUEST_DBUS (guest); + + *setme_guest = guest; + } + + data->cancellable = g_object_ref (cancellable); + + indicator_session_util_get_session_proxies (on_proxies_ready, + data->cancellable, + data); +} diff --git a/src/backend-dbus/backend-dbus.h b/src/backend-dbus/backend-dbus.h new file mode 100644 index 0000000..daf6ac3 --- /dev/null +++ b/src/backend-dbus/backend-dbus.h @@ -0,0 +1,38 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef __INDICATOR_SESSION_BACKEND_DESKTOP_H__ +#define __INDICATOR_SESSION_BACKEND_DESKTOP_H__ + +#include /* GCancellable */ + +#include "../actions.h" +#include "../guest.h" +#include "../users.h" + +G_BEGIN_DECLS + +void backend_get (GCancellable * cancellable, + IndicatorSessionActions ** setme_actions, + IndicatorSessionUsers ** setme_users, + IndicatorSessionGuest ** setme_guest); + +G_END_DECLS + +#endif diff --git a/src/backend-dbus/com.canonical.indicators.webcredentials.xml b/src/backend-dbus/com.canonical.indicators.webcredentials.xml new file mode 100644 index 0000000..d215081 --- /dev/null +++ b/src/backend-dbus/com.canonical.indicators.webcredentials.xml @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/backend-dbus/display-manager.xml b/src/backend-dbus/display-manager.xml new file mode 100644 index 0000000..07b5f29 --- /dev/null +++ b/src/backend-dbus/display-manager.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/backend-dbus/guest.c b/src/backend-dbus/guest.c new file mode 100644 index 0000000..516ba00 --- /dev/null +++ b/src/backend-dbus/guest.c @@ -0,0 +1,570 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include + +#include "dbus-accounts.h" +#include "dbus-display-manager.h" +#include "dbus-user.h" +#include "dbus-consolekit-seat.h" +#include "dbus-consolekit-manager.h" +#include "dbus-consolekit-session.h" + +#include "guest.h" + +struct _IndicatorSessionGuestDbusPriv +{ + GCancellable * cancellable; + + Accounts * accounts; + AccountsUser * guest; + DisplayManagerSeat * display_manager_seat; + + ConsoleKitSeat * seat; + ConsoleKitSession * active_session; + guint active_uid; + + gboolean guest_is_active; + gboolean guest_is_allowed; +}; + +typedef IndicatorSessionGuestDbusPriv priv_t; + +G_DEFINE_TYPE (IndicatorSessionGuestDbus, + indicator_session_guest_dbus, + INDICATOR_TYPE_SESSION_GUEST) + +/*** +**** +***/ + +static void +check_for_active_guest (IndicatorSessionGuestDbus * self) +{ + gboolean guest_is_active; + priv_t * p = self->priv; + + guest_is_active = (p->active_uid) + && (p->guest != NULL) + && (p->active_uid == accounts_user_get_uid (p->guest)); + + if (p->guest_is_active != guest_is_active) + { + p->guest_is_active = guest_is_active; + + indicator_session_guest_notify_active (INDICATOR_SESSION_GUEST(self)); + } +} + +static void +set_active_uid (IndicatorSessionGuestDbus * self, guint uid) +{ + self->priv->active_uid = uid; + + check_for_active_guest (self); +} + +static void +on_active_uid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) +{ + guint uid; + GError * err; + IndicatorSessionGuestDbus * self; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + uid = 0; + err = NULL; + self = INDICATOR_SESSION_GUEST_DBUS (gself); + console_kit_session_call_get_unix_user_finish (self->priv->active_session, &uid, res, &err); + + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } + else + { + set_active_uid (self, uid); + } +} + + +static void +set_active_session (IndicatorSessionGuestDbus * self, + ConsoleKitSession * session) +{ + priv_t * p = self->priv; + + if (p->active_session != NULL) + { + g_debug ("%s %s active_session refcount is %d before we unref", G_STRLOC, G_STRFUNC, G_OBJECT(self->priv->active_session)->ref_count); + + g_clear_object (&p->active_session); + } + + if (session != NULL) + { + p->active_session = g_object_ref (session); + + console_kit_session_call_get_unix_user (session, + p->cancellable, + on_active_uid_ready, + self); + } +} + +static void +on_active_session_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) +{ + GError * err; + ConsoleKitSession * session; + + err = NULL; + session = console_kit_session_proxy_new_finish (res, &err); + + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + } + else + { + set_active_session (gself, session); + } + + g_clear_object (&session); +} + + +static void +on_active_session_changed (ConsoleKitSeat * seat G_GNUC_UNUSED, + const gchar * ssid, + IndicatorSessionGuestDbus * self) +{ + console_kit_session_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.ConsoleKit", + ssid, + self->priv->cancellable, + on_active_session_proxy_ready, + self); +} + +static void +set_seat (IndicatorSessionGuestDbus * self, + ConsoleKitSeat * seat) +{ + priv_t * p = self->priv; + + if (p->seat != NULL) + { +g_debug ("%s %s guest-dbus disconnecting from %p", G_STRLOC, G_STRFUNC, (void*)p->seat); + g_signal_handlers_disconnect_by_data (p->seat, self); +g_debug ("%s %s seat refcount is %d before our unref", G_STRLOC, G_STRFUNC, G_OBJECT(p->seat)->ref_count); + + g_clear_object (&p->seat); + } + + if (seat != NULL) + { + p->seat = g_object_ref (seat); +g_debug ("%s %s guest-dbus connecting to %p", G_STRLOC, G_STRFUNC, (void*)p->seat); + + g_signal_connect (seat, "active-session-changed", + G_CALLBACK(on_active_session_changed), self); + } +} + +/*** +**** +***/ + +static void +set_guest (IndicatorSessionGuestDbus * self, + AccountsUser * guest) +{ + priv_t * p = self->priv; + + if (p->guest != NULL) + { + g_debug ("%s %s guest refcount is %d before we unref", G_STRLOC, G_STRFUNC, G_OBJECT(p->guest)->ref_count); + + g_clear_object (&p->guest); + } + + if (guest != NULL) + { + p->guest = g_object_ref (guest); + } + + g_debug ("%s %s guest proxy is now %p", G_STRLOC, G_STRFUNC, (void*)guest); + indicator_session_guest_notify_logged_in (INDICATOR_SESSION_GUEST(self)); + + check_for_active_guest (self); +} + +static void +on_user_deleted (IndicatorSessionGuestDbus * self, + const gchar * path) +{ + AccountsUser * guest = self->priv->guest; + g_debug ("%s %s %s", G_STRLOC, G_STRFUNC, path); + + if (guest != NULL) + if (!g_strcmp0 (path, g_dbus_proxy_get_object_path (G_DBUS_PROXY(guest)))) + set_guest (self, NULL); +} + +static gboolean +is_guest (AccountsUser * user) +{ + /* a guest will look like this: + username:[guest-jjbEVV] realname:[Guest] system:[1] */ + return IS_ACCOUNTS_USER(user) + && accounts_user_get_system_account (user) + && !g_ascii_strcasecmp (accounts_user_get_real_name(user), "Guest"); +} + +static void +on_user_proxy_ready (GObject * o G_GNUC_UNUSED, + GAsyncResult * res, + gpointer self) +{ + GError * err; + AccountsUser * user; + + err = NULL; + user = accounts_user_proxy_new_for_bus_finish (res, &err); + + if (err != NULL) + { + g_warning ("%s: %s", G_STRFUNC, err->message); + g_error_free (err); + } + else if (is_guest (user)) + { + g_debug ("%s %s got guest", G_STRLOC, G_STRFUNC); + set_guest (INDICATOR_SESSION_GUEST_DBUS(self), user); + } + + g_clear_object (&user); +} + +static void +create_user_proxy_for_path (IndicatorSessionGuestDbus * self, + const char * path) +{ + const char * name = "org.freedesktop.Accounts"; + const GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES; + g_debug ("%s %s creating proxy for %s", G_STRLOC, G_STRFUNC, path); + + accounts_user_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + flags, name, path, + self->priv->cancellable, + on_user_proxy_ready, self); +} + +static void +on_user_list_ready (GObject * o, GAsyncResult * res, gpointer gself) +{ + GError * err; + gchar ** paths; + + err = NULL; + paths = NULL; + accounts_call_list_cached_users_finish (ACCOUNTS(o), &paths, res, &err); + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } + else + { + int i; + + for (i=0; paths && paths[i]; ++i) + create_user_proxy_for_path (gself, paths[i]); + + g_strfreev (paths); + } +} + +static void +set_account_manager (IndicatorSessionGuestDbus * self, + Accounts * a) +{ + g_debug ("%s %s setting account manager to %p", G_STRLOC, G_STRFUNC, (void*)a); + + if (self->priv->accounts != NULL) + { +g_debug ("%s %s guest-dbus disconnecting from %p", G_STRLOC, G_STRFUNC, (void*)self->priv->accounts); + g_signal_handlers_disconnect_by_data (self->priv->accounts, self); +g_debug ("%s %s account manager refcount is %d before our unref", G_STRLOC, G_STRFUNC, G_OBJECT(self->priv->accounts)->ref_count); + g_clear_object (&self->priv->accounts); + } + + if (a != NULL) + { + self->priv->accounts = g_object_ref (a); + +g_debug ("%s %s guest-dbus connecting to %p", G_STRLOC, G_STRFUNC, (void*)self->priv->accounts); + g_signal_connect_swapped (a, "user-added", + G_CALLBACK(create_user_proxy_for_path), self); + + g_signal_connect_swapped (a, "user-deleted", + G_CALLBACK(on_user_deleted), self); + + accounts_call_list_cached_users (a, + self->priv->cancellable, + on_user_list_ready, + self); + } +} + +static void +set_guest_is_allowed (IndicatorSessionGuestDbus * self, gboolean guest_is_allowed) +{ + priv_t * p = self->priv; + g_debug ("%s %s guest_is_allowed: %d", G_STRLOC, G_STRFUNC, (int)guest_is_allowed); + + if (p->guest_is_allowed != guest_is_allowed) + { + p->guest_is_allowed = guest_is_allowed; + + indicator_session_guest_notify_allowed (INDICATOR_SESSION_GUEST (self)); + } +} + +static void +on_notify_has_guest_account (GObject * seat, GParamSpec * pspec G_GNUC_UNUSED, gpointer gself) +{ + set_guest_is_allowed (INDICATOR_SESSION_GUEST_DBUS (gself), + display_manager_seat_get_has_guest_account (DISPLAY_MANAGER_SEAT(seat))); +} + +static void +set_display_manager_seat (IndicatorSessionGuestDbus * self, DisplayManagerSeat * seat) +{ + priv_t * p = self->priv; + + if (p->display_manager_seat != NULL) + { + g_signal_handlers_disconnect_by_data (p->display_manager_seat, self); + g_debug ("%s %s before we unref, dm seat's refcount is %d", G_STRLOC, G_STRFUNC, G_OBJECT(p->display_manager_seat)->ref_count); + g_clear_object (&p->display_manager_seat); + } + + if (seat != NULL) + { + p->display_manager_seat = g_object_ref (seat); + + g_signal_connect (seat, "notify::has-guest-account", G_CALLBACK(on_notify_has_guest_account), self); + + on_notify_has_guest_account (G_OBJECT(seat), NULL, self); + } +} + +#if 0 +static void +on_display_manager_seat_proxy_ready (GObject * o, GAsyncResult * res, gpointer gself) +{ + GError * err; + DisplayManagerSeat * seat; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + err = NULL; + seat = display_manager_seat_proxy_new_for_bus_finish (res, &err); + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } + else + { + set_display_manager_seat (INDICATOR_SESSION_GUEST_DBUS(gself), seat); + } + + g_clear_object (&seat); +} +#endif + +static void +on_switch_to_guest_done (GObject * o, GAsyncResult * res, gpointer unused G_GNUC_UNUSED) +{ + GError * err; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + err = NULL; + display_manager_seat_call_switch_to_guest_finish (DISPLAY_MANAGER_SEAT(o), res, &err); + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } +} + +/*** +**** Virtual Functions +***/ + +static void +my_dispose (GObject * o) +{ + IndicatorSessionGuestDbus * self = INDICATOR_SESSION_GUEST_DBUS (o); + + if (self->priv->cancellable != NULL) + { + g_cancellable_cancel (self->priv->cancellable); + g_clear_object (&self->priv->cancellable); + } + + set_seat (self, NULL); + set_active_session (self, NULL); + set_account_manager (self, NULL); + set_display_manager_seat (self, NULL); + g_clear_object (&self->priv->guest); + + G_OBJECT_CLASS (indicator_session_guest_dbus_parent_class)->dispose (o); +} + +static void +my_finalize (GObject * o) +{ + /*IndicatorSessionGuestDbus * u = INDICATOR_SESSION_GUEST_DBUS (o);*/ + + G_OBJECT_CLASS (indicator_session_guest_dbus_parent_class)->finalize (o); +} + +static gboolean +my_is_allowed (IndicatorSessionGuest * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self), FALSE); + + return INDICATOR_SESSION_GUEST_DBUS(self)->priv->guest_is_allowed; +} + +static gboolean +my_is_logged_in (IndicatorSessionGuest * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self), FALSE); + + return INDICATOR_SESSION_GUEST_DBUS(self)->priv->guest != NULL; +} + +static gboolean +my_is_active (IndicatorSessionGuest * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self), FALSE); + + return INDICATOR_SESSION_GUEST_DBUS(self)->priv->guest_is_active; +} + +static void +my_switch_to_guest (IndicatorSessionGuest * self) +{ + priv_t * p; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + g_return_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self)); + + p = INDICATOR_SESSION_GUEST_DBUS(self)->priv; + + if (p->display_manager_seat != NULL) + { + display_manager_seat_call_switch_to_guest (p->display_manager_seat, + "", + p->cancellable, + on_switch_to_guest_done, + self); + } +} + +/*** +**** GObject Boilerplate +***/ + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_guest_dbus_class_init (IndicatorSessionGuestDbusClass * klass) +{ + GObjectClass * object_class; + IndicatorSessionGuestClass * guest_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->dispose = my_dispose; + object_class->finalize = my_finalize; + + guest_class = INDICATOR_SESSION_GUEST_CLASS (klass); + guest_class->is_allowed = my_is_allowed; + guest_class->is_logged_in = my_is_logged_in; + guest_class->is_active = my_is_active; + guest_class->switch_to_guest = my_switch_to_guest; + + g_type_class_add_private (klass, sizeof (IndicatorSessionGuestDbusPriv)); +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_guest_dbus_init (IndicatorSessionGuestDbus * self) +{ + priv_t * p; + + p = G_TYPE_INSTANCE_GET_PRIVATE (self, + INDICATOR_TYPE_SESSION_GUEST_DBUS, + IndicatorSessionGuestDbusPriv); + p->cancellable = g_cancellable_new (); + self->priv = p; + +#if 0 + display_manager_seat_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.DisplayManager", + g_getenv ("XDG_SEAT_PATH"), + self->priv->cancellable, + on_display_manager_seat_proxy_ready, + self); +#endif +} + +/*** +**** Public +***/ + +IndicatorSessionGuest * +indicator_session_guest_dbus_new (void) +{ + gpointer o = g_object_new (INDICATOR_TYPE_SESSION_GUEST_DBUS, NULL); + + return INDICATOR_SESSION_GUEST (o); +} + +void +indicator_session_guest_dbus_set_proxies (IndicatorSessionGuestDbus * self, + Accounts * accounts, + DisplayManagerSeat * dm_seat, + ConsoleKitSeat * seat, + ConsoleKitSession * session) +{ + g_return_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self)); + g_debug ("%s %s accounts %p seat %p session %p", G_STRLOC, G_STRFUNC, (void*)accounts, (void*)seat, (void*)session); + + set_account_manager (self, accounts); + set_display_manager_seat (self, dm_seat); + set_seat (self, seat); + set_active_session (self, session); +} diff --git a/src/backend-dbus/guest.h b/src/backend-dbus/guest.h new file mode 100644 index 0000000..03b6b28 --- /dev/null +++ b/src/backend-dbus/guest.h @@ -0,0 +1,72 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef __GUEST_DBUS_H__ +#define __GUEST_DBUS_H__ + +#include +#include + +#include "../guest.h" /* parent class */ +#include "dbus-accounts.h" +#include "dbus-consolekit-seat.h" +#include "dbus-consolekit-session.h" +#include "dbus-display-manager.h" + + +G_BEGIN_DECLS + +#define INDICATOR_TYPE_SESSION_GUEST_DBUS (indicator_session_guest_dbus_get_type()) +#define INDICATOR_SESSION_GUEST_DBUS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_SESSION_GUEST_DBUS, IndicatorSessionGuestDbus)) +#define INDICATOR_SESSION_GUEST_DBUS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_TYPE_SESSION_GUEST_DBUS, IndicatorSessionGuestDbusClass)) +#define INDICATOR_IS_SESSION_GUEST_DBUS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_SESSION_GUEST_DBUS)) + +typedef struct _IndicatorSessionGuestDbus IndicatorSessionGuestDbus; +typedef struct _IndicatorSessionGuestDbusPriv IndicatorSessionGuestDbusPriv; +typedef struct _IndicatorSessionGuestDbusClass IndicatorSessionGuestDbusClass; + +/** + * An implementation of IndicatorSessionGuest that gets its user information + * from org.freedesktop.ConsoleKit and org.freedesktop.Accounts over DBus. + */ +struct _IndicatorSessionGuestDbus +{ + /*< private >*/ + IndicatorSessionGuest parent; + IndicatorSessionGuestDbusPriv * priv; +}; + +struct _IndicatorSessionGuestDbusClass +{ + IndicatorSessionGuestClass parent_class; +}; + +GType indicator_session_guest_dbus_get_type (void); + +IndicatorSessionGuest * indicator_session_guest_dbus_new (void); + +void indicator_session_guest_dbus_set_proxies (IndicatorSessionGuestDbus *, + Accounts *, + DisplayManagerSeat *, + ConsoleKitSeat *, + ConsoleKitSession *); + +G_END_DECLS + +#endif diff --git a/src/backend-dbus/org.freedesktop.Accounts.User.xml b/src/backend-dbus/org.freedesktop.Accounts.User.xml new file mode 100644 index 0000000..53f54d4 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.Accounts.User.xml @@ -0,0 +1,744 @@ + + + + + + + + + + + The new username. + + + + + + + Sets the users username. Note that it is usually not allowed + to have multiple users with the same username. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To change the username of any user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new name, typically in the form "Firstname Lastname". + + + + + + + Sets the users real name. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.change-own-user-data + To change his own name + + + org.freedesktop.accounts.user-administration + To change the name of another user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new email address. + + + + + + + Sets the users email address. + + + Note that setting an email address in the AccountsService is + not the same as configuring a mail client. Mail clients might + default to email address that is configured here, though. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.change-own-user-data + To change his own email address + + + org.freedesktop.accounts.user-administration + To change the email address of another user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new language, as a locale specification like "de_DE.UTF-8". + + + + + + + Sets the users language. + + + The expectation is that display managers will start the + users session with this locale. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.change-own-user-data + To change his own language + + + org.freedesktop.accounts.user-administration + To change the language of another user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + + The new xsession to start (e.g. "gnome") + + + + + + + Sets the users x session. + + + The expectation is that display managers will log the user in to this + specified session, if available. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.change-own-user-data + To change his own language + + + org.freedesktop.accounts.user-administration + To change the language of another user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new location as a freeform string. + + + + + + + Sets the users location. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.change-own-user-data + To change his own location + + + org.freedesktop.accounts.user-administration + To change the location of another user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new homedir as an absolute path. + + + + + + + Sets the users home directory. + + + Note that changing the users home directory moves all the content + from the old location to the new one, and is potentially an + expensive operation. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To change the home directory of a user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new user shell. + + + + + + + Sets the users shell. + + + Note that setting the shell to a non-allowed program may + prevent the user from logging in. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To change the shell of a user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The absolute filename of a png file to use as the users icon. + + + + + + + Sets the users icon. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.change-own-user-data + To change his own icon + + + org.freedesktop.accounts.user-administration + To change the icon of another user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + Whether to lock or unlock the users account. + + + + + + + Locks or unlocks a users account. + + + Locking an account prevents the user from logging in. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To lock or unlock user accounts + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new account type, encoded as an integer: + + + 0 + Standard user + + + 1 + Administrator + + + + + + + + + Changes the users account type. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To change an account type + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The new password mode, encoded as an integer: + + + 0 + Regular password + + + 1 + Password must be set at next login + + + 2 + No password + + + + + + + + + Changes the users password mode. + + + Note that changing the password mode has the side-effect of + unlocking the account. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To change a users password mode + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + The crypted password. + + + + + + + The password hint. + + + + + + + Sets a new password for this user. + + + Note that setting a password has the side-effect of + unlocking the account. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.user-administration + To change the password of a user + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + + Whether to enable automatic login for this user. + + + + + + + Enables or disables automatic login for a user. + + + Note that usually only one user can have automatic login + enabled, so turning it on for a user will disable it for + the previously configured autologin user. + + + + The caller needs one of the following PolicyKit authorizations: + + + org.freedesktop.accounts.set-login-option + To change the login screen configuration + + + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + + The uid of the user. + + + + + + + + + + The username of the user. + + + + + + + + + + The users real name. + + + + + + + + + + The users account type, encoded as an integer: + + + 0 + Standard user + + + 1 + Administrator + + + + + + + + + + + + The users home directory. + + + + + + + + + + The users shell. + + + + + + + + + + The email address. + + + + + + + + + + The users language, as a locale specification like "de_DE.UTF-8". + + + + + + + + + + The users x session. + + + + + + + + + + The users location. + + + + + + + + + + How often the user has logged in. + + + + + + + + + + The filename of a png file containing the users icon. + + + + + + + + + + Whether the users account is locked. + + + + + + + + + + The password mode for the user account, encoded as an integer: + + + 0 + Regular password + + + 1 + Password must be set at next login + + + 2 + No password + + + + + + + + + + + + The password hint for the user. + + + + + + + + + + Whether automatic login is enabled for the user. + + + + + + + + + + Whether this is a 'system' account, like 'root' or 'nobody'. + System accounts should normally not appear in lists of + users, and ListCachedUsers will not include such accounts. + + + + + + + + + + Emitted when the user is changed. + + + + + + + diff --git a/src/backend-dbus/org.freedesktop.Accounts.xml b/src/backend-dbus/org.freedesktop.Accounts.xml new file mode 100644 index 0000000..9c19761 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.Accounts.xml @@ -0,0 +1,194 @@ + + + + + + + + + + Object paths of cached users + + + + + + Lists users which have logged into the system locally before. + This is not meant to return an exhaustive list of all users. + It is possible for FindUserByName() + to return a user that's not on the list. + + + + + + + + + The uid to look up + + + Object path of user + + + + + + Finds a user by uid. + + + + if no user with the given uid exists + + + + + + + + The username to look up + + + Object path of user + + + + + + Finds a user by its username. + + + + if no user with the given username exists + + + + + + + + The username for the new user + + + + The real name for the new user + + + Object path of the new user + + + + The account type, encoded as an integer + + + + + + Creates a new user account. + + + The accountType argument can take the following values: + + + + 0 + Standard user + + + 1 + Administrator + + + 2 + Supervised user + + + + + The caller needs the org.freedesktop.accounts.user-administration PolicyKit authorization. + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + + The uid to delete + + + Whether to remove the users files + + + + + + Deletes a user account. + + + + The caller needs the org.freedesktop.accounts.user-administration PolicyKit authorization. + + + if the caller lacks the appropriate PolicyKit authorization + if the operation failed + + + + + + + Object path of the user that was added. + + + + + Emitted when a user is added. + + + + + + + + Object path of the user that was deleted. + + + + + Emitted when a user is deleted. + + + + + + + + Object path of the user that was changed. + + + + + Emitted when a user is changed. + + + + + + + + + + The version of the running daemon. + + + + + + + diff --git a/src/backend-dbus/org.freedesktop.ConsoleKit.Manager.xml b/src/backend-dbus/org.freedesktop.ConsoleKit.Manager.xml new file mode 100644 index 0000000..f903b55 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.ConsoleKit.Manager.xml @@ -0,0 +1,353 @@ + + + + + + + + + This method initiates a request to restart (ie. reboot) the computer system. + + + + + + + + + + + + + + This method initiates a request to stop (ie. shutdown) the computer system. + + + + + + + + + + + + + + The secret cookie that is used to identify the new session + + + + + This method requests that a new Session + be created for the calling process. The properties of this new Session are set automatically + from information collected about the calling process. + + This new session exists until the calling process disconnects from the system bus or + calls CloseSession(). + + It is the responsibility of the calling process to set the environment variable + XDG_SESSION_COOKIE to the value of the returned cookie. This cookie should only + be made available to child processes of the caller so that they may be identified + as members of this session. + + See this simple example: + + DBusError error; + DBusMessage *message; + DBusMessage *reply; + + message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit", + "/org/freedesktop/ConsoleKit/Manager", + "org.freedesktop.ConsoleKit.Manager", + "OpenSession"); + if (message == NULL) { + goto out; + } + + dbus_error_init (&error); + reply = dbus_connection_send_with_reply_and_block (connector->connection, + message, + -1, + &error); + if (reply == NULL) { + goto out; + } + + dbus_error_init (&error); + if (! dbus_message_get_args (reply, + &error, + DBUS_TYPE_STRING, &cookie, + DBUS_TYPE_INVALID)) { + goto out; + } + + + + OpenSessionWithParameters() + + + + + + + An array of sets of property names and values + + + + + The secret cookie that is used to identify the new session + + + + + This method requests that a new Session + be created for the calling process. The properties of this new Session are from the + parameters provided. + + This new session exists until the calling process disconnects from the system bus or + calls CloseSession(). + + It is the responsibility of the calling process to set the environment variable + XDG_SESSION_COOKIE to the value of the returned cookie. This cookie should only + be made available to child processes of the caller so that they may be identified + as members of this session. + + See the Session properties for a list of valid parameters. + + org.freedesktop.ConsoleKit.Session + This method is restricted to privileged users by D-Bus policy. + + + + + + + The secret cookie that is used to identify the session + + + + + Whether the session was successfully closed + + + + + This method is used to close the session identified by the supplied cookie. + + The session can only be closed by the same process that opened the session. + + + + + + + + + an array of Seat IDs + + + + + This gets a list of all the Seats + that are currently present on the system. + Each Seat ID is an D-Bus object path for the object that implements the + Seat interface. + + org.freedesktop.ConsoleKit.Seat + + + + + + + an array of Session IDs + + + + + This gets a list of all the Sessions + that are currently present on the system. + Each Session ID is an D-Bus object path for the object that implements the + Session interface. + + org.freedesktop.ConsoleKit.Session + + + + + + + + The secret cookie that is used to identify the session + + + + + The object identifier for the current session + + + + + Returns the session ID that is associated with the specified cookie. + + + + + + + + + The POSIX process ID + + + + + The object identifier for the current session + + + + + Attempts to determine the session ID for the specified + POSIX process ID (pid). + + + + + + + + + The object identifier for the current session + + + + + Attempts to determine the session ID that the caller belongs to. + + See this example of using dbus-send: + + dbus-send --system --dest=org.freedesktop.ConsoleKit \ + --type=method_call --print-reply --reply-timeout=2000 \ + /org/freedesktop/ConsoleKit/Manager \ + org.freedesktop.ConsoleKit.Manager.GetCurrentSession + + + + + + + + + POSIX User identification + + + + + an array of Session IDs + + + + + This gets a list of all the Sessions + that are currently open for the specified user. + Each Session ID is an D-Bus object path for the object that implements the + Session interface. + + + + + + + + User identification + + + + + an array of Session IDs + + + + + This gets a list of all the Sessions + that are currently open for the specified user. + Each Session ID is an D-Bus object path for the object that implements the + Session interface. + + + + + + + + + The value of the system-idle-hint + + + + + Returns TRUE if the idle-hint + property of every open session is TRUE or if there are no open sessions. + + + + + + + + An ISO 8601 format date-type string + + + + + Returns an ISO 8601 date-time string that corresponds to + the time of the last change of the system-idle-hint. + + + + + + + + + The Seat ID for the added seat + + + + + Emitted when a Seat has been added to the system. + + + + + + + + The Seat ID for the removed seat + + + + + Emitted when a Seat has been removed from the system. + + + + + + + + The value of the system-idle-hint + + + + + Emitted when the value of the system-idle-hint has changed. + + + + + + diff --git a/src/backend-dbus/org.freedesktop.ConsoleKit.Seat.xml b/src/backend-dbus/org.freedesktop.ConsoleKit.Seat.xml new file mode 100644 index 0000000..58c2ce7 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.ConsoleKit.Seat.xml @@ -0,0 +1,164 @@ + + + + + + + A seat is a collection of sessions and a set of hardware (usually at +least a keyboard and mouse). Only one session may be active on a +seat at a time. + + + + + + + Seat ID + + + + + Returns the ID for Seat. + + + + + + + + an array of Session IDs + + + + + This gets a list of all the Sessions + that are currently attached to this seat. + Each Session ID is an D-Bus object path for the object that implements the + Session interface. + + + + + + + + an array of devices + + + + + This gets a list of all the devices + that are currently associated with this seat. + Each device is an D-Bus structure that represents + the device type and the device id. + + + + + + + + + Session ID + + + + + Gets the Session ID that is currently active on this Seat. + Returns NULL if there is no active session. + + + + + + + + TRUE if seat supports session activation + + + + Used to determine whether the seat supports session activation. + + + + + + + + + Session ID + + + + + Attempt to activate the specified session. In most + cases, if successful, this will cause the session to + become visible and take control of the hardware that is + associated with this seat. + + Activate() + + + + + + + Session ID + + + + + Emitted when the active session has changed. + + + + + + + Session ID + + + + + Emitted when a session has been added to the seat. + + + + + + + Session ID + + + + + Emitted when a session has been removed from the seat. + + + + + + + Device structure + + + + + Emitted when a device has been associated with the seat. + + + + + + + Device structure + + + + + Emitted when a device has been dissociated from the seat. + + + + + diff --git a/src/backend-dbus/org.freedesktop.ConsoleKit.Session.xml b/src/backend-dbus/org.freedesktop.ConsoleKit.Session.xml new file mode 100644 index 0000000..b6e1cdb --- /dev/null +++ b/src/backend-dbus/org.freedesktop.ConsoleKit.Session.xml @@ -0,0 +1,435 @@ + + + + + + + Session objects represent and store information + related to a user session. + + The properties associated with the Session + specifically refer to the properties of the "session leader". + + + + + + + Session ID + + + + Returns the ID for Session. + + + + + + + Seat ID + + + + Returns the ID for the Seat the Session is + attached to. + + org.freedesktop.ConsoleKit.Seat + + + + + + Session type + + + + + Returns the type of the session. + Warning: we haven't yet defined the allowed values for this property. + It is probably best to avoid this until we do. + + + session-type + + + + + + User ID + + + + Returns the user that the session belongs to. + + + user + + + + + + POSIX User ID + + + + Returns the POSIX user ID that the session belongs to. + + unix-user + + + + + + The value of the X11 display + + + + Returns the value of the X11 DISPLAY for this session + if one is present. + + x11-display + + + + + + The value of the X11 display device + + + + Returns the value of the display device (aka TTY) that the + X11 display for the session is connected to. If there is no x11-display set then this value + is undefined. + + x11-display-device + + + + + + The value of the display device + + + + Returns the value of the display device (aka TTY) that the + session is connected to. + + display-device + + + + + + The remote host name + + + + Returns the value of the remote host name for the session. + + + remote-host-name + + + + + + The value of the native system login session ID + + + + Returns the value of the login session ID that the + underlying system uses to enforce session boundaries. If there is no login session ID + set then this value is an empty string. + + + + + + + TRUE if the session is active, otherwise FALSE + + + + Returns whether the session is active on the Seat that + it is attached to. + If the session is not attached to a seat this value is undefined. + + + active + + + + + + TRUE if the session is local, otherwise FALSE + + + + Returns whether the session is local + FIXME: we need to come up with a concrete definition for this value. + It was originally used as a way to identify XDMCP sessions that originate + from a remote system. + + + is-local + + + + + + An ISO 8601 format date-type string + + + + + Returns an ISO 8601 date-time string that corresponds to + the time that the session was opened. + + + + + + + + + + Attempt to activate the this session. In most + cases, if successful, this will cause the session to + become visible and become active on the seat that it + is attached to. + + Seat.ActivateSession() + + + + + + + This will cause a Lock + signal to be emitted for this session. + + + This method is restricted to privileged users by D-Bus policy. + Lock signal + + + + + + + This will cause an Unlock + signal to be emitted for this session. + + This can be used by login managers to unlock a session before it is + re-activated during fast-user-switching. + + + This method is restricted to privileged users by D-Bus policy. + Unlock signal + + + + + + + The value of the idle-hint + + + + + Gets the value of the idle-hint + property. + + + idle-hint + + + + + + An ISO 8601 format date-type string + + + + + Returns an ISO 8601 date-time string that corresponds to + the time of the last change of the idle-hint. + + + + + + + + + boolean value to set the idle-hint to + + + + + This may be used by the session to indicate that + it is idle. + + Use of this method is restricted to the user + that owns the session. + + + + + + + + TRUE if the session is active, otherwise FALSE + + + + + Emitted when the active property has changed. + + + + + + + the new value of idle-hint + + + + + Emitted when the idle-hint property has changed. + + + + + + + Emitted in response to a call to the Lock() method. + It is intended that the screensaver for the session should lock the screen in response to this signal. + + + + + + + Emitted in response to a call to the Unlock() method. + It is intended that the screensaver for the session should unlock the screen in response to this signal. + + + + + + + + The user assigned to the session. + + + + + + + The user assigned to the session. + + + + + + + + The type of the session. + Warning: we haven't yet defined the allowed values for this property. + It is probably best to avoid this until we do. + + + + + + + + The remote host name for the session. + + This will be set in situations where the session is + opened and controlled from a remote system. + + For example, this value will be set when the + session is created from an SSH or XDMCP connection. + + + + + + + + The display device (aka TTY) that the + session is connected to. + + + + + + + + Value of the X11 DISPLAY for this session + if one is present. + + + + + + + + + The display device (aka TTY) that the X11 display for the + session is connected to. If there is no x11-display set then + this value is undefined. + + + + + + + + + Whether the session is active on the Seat that + it is attached to. + If the session is not attached to a seat this value is undefined. + + + + + + + + + Whether the session is local + FIXME: we need to come up with a concrete definition for this value. + It was originally used as a way to identify XDMCP sessions that originate + from a remote system. + + + + + + + + + This is a hint used to indicate that the session may be idle. + + + For sessions with a x11-display set (ie. graphical + sessions), it is up to each session to delegate the + responsibility for updating this value. Typically, the + screensaver will set this. + + However, for non-graphical sessions with a display-device set + the Session object itself will periodically update this value based + on the activity detected on the display-device itself. + + + This should not be considered authoritative. + + + + + + + diff --git a/src/backend-dbus/org.gnome.ScreenSaver.xml b/src/backend-dbus/org.gnome.ScreenSaver.xml new file mode 100644 index 0000000..c21fdc5 --- /dev/null +++ b/src/backend-dbus/org.gnome.ScreenSaver.xml @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + diff --git a/src/backend-dbus/org.gnome.SessionManager.EndSessionDialog.xml b/src/backend-dbus/org.gnome.SessionManager.EndSessionDialog.xml new file mode 100644 index 0000000..5392de0 --- /dev/null +++ b/src/backend-dbus/org.gnome.SessionManager.EndSessionDialog.xml @@ -0,0 +1,53 @@ + + + + + + + + + The type of dialog to show. + 0 for logout, 1 for shutdown, 2 for restart. + + + + + + + Timestamp of the user-initiated event which triggered + the call, or 0 if the call was not triggered by an event. + + + + + + + The number of seconds which the dialog should stay open + before automatic action is taken. + + + + + + + The object paths of all inhibitors that are registered + for the action. + + + + + + This function opens a dialog which asks the user for confirmation + of a logout, poweroff or reboot action. The dialog has a timeout + after which the action is automatically taken, and it should show + the inhibitors to the user. + + + + + + + + + + diff --git a/src/backend-dbus/org.gnome.SessionManager.xml b/src/backend-dbus/org.gnome.SessionManager.xml new file mode 100644 index 0000000..eb69180 --- /dev/null +++ b/src/backend-dbus/org.gnome.SessionManager.xml @@ -0,0 +1,451 @@ + + + + + + + + + + + The variable name + + + + + The value + + + + + Adds the variable name to the application launch environment with the specified value. May only be used during the Session Manager initialization phase. + + + + + + + + The locale category + + + + + The value + + + + + Reads the current state of the specific locale category. + + + + + + + + The error message + + + + + Whether the error should be treated as fatal + + + + + May be used by applications launched during the Session Manager initialization phase to indicate there was a problem. + + + + + + + + + + + The application identifier + + + + + Client startup identifier + + + + + The object path of the newly registered client + + + + + Register the caller as a Session Management client. + + + + + + + + + The object path of the client + + + + + Unregister the specified client from Session Management. + + + + + + + + + The application identifier + + + + + The toplevel X window identifier + + + + + The reason for the inhibit + + + + + Flags that specify what should be inhibited + + + + + The cookie + + + + + Proactively indicates that the calling application is performing an action that should not be interrupted and sets a reason to be displayed to the user when an interruption is about to take placea. + + + Applications should invoke this method when they begin an operation that + should not be interrupted, such as creating a CD or DVD. The types of actions + that may be blocked are specified by the flags parameter. When the application + completes the operation it should call Uninhibit() + or disconnect from the session bus. + + + Applications should not expect that they will always be able to block the + action. In most cases, users will be given the option to force the action + to take place. + + + Reasons should be short and to the point. + + + The flags parameter must include at least one of the following: + + + 1 + Inhibit logging out + + + 2 + Inhibit user switching + + + 4 + Inhibit suspending the session or computer + + + 8 + Inhibit the session being marked as idle + + + 16 + Inhibit auto-mounting removable media for the session + + + Values for flags may be bitwise or'ed together. + + + The returned cookie is used to uniquely identify this request. It should be used + as an argument to Uninhibit() in + order to remove the request. + + + + + + + + + + The cookie + + + + + Cancel a previous call to Inhibit() identified by the cookie. + + + + + + + + Flags that spefify what should be inhibited + + + + + Returns TRUE if any of the operations in the bitfield flags are inhibited + + + + + Determine if operation(s) specified by the flags + are currently inhibited. Flags are same as those accepted + by the + Inhibit() + method. + + + + + + + + an array of client IDs + + + + + This gets a list of all the Clients + that are currently known to the session manager. + Each Client ID is an D-Bus object path for the object that implements the + Client interface. + + org.gnome.SessionManager.Client + + + + + + + an array of inhibitor IDs + + + + + This gets a list of all the Inhibitors + that are currently known to the session manager. + Each Inhibitor ID is an D-Bus object path for the object that implements the + Inhibitor interface. + + org.gnome.SessionManager.Inhibitor + + + + + + + + The autostart condition string + + + + + True if condition is handled, false otherwise + + + + + Allows the caller to determine whether the session manager is + handling changes to the specified autostart condition. + + + + + + + + Request a shutdown dialog. + + + + + + + + Request a reboot dialog. + + + + + + + + True if shutdown is available to the user, false otherwise + + + + + Allows the caller to determine whether or not it's okay to show + a shutdown option in the UI + + + + + + + + The type of logout that is being requested + + + + + Request a logout dialog + + Allowed values for the mode parameter are: + + + 0 + Normal. + + + 1 + No confirmation inferface should be shown. + + + 2 + Forcefully logout. No confirmation will be shown and any inhibitors will be ignored. + + + Values for flags may be bitwise or'ed together. + + + + + + + + + True if the session has entered the Running phase, false otherwise + + + + + Allows the caller to determine whether the session manager + has entered the Running phase, in case the client missed the + SessionRunning signal. + + + + + + + + + + The object path for the added client + + + + + Emitted when a client has been added to the session manager. + + + + + + + + The object path for the removed client + + + + + Emitted when a client has been removed from the session manager. + + + + + + + + + The object path for the added inhibitor + + + + + Emitted when an inhibitor has been added to the session manager. + + + + + + + + The object path for the removed inhibitor + + + + + Emitted when an inhibitor has been removed from the session manager. + + + + + + + + + Indicates the session has entered the Running phase. + + + + + + + + Indicates the session is about to end. + + + + + + + + + + The name of the session that has been loaded. + + + + + + + + If true, the session is currently in the + foreground and available for user input. + + + + + + + + A bitmask of flags to indicate which actions + are inhibited. See the Inhibit() function's description + for a list of possible values. + + + + + + diff --git a/src/backend-dbus/session-dbus.xml b/src/backend-dbus/session-dbus.xml new file mode 100644 index 0000000..96e9837 --- /dev/null +++ b/src/backend-dbus/session-dbus.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/backend-dbus/upower.xml b/src/backend-dbus/upower.xml new file mode 100644 index 0000000..18d5fbd --- /dev/null +++ b/src/backend-dbus/upower.xml @@ -0,0 +1,309 @@ + + + + + + + + The DeviceKit-power service is available via the system message + bus. To access the service, use + the org.freedesktop.UPower interface on + the /org/freedesktop/UPower object on + the D-Bus system bus service with the well-known + name org.freedesktop.UPower. + + + + +$ dbus-send --print-reply \ + --system \ + --dest=org.freedesktop.UPower \ + /org/freedesktop/UPower \ + org.freedesktop.UPower.EnumerateDevices + +method return sender=:1.386 -> dest=:1.451 reply_serial=2 + array [ + object path "/org/freedesktop/UPower/devices/line_power_AC" + object path "/org/freedesktop/UPower/devices/battery_BAT0" + ] + + + + + + + + + + + + An array of object paths for devices. + + + + + + Enumerate all power objects on the system. + + + + + + + + + + Object path of device that was added. + + + + + + Emitted when a device is added. + + + + + + + + + + Object path of device that was removed. + + + + + + Emitted when a device is removed. + + + + + + + + + + Object path of device that was changed. + + + + + + Emitted when a device changed. + + + + + + + + + + + + Emitted when one or more properties on the object changes. + + + + + + + + + + + + This signal is sent when the session is about to be suspended or + hibernated. + Session and system programs have one second to do anything required + before the sleep action is taken (such as sending out Avahi or + Jabber messages). + + + + + + + + + + + + This signal is sent when the session has just returned from + Suspend() or Hibernate(). + Session and system programs can then do anything required (such as + sending out Avahi or Jabber messages). + + + + + + + + + + + + + This method tells UPower that the Suspend() or Hibernate() method + is about to be called. + This allows UPower to emit the Suspending signal whilst + session activities are happening that have to be done before the + suspend process is started. + + + This method would typically be called by the session power + management daemon, before it locks the screen and waits for the + screen to fade to black. + The session power management component would then call Suspend() or + Hibernate() when these syncronous tasks have completed. + + + If this method is not called than nothing bad will happen and + Suspend() or Hibernate() will block for the required second. + + + + + + + + + + + + + Suspends the computer into a low power state. + System state is not preserved if the power is lost. + + + If AboutToRequestSleep() has not been called then UPower will send + the Sleeping() signal and block for one second. + + + If AboutToRequestSleep() has been called less than one second + before this method is called then UPower will block for the + remaining time to complete one second of delay. + + + + + + + + + + + TRUE if allowed, otherwise FALSE + + + + + Check if the caller has (or can get) the PolicyKit privilege to call + Suspend. + + + + + + + + + + + + + Hibernates the computer into a low power state. + System state is preserved if the power is lost. + + + If AboutToRequestSleep() has not been called then UPower will send + the Sleeping() signal and block for one second. + + + If AboutToRequestSleep() has been called less than one second + before this method is called then UPower will block for the + remaining time to complete one second of delay. + + + + + + + + + + + TRUE if allowed, otherwise FALSE + + + + + Check if the caller has (or can get) the PolicyKit privilege to call + Hibernate. + + + + + + + + + + Version of the running daemon, e.g. 002. + + + + + + Whether the system is able to suspend. + + + + + + Whether the system is able to hibernate. + + + + + + Indicates whether the system is running on battery power. + This property is provided for convenience. + + + + + + Indicates whether the system is running on battery power and if the battery is critically low. + This property is provided for convenience. + + + + + + + + Indicates if the laptop lid is closed where the display cannot be seen. + + + + + + + + + + If the system has a lid device. + + + + + + + + diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c new file mode 100644 index 0000000..4798d33 --- /dev/null +++ b/src/backend-dbus/users.c @@ -0,0 +1,810 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include "dbus-accounts.h" +#include "dbus-consolekit-seat.h" +#include "dbus-consolekit-session.h" +#include "dbus-consolekit-manager.h" +#include "dbus-user.h" + +#include "users.h" + +struct _IndicatorSessionUsersDbusPriv +{ + char * active_session_id; + + Accounts * accounts; + + DisplayManagerSeat * dm_seat; + + ConsoleKitSeat * seat_proxy; + + /* user's dbus object path -> AccountsUser* */ + GHashTable * path_to_user; + + /* uint32 user-id --> user's dbus object path */ + GHashTable * uid_to_user_path; + + /* uint32 user-id --> hashset of ssid strings */ + GHashTable * uid_to_sessions; + + /* ssid string --> uint32 user-id */ + GHashTable * session_to_uid; + + GCancellable * cancellable; +}; + +typedef IndicatorSessionUsersDbusPriv priv_t; + +G_DEFINE_TYPE (IndicatorSessionUsersDbus, + indicator_session_users_dbus, + INDICATOR_TYPE_SESSION_USERS) + +/*** +**** +***/ + +static void create_user_proxy_for_path (IndicatorSessionUsersDbus * self, + const char * path); + +static void create_session_proxy_for_ssid (IndicatorSessionUsersDbus * self, + const char * ssid); + +static void +emit_user_changed_for_path (IndicatorSessionUsersDbus * self, const char * path) +{ + AccountsUser * user = g_hash_table_lookup (self->priv->path_to_user, path); + + if (user && !accounts_user_get_system_account (user)) + indicator_session_users_changed (INDICATOR_SESSION_USERS(self), path); +} + +static void +emit_user_changed_for_uid (IndicatorSessionUsersDbus * self, guint uid) +{ + const char * path; + + if ((path = g_hash_table_lookup (self->priv->uid_to_user_path, GUINT_TO_POINTER(uid)))) + emit_user_changed_for_path (self, path); +} + +/*** +**** ACCOUNT MANAGER / USER TRACKING +***/ + +/* called when a user proxy gets the 'Changed' signal */ +static void +on_user_changed (AccountsUser * user, gpointer gself) +{ + /* Accounts.User doesn't update properties in the standard way, + * so create a new proxy to pull in the new properties. + * The older proxy is freed when it's removed from our path_to_user hash */ + const char * path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(user)); + create_user_proxy_for_path (gself, path); +} + +static void +track_user (IndicatorSessionUsersDbus * self, + AccountsUser * user) +{ + priv_t * p; + const char * path; + gboolean already_had_user; + + p = self->priv; + + path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(user)); + already_had_user = g_hash_table_contains (p->path_to_user, path); + + g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self); + g_hash_table_insert (p->path_to_user, g_strdup(path), user); + + if (already_had_user) + { + emit_user_changed_for_path (self, path); + } + else + { + const guint uid = (guint) accounts_user_get_uid (user); + + g_hash_table_insert (p->uid_to_user_path, + GUINT_TO_POINTER(uid), + g_strdup(path)); + + if (!accounts_user_get_system_account (user)) + indicator_session_users_added (INDICATOR_SESSION_USERS(self), path); + } +} + +static void +untrack_user (IndicatorSessionUsersDbus * self, + const gchar * path) +{ + g_hash_table_remove (self->priv->path_to_user, path); + + indicator_session_users_removed (INDICATOR_SESSION_USERS(self), path); +} + + +static void +on_user_proxy_ready (GObject * o G_GNUC_UNUSED, + GAsyncResult * res, + gpointer self) +{ + GError * err; + AccountsUser * user; + + err = NULL; + user = accounts_user_proxy_new_for_bus_finish (res, &err); + if (err != NULL) + { + g_warning ("%s: %s", G_STRFUNC, err->message); + g_error_free (err); + } + else + { + track_user (self, user); + } +} + +static void +create_user_proxy_for_path (IndicatorSessionUsersDbus * self, + const char * path) +{ + const char * name = "org.freedesktop.Accounts"; + const GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES; + + accounts_user_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + flags, name, path, + self->priv->cancellable, + on_user_proxy_ready, self); +} + +static void +on_user_list_ready (GObject * o, GAsyncResult * res, gpointer gself) +{ + GError * err; + gchar ** paths; + + err = NULL; + paths = NULL; + accounts_call_list_cached_users_finish (ACCOUNTS(o), &paths, res, &err); + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } + else + { + int i; + + for (i=0; paths && paths[i]; ++i) + create_user_proxy_for_path (gself, paths[i]); + + g_strfreev (paths); + } +} + +static void +set_account_manager (IndicatorSessionUsersDbus * self, Accounts * a) +{ + priv_t * p = self->priv; + + if (p->accounts != NULL) + { + g_signal_handlers_disconnect_by_data (p->accounts, self); + g_clear_object (&p->accounts); + } + + if (a != NULL) + { + p->accounts = g_object_ref (a); + + accounts_call_list_cached_users (a, + self->priv->cancellable, + on_user_list_ready, + self); + + g_signal_connect_swapped (a, "user-added", + G_CALLBACK(create_user_proxy_for_path), self); + + g_signal_connect_swapped (a, "user-deleted", + G_CALLBACK(untrack_user), self); + } +} + +#if 0 +static void +create_accounts_proxy (IndicatorSessionUsersDbus * self) +{ + const char * name = "org.freedesktop.Accounts"; + const char * path = "/org/freedesktop/Accounts"; + GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES; + + accounts_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + flags, name, path, + self->priv->cancellable, + on_accounts_proxy_ready, self); +} +#endif + +/** + * SEAT / SESSION TRACKING + * + * There are two simple goals here: + * + * 1. Keep track of how many GUI sessions each user has + * so that we can set the 'is_logged_in' flag correctly + * + * 2. Also track which is the current session, + * so that we can compare it to those GUI sessions to + * set the 'is_current_session' flag correctly. + * + * Now that you know the goals, these steps may make more sense: + * + * 1. create a ConsoleKitManager proxy + * 2. ask it for the current session + * 3. create a corresponding Session proxy + * 4. ask that Session proxy for its seat + * 5. create a corresponding Seat proxy + * 6. connect to that seat's session-added / session-removed signals + * 7. ask the seat for a list of its current sessions + * 8. create corresponding Session proxies + * 9. of them, look for the GUI sessions by checking their X11 properties + * 10. for each GUI session, get the corresponding uid + * 11. use the information to update our uid <--> GUI sessions tables + */ + +static void +track_session (IndicatorSessionUsersDbus * self, + const char * ssid, + guint uid) +{ + gpointer uid_key; + GHashTable * sessions; + + uid_key = GUINT_TO_POINTER (uid); + sessions = g_hash_table_lookup (self->priv->uid_to_sessions, uid_key); + if (sessions == NULL) + { + sessions = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); + g_hash_table_insert (self->priv->uid_to_sessions, uid_key, sessions); + } + + g_hash_table_add (sessions, g_strdup (ssid)); + g_hash_table_insert (self->priv->session_to_uid, g_strdup(ssid), uid_key); + + g_debug ("%s %s now tracking ssid:%s uid:%u. uid has %u tracked ssids.", + G_STRLOC, G_STRFUNC, ssid, uid, g_hash_table_size (sessions)); + + emit_user_changed_for_uid (self, uid); +} + +static void +untrack_session (IndicatorSessionUsersDbus * self, + const char * ssid) +{ + gpointer uidptr; + priv_t * p = self->priv; + + if (g_hash_table_lookup_extended (p->session_to_uid, ssid, NULL, &uidptr)) + { + const guint uid = GPOINTER_TO_UINT (uidptr); + GHashTable * sessions = g_hash_table_lookup (p->uid_to_sessions, uidptr); + + g_hash_table_remove (p->session_to_uid, ssid); + g_hash_table_remove (sessions, ssid); + g_debug ("%s %s not tracking ssid:%s uid:%u. uid has %u tracked ssids.", + G_STRLOC, G_STRFUNC, ssid, uid, + sessions ? g_hash_table_size (sessions) : 0); + + emit_user_changed_for_uid (self, uid); + } +} + +static void +on_session_proxy_uid_ready (GObject * o, + GAsyncResult * res, + gpointer gself) +{ + guint uid; + GError * err; + ConsoleKitSession * session = CONSOLE_KIT_SESSION (o); + + uid = 0; + err = NULL; + console_kit_session_call_get_unix_user_finish (session, &uid, res, &err); + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } + else if (uid) + { + const char * path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(session)); + track_session (gself, path, uid); + } + + g_object_unref (o); +} + +static void +on_session_x11_display_ready (GObject * o, + GAsyncResult * res, + gpointer gself) +{ + priv_t * p; + GError * err; + gchar * gui; + ConsoleKitSession * session; + + p = INDICATOR_SESSION_USERS_DBUS(gself)->priv; + + err = NULL; + gui = NULL; + session = CONSOLE_KIT_SESSION (o); + console_kit_session_call_get_x11_display_finish (session, &gui, res, &err); + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } + else + { + gboolean is_gui_session; + + is_gui_session = gui && *gui; + + if (!is_gui_session) + g_clear_object (&session); + else + console_kit_session_call_get_unix_user (session, + p->cancellable, + on_session_proxy_uid_ready, + gself); + + g_free (gui); + } +} + +static void +on_session_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) +{ + GError * err; + ConsoleKitSession * session; + + err = NULL; + session = console_kit_session_proxy_new_finish (res, &err); + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } + else if (session != NULL) + { + priv_t * p = INDICATOR_SESSION_USERS_DBUS(gself)->priv; + + console_kit_session_call_get_x11_display (session, + p->cancellable, + on_session_x11_display_ready, + gself); + } +} + +static void +create_session_proxy_for_ssid (IndicatorSessionUsersDbus * self, + const char * ssid) +{ + const char * name = "org.freedesktop.ConsoleKit"; + GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES; + + console_kit_session_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + flags, name, ssid, + self->priv->cancellable, + on_session_proxy_ready, self); +} + +static void +on_session_list_ready (GObject * o, GAsyncResult * res, gpointer gself) +{ + GError * err; + gchar ** sessions; + + err = NULL; + sessions = NULL; + console_kit_seat_call_get_sessions_finish (CONSOLE_KIT_SEAT(o), + &sessions, res, &err); + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } + else + { + int i; + + for (i=0; sessions && sessions[i]; i++) + create_session_proxy_for_ssid (gself, sessions[i]); + + g_strfreev (sessions); + } +} + +static inline guint +get_uid_for_session (IndicatorSessionUsersDbus * self, const char * ssid) +{ + guint uid = 0; + gpointer value; + + if (ssid != NULL) + if ((value = g_hash_table_lookup (self->priv->session_to_uid, ssid))) + uid = GPOINTER_TO_UINT (value); + + return uid; +} + +/* it's a live session if username is 'ubuntu' and uid is 999 */ +static gboolean +is_live_ssid (IndicatorSessionUsersDbus * self, const char * ssid) +{ + priv_t * p; + guint uid; + + p = INDICATOR_SESSION_USERS_DBUS (self)->priv; + uid = get_uid_for_session (self, ssid); + + if (uid == 999) + { + const char * path; + AccountsUser * user = NULL; + + if ((path = g_hash_table_lookup (p->uid_to_user_path, GUINT_TO_POINTER (uid)))) + user = g_hash_table_lookup (p->path_to_user, path); + + return (user != NULL) && !g_strcmp0 (accounts_user_get_user_name(user), "ubuntu"); + } + + return FALSE; +} + + +static void +set_active_session (IndicatorSessionUsersDbus * self, const char * ssid) +{ + priv_t * p = self->priv; + const guint old_uid = get_uid_for_session (self, p->active_session_id); + const guint new_uid = get_uid_for_session (self, ssid); + const gboolean old_live = is_live_ssid (self, p->active_session_id); + const gboolean new_live = is_live_ssid (self, ssid); + + g_debug ("%s %s changing active_session_id from '%s' to '%s'", + G_STRLOC, G_STRFUNC, p->active_session_id, ssid); + g_free (p->active_session_id); + p->active_session_id = g_strdup (ssid); + + if (old_uid != new_uid) + { + emit_user_changed_for_uid (self, old_uid); + emit_user_changed_for_uid (self, new_uid); + } + + if (old_live != new_live) + { + indicator_session_users_notify_is_live_session (INDICATOR_SESSION_USERS(self)); + } +} + +static void +on_seat_active_session_ready (GObject * o, GAsyncResult * res, gpointer gself) +{ + GError * err; + gchar * ssid; + ConsoleKitSeat * seat; + + err = NULL; + ssid = NULL; + seat = CONSOLE_KIT_SEAT (o); + console_kit_seat_call_get_active_session_finish (seat, &ssid, res, &err); + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } + else if (ssid != NULL) + { + set_active_session (INDICATOR_SESSION_USERS_DBUS(gself), ssid); + g_free (ssid); + } +} + +static void +set_seat (IndicatorSessionUsersDbus * self, ConsoleKitSeat * seat) +{ + priv_t * p = self->priv; + + if (p->seat_proxy != NULL) + { + g_signal_handlers_disconnect_by_data (p->seat_proxy, self); + g_clear_object (&p->seat_proxy); + } + + if (seat != NULL) + { + p->seat_proxy = g_object_ref (seat); + + /* ask the seat for a list of all the sessions */ + console_kit_seat_call_get_sessions (seat, + p->cancellable, + on_session_list_ready, + self); + + /* ask the seat for the name of the active session */ + console_kit_seat_call_get_active_session (p->seat_proxy, + p->cancellable, + on_seat_active_session_ready, + self); + + /* listen for session changes in this seat */ + g_signal_connect_swapped (seat, "session-added", + G_CALLBACK(create_session_proxy_for_ssid),self); + g_signal_connect_swapped (seat, "session-removed", + G_CALLBACK(untrack_session), self); + g_signal_connect_swapped (seat, "active-session-changed", + G_CALLBACK(set_active_session), self); + } +} + +/*** +**** +***/ + +static void +set_dm_seat (IndicatorSessionUsersDbus * self, DisplayManagerSeat * dm_seat) +{ + priv_t * p = self->priv; + + g_clear_object (&p->dm_seat); + + if (dm_seat != NULL) + p->dm_seat = g_object_ref (dm_seat); +} + +static void +activate_username (IndicatorSessionUsersDbus * self, const char * username) +{ + priv_t * p = self->priv; + const char * session = ""; + + g_return_if_fail (p->dm_seat != NULL); + + display_manager_seat_call_switch_to_user (p->dm_seat, username, session, + p->cancellable, NULL, NULL); +} + +/*** +**** +***/ + +static void +my_dispose (GObject * o) +{ + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (o); + priv_t * p = self->priv; + + if (p->cancellable) + { + g_cancellable_cancel (p->cancellable); + g_clear_object (&p->cancellable); + } + + set_seat (self, NULL); + set_dm_seat (self, NULL); + set_account_manager (self, NULL); + + g_clear_pointer (&p->path_to_user, g_hash_table_destroy); + g_clear_pointer (&p->session_to_uid, g_hash_table_destroy); + g_clear_pointer (&p->uid_to_sessions, g_hash_table_destroy); + g_clear_pointer (&p->uid_to_user_path, g_hash_table_destroy); + + G_OBJECT_CLASS (indicator_session_users_dbus_parent_class)->dispose (o); +} + +static void +my_finalize (GObject * o) +{ + IndicatorSessionUsersDbus * u = INDICATOR_SESSION_USERS_DBUS (o); + + g_free (u->priv->active_session_id); + + G_OBJECT_CLASS (indicator_session_users_dbus_parent_class)->finalize (o); +} + +static void +my_activate_user (IndicatorSessionUsers * users, const char * key) +{ + priv_t * p; + const char * username = 0; + + p = INDICATOR_SESSION_USERS_DBUS (users)->priv; + if (p != 0) + { + AccountsUser * au = g_hash_table_lookup (p->path_to_user, key); + + if (au != NULL) + username = accounts_user_get_user_name (au); + } + + if (username != 0) + activate_username (INDICATOR_SESSION_USERS_DBUS(users), username); + else + g_warning ("%s %s can't find user for '%s'", G_STRLOC, G_STRFUNC, key); +} + +static gboolean +my_is_live_session (IndicatorSessionUsers * users) +{ + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS(users); + + return is_live_ssid (self, self->priv->active_session_id); +} + +static GStrv +my_get_keys (IndicatorSessionUsers * users) +{ + int i; + priv_t * p; + gchar ** keys; + GHashTableIter iter; + gpointer path; + gpointer user; + + g_return_val_if_fail (INDICATOR_IS_SESSION_USERS_DBUS(users), NULL); + p = INDICATOR_SESSION_USERS_DBUS (users)->priv; + + i = 0; + keys = g_new (gchar*, g_hash_table_size(p->path_to_user)+1); + g_hash_table_iter_init (&iter, p->path_to_user); + while (g_hash_table_iter_next (&iter, &path, &user)) + if (!accounts_user_get_system_account (user)) + keys[i++] = g_strdup (path); + keys[i] = NULL; + + return keys; +} + +static IndicatorSessionUser * +my_get_user (IndicatorSessionUsers * users, const gchar * key) +{ + priv_t * p; + AccountsUser * au; + IndicatorSessionUser * ret = NULL; + + p = INDICATOR_SESSION_USERS_DBUS (users)->priv; + + au = g_hash_table_lookup (p->path_to_user, key); + if (au && !accounts_user_get_system_account(au)) + { + const guint uid = (guint) accounts_user_get_uid (au); + GHashTable * s; + + ret = g_new0 (IndicatorSessionUser, 1); + + s = g_hash_table_lookup (p->uid_to_sessions, GUINT_TO_POINTER(uid)); + if (s == NULL) + { + ret->is_logged_in = FALSE; + ret->is_current_user = FALSE; + } + else + { + ret->is_logged_in = g_hash_table_size (s) > 0; + ret->is_current_user = g_hash_table_contains (s, p->active_session_id); + } + + ret->uid = uid; + ret->user_name = g_strdup (accounts_user_get_user_name (au)); + ret->real_name = g_strdup (accounts_user_get_real_name (au)); + ret->icon_file = g_strdup (accounts_user_get_icon_file (au)); + ret->login_frequency = accounts_user_get_login_frequency (au); + } + + return ret; +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_users_dbus_class_init (IndicatorSessionUsersDbusClass * klass) +{ + GObjectClass * object_class; + IndicatorSessionUsersClass * users_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->dispose = my_dispose; + object_class->finalize = my_finalize; + + users_class = INDICATOR_SESSION_USERS_CLASS (klass); + users_class->is_live_session = my_is_live_session; + users_class->get_keys = my_get_keys; + users_class->get_user = my_get_user; + users_class->activate_user = my_activate_user; + + g_type_class_add_private (klass, sizeof (IndicatorSessionUsersDbusPriv)); +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_users_dbus_init (IndicatorSessionUsersDbus * self) +{ + priv_t * p; + + p = G_TYPE_INSTANCE_GET_PRIVATE (self, + INDICATOR_TYPE_SESSION_USERS_DBUS, + IndicatorSessionUsersDbusPriv); + self->priv = p; + p->cancellable = g_cancellable_new (); + + p->path_to_user = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, g_object_unref); + + p->uid_to_user_path = g_hash_table_new_full (g_direct_hash, g_direct_equal, + NULL, g_free); + + p->session_to_uid = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, NULL); + + p->uid_to_sessions = g_hash_table_new_full (g_direct_hash, g_direct_equal, + NULL, + (GDestroyNotify)g_hash_table_destroy); + +#if 0 + console_kit_manager_proxy_new_for_bus ( + G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.ConsoleKit", + "/org/freedesktop/ConsoleKit/Manager", + p->cancellable, + on_console_kit_manager_proxy_ready, + self); +#endif +} + +/*** +**** Public +***/ + +IndicatorSessionUsers * +indicator_session_users_dbus_new (void) +{ + gpointer o = g_object_new (INDICATOR_TYPE_SESSION_USERS_DBUS, NULL); + + return INDICATOR_SESSION_USERS (o); +} + +void +indicator_session_users_dbus_set_proxies (IndicatorSessionUsersDbus * self, + Accounts * accounts, + DisplayManagerSeat * dm_seat, + ConsoleKitSeat * seat) +{ + g_return_if_fail (INDICATOR_IS_SESSION_USERS_DBUS (self)); + + set_account_manager (self, accounts); + set_seat (self, seat); + set_dm_seat (self, dm_seat); +} diff --git a/src/backend-dbus/users.h b/src/backend-dbus/users.h new file mode 100644 index 0000000..ff1e0ad --- /dev/null +++ b/src/backend-dbus/users.h @@ -0,0 +1,71 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef __USERS_DBUS_H__ +#define __USERS_DBUS_H__ + +#include +#include + +#include "../users.h" /* parent class */ +#include "dbus-accounts.h" +#include "dbus-consolekit-seat.h" +#include "dbus-display-manager.h" + +G_BEGIN_DECLS + +#define INDICATOR_TYPE_SESSION_USERS_DBUS (indicator_session_users_dbus_get_type()) +#define INDICATOR_SESSION_USERS_DBUS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_SESSION_USERS_DBUS, IndicatorSessionUsersDbus)) +#define INDICATOR_SESSION_USERS_DBUS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_TYPE_SESSION_USERS_DBUS, IndicatorSessionUsersDbusClass)) +#define INDICATOR_IS_SESSION_USERS_DBUS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_SESSION_USERS_DBUS)) + +typedef struct _IndicatorSessionUsersDbus IndicatorSessionUsersDbus; +typedef struct _IndicatorSessionUsersDbusPriv IndicatorSessionUsersDbusPriv; +typedef struct _IndicatorSessionUsersDbusClass IndicatorSessionUsersDbusClass; + +/** + * An implementation of IndicatorSessionUsers that gets its user information + * from org.freedesktop.ConsoleKit and org.freedesktop.Accounts over DBus. + */ +struct _IndicatorSessionUsersDbus +{ + /*< private >*/ + IndicatorSessionUsers parent; + IndicatorSessionUsersDbusPriv * priv; +}; + +struct _IndicatorSessionUsersDbusClass +{ + IndicatorSessionUsersClass parent_class; +}; + +GType indicator_session_users_dbus_get_type (void); + +IndicatorSessionUsers * indicator_session_users_dbus_new (void); + +void indicator_session_users_dbus_set_proxies (IndicatorSessionUsersDbus *, + Accounts *, + DisplayManagerSeat *, + ConsoleKitSeat *); + + + +G_END_DECLS + +#endif diff --git a/src/backend-dbus/utils.c b/src/backend-dbus/utils.c new file mode 100644 index 0000000..86a5e5a --- /dev/null +++ b/src/backend-dbus/utils.c @@ -0,0 +1,399 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include "utils.h" + +/*** +**** indicator_session_util_get_session_proxies() +***/ + +struct session_proxy_data +{ + ConsoleKitManager * ck_manager; + Accounts * account_manager; + DisplayManagerSeat * dm_seat; + + ConsoleKitSeat * current_seat; + ConsoleKitSession * current_session; + AccountsUser * active_user; + + GCancellable * cancellable; + GError * error; + int pending; + + indicator_session_util_session_proxies_func callback; + gpointer user_data; +}; + +static void +session_proxy_data_free (struct session_proxy_data * data) +{ + g_clear_object (&data->ck_manager); + g_clear_object (&data->account_manager); + g_clear_object (&data->dm_seat); + + g_clear_object (&data->current_seat); + g_clear_object (&data->current_session); + g_clear_object (&data->active_user); + + g_clear_object (&data->cancellable); + g_clear_error (&data->error); + + g_free (data); +} + +static void +finish_callback (struct session_proxy_data * data) +{ + g_assert (data != NULL); + g_debug ("%s %s: pending is %d", G_STRLOC, G_STRFUNC, (data->pending-1)); + + if (!--data->pending) + { + data->callback (data->ck_manager, + data->account_manager, + data->dm_seat, + data->current_seat, + data->current_session, + data->active_user, + data->error, + data->user_data); + + session_proxy_data_free (data); + } +} + +static void +on_user_proxy_ready (GObject * o G_GNUC_UNUSED, + GAsyncResult * res, + gpointer gdata) +{ + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + data->active_user = accounts_user_proxy_new_for_bus_finish (res, &data->error); + + if (data->error != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + else + { + g_debug ("%s %s user proxy is %p", G_STRLOC, G_STRFUNC, (void*)data->active_user); + } + + finish_callback (data); +} + +static void +on_user_path_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +{ + char * path = NULL; + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + accounts_call_find_user_by_id_finish (data->account_manager, &path, res, &data->error); + + if (data->error != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + else if (path != NULL) + { + g_debug ("%s %s user path is %s", G_STRLOC, G_STRFUNC, path); + ++data->pending; + accounts_user_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.Accounts", + path, + data->cancellable, + on_user_proxy_ready, + data); + } + + finish_callback (data); + g_free (path); +} + +static void +on_uid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +{ + guint uid = 0; + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + console_kit_session_call_get_unix_user_finish (data->current_session, &uid, res, &data->error); + if (data->error != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + else if (uid) + { + g_debug ("%s %s uid is %u", G_STRLOC, G_STRFUNC, uid); + ++data->pending; + accounts_call_find_user_by_id (data->account_manager, + uid, + data->cancellable, + on_user_path_ready, + data); + } + + finish_callback (data); +} + +static void +on_seat_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +{ + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + data->current_seat = console_kit_seat_proxy_new_for_bus_finish (res, &data->error); + + if (data->error != NULL) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + + finish_callback (data); +} + +static void +on_sid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +{ + char * sid = NULL; + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + console_kit_session_call_get_seat_id_finish (data->current_session, &sid, res, &data->error); + + if (data->error != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + else if (sid != NULL) + { + g_debug ("%s %s sid is %s", G_STRLOC, G_STRFUNC, sid); + ++data->pending; + console_kit_seat_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.ConsoleKit", + sid, + data->cancellable, + on_seat_proxy_ready, + data); + } + + finish_callback (data); + g_free (sid); +} + +static void +on_session_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +{ + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + data->current_session = console_kit_session_proxy_new_finish (res, &data->error); + if (data->error != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + else + { + ++data->pending; + console_kit_session_call_get_seat_id (data->current_session, + data->cancellable, + on_sid_ready, + data); + + ++data->pending; + console_kit_session_call_get_unix_user (data->current_session, + data->cancellable, + on_uid_ready, + data); + } + + finish_callback (data); +} + +static void +on_current_session_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +{ + char * ssid = NULL; + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + ssid = NULL; + console_kit_manager_call_get_current_session_finish (data->ck_manager, + &ssid, res, + &data->error); + if (data->error != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + else if (ssid) + { + g_debug ("%s %s ssid is %s", G_STRLOC, G_STRFUNC, ssid); + data->pending++; + console_kit_session_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.ConsoleKit", + ssid, + data->cancellable, + on_session_proxy_ready, + data); + + } + + finish_callback (data); + g_free (ssid); +} + +static void +on_display_manager_seat_proxy_ready (GObject * o G_GNUC_UNUSED, + GAsyncResult * res, + gpointer gdata) +{ + DisplayManagerSeat * seat; + struct session_proxy_data * data = gdata; + + seat = display_manager_seat_proxy_new_for_bus_finish (res, &data->error); + + if (data->error != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + else if (seat != NULL) + { + data->dm_seat = g_object_ref (seat); + } + + finish_callback (data); + g_clear_object (&seat); +} + +static void +on_console_kit_manager_proxy_ready (GObject * o G_GNUC_UNUSED, + GAsyncResult * res, + gpointer gdata) +{ + ConsoleKitManager * mgr; + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + if (data->error == NULL) + { + mgr = console_kit_manager_proxy_new_for_bus_finish (res, &data->error); + g_debug ("%s %s mgr is %p, err is %p", G_STRLOC, G_STRFUNC, (void*)mgr, (void*)data->error); + + if (data->error != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + else + { + data->ck_manager = mgr; + + data->pending++; + console_kit_manager_call_get_current_session (mgr, + data->cancellable, + on_current_session_ready, + data); + + } + } + + finish_callback (data); +} + +static void +on_accounts_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +{ + struct session_proxy_data * data = gdata; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + if (data->error == NULL) + { + data->account_manager = accounts_proxy_new_for_bus_finish (res, &data->error); + + if (data->error != NULL) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + } + + finish_callback (data); +} + +/** + * Getting all the proxies we want is kind of a pain -- + * especially without blocking (ie, using _sync() funcs) -- + * so it's farmed out to this wrapper utility. + * + * 1. in this func, start getting the ConsoleKit and Accounts proxies + * 2. when the accounts proxy is ready, stash it in data.account_manager + * 3. when the ck manager proxy is ready, stash it in data.ck_manager and + * ask it for the current session's ssid + * 4. when the ssid is ready, start getting a proxy for it + * 5. when the session's proxy is ready, stash it in data.current_session + * and ask it for both the current seat's sid and the active user's uid + * 6. When the current seat's sid is ready, start getting a proxy for it + * 7. When the current seat's proxy is ready, stash it in data.current_seat + * 8. when the active user's uid is ready, ask data.account_manager for the path + * 9. when the user path is ready, start getting an Accounts.User proxy for it + * 10. when the Accounts.User proxy is read, stash it in data.active_user + * + * When everything is done, or if there's an error, invoke the data.callback + */ +void +indicator_session_util_get_session_proxies ( + indicator_session_util_session_proxies_func func, + GCancellable * cancellable, + gpointer user_data) +{ + struct session_proxy_data * data; + + data = g_new0 (struct session_proxy_data, 1); + data->callback = func; + data->user_data = user_data; + data->cancellable = g_object_ref (cancellable); + + data->pending++; + accounts_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.Accounts", + "/org/freedesktop/Accounts", + data->cancellable, + on_accounts_proxy_ready, data); + + data->pending++; + console_kit_manager_proxy_new_for_bus ( + G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.ConsoleKit", + "/org/freedesktop/ConsoleKit/Manager", + data->cancellable, + on_console_kit_manager_proxy_ready, data); + + data->pending++; + display_manager_seat_proxy_new_for_bus ( + G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.DisplayManager", + g_getenv ("XDG_SEAT_PATH"), + data->cancellable, + on_display_manager_seat_proxy_ready, data); + +} diff --git a/src/backend-dbus/utils.h b/src/backend-dbus/utils.h new file mode 100644 index 0000000..b4f26c3 --- /dev/null +++ b/src/backend-dbus/utils.h @@ -0,0 +1,53 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef __DBUS_UTILS_H__ +#define __DBUS_UTILS_H__ + +#include +#include + +#include "dbus-accounts.h" +#include "dbus-display-manager.h" +#include "dbus-user.h" +#include "dbus-consolekit-seat.h" +#include "dbus-consolekit-session.h" +#include "dbus-consolekit-manager.h" + +typedef void (*indicator_session_util_session_proxies_func)( + ConsoleKitManager * ck_manager, + Accounts * account_manager, + DisplayManagerSeat * dm_seat, + ConsoleKitSeat * current_ck_seat, + ConsoleKitSession * current_ck_session, + AccountsUser * active_user, + const GError * error, + gpointer user_data); + +/** + * Both users-dbus and guest-dbus need some of these proxies. + * Getting them all involves a lot of steps, so instead of repeating + * ourselves, the common dbus steps are extracted to this func. + */ +void indicator_session_util_get_session_proxies ( + indicator_session_util_session_proxies_func func, + GCancellable * cancellable, + gpointer user_data); + +#endif diff --git a/src/backend.h b/src/backend.h new file mode 100644 index 0000000..2df215d --- /dev/null +++ b/src/backend.h @@ -0,0 +1,47 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef __INDICATOR_SESSION_BACKEND_H__ +#define __INDICATOR_SESSION_BACKEND_H__ + +#include /* GCancellable */ + +#include "actions.h" +#include "guest.h" +#include "users.h" + +G_BEGIN_DECLS + +/** + * Gets instances of the backend abstract base classes. + * These are how IndicatorSystemService knows what's happening on the system. + * + * This function isn't defined in libindicatorsessionservice. + * Instead, one of two implementations is statically linked at build time: + * one for production in libbackenddbus (in src/backend-dbus/) or + * one for testing in libbackendmock (in tests/). + */ +void backend_get (GCancellable * cancellable, + IndicatorSessionActions ** setme_actions, + IndicatorSessionUsers ** setme_users, + IndicatorSessionGuest ** setme_guest); + +G_END_DECLS + +#endif diff --git a/src/dialog.c b/src/dialog.c deleted file mode 100644 index eb91f57..0000000 --- a/src/dialog.c +++ /dev/null @@ -1,248 +0,0 @@ -/* -A dialog to ask the user about the various logout options that -are available. - -Copyright 2010 Canonical Ltd. - -Authors: - Ted Gould - -This program 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. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "dbus-consolekit-manager.h" -#include "dialog.h" - -/* Strings */ - -static const gchar * title_strings[LOGOUT_DIALOG_TYPE_CNT] = { - /* LOGOUT_DIALOG_LOGOUT, */ NC_("title", "Log Out"), - /* LOGOUT_DIALOG_RESTART, */ NC_("title", "Restart"), - /* LOGOUT_DIALOG_SHUTDOWN, */ NC_("title", "Shut Down") -}; - -static const gchar * body_strings[LOGOUT_DIALOG_TYPE_CNT] = { - /* LOGOUT_DIALOG_LOGOUT, */ N_("Are you sure you want to close all programs and log out of the computer?"), - /* LOGOUT_DIALOG_RESTART, */ N_("Are you sure you want to close all programs and restart the computer?"), - /* LOGOUT_DIALOG_SHUTDOWN, */ N_("Are you sure you want to close all programs and shut down the computer?") -}; - -static const gchar * button_strings[LOGOUT_DIALOG_TYPE_CNT] = { - /* LOGOUT_DIALOG_LOGOUT, */ NC_("button", "Log Out"), - /* LOGOUT_DIALOG_RESTART, */ NC_("button", "Restart"), - /* LOGOUT_DIALOG_SHUTDOWN, */ NC_("button", "Shut Down") -}; - -/* TRANSLATORS: These strings have an ellipsis so that the user knows - they are also going to get a password dialog to do the action. */ -static const gchar * button_auth_strings[LOGOUT_DIALOG_TYPE_CNT] = { - /* LOGOUT_DIALOG_LOGOUT, */ NC_("button auth", "Log Out"), - /* LOGOUT_DIALOG_RESTART, */ NC_("button auth", "Restart…"), - /* LOGOUT_DIALOG_SHUTDOWN, */ NC_("button auth", "Shut Down…") -}; - -/* TRANSLATORS: This button appears on the logout dialog when - there are updates that require restart. It will do a restart - in place of a log out. */ -static const gchar * restart_updates = N_("Restart Instead"); -static const gchar * restart_auth = N_("Restart Instead…"); -static const gchar * body_logout_update = N_("Some software updates won’t apply until the computer next restarts."); - -static const gchar * icon_strings[LOGOUT_DIALOG_TYPE_CNT] = { - /* LOGOUT_DIALOG_LOGOUT, */ "system-log-out", - /* LOGOUT_DIALOG_RESTART, */ "system-restart", - /* LOGOUT_DIALOG_SHUTDOWN, */ "system-shutdown" -}; - - - -typedef struct _LogoutDialogPrivate LogoutDialogPrivate; -struct _LogoutDialogPrivate { - guint type; -}; - -#define LOGOUT_DIALOG_GET_PRIVATE(o) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((o), LOGOUT_DIALOG_TYPE, LogoutDialogPrivate)) - -static void logout_dialog_class_init (LogoutDialogClass *klass); -static void logout_dialog_init (LogoutDialog *self); -static void logout_dialog_dispose (GObject *object); -static void logout_dialog_finalize (GObject *object); - -G_DEFINE_TYPE (LogoutDialog, logout_dialog, GTK_TYPE_MESSAGE_DIALOG); - -static void -logout_dialog_class_init (LogoutDialogClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (LogoutDialogPrivate)); - - object_class->dispose = logout_dialog_dispose; - object_class->finalize = logout_dialog_finalize; - - return; -} - -static void -logout_dialog_init (LogoutDialog *self) -{ - - return; -} - -static void -logout_dialog_dispose (GObject *object) -{ - - - G_OBJECT_CLASS (logout_dialog_parent_class)->dispose (object); - return; -} - -static void -logout_dialog_finalize (GObject *object) -{ - - - G_OBJECT_CLASS (logout_dialog_parent_class)->finalize (object); - return; -} - -/* Checks for updates that would signal that a restart is - required for them to apply */ -static gboolean -check_restart_required (void) -{ - return g_file_test("/var/run/reboot-required", G_FILE_TEST_EXISTS); -} - -/* Checks with console kit to see if we can do what we want */ -static gboolean -ck_check_allowed (LogoutDialogType type) -{ - gboolean allowed = TRUE; - - ConsoleKitManager * ck_proxy = console_kit_manager_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - "org.freedesktop.ConsoleKit", - "/org/freedesktop/ConsoleKit/Manager", - NULL, - NULL); - if (ck_proxy != NULL) - { - switch (type) { - case LOGOUT_DIALOG_TYPE_RESTART: - console_kit_manager_call_can_restart_sync (ck_proxy, &allowed, NULL, NULL); - break; - case LOGOUT_DIALOG_TYPE_SHUTDOWN: - console_kit_manager_call_can_stop_sync (ck_proxy, &allowed, NULL, NULL); - break; - default: - break; - } - - g_object_unref(ck_proxy); - } - - return allowed; -} - -LogoutDialog * -logout_dialog_new (LogoutDialogType type) -{ - GtkWidget * image = gtk_image_new_from_icon_name(icon_strings[type], GTK_ICON_SIZE_DIALOG); - gtk_widget_show(image); - - LogoutDialog * dialog = LOGOUT_DIALOG(g_object_new(LOGOUT_DIALOG_TYPE, - /* Window */ - "icon-name", icon_strings[type], - "modal", TRUE, - "resizable", FALSE, - "title", g_dpgettext2 (NULL, "title", title_strings[type]), - "window-position", GTK_WIN_POS_CENTER_ALWAYS, - /* Message Dialog */ - "buttons", GTK_BUTTONS_NONE, - "image", image, - "message-type", GTK_MESSAGE_OTHER, - "text", _(body_strings[type]), - NULL)); - - gtk_window_set_keep_above(GTK_WINDOW(dialog), TRUE); - - gboolean allowed = FALSE; - if (type == LOGOUT_DIALOG_TYPE_LOG_OUT) { - allowed = ck_check_allowed(LOGOUT_DIALOG_TYPE_RESTART); - } else { - allowed = ck_check_allowed(type); - } - - gboolean restart_required = FALSE; - if (type == LOGOUT_DIALOG_TYPE_LOG_OUT) { - restart_required = check_restart_required(); - } - - const gchar * button_text; - if (allowed) { - button_text = g_dpgettext2 (NULL, "button", button_strings[type]); - } else { - button_text = g_dpgettext2 (NULL, "button auth", button_auth_strings[type]); - } - - if (restart_required) { - const gchar * restart_req; - if (allowed) { - restart_req = restart_updates; - } else { - restart_req = restart_auth; - } - - g_object_set(dialog, "secondary-text", _(body_logout_update), NULL); - - gtk_dialog_add_buttons(GTK_DIALOG(dialog), - _(restart_req), GTK_RESPONSE_HELP, - _("Cancel"), GTK_RESPONSE_CANCEL, - button_text, GTK_RESPONSE_OK, - NULL); - } else { - gtk_dialog_add_buttons(GTK_DIALOG(dialog), - _("Cancel"), GTK_RESPONSE_CANCEL, - button_text, GTK_RESPONSE_OK, - NULL); - } - - gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_OK); - - /* The following is a workaround to fix an issue in GtkMessageDialog - in which the user can tab through the text in addition to - the buttons. */ - GtkWidget *message_area = gtk_message_dialog_get_message_area(GTK_MESSAGE_DIALOG(dialog)); - GList *children = gtk_container_get_children(GTK_CONTAINER(message_area)); - GList *l; - - for (l = children; l != NULL; l = g_list_next (l)) - { - GtkWidget *child = l->data; - gtk_widget_set_can_focus(child, FALSE); - } - - g_list_free (children); - - return dialog; -} diff --git a/src/dialog.h b/src/dialog.h deleted file mode 100644 index 18a55a7..0000000 --- a/src/dialog.h +++ /dev/null @@ -1,64 +0,0 @@ -/* -A dialog to ask the user about the various logout options that -are available. - -Copyright 2010 Canonical Ltd. - -Authors: - Ted Gould - -This program 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. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . -*/ - -#ifndef __LOGOUT_DIALOG_H__ -#define __LOGOUT_DIALOG_H__ - -#include -#include - -#include - -G_BEGIN_DECLS - -#define LOGOUT_DIALOG_TYPE (logout_dialog_get_type ()) -#define LOGOUT_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), LOGOUT_DIALOG_TYPE, LogoutDialog)) -#define LOGOUT_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), LOGOUT_DIALOG_TYPE, LogoutDialogClass)) -#define IS_LOGOUT_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), LOGOUT_DIALOG_TYPE)) -#define IS_LOGOUT_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LOGOUT_DIALOG_TYPE)) -#define LOGOUT_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), LOGOUT_DIALOG_TYPE, LogoutDialogClass)) - -typedef enum _LogoutDialogType LogoutDialogType; -enum _LogoutDialogType { - LOGOUT_DIALOG_TYPE_LOG_OUT, - LOGOUT_DIALOG_TYPE_RESTART, - LOGOUT_DIALOG_TYPE_SHUTDOWN, - LOGOUT_DIALOG_TYPE_CNT -}; - -typedef struct _LogoutDialog LogoutDialog; -typedef struct _LogoutDialogClass LogoutDialogClass; - -struct _LogoutDialogClass { - GtkMessageDialogClass parent_class; -}; - -struct _LogoutDialog { - GtkMessageDialog parent; -}; - -GType logout_dialog_get_type (void); -LogoutDialog * logout_dialog_new (LogoutDialogType type); - -G_END_DECLS - -#endif diff --git a/src/display-manager.xml b/src/display-manager.xml deleted file mode 100644 index 07b5f29..0000000 --- a/src/display-manager.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gtk-logout-helper.c b/src/gtk-logout-helper.c deleted file mode 100644 index 55db630..0000000 --- a/src/gtk-logout-helper.c +++ /dev/null @@ -1,266 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould - Christoph Korn - -This program 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. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . -*/ - -#include "config.h" - -#include -#include -#include /* textdomain(), bindtextdomain() */ -#include -#include "dialog.h" -#include "shared-names.h" - -static GVariant * -call_console_kit (const gchar *method, GVariant *parameters, GError **error) -{ - GDBusConnection * bus = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, error); - if (!bus) - { - g_variant_unref (parameters); - return NULL; - } - - GVariant *result = g_dbus_connection_call_sync(bus, - "org.freedesktop.ConsoleKit", - "/org/freedesktop/ConsoleKit/Manager", - "org.freedesktop.ConsoleKit.Manager", - method, - parameters, - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - error); - g_object_unref (bus); - - return result; -} - -static void -consolekit_fallback (LogoutDialogType action) -{ - GError * error = NULL; - GVariant *result = NULL; - - g_debug("Falling back to using ConsoleKit for action"); - - switch (action) { - case LOGOUT_DIALOG_TYPE_LOG_OUT: - g_warning("Unable to fallback to ConsoleKit for logout as it's a session issue. We need some sort of session handler."); - break; - case LOGOUT_DIALOG_TYPE_SHUTDOWN: - g_debug("Telling ConsoleKit to 'Stop'"); - result = call_console_kit ("Stop", g_variant_new ("()"), &error); - break; - case LOGOUT_DIALOG_TYPE_RESTART: - g_debug("Telling ConsoleKit to 'Restart'"); - result = call_console_kit ("Restart", g_variant_new ("()"), &error); - break; - default: - g_warning("Unknown action"); - break; - } - - if (!result) { - if (error != NULL) { - g_warning ("ConsoleKit action failed: %s", error->message); - } else { - g_warning ("ConsoleKit action failed: unknown error"); - } - - consolekit_fallback(action); - } - else - g_variant_unref (result); - g_clear_error (&error); - - return; -} - -static GVariant * -call_gnome_session (const gchar *method, GVariant *parameters, GError **error) -{ - GDBusConnection * bus = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, error); - if (!bus) - { - g_variant_unref (parameters); - return NULL; - } - - GVariant *result = g_dbus_connection_call_sync(bus, - "org.gnome.SessionManager", - "/org/gnome/SessionManager", - "org.gnome.SessionManager", - method, - parameters, - NULL, - G_DBUS_CALL_FLAGS_NONE, - G_MAXINT, - NULL, - error); - g_object_unref (bus); - - return result; -} - -static void -session_action (LogoutDialogType action) -{ - GError * error = NULL; - GVariant *result = NULL; - - if (action == LOGOUT_DIALOG_TYPE_LOG_OUT) { - g_debug("Asking Session manager to 'Logout'"); - result = call_gnome_session ("Logout", g_variant_new ("(u)", 1), &error); - } else if (action == LOGOUT_DIALOG_TYPE_SHUTDOWN) { - g_debug("Asking Session manager to 'RequestShutdown'"); - result = call_gnome_session ("RequestShutdown", g_variant_new ("()"), &error); - } else if (action == LOGOUT_DIALOG_TYPE_RESTART) { - g_debug("Asking Session manager to 'RequestReboot'"); - result = call_gnome_session ("RequestReboot", g_variant_new ("()"), &error); - } else { - g_warning ("Unknown session action"); - } - - if (!result) { - if (error != NULL) { - g_warning ("SessionManager action failed: %s", error->message); - } else { - g_warning ("SessionManager action failed: unknown error"); - } - - consolekit_fallback(action); - } - else - g_variant_unref (result); - g_clear_error (&error); - - return; -} - -static LogoutDialogType type = LOGOUT_DIALOG_TYPE_LOG_OUT; - -static gboolean -option_logout (const gchar * arg, const gchar * value, gpointer data, GError * error) -{ - type = LOGOUT_DIALOG_TYPE_LOG_OUT; - g_debug("Dialog type: logout"); - return TRUE; -} - -static gboolean -option_shutdown (const gchar * arg, const gchar * value, gpointer data, GError * error) -{ - type = LOGOUT_DIALOG_TYPE_SHUTDOWN; - g_debug("Dialog type: shutdown"); - return TRUE; -} - -static gboolean -option_restart (const gchar * arg, const gchar * value, gpointer data, GError * error) -{ - type = LOGOUT_DIALOG_TYPE_RESTART; - g_debug("Dialog type: restart"); - return TRUE; -} - -static GOptionEntry options[] = { - {"logout", 'l', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, option_logout, "Log out of the current session", NULL}, - {"shutdown", 's', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, option_shutdown, "Switch off the entire system", NULL}, - {"restart", 'r', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK, option_restart, "Restart the system", NULL}, - - {NULL} -}; - -static gboolean -suppress_confirmations (void) -{ - GSettings * s = g_settings_new (SESSION_SCHEMA); - const gboolean suppress = g_settings_get_boolean (s, SUPPRESS_KEY); - g_clear_object (&s); - return suppress; -} - - - -int -main (int argc, char * argv[]) -{ - gtk_init(&argc, &argv); - - /* Setting up i18n and gettext. Apparently, we need - all of these. */ - setlocale (LC_ALL, ""); - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - textdomain (GETTEXT_PACKAGE); - - GError * error = NULL; - GOptionContext * context = g_option_context_new(" - logout of the current session"); - g_option_context_add_main_entries(context, options, "gtk-logout-helper"); - g_option_context_add_group(context, gtk_get_option_group(TRUE)); - g_option_context_set_help_enabled(context, TRUE); - - if (!g_option_context_parse(context, &argc, &argv, &error)) { - g_debug("Option parsing failed: %s", error->message); - g_error_free(error); - return 1; - } - - /* Init some theme/icon stuff */ - gtk_icon_theme_append_search_path(gtk_icon_theme_get_default(), - INDICATOR_ICONS_DIR); - - GtkWidget * dialog = NULL; - if (!suppress_confirmations()) { - g_debug("Showing dialog to ask for user confirmation"); - dialog = GTK_WIDGET(logout_dialog_new(type)); - } - - if (dialog != NULL) { - GtkResponseType response = gtk_dialog_run(GTK_DIALOG(dialog)); - gtk_widget_hide(dialog); - - if (response == GTK_RESPONSE_OK) { - g_debug("Dialog return response: 'okay'"); - } else if (response == GTK_RESPONSE_HELP) { - g_debug("Dialog return response: 'help'"); - } else { - g_debug("Dialog return response: %d", response); - } - - if (response == GTK_RESPONSE_HELP) { - type = LOGOUT_DIALOG_TYPE_RESTART; - response = GTK_RESPONSE_OK; - } - - if (response != GTK_RESPONSE_OK) { - g_debug("Final response was not okay, quiting"); - return 0; - } - } - - session_action(type); - g_debug("Finished action, quiting"); - - return 0; -} diff --git a/src/guest.c b/src/guest.c new file mode 100644 index 0000000..bcbd384 --- /dev/null +++ b/src/guest.c @@ -0,0 +1,190 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include "guest.h" + +G_DEFINE_TYPE (IndicatorSessionGuest, + indicator_session_guest, + G_TYPE_OBJECT) + +enum +{ + PROP_0, + PROP_ALLOWED, + PROP_LOGGED_IN, + PROP_ACTIVE, + PROP_LAST +}; + +static GParamSpec *properties[PROP_LAST]; + +static void +my_get_property (GObject * o, + guint property_id, + GValue * value, + GParamSpec * pspec) +{ + IndicatorSessionGuest * self = INDICATOR_SESSION_GUEST (o); + + switch (property_id) + { + case PROP_ALLOWED: + g_value_set_boolean (value, indicator_session_guest_is_allowed (self)); + break; + + case PROP_LOGGED_IN: + g_value_set_boolean (value, indicator_session_guest_is_logged_in (self)); + break; + + case PROP_ACTIVE: + g_value_set_boolean (value, indicator_session_guest_is_active (self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec); + } +} + +static void +my_dispose (GObject *object) +{ + G_OBJECT_CLASS (indicator_session_guest_parent_class)->dispose (object); +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_guest_class_init (IndicatorSessionGuestClass * klass) +{ + GObjectClass * object_class; + const GParamFlags flags = G_PARAM_READABLE | G_PARAM_STATIC_STRINGS; + + object_class = G_OBJECT_CLASS (klass); + object_class->get_property = my_get_property; + object_class->dispose = my_dispose; + + klass->is_allowed = NULL; + klass->is_logged_in = NULL; + klass->is_active = NULL; + klass->switch_to_guest = NULL; + + properties[PROP_0] = NULL; + + properties[PROP_ALLOWED] = + g_param_spec_boolean (INDICATOR_SESSION_GUEST_PROPERTY_ALLOWED, + "Is Allowed", + "Whether or not a Guest user is allowed", + FALSE, flags); + + properties[PROP_LOGGED_IN] = + g_param_spec_boolean (INDICATOR_SESSION_GUEST_PROPERTY_LOGGED_IN, + "Is Logged In", + "Whether or not the Guest account is logged in", + FALSE, flags); + + properties[PROP_ACTIVE] = + g_param_spec_boolean (INDICATOR_SESSION_GUEST_PROPERTY_ACTIVE, + "Is Active", + "If the Guest account has the current session", + FALSE, flags); + + g_object_class_install_properties (object_class, PROP_LAST, properties); +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_guest_init (IndicatorSessionGuest *self G_GNUC_UNUSED) +{ +} + +/*** +**** +***/ + +gboolean +indicator_session_guest_is_active (IndicatorSessionGuest * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_GUEST (self), FALSE); + + return INDICATOR_SESSION_GUEST_GET_CLASS (self)->is_active (self); +} + +gboolean +indicator_session_guest_is_allowed (IndicatorSessionGuest * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_GUEST (self), FALSE); + + return INDICATOR_SESSION_GUEST_GET_CLASS (self)->is_allowed (self); +} + +gboolean +indicator_session_guest_is_logged_in (IndicatorSessionGuest * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_GUEST (self), FALSE); + + return INDICATOR_SESSION_GUEST_GET_CLASS (self)->is_logged_in (self); +} + +/*** +**** +***/ +static void +notify_func (IndicatorSessionGuest * self, int prop) +{ + g_return_if_fail (INDICATOR_IS_SESSION_GUEST (self)); + + g_debug ("%s %s emitting '%s' prop notify", G_STRLOC, G_STRFUNC, properties[prop]->name); + + g_object_notify_by_pspec (G_OBJECT(self), properties[prop]); +} + +void +indicator_session_guest_notify_active (IndicatorSessionGuest * self) +{ + notify_func (self, PROP_ACTIVE); +} + +void +indicator_session_guest_notify_allowed (IndicatorSessionGuest * self) +{ + notify_func (self, PROP_ALLOWED); +} + +void +indicator_session_guest_notify_logged_in (IndicatorSessionGuest * self) +{ + notify_func (self, PROP_LOGGED_IN); +} + +/*** +**** +***/ + +void +indicator_session_guest_switch_to_guest (IndicatorSessionGuest * self) +{ + gboolean allowed; + + g_return_if_fail (INDICATOR_IS_SESSION_GUEST (self)); + + g_object_get (self, INDICATOR_SESSION_GUEST_PROPERTY_ALLOWED, &allowed, NULL); + g_return_if_fail (allowed); + + INDICATOR_SESSION_GUEST_GET_CLASS (self)->switch_to_guest (self); +} + diff --git a/src/guest.h b/src/guest.h new file mode 100644 index 0000000..30947d5 --- /dev/null +++ b/src/guest.h @@ -0,0 +1,82 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef __GUEST_H__ +#define __GUEST_H__ + +#include +#include + +G_BEGIN_DECLS + +#define INDICATOR_TYPE_SESSION_GUEST (indicator_session_guest_get_type()) +#define INDICATOR_SESSION_GUEST(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_SESSION_GUEST, IndicatorSessionGuest)) +#define INDICATOR_SESSION_GUEST_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_TYPE_SESSION_GUEST, IndicatorSessionGuestClass)) +#define INDICATOR_SESSION_GUEST_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), INDICATOR_TYPE_SESSION_GUEST, IndicatorSessionGuestClass)) +#define INDICATOR_IS_SESSION_GUEST(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_SESSION_GUEST)) + +typedef struct _IndicatorSessionGuest IndicatorSessionGuest; +typedef struct _IndicatorSessionGuestClass IndicatorSessionGuestClass; + +GType indicator_session_guest_get_type (void); + +/** + * A base class for getting state information about the system's guest user. + * Use backend.h's get_backend() to get an instance. + */ +struct _IndicatorSessionGuest +{ + /*< private >*/ + GObject parent; +}; + +/* properties */ +#define INDICATOR_SESSION_GUEST_PROPERTY_ALLOWED "guest-is-allowed" +#define INDICATOR_SESSION_GUEST_PROPERTY_LOGGED_IN "guest-is-logged-in" +#define INDICATOR_SESSION_GUEST_PROPERTY_ACTIVE "guest-is-active-session" + +struct _IndicatorSessionGuestClass +{ + GObjectClass parent_class; + + /* virtual functions */ + gboolean (* is_allowed) (IndicatorSessionGuest * self); + gboolean (* is_logged_in) (IndicatorSessionGuest * self); + gboolean (* is_active) (IndicatorSessionGuest * self); + void (* switch_to_guest) (IndicatorSessionGuest * self); +}; + +gboolean indicator_session_guest_is_allowed (IndicatorSessionGuest * self); +gboolean indicator_session_guest_is_logged_in (IndicatorSessionGuest * self); +gboolean indicator_session_guest_is_active (IndicatorSessionGuest * self); + +void indicator_session_guest_switch_to_guest (IndicatorSessionGuest * self); + +/** + * Emit 'notify' signals for the corresponding properties. + * These functions should only be called by IndicatorSessionGuest implementations. + */ +void indicator_session_guest_notify_allowed (IndicatorSessionGuest * self); +void indicator_session_guest_notify_logged_in (IndicatorSessionGuest * self); +void indicator_session_guest_notify_active (IndicatorSessionGuest * self); + + +G_END_DECLS + +#endif diff --git a/src/indicator-session.c b/src/indicator-session.c deleted file mode 100644 index 431292e..0000000 --- a/src/indicator-session.c +++ /dev/null @@ -1,495 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using its applet interface. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould - Conor Curran - -This program 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. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include "shared-names.h" -#include "user-widget.h" - -#define INDICATOR_SESSION_TYPE (indicator_session_get_type ()) -#define INDICATOR_SESSION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), INDICATOR_SESSION_TYPE, IndicatorSession)) -#define INDICATOR_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), INDICATOR_SESSION_TYPE, IndicatorSessionClass)) -#define IS_INDICATOR_SESSION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), INDICATOR_SESSION_TYPE)) -#define IS_INDICATOR_SESSION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), INDICATOR_SESSION_TYPE)) -#define INDICATOR_SESSION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), INDICATOR_SESSION_TYPE, IndicatorSessionClass)) - -typedef struct _IndicatorSession IndicatorSession; -typedef struct _IndicatorSessionClass IndicatorSessionClass; - -struct _IndicatorSessionClass -{ - IndicatorObjectClass parent_class; -}; - -struct _IndicatorSession -{ - IndicatorObject parent; - IndicatorServiceManager * service; - IndicatorObjectEntry entry; - GCancellable * service_proxy_cancel; - GDBusProxy * service_proxy; - GSettings * settings; - DbusmenuClient * menu_client; - GtkIconTheme * icon_theme; -}; - -GType indicator_session_get_type (void); - -/* Indicator stuff */ -INDICATOR_SET_VERSION -INDICATOR_SET_TYPE(INDICATOR_SESSION_TYPE) - -/* Prototypes */ -static gboolean new_user_item (DbusmenuMenuitem * newitem, - DbusmenuMenuitem * parent, - DbusmenuClient * client, - gpointer user_data); -static void on_menu_layout_updated (DbusmenuClient * client, IndicatorSession * session); -static void indicator_session_update_icon_callback (GtkWidget * widget, gpointer callback_data); -static void indicator_session_update_icon_and_a11y (IndicatorSession * self); -static void indicator_session_update_users_label (IndicatorSession* self, - const gchar* name); -static void service_connection_cb (IndicatorServiceManager * sm, gboolean connected, gpointer user_data); -static void receive_signal (GDBusProxy * proxy, gchar * sender_name, gchar * signal_name, GVariant * parameters, gpointer user_data); -static void service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data); -static void user_real_name_get_cb (GObject * obj, GAsyncResult * res, gpointer user_data); - -static void indicator_session_class_init (IndicatorSessionClass *klass); -static void indicator_session_init (IndicatorSession *self); -static void indicator_session_dispose (GObject *object); -static void indicator_session_finalize (GObject *object); -static GList* indicator_session_get_entries (IndicatorObject* obj); -static guint indicator_session_get_location (IndicatorObject * io, - IndicatorObjectEntry * entry); - -G_DEFINE_TYPE (IndicatorSession, indicator_session, INDICATOR_OBJECT_TYPE); - -static void -indicator_session_class_init (IndicatorSessionClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = indicator_session_dispose; - object_class->finalize = indicator_session_finalize; - - IndicatorObjectClass * io_class = INDICATOR_OBJECT_CLASS(klass); - io_class->get_entries = indicator_session_get_entries; - io_class->get_location = indicator_session_get_location; - return; -} - -static void -indicator_session_init (IndicatorSession *self) -{ - self->settings = g_settings_new ("com.canonical.indicator.session"); - - /* Now let's fire these guys up. */ - self->service = indicator_service_manager_new_version(INDICATOR_SESSION_DBUS_NAME, - INDICATOR_SESSION_DBUS_VERSION); - g_signal_connect (G_OBJECT(self->service), - INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, - G_CALLBACK(service_connection_cb), self); - - self->entry.name_hint = PACKAGE; - self->entry.label = GTK_LABEL (gtk_label_new ("User Name")); - self->entry.image = GTK_IMAGE (gtk_image_new()); - self->entry.menu = GTK_MENU (dbusmenu_gtkmenu_new(INDICATOR_SESSION_DBUS_NAME, - INDICATOR_SESSION_DBUS_OBJECT)); - /* We need to check if the current icon theme has the hard coded icons. - * If not, we'll fall back to a standard icon */ - self->icon_theme = gtk_icon_theme_get_default(); - g_signal_connect(G_OBJECT(self->icon_theme), - "changed", - G_CALLBACK(indicator_session_update_icon_callback), self); - - indicator_session_update_icon_and_a11y (self); - g_settings_bind (self->settings, "show-real-name-on-panel", - self->entry.label, "visible", - G_SETTINGS_BIND_GET); - - /* show-real-name-on-panel affects the a11y string */ - g_signal_connect_swapped (self->settings, - "notify::show-real-name-on-panel", - G_CALLBACK(indicator_session_update_icon_and_a11y), - self); - - gtk_widget_show (GTK_WIDGET(self->entry.menu)); - gtk_widget_show (GTK_WIDGET(self->entry.image)); - g_object_ref_sink (self->entry.menu); - g_object_ref_sink (self->entry.image); - - // set up the handlers - self->menu_client = DBUSMENU_CLIENT(dbusmenu_gtkmenu_get_client(DBUSMENU_GTKMENU(self->entry.menu))); - g_signal_connect (self->menu_client, "layout-updated", - G_CALLBACK(on_menu_layout_updated), self); - - dbusmenu_client_add_type_handler (self->menu_client, - USER_ITEM_TYPE, - new_user_item); - dbusmenu_gtkclient_set_accel_group (DBUSMENU_GTKCLIENT(self->menu_client), - gtk_accel_group_new()); -} - -static void -indicator_session_dispose (GObject *object) -{ - IndicatorSession * self = INDICATOR_SESSION(object); - - g_clear_object (&self->settings); - g_clear_object (&self->service); - g_clear_object (&self->service_proxy); - - if (self->service_proxy_cancel != NULL) - { - g_cancellable_cancel(self->service_proxy_cancel); - g_clear_object (&self->service_proxy_cancel); - } - - g_clear_object (&self->entry.menu); - - G_OBJECT_CLASS (indicator_session_parent_class)->dispose (object); -} - -static void -indicator_session_finalize (GObject *object) -{ - - G_OBJECT_CLASS (indicator_session_parent_class)->finalize (object); - return; -} - -static GList* -indicator_session_get_entries (IndicatorObject* obj) -{ - g_return_val_if_fail(IS_INDICATOR_SESSION(obj), NULL); - - IndicatorSession* self = INDICATOR_SESSION (obj); - return g_list_append (NULL, &self->entry); -} - -static guint -indicator_session_get_location (IndicatorObject * io, - IndicatorObjectEntry * entry) -{ - return 0; -} - -/* callback for the service manager state of being */ -static void -service_connection_cb (IndicatorServiceManager * sm, gboolean connected, gpointer user_data) -{ - IndicatorSession * self = INDICATOR_SESSION (user_data); - - if (connected) { - if (self->service_proxy != NULL){ - // Its a reconnect ! - // Fetch synchronisation data and return (proxy is still legit) - g_dbus_proxy_call (self->service_proxy, - "GetUserRealName", - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - user_real_name_get_cb, - user_data); - return; - } - - self->service_proxy_cancel = g_cancellable_new(); - g_dbus_proxy_new_for_bus (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - INDICATOR_SESSION_DBUS_NAME, - INDICATOR_SESSION_SERVICE_DBUS_OBJECT, - INDICATOR_SESSION_SERVICE_DBUS_IFACE, - self->service_proxy_cancel, - service_proxy_cb, - self); - } - return; -} - - -static void -service_proxy_cb (GObject * object, GAsyncResult * res, gpointer user_data) -{ - GError * error = NULL; - - IndicatorSession * self = INDICATOR_SESSION(user_data); - g_return_if_fail(self != NULL); - - GDBusProxy * proxy = g_dbus_proxy_new_for_bus_finish(res, &error); - - g_clear_object (&self->service_proxy_cancel); - - if (error != NULL) { - g_warning("Could not grab DBus proxy for %s: %s", INDICATOR_SESSION_DBUS_NAME, error->message); - g_error_free(error); - return; - } - - /* Okay, we're good to grab the proxy at this point, we're - sure that it's ours. */ - self->service_proxy = proxy; - - g_signal_connect(proxy, "g-signal", G_CALLBACK(receive_signal), self); - - // Fetch the user's real name for the user entry label - g_dbus_proxy_call (self->service_proxy, - "GetUserRealName", - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - user_real_name_get_cb, - user_data); - return; -} - - -static gboolean -new_user_item (DbusmenuMenuitem * newitem, - DbusmenuMenuitem * parent, - DbusmenuClient * client, - gpointer user_data) -{ - g_return_val_if_fail (DBUSMENU_IS_MENUITEM(newitem), FALSE); - g_return_val_if_fail (DBUSMENU_IS_GTKCLIENT(client), FALSE); - - GtkWidget * user_item = user_widget_new (newitem); - - GtkMenuItem *user_widget = GTK_MENU_ITEM(user_item); - - dbusmenu_gtkclient_newitem_base (DBUSMENU_GTKCLIENT(client), - newitem, - user_widget, - parent); - - g_debug ("%s (\"%s\")", __func__, - dbusmenu_menuitem_property_get (newitem, - USER_ITEM_PROP_NAME)); - return TRUE; -} - -static void -user_real_name_get_cb (GObject * obj, GAsyncResult * res, gpointer user_data) -{ - IndicatorSession * self = INDICATOR_SESSION(user_data); - - GError * error = NULL; - GVariant * result = g_dbus_proxy_call_finish(self->service_proxy, res, &error); - - if (error != NULL) - { - g_warning ("Unable to complete real name dbus query: %s", error->message); - g_clear_error (&error); - } - else - { - const gchar * username = NULL; - g_variant_get (result, "(&s)", &username); - indicator_session_update_users_label (self, username); - g_variant_unref (result); - } -} - -/* Receives all signals from the service, routed to the appropriate functions */ -static void -receive_signal (GDBusProxy * proxy, - gchar * sender_name, - gchar * signal_name, - GVariant * parameters, - gpointer user_data) -{ - IndicatorSession * self = INDICATOR_SESSION(user_data); - - if (!g_strcmp0(signal_name, "UserRealNameUpdated")) - { - const gchar * username = NULL; - g_variant_get (parameters, "(&s)", &username); - indicator_session_update_users_label (self, username); - } -} - -static void -indicator_session_update_users_label (IndicatorSession * self, - const gchar * name) -{ - gtk_label_set_text (self->entry.label, name ? name : ""); -} - -/*** -**** Disposition -***/ - -enum -{ - DISPOSITION_NORMAL, - DISPOSITION_INFO, - DISPOSITION_WARNING, - DISPOSITION_ALERT -}; - -static void -indicator_session_update_a11y_from_disposition (IndicatorSession * indicator, - int disposition) -{ - gchar * a11y; - const gchar * username = gtk_label_get_text (indicator->entry.label); - const gboolean need_attn = disposition != DISPOSITION_NORMAL; - const gboolean show_name = g_settings_get_boolean (indicator->settings, - "show-real-name-on-panel"); - - if (show_name && need_attn) - /* Translators: the name of the menu ("System"), followed by the user's name, - followed by a hint that an item in this menu requires an action from the user */ - a11y = g_strdup_printf (_("System %s (Attention Required)"), username); - else if (show_name) - /* Translators: the name of the menu ("System"), followed by the user's name */ - a11y = g_strdup_printf (_("System %s"), username); - else if (need_attn) - a11y = g_strdup (_("System (Attention Required)")); - else - a11y = g_strdup (_("System")); - - g_debug (G_STRLOC" setting a11y to \"%s\"", a11y); - g_clear_pointer (&indicator->entry.accessible_desc, g_free); - indicator->entry.accessible_desc = a11y; - g_signal_emit (indicator, - INDICATOR_OBJECT_SIGNAL_ACCESSIBLE_DESC_UPDATE_ID, - 0, - &indicator->entry); -} - -static void -indicator_session_update_icon_from_disposition (IndicatorSession * indicator, - int disposition) -{ - const gchar * icon; - - if (disposition == DISPOSITION_NORMAL) - icon = ICON_DEFAULT; - else if (disposition == DISPOSITION_INFO) - icon = ICON_INFO; - else - icon = ICON_ALERT; - - if (gtk_icon_theme_has_icon (indicator->icon_theme, icon) == FALSE) - icon = "gtk-missing-image"; - - g_debug (G_STRLOC" setting icon to \"%s\"", icon); - gtk_image_set_from_icon_name (GTK_IMAGE(indicator->entry.image), - icon, - GTK_ICON_SIZE_BUTTON); -} - -static int -calculate_disposition (IndicatorSession * indicator) -{ - GList * l; - DbusmenuMenuitem * root = dbusmenu_client_get_root (indicator->menu_client); - GList * children = dbusmenu_menuitem_get_children (root); - int ret = DISPOSITION_NORMAL; - - for (l=children; l!=NULL; l=l->next) - { - int val; - const gchar * key = DBUSMENU_MENUITEM_PROP_DISPOSITION; - const gchar * val_str = dbusmenu_menuitem_property_get (l->data, key); - - if (!g_strcmp0 (val_str, DBUSMENU_MENUITEM_DISPOSITION_ALERT)) - val = DISPOSITION_ALERT; - else if (!g_strcmp0 (val_str, DBUSMENU_MENUITEM_DISPOSITION_WARNING)) - val = DISPOSITION_WARNING; - else if (!g_strcmp0 (val_str, DBUSMENU_MENUITEM_DISPOSITION_INFORMATIVE)) - val = DISPOSITION_INFO; - else - val = DISPOSITION_NORMAL; - - if (ret < val) - ret = val; - } - - return ret; -} - -static void -indicator_session_update_icon_callback (GtkWidget * widget, gpointer callback_data) -{ - indicator_session_update_icon_and_a11y ((IndicatorSession *)callback_data); -} - -static void -indicator_session_update_icon_and_a11y (IndicatorSession * indicator) -{ - const int disposition = calculate_disposition (indicator); - indicator_session_update_a11y_from_disposition (indicator, disposition); - indicator_session_update_icon_from_disposition (indicator, disposition); -} - -static void -on_menuitem_property_changed (DbusmenuMenuitem * mi, - gchar * property, - GValue * value, - gpointer indicator) -{ - if (!g_strcmp0 (property, DBUSMENU_MENUITEM_PROP_DISPOSITION)) - indicator_session_update_icon_and_a11y (indicator); -} - -static void -on_menu_layout_updated (DbusmenuClient * client, IndicatorSession * session) -{ - GList * l; - DbusmenuMenuitem * root = dbusmenu_client_get_root (client); - GList * children = dbusmenu_menuitem_get_children (root); - static GQuark tag = 0; - - if (G_UNLIKELY (tag == 0)) - { - tag = g_quark_from_static_string ("x-tagged-by-indicator-session"); - } - - for (l=children; l!=NULL; l=l->next) - { - if (g_object_get_qdata (l->data, tag) == NULL) - { - g_object_set_qdata (l->data, tag, GINT_TO_POINTER(1)); - g_signal_connect (l->data, "property-changed", G_CALLBACK(on_menuitem_property_changed), session); - } - } -} diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..ff5997b --- /dev/null +++ b/src/main.c @@ -0,0 +1,87 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include +#include /* exit() */ + +#include +#include + +#include "service.h" + +/*** +**** +***/ + +static gboolean replace = FALSE; + +static void +parse_command_line (int * argc, char *** argv) +{ + GError * error; + GOptionContext * option_context; + + static GOptionEntry entries[] = + { + { "replace", 'r', 0, G_OPTION_ARG_NONE, &replace, "Replace the currently-running service", NULL }, + { NULL } + }; + + error = NULL; + option_context = g_option_context_new ("- indicator-session service"); + g_option_context_add_main_entries (option_context, entries, GETTEXT_PACKAGE); + if (!g_option_context_parse (option_context, argc, argv, &error)) + { + g_print ("option parsing failed: %s\n", error->message); + g_error_free (error); + exit (EXIT_FAILURE); + } + + g_option_context_free (option_context); +} + +/*** +**** +***/ + +int +main (int argc, char ** argv) +{ + GMainLoop * loop; + IndicatorSessionService * service; + + signal (SIGPIPE, SIG_IGN); + + /* boilerplate i18n */ + setlocale (LC_ALL, ""); + bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); + textdomain (GETTEXT_PACKAGE); + + parse_command_line (&argc, &argv); + + /* run */ + service = indicator_session_service_new (replace); + loop = g_main_loop_new (NULL, FALSE); + g_main_loop_run (loop); + + /* cleanup */ + g_clear_object (&service); + g_main_loop_unref (loop); + return 0; +} diff --git a/src/online-accounts-mgr.c b/src/online-accounts-mgr.c deleted file mode 100644 index 4abba00..0000000 --- a/src/online-accounts-mgr.c +++ /dev/null @@ -1,166 +0,0 @@ -/* -Copyright 2012 Canonical Ltd. - -Authors: - Alberto Mardegan - -This program 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. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . -*/ - -#include -#include - -#include "online-accounts-mgr.h" - -#include - -struct _OnlineAccountsMgr -{ - GObject parent_instance; - GDBusProxy *proxy; - DbusmenuMenuitem *menu_item; -}; - -#define ONLINE_ACCOUNTS_OBJECT_PATH "/com/canonical/indicators/webcredentials" -#define ONLINE_ACCOUNTS_BUS_NAME "com.canonical.indicators.webcredentials" -#define ONLINE_ACCOUNTS_INTERFACE ONLINE_ACCOUNTS_BUS_NAME - -G_DEFINE_TYPE (OnlineAccountsMgr, online_accounts_mgr, G_TYPE_OBJECT); - -static void -update_disposition (OnlineAccountsMgr *self, GVariant *error_status_prop) -{ - gboolean error_status; - - error_status = g_variant_get_boolean (error_status_prop); - dbusmenu_menuitem_property_set (self->menu_item, - DBUSMENU_MENUITEM_PROP_DISPOSITION, - error_status ? - DBUSMENU_MENUITEM_DISPOSITION_ALERT : - DBUSMENU_MENUITEM_DISPOSITION_NORMAL); -} - -static void -on_properties_changed (GDBusProxy *proxy, - GVariant *changed_properties, - GStrv invalidated_properties, - OnlineAccountsMgr *self) -{ - if (g_variant_n_children (changed_properties) > 0) { - GVariantIter *iter; - const gchar *key; - GVariant *value; - - g_variant_get (changed_properties, "a{sv}", &iter); - while (g_variant_iter_loop (iter, "{&sv}", &key, &value)) { - if (g_strcmp0 (key, "ErrorStatus") == 0) { - update_disposition (self, value); - } - } - g_variant_iter_free (iter); - } -} - -static void -on_menu_item_activated (DbusmenuMenuitem *menu_item, - guint timestamp, - OnlineAccountsMgr *self) -{ - GError *error = NULL; - - if (!g_spawn_command_line_async("gnome-control-center credentials", &error)) - { - g_warning("Unable to show control center: %s", error->message); - g_error_free(error); - } -} - -static void -online_accounts_mgr_init (OnlineAccountsMgr *self) -{ - GError *error = NULL; - GVariant *error_status_prop; - - self->menu_item = dbusmenu_menuitem_new (); - dbusmenu_menuitem_property_set (self->menu_item, - DBUSMENU_MENUITEM_PROP_TYPE, - DBUSMENU_CLIENT_TYPES_DEFAULT); - dbusmenu_menuitem_property_set (self->menu_item, - DBUSMENU_MENUITEM_PROP_LABEL, - _("Online Accounts\342\200\246")); - g_signal_connect (self->menu_item, - DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK (on_menu_item_activated), - self); - - self->proxy = - g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START, - NULL, - ONLINE_ACCOUNTS_BUS_NAME, - ONLINE_ACCOUNTS_OBJECT_PATH, - ONLINE_ACCOUNTS_INTERFACE, - NULL, - &error); - if (G_UNLIKELY (error != NULL)) { - g_warning ("Couldn't create online_accounts proxy: %s", error->message); - g_clear_error (&error); - return; - } - - g_signal_connect (self->proxy, "g-properties-changed", - G_CALLBACK (on_properties_changed), self); - - error_status_prop = - g_dbus_proxy_get_cached_property (self->proxy, "ErrorStatus"); - if (error_status_prop != NULL) { - update_disposition (self, error_status_prop); - g_variant_unref (error_status_prop); - } -} - -static void -online_accounts_mgr_dispose (GObject *object) -{ - OnlineAccountsMgr *self = ONLINE_ACCOUNTS_MGR (object); - - if (self->proxy != NULL) { - g_object_unref (self->proxy); - self->proxy = NULL; - } - - if (self->menu_item != NULL) { - g_object_unref (self->menu_item); - self->menu_item = NULL; - } - - G_OBJECT_CLASS (online_accounts_mgr_parent_class)->dispose (object); -} - -static void -online_accounts_mgr_class_init (OnlineAccountsMgrClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - object_class->dispose = online_accounts_mgr_dispose; -} - -OnlineAccountsMgr *online_accounts_mgr_new () -{ - return g_object_new (ONLINE_ACCOUNTS_TYPE_MGR, NULL); -} - -DbusmenuMenuitem *online_accounts_mgr_get_menu_item (OnlineAccountsMgr *self) -{ - g_return_val_if_fail (ONLINE_ACCOUNTS_IS_MGR (self), NULL); - return self->menu_item; -} diff --git a/src/online-accounts-mgr.h b/src/online-accounts-mgr.h deleted file mode 100644 index 16c0461..0000000 --- a/src/online-accounts-mgr.h +++ /dev/null @@ -1,50 +0,0 @@ -/* -Copyright 2012 Canonical Ltd. - -Authors: - Alberto Mardegan - -This program 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. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . -*/ - -#ifndef _ONLINE_ACCOUNTS_MGR_H_ -#define _ONLINE_ACCOUNTS_MGR_H_ - -#include -#include - -G_BEGIN_DECLS - -#define ONLINE_ACCOUNTS_TYPE_MGR (online_accounts_mgr_get_type ()) -#define ONLINE_ACCOUNTS_MGR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ONLINE_ACCOUNTS_TYPE_MGR, OnlineAccountsMgr)) -#define ONLINE_ACCOUNTS_MGR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ONLINE_ACCOUNTS_TYPE_MGR, OnlineAccountsMgrClass)) -#define ONLINE_ACCOUNTS_IS_MGR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ONLINE_ACCOUNTS_TYPE_MGR)) -#define ONLINE_ACCOUNTS_IS_MGR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), ONLINE_ACCOUNTS_TYPE_MGR)) -#define ONLINE_ACCOUNTS_MGR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ONLINE_ACCOUNTS_TYPE_MGR, OnlineAccountsMgrClass)) - -typedef struct _OnlineAccountsMgrClass OnlineAccountsMgrClass; -typedef struct _OnlineAccountsMgr OnlineAccountsMgr; - -struct _OnlineAccountsMgrClass -{ - GObjectClass parent_class; -}; - -GType online_accounts_mgr_get_type (void) G_GNUC_CONST; -OnlineAccountsMgr *online_accounts_mgr_new (void); - -DbusmenuMenuitem *online_accounts_mgr_get_menu_item (OnlineAccountsMgr *self); - -G_END_DECLS - -#endif /* _ONLINE_ACCOUNTS_MGR_H_ */ diff --git a/src/org.freedesktop.Accounts.User.xml b/src/org.freedesktop.Accounts.User.xml deleted file mode 100644 index 53f54d4..0000000 --- a/src/org.freedesktop.Accounts.User.xml +++ /dev/null @@ -1,744 +0,0 @@ - - - - - - - - - - - The new username. - - - - - - - Sets the users username. Note that it is usually not allowed - to have multiple users with the same username. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.user-administration - To change the username of any user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The new name, typically in the form "Firstname Lastname". - - - - - - - Sets the users real name. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.change-own-user-data - To change his own name - - - org.freedesktop.accounts.user-administration - To change the name of another user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The new email address. - - - - - - - Sets the users email address. - - - Note that setting an email address in the AccountsService is - not the same as configuring a mail client. Mail clients might - default to email address that is configured here, though. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.change-own-user-data - To change his own email address - - - org.freedesktop.accounts.user-administration - To change the email address of another user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The new language, as a locale specification like "de_DE.UTF-8". - - - - - - - Sets the users language. - - - The expectation is that display managers will start the - users session with this locale. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.change-own-user-data - To change his own language - - - org.freedesktop.accounts.user-administration - To change the language of another user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - - The new xsession to start (e.g. "gnome") - - - - - - - Sets the users x session. - - - The expectation is that display managers will log the user in to this - specified session, if available. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.change-own-user-data - To change his own language - - - org.freedesktop.accounts.user-administration - To change the language of another user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The new location as a freeform string. - - - - - - - Sets the users location. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.change-own-user-data - To change his own location - - - org.freedesktop.accounts.user-administration - To change the location of another user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The new homedir as an absolute path. - - - - - - - Sets the users home directory. - - - Note that changing the users home directory moves all the content - from the old location to the new one, and is potentially an - expensive operation. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.user-administration - To change the home directory of a user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The new user shell. - - - - - - - Sets the users shell. - - - Note that setting the shell to a non-allowed program may - prevent the user from logging in. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.user-administration - To change the shell of a user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The absolute filename of a png file to use as the users icon. - - - - - - - Sets the users icon. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.change-own-user-data - To change his own icon - - - org.freedesktop.accounts.user-administration - To change the icon of another user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - Whether to lock or unlock the users account. - - - - - - - Locks or unlocks a users account. - - - Locking an account prevents the user from logging in. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.user-administration - To lock or unlock user accounts - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The new account type, encoded as an integer: - - - 0 - Standard user - - - 1 - Administrator - - - - - - - - - Changes the users account type. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.user-administration - To change an account type - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The new password mode, encoded as an integer: - - - 0 - Regular password - - - 1 - Password must be set at next login - - - 2 - No password - - - - - - - - - Changes the users password mode. - - - Note that changing the password mode has the side-effect of - unlocking the account. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.user-administration - To change a users password mode - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - The crypted password. - - - - - - - The password hint. - - - - - - - Sets a new password for this user. - - - Note that setting a password has the side-effect of - unlocking the account. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.user-administration - To change the password of a user - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - - Whether to enable automatic login for this user. - - - - - - - Enables or disables automatic login for a user. - - - Note that usually only one user can have automatic login - enabled, so turning it on for a user will disable it for - the previously configured autologin user. - - - - The caller needs one of the following PolicyKit authorizations: - - - org.freedesktop.accounts.set-login-option - To change the login screen configuration - - - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - - The uid of the user. - - - - - - - - - - The username of the user. - - - - - - - - - - The users real name. - - - - - - - - - - The users account type, encoded as an integer: - - - 0 - Standard user - - - 1 - Administrator - - - - - - - - - - - - The users home directory. - - - - - - - - - - The users shell. - - - - - - - - - - The email address. - - - - - - - - - - The users language, as a locale specification like "de_DE.UTF-8". - - - - - - - - - - The users x session. - - - - - - - - - - The users location. - - - - - - - - - - How often the user has logged in. - - - - - - - - - - The filename of a png file containing the users icon. - - - - - - - - - - Whether the users account is locked. - - - - - - - - - - The password mode for the user account, encoded as an integer: - - - 0 - Regular password - - - 1 - Password must be set at next login - - - 2 - No password - - - - - - - - - - - - The password hint for the user. - - - - - - - - - - Whether automatic login is enabled for the user. - - - - - - - - - - Whether this is a 'system' account, like 'root' or 'nobody'. - System accounts should normally not appear in lists of - users, and ListCachedUsers will not include such accounts. - - - - - - - - - - Emitted when the user is changed. - - - - - - - diff --git a/src/org.freedesktop.Accounts.xml b/src/org.freedesktop.Accounts.xml deleted file mode 100644 index 9c19761..0000000 --- a/src/org.freedesktop.Accounts.xml +++ /dev/null @@ -1,194 +0,0 @@ - - - - - - - - - - Object paths of cached users - - - - - - Lists users which have logged into the system locally before. - This is not meant to return an exhaustive list of all users. - It is possible for FindUserByName() - to return a user that's not on the list. - - - - - - - - - The uid to look up - - - Object path of user - - - - - - Finds a user by uid. - - - - if no user with the given uid exists - - - - - - - - The username to look up - - - Object path of user - - - - - - Finds a user by its username. - - - - if no user with the given username exists - - - - - - - - The username for the new user - - - - The real name for the new user - - - Object path of the new user - - - - The account type, encoded as an integer - - - - - - Creates a new user account. - - - The accountType argument can take the following values: - - - - 0 - Standard user - - - 1 - Administrator - - - 2 - Supervised user - - - - - The caller needs the org.freedesktop.accounts.user-administration PolicyKit authorization. - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - - The uid to delete - - - Whether to remove the users files - - - - - - Deletes a user account. - - - - The caller needs the org.freedesktop.accounts.user-administration PolicyKit authorization. - - - if the caller lacks the appropriate PolicyKit authorization - if the operation failed - - - - - - - Object path of the user that was added. - - - - - Emitted when a user is added. - - - - - - - - Object path of the user that was deleted. - - - - - Emitted when a user is deleted. - - - - - - - - Object path of the user that was changed. - - - - - Emitted when a user is changed. - - - - - - - - - - The version of the running daemon. - - - - - - - diff --git a/src/org.freedesktop.ConsoleKit.Manager.xml b/src/org.freedesktop.ConsoleKit.Manager.xml deleted file mode 100644 index f903b55..0000000 --- a/src/org.freedesktop.ConsoleKit.Manager.xml +++ /dev/null @@ -1,353 +0,0 @@ - - - - - - - - - This method initiates a request to restart (ie. reboot) the computer system. - - - - - - - - - - - - - - This method initiates a request to stop (ie. shutdown) the computer system. - - - - - - - - - - - - - - The secret cookie that is used to identify the new session - - - - - This method requests that a new Session - be created for the calling process. The properties of this new Session are set automatically - from information collected about the calling process. - - This new session exists until the calling process disconnects from the system bus or - calls CloseSession(). - - It is the responsibility of the calling process to set the environment variable - XDG_SESSION_COOKIE to the value of the returned cookie. This cookie should only - be made available to child processes of the caller so that they may be identified - as members of this session. - - See this simple example: - - DBusError error; - DBusMessage *message; - DBusMessage *reply; - - message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit", - "/org/freedesktop/ConsoleKit/Manager", - "org.freedesktop.ConsoleKit.Manager", - "OpenSession"); - if (message == NULL) { - goto out; - } - - dbus_error_init (&error); - reply = dbus_connection_send_with_reply_and_block (connector->connection, - message, - -1, - &error); - if (reply == NULL) { - goto out; - } - - dbus_error_init (&error); - if (! dbus_message_get_args (reply, - &error, - DBUS_TYPE_STRING, &cookie, - DBUS_TYPE_INVALID)) { - goto out; - } - - - - OpenSessionWithParameters() - - - - - - - An array of sets of property names and values - - - - - The secret cookie that is used to identify the new session - - - - - This method requests that a new Session - be created for the calling process. The properties of this new Session are from the - parameters provided. - - This new session exists until the calling process disconnects from the system bus or - calls CloseSession(). - - It is the responsibility of the calling process to set the environment variable - XDG_SESSION_COOKIE to the value of the returned cookie. This cookie should only - be made available to child processes of the caller so that they may be identified - as members of this session. - - See the Session properties for a list of valid parameters. - - org.freedesktop.ConsoleKit.Session - This method is restricted to privileged users by D-Bus policy. - - - - - - - The secret cookie that is used to identify the session - - - - - Whether the session was successfully closed - - - - - This method is used to close the session identified by the supplied cookie. - - The session can only be closed by the same process that opened the session. - - - - - - - - - an array of Seat IDs - - - - - This gets a list of all the Seats - that are currently present on the system. - Each Seat ID is an D-Bus object path for the object that implements the - Seat interface. - - org.freedesktop.ConsoleKit.Seat - - - - - - - an array of Session IDs - - - - - This gets a list of all the Sessions - that are currently present on the system. - Each Session ID is an D-Bus object path for the object that implements the - Session interface. - - org.freedesktop.ConsoleKit.Session - - - - - - - - The secret cookie that is used to identify the session - - - - - The object identifier for the current session - - - - - Returns the session ID that is associated with the specified cookie. - - - - - - - - - The POSIX process ID - - - - - The object identifier for the current session - - - - - Attempts to determine the session ID for the specified - POSIX process ID (pid). - - - - - - - - - The object identifier for the current session - - - - - Attempts to determine the session ID that the caller belongs to. - - See this example of using dbus-send: - - dbus-send --system --dest=org.freedesktop.ConsoleKit \ - --type=method_call --print-reply --reply-timeout=2000 \ - /org/freedesktop/ConsoleKit/Manager \ - org.freedesktop.ConsoleKit.Manager.GetCurrentSession - - - - - - - - - POSIX User identification - - - - - an array of Session IDs - - - - - This gets a list of all the Sessions - that are currently open for the specified user. - Each Session ID is an D-Bus object path for the object that implements the - Session interface. - - - - - - - - User identification - - - - - an array of Session IDs - - - - - This gets a list of all the Sessions - that are currently open for the specified user. - Each Session ID is an D-Bus object path for the object that implements the - Session interface. - - - - - - - - - The value of the system-idle-hint - - - - - Returns TRUE if the idle-hint - property of every open session is TRUE or if there are no open sessions. - - - - - - - - An ISO 8601 format date-type string - - - - - Returns an ISO 8601 date-time string that corresponds to - the time of the last change of the system-idle-hint. - - - - - - - - - The Seat ID for the added seat - - - - - Emitted when a Seat has been added to the system. - - - - - - - - The Seat ID for the removed seat - - - - - Emitted when a Seat has been removed from the system. - - - - - - - - The value of the system-idle-hint - - - - - Emitted when the value of the system-idle-hint has changed. - - - - - - diff --git a/src/org.freedesktop.ConsoleKit.Seat.xml b/src/org.freedesktop.ConsoleKit.Seat.xml deleted file mode 100644 index 58c2ce7..0000000 --- a/src/org.freedesktop.ConsoleKit.Seat.xml +++ /dev/null @@ -1,164 +0,0 @@ - - - - - - - A seat is a collection of sessions and a set of hardware (usually at -least a keyboard and mouse). Only one session may be active on a -seat at a time. - - - - - - - Seat ID - - - - - Returns the ID for Seat. - - - - - - - - an array of Session IDs - - - - - This gets a list of all the Sessions - that are currently attached to this seat. - Each Session ID is an D-Bus object path for the object that implements the - Session interface. - - - - - - - - an array of devices - - - - - This gets a list of all the devices - that are currently associated with this seat. - Each device is an D-Bus structure that represents - the device type and the device id. - - - - - - - - - Session ID - - - - - Gets the Session ID that is currently active on this Seat. - Returns NULL if there is no active session. - - - - - - - - TRUE if seat supports session activation - - - - Used to determine whether the seat supports session activation. - - - - - - - - - Session ID - - - - - Attempt to activate the specified session. In most - cases, if successful, this will cause the session to - become visible and take control of the hardware that is - associated with this seat. - - Activate() - - - - - - - Session ID - - - - - Emitted when the active session has changed. - - - - - - - Session ID - - - - - Emitted when a session has been added to the seat. - - - - - - - Session ID - - - - - Emitted when a session has been removed from the seat. - - - - - - - Device structure - - - - - Emitted when a device has been associated with the seat. - - - - - - - Device structure - - - - - Emitted when a device has been dissociated from the seat. - - - - - diff --git a/src/org.freedesktop.ConsoleKit.Session.xml b/src/org.freedesktop.ConsoleKit.Session.xml deleted file mode 100644 index b6e1cdb..0000000 --- a/src/org.freedesktop.ConsoleKit.Session.xml +++ /dev/null @@ -1,435 +0,0 @@ - - - - - - - Session objects represent and store information - related to a user session. - - The properties associated with the Session - specifically refer to the properties of the "session leader". - - - - - - - Session ID - - - - Returns the ID for Session. - - - - - - - Seat ID - - - - Returns the ID for the Seat the Session is - attached to. - - org.freedesktop.ConsoleKit.Seat - - - - - - Session type - - - - - Returns the type of the session. - Warning: we haven't yet defined the allowed values for this property. - It is probably best to avoid this until we do. - - - session-type - - - - - - User ID - - - - Returns the user that the session belongs to. - - - user - - - - - - POSIX User ID - - - - Returns the POSIX user ID that the session belongs to. - - unix-user - - - - - - The value of the X11 display - - - - Returns the value of the X11 DISPLAY for this session - if one is present. - - x11-display - - - - - - The value of the X11 display device - - - - Returns the value of the display device (aka TTY) that the - X11 display for the session is connected to. If there is no x11-display set then this value - is undefined. - - x11-display-device - - - - - - The value of the display device - - - - Returns the value of the display device (aka TTY) that the - session is connected to. - - display-device - - - - - - The remote host name - - - - Returns the value of the remote host name for the session. - - - remote-host-name - - - - - - The value of the native system login session ID - - - - Returns the value of the login session ID that the - underlying system uses to enforce session boundaries. If there is no login session ID - set then this value is an empty string. - - - - - - - TRUE if the session is active, otherwise FALSE - - - - Returns whether the session is active on the Seat that - it is attached to. - If the session is not attached to a seat this value is undefined. - - - active - - - - - - TRUE if the session is local, otherwise FALSE - - - - Returns whether the session is local - FIXME: we need to come up with a concrete definition for this value. - It was originally used as a way to identify XDMCP sessions that originate - from a remote system. - - - is-local - - - - - - An ISO 8601 format date-type string - - - - - Returns an ISO 8601 date-time string that corresponds to - the time that the session was opened. - - - - - - - - - - Attempt to activate the this session. In most - cases, if successful, this will cause the session to - become visible and become active on the seat that it - is attached to. - - Seat.ActivateSession() - - - - - - - This will cause a Lock - signal to be emitted for this session. - - - This method is restricted to privileged users by D-Bus policy. - Lock signal - - - - - - - This will cause an Unlock - signal to be emitted for this session. - - This can be used by login managers to unlock a session before it is - re-activated during fast-user-switching. - - - This method is restricted to privileged users by D-Bus policy. - Unlock signal - - - - - - - The value of the idle-hint - - - - - Gets the value of the idle-hint - property. - - - idle-hint - - - - - - An ISO 8601 format date-type string - - - - - Returns an ISO 8601 date-time string that corresponds to - the time of the last change of the idle-hint. - - - - - - - - - boolean value to set the idle-hint to - - - - - This may be used by the session to indicate that - it is idle. - - Use of this method is restricted to the user - that owns the session. - - - - - - - - TRUE if the session is active, otherwise FALSE - - - - - Emitted when the active property has changed. - - - - - - - the new value of idle-hint - - - - - Emitted when the idle-hint property has changed. - - - - - - - Emitted in response to a call to the Lock() method. - It is intended that the screensaver for the session should lock the screen in response to this signal. - - - - - - - Emitted in response to a call to the Unlock() method. - It is intended that the screensaver for the session should unlock the screen in response to this signal. - - - - - - - - The user assigned to the session. - - - - - - - The user assigned to the session. - - - - - - - - The type of the session. - Warning: we haven't yet defined the allowed values for this property. - It is probably best to avoid this until we do. - - - - - - - - The remote host name for the session. - - This will be set in situations where the session is - opened and controlled from a remote system. - - For example, this value will be set when the - session is created from an SSH or XDMCP connection. - - - - - - - - The display device (aka TTY) that the - session is connected to. - - - - - - - - Value of the X11 DISPLAY for this session - if one is present. - - - - - - - - - The display device (aka TTY) that the X11 display for the - session is connected to. If there is no x11-display set then - this value is undefined. - - - - - - - - - Whether the session is active on the Seat that - it is attached to. - If the session is not attached to a seat this value is undefined. - - - - - - - - - Whether the session is local - FIXME: we need to come up with a concrete definition for this value. - It was originally used as a way to identify XDMCP sessions that originate - from a remote system. - - - - - - - - - This is a hint used to indicate that the session may be idle. - - - For sessions with a x11-display set (ie. graphical - sessions), it is up to each session to delegate the - responsibility for updating this value. Typically, the - screensaver will set this. - - However, for non-graphical sessions with a display-device set - the Session object itself will periodically update this value based - on the activity detected on the display-device itself. - - - This should not be considered authoritative. - - - - - - - diff --git a/src/service.c b/src/service.c new file mode 100644 index 0000000..1345681 --- /dev/null +++ b/src/service.c @@ -0,0 +1,1192 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include + +#include +#include + +#include "backend.h" +#include "service.h" + +/* FIXME: remove -test */ +#define BUS_NAME "com.canonical.indicator.session-test" +#define BUS_PATH "/com/canonical/indicator/session" + +#define ICON_DEFAULT "system-devices-panel" +#define ICON_INFO "system-devices-panel-information" +#define ICON_ALERT "system-devices-panel-alert" + +G_DEFINE_TYPE (IndicatorSessionService, + indicator_session_service, + G_TYPE_OBJECT) + +enum +{ + PROP_0, + PROP_REPLACE, + PROP_MAX_USERS, + PROP_LAST +}; + +static GParamSpec * properties[PROP_LAST]; + +enum +{ + SECTION_HEADER = (1<<0), + SECTION_ADMIN = (1<<1), + SECTION_SETTINGS = (1<<2), + SECTION_SWITCH = (1<<3), + SECTION_SESSION = (1<<4) +}; + +enum +{ + FORM_DESKTOP, + FORM_GREETER, + N_FORMS +}; + +static const char * const menu_names[N_FORMS] = +{ + "desktop", + "desktop_greeter" +}; + +struct FormMenuInfo +{ + /* the root level -- the header is the only child of this */ + GMenu * menu; + + /* parent of the sections. This is the header's submenu */ + GMenu * submenu; + + guint export_id; +}; + +struct _IndicatorSessionServicePrivate +{ + guint own_id; + guint max_users; + IndicatorSessionUsers * backend_users; + IndicatorSessionGuest * backend_guest; + IndicatorSessionActions * backend_actions; + GSettings * indicator_settings; + GSettings * keybinding_settings; + GSimpleActionGroup * actions; + guint actions_export_id; + struct FormMenuInfo menus[N_FORMS]; + GSimpleAction * header_action; + GSimpleAction * user_switcher_action; + GSimpleAction * guest_switcher_action; + GHashTable * users; + guint rebuild_id; + int rebuild_flags; + GDBusConnection * conn; + + gboolean replace; +}; + +typedef IndicatorSessionServicePrivate priv_t; + +static const char * get_current_real_name (IndicatorSessionService * self); + +/*** +**** +***/ + +static void rebuild_now (IndicatorSessionService * self, int section); +static void rebuild_soon (IndicatorSessionService * self, int section); + +static inline void +rebuild_header_soon (IndicatorSessionService * self) +{ + rebuild_soon (self, SECTION_HEADER); +} +static inline void +rebuild_switch_section_soon (IndicatorSessionService * self) +{ + rebuild_soon (self, SECTION_SWITCH); +} +static inline void +rebuild_session_section_soon (IndicatorSessionService * self) +{ + rebuild_soon (self, SECTION_SESSION); +} +static inline void +rebuild_settings_section_soon (IndicatorSessionService * self) +{ + rebuild_soon (self, SECTION_SETTINGS); +} + +/*** +**** +***/ + +static void +update_header_action (IndicatorSessionService * self) +{ + gchar * a11y; + gboolean need_attn; + gboolean show_name; + GVariant * variant; + const gchar * real_name; + const gchar * label; + const gchar * iconstr; + const priv_t * const p = self->priv; + + g_return_if_fail (p->header_action != NULL); + + if (indicator_session_actions_has_online_account_error (p->backend_actions)) + { + need_attn = TRUE; + iconstr = ICON_ALERT; + } + else + { + need_attn = FALSE; + iconstr = ICON_DEFAULT; + } + + show_name = g_settings_get_boolean (p->indicator_settings, + "show-real-name-on-panel"); + + real_name = get_current_real_name (self); + label = show_name && real_name ? real_name : ""; + + if (*label && need_attn) + { + /* Translators: the name of the menu ("System"), then the user's name, + then a hint that something in this menu requires user attention */ + a11y = g_strdup_printf (_("System, %s (Attention Required)"), real_name); + } + else if (*label) + { + /* Translators: the name of the menu ("System"), then the user's name */ + a11y = g_strdup_printf (_("System, %s"), label); + } + else if (need_attn) + { + a11y = g_strdup (_("System (Attention Required)")); + } + else + { + a11y = g_strdup (_("System")); + } + + variant = g_variant_new ("(sssb)", label, iconstr, a11y, TRUE); + g_simple_action_set_state (p->header_action, variant); + g_free (a11y); +} + +/*** +**** USERS +***/ + +static GMenuModel * create_switch_section (IndicatorSessionService * self); + +static void +add_user (IndicatorSessionService * self, const gchar * key) +{ + IndicatorSessionUser * u; + + /* update our user table */ + u = indicator_session_users_get_user (self->priv->backend_users, key); + g_hash_table_insert (self->priv->users, g_strdup(key), u); + + /* enqueue rebuilds for the affected sections */ + rebuild_switch_section_soon (self); + if (u->is_current_user) + rebuild_header_soon (self); +} + +static void +on_user_added (IndicatorSessionUsers * backend_users G_GNUC_UNUSED, + const char * key, + gpointer gself) +{ + add_user (INDICATOR_SESSION_SERVICE(gself), key); +} + +static void +on_user_changed (IndicatorSessionUsers * backend_users G_GNUC_UNUSED, + const char * key, + gpointer gself) +{ + add_user (INDICATOR_SESSION_SERVICE(gself), key); +} + +static void +on_user_removed (IndicatorSessionUsers * backend_users G_GNUC_UNUSED, + const char * key, + gpointer gself) +{ + IndicatorSessionService * self = INDICATOR_SESSION_SERVICE (gself); + g_return_if_fail (self != NULL); + + /* update our user table */ + g_hash_table_remove (self->priv->users, key); + + /* enqueue rebuilds for the affected sections */ + rebuild_switch_section_soon (self); +} + +static const char * +get_current_real_name (IndicatorSessionService * self) +{ + GHashTableIter iter; + gpointer key, value; + + /* is it the guest? */ + if (indicator_session_guest_is_active (self->priv->backend_guest)) + return _("Guest"); + + /* is it a user? */ + g_hash_table_iter_init (&iter, self->priv->users); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + IndicatorSessionUser * user = value; + if (user->is_current_user) + return user->real_name; + } + + return ""; +} + +/*** +**** +***/ + +static GMenuModel * +create_admin_section (void) +{ + GMenu * menu; + GMenuItem * item; + + menu = g_menu_new (); + + item = g_menu_item_new (_("About This Computer"), "indicator.about"); + g_menu_append_item (menu, item); + g_object_unref (G_OBJECT(item)); + + item = g_menu_item_new (_("Ubuntu Help"), "indicator.help"); + g_menu_append_item (menu, item); + g_object_unref (G_OBJECT(item)); + + return G_MENU_MODEL (menu); +} + +static GMenuModel * +create_settings_section (IndicatorSessionService * self) +{ + GMenu * menu; + GMenuItem * item; + priv_t * p = self->priv; + + menu = g_menu_new (); + + item = g_menu_item_new (_("System Settings\342\200\246"), "indicator.settings"); + g_menu_append_item (menu, item); + g_object_unref (G_OBJECT(item)); + + if (indicator_session_actions_has_online_account_error (p->backend_actions)) + { + item = g_menu_item_new (_("Online Accounts\342\200\246"), "indicator.online-accounts"); + g_menu_append_item (menu, item); + g_object_unref (G_OBJECT(item)); + } + + return G_MENU_MODEL (menu); +} + +/** + * The switch-to-guest action's state is a dictionary with these entries: + * - "is-active" (boolean) + * - "is-logged-in" (boolean) + */ +static GVariant * +create_guest_switcher_state (IndicatorSessionService * self) +{ + GVariant * val; + GVariantBuilder * b; + IndicatorSessionGuest * const g = self->priv->backend_guest; + + b = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); + val = g_variant_new_boolean (indicator_session_guest_is_active (g)); + g_variant_builder_add (b, "{sv}", "is-active", val); + val = g_variant_new_boolean (indicator_session_guest_is_logged_in (g)); + g_variant_builder_add (b, "{sv}", "is-logged-in", val); + return g_variant_builder_end (b); +} + +/** + * The switch-to-user action's state is a dictionary with these entries: + * - "active-user" (username string) + * - "logged-in-users" (array of username strings) + */ +static GVariant * +create_user_switcher_state (IndicatorSessionService * self) +{ + GVariantBuilder * a; + GVariantBuilder * b; + GVariant * val; + GHashTableIter ht_iter; + gpointer ht_key, ht_value; + const char * current_user; + + current_user = ""; + a = g_variant_builder_new (G_VARIANT_TYPE("as")); + g_hash_table_iter_init (&ht_iter, self->priv->users); + while (g_hash_table_iter_next (&ht_iter, &ht_key, &ht_value)) + { + const IndicatorSessionUser * u = ht_value; + + if (u->is_current_user) + current_user = u->user_name; + + if (u->is_logged_in) + g_variant_builder_add (a, "s", u->user_name); + } + + b = g_variant_builder_new (G_VARIANT_TYPE("a{sv}")); + val = g_variant_new_string (current_user); + g_variant_builder_add (b, "{sv}", "active-user", val); + val = g_variant_builder_end (a); + g_variant_builder_add (b, "{sv}", "logged-in-users", val); + return g_variant_builder_end (b); +} + +static void +update_switch_actions (IndicatorSessionService * self) +{ + g_simple_action_set_state (self->priv->guest_switcher_action, + create_guest_switcher_state (self)); + + g_simple_action_set_state (self->priv->user_switcher_action, + create_user_switcher_state (self)); +} + +static gboolean +use_ellipsis (IndicatorSessionService * self) +{ + /* does the backend support confirmation prompts? */ + if (!indicator_session_actions_can_prompt (self->priv->backend_actions)) + return FALSE; + + /* has the user disabled prompts? */ + if (g_settings_get_boolean (self->priv->indicator_settings, + "suppress-logout-restart-shutdown")) + return FALSE; + + return TRUE; +} + +/* lower index == more useful. + When there are too many users for the menu, + we use this to decide which to cull. */ +static int +compare_users_by_usefulness (gconstpointer ga, gconstpointer gb) +{ + const IndicatorSessionUser * a = *(const IndicatorSessionUser**)ga; + const IndicatorSessionUser * b = *(const IndicatorSessionUser**)gb; + + if (a->is_current_user != b->is_current_user) + return a->is_current_user ? -1 : 1; + + if (a->is_logged_in != b->is_logged_in) + return a->is_logged_in ? -1 : 1; + + if (a->login_frequency != b->login_frequency) + return a->login_frequency > b->login_frequency ? -1 : 1; + + return 0; +} + +/* sorting them for display in the menu */ +static int +compare_users_by_label (gconstpointer ga, gconstpointer gb) +{ + int i; + const IndicatorSessionUser * a = *(const IndicatorSessionUser**)ga; + const IndicatorSessionUser * b = *(const IndicatorSessionUser**)gb; + + if ((i = g_strcmp0 (a->real_name, b->real_name))) + return i; + + return g_strcmp0 (a->user_name, b->user_name); +} + +static GMenuModel * +create_switch_section (IndicatorSessionService * self) +{ + gchar * str; + GMenu * menu; + GMenuItem * item; + guint i; + gpointer guser; + GHashTableIter iter; + GPtrArray * users; + const priv_t * const p = self->priv; + const gboolean ellipsis = use_ellipsis (self); + + menu = g_menu_new (); + + /* lockswitch */ + if (indicator_session_users_is_live_session (p->backend_users)) + { + const char * action = "indicator.switch-to-screensaver"; + item = g_menu_item_new (_("Start Screen Saver"), action); + } + else if (indicator_session_guest_is_active (p->backend_guest)) + { + const char * action = "indicator.switch-to-greeter"; + item = g_menu_item_new (ellipsis ? _("Switch Account\342\200\246") + : _("Switch Account"), action); + } + else if (g_hash_table_size (p->users) == 1) + { + const char * action = "indicator.switch-to-greeter"; + item = g_menu_item_new (ellipsis ? _("Lock\342\200\246") + : _("Lock"), action); + } + else + { + const char * action = "indicator.switch-to-greeter"; + item = g_menu_item_new (ellipsis ? _("Lock/Switch Account\342\200\246") + : _("Lock/Switch Account"), action); + } + str = g_settings_get_string (p->keybinding_settings, "screensaver"); + g_menu_item_set_attribute (item, "accel", "s", str); + g_free (str); + g_menu_append_item (menu, item); + g_object_unref (G_OBJECT(item)); + + if (indicator_session_guest_is_allowed (p->backend_guest)) + { + item = g_menu_item_new (_("Guest Session"), "indicator.switch-to-guest"); + g_menu_append_item (menu, item); + g_object_unref (G_OBJECT(item)); + } + + /* build an array of all the users we know of */ + users = g_ptr_array_new (); + g_hash_table_iter_init (&iter, p->users); + while (g_hash_table_iter_next (&iter, NULL, &guser)) + g_ptr_array_add (users, guser); + + /* if there are too many users, cull out the less interesting ones */ + if (users->len > p->max_users) + { + g_ptr_array_sort (users, compare_users_by_usefulness); + g_ptr_array_set_size (users, p->max_users); + } + + /* sort the users by name */ + g_ptr_array_sort (users, compare_users_by_label); + + /* add the users */ + for (i=0; ilen; ++i) + { + const IndicatorSessionUser * u = g_ptr_array_index (users, i); + item = g_menu_item_new (u->real_name, NULL); + g_menu_item_set_action_and_target (item, "indicator.switch-to-user", "s", u->user_name); + g_menu_append_item (menu, item); + g_object_unref (G_OBJECT(item)); + } + + /* cleanup */ + g_ptr_array_free (users, TRUE); + return G_MENU_MODEL (menu); +} + +static GMenuModel * +create_session_section (IndicatorSessionService * self) +{ + GMenu * menu; + GMenuItem * item; + const priv_t * const p = self->priv; + GSettings * const s = p->indicator_settings; + const gboolean ellipsis = use_ellipsis (self); + + menu = g_menu_new (); + + if (indicator_session_actions_can_logout (p->backend_actions) && !g_settings_get_boolean (s, "suppress-logout-menuitem")) + { + item = g_menu_item_new (ellipsis ? _("Log Out\342\200\246") + : _("Log Out"), "indicator.logout"); + g_menu_append_item (menu, item); + g_object_unref (G_OBJECT(item)); + } + + if (indicator_session_actions_can_suspend (p->backend_actions)) + { + item = g_menu_item_new (_("Suspend"), "indicator.suspend"); + g_menu_append_item (menu, item); + g_object_unref (G_OBJECT(item)); + } + + if (indicator_session_actions_can_hibernate (p->backend_actions)) + { + item = g_menu_item_new (_("Hibernate"), "indicator.hibernate"); + g_menu_append_item (menu, item); + g_object_unref (G_OBJECT(item)); + } + + if (!g_settings_get_boolean (s, "suppress-restart-menuitem")) + { + item = g_menu_item_new (ellipsis ? _("Restart\342\200\246") + : _("Restart"), "indicator.restart"); + g_menu_append_item (menu, item); + g_object_unref (G_OBJECT(item)); + } + + if (!g_settings_get_boolean (s, "suppress-shutdown-menuitem")) + { + item = g_menu_item_new (ellipsis ? _("Shutdown\342\200\246") + : _("Shutdown"), "indicator.shutdown"); + g_menu_append_item (menu, item); + g_object_unref (G_OBJECT(item)); + } + + return G_MENU_MODEL (menu); +} + +static void +create_menu (IndicatorSessionService * self, int form_factor) +{ + GMenu * menu; + GMenu * submenu; + GMenuItem * header; + GMenuModel * sections[16]; + int i; + int n = 0; + + g_assert (0<=form_factor && form_factorpriv->menus[form_factor].menu == NULL); + + if (form_factor == FORM_DESKTOP) + { + sections[n++] = create_admin_section (); + sections[n++] = create_settings_section (self); + sections[n++] = create_switch_section (self); + sections[n++] = create_session_section (self); + } + else if (form_factor == FORM_GREETER) + { + sections[n++] = create_session_section (self); + } + + /* add sections to the submenu */ + submenu = g_menu_new (); + for (i=0; ipriv->menus[form_factor].menu = menu; + self->priv->menus[form_factor].submenu = submenu; +} + +/*** +**** GActions +***/ + +static IndicatorSessionActions * +get_backend_actions (gpointer gself) +{ + return INDICATOR_SESSION_SERVICE(gself)->priv->backend_actions; +} + +static void +on_about_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) +{ + indicator_session_actions_about (get_backend_actions(gself)); +} + +static void +on_help_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) +{ + indicator_session_actions_help (get_backend_actions(gself)); +} + +static void +on_settings_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) +{ + indicator_session_actions_settings (get_backend_actions(gself)); +} + +static void +on_logout_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) +{ + indicator_session_actions_logout (get_backend_actions(gself)); +} + +static void +on_suspend_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) +{ + indicator_session_actions_suspend (get_backend_actions(gself)); +} + +static void +on_hibernate_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) +{ + indicator_session_actions_hibernate (get_backend_actions(gself)); +} + +static void +on_restart_activated (GSimpleAction * action G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) +{ + indicator_session_actions_restart (get_backend_actions(gself)); +} + +static void +on_shutdown_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) +{ + indicator_session_actions_shutdown (get_backend_actions(gself)); +} + +static void +on_guest_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) +{ + indicator_session_actions_switch_to_guest (get_backend_actions(gself)); +} + +static void +on_screensaver_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) +{ + indicator_session_actions_switch_to_screensaver (get_backend_actions(gself)); +} + +static void +on_greeter_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) +{ + indicator_session_actions_switch_to_greeter (get_backend_actions(gself)); +} + +static void +on_user_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param, + gpointer gself) +{ + const char * username = g_variant_get_string (param, NULL); + indicator_session_actions_switch_to_username (get_backend_actions(gself), + username); +} + +static void +init_gactions (IndicatorSessionService * self) +{ + GVariant * v; + GSimpleAction * a; + priv_t * p = self->priv; + + GActionEntry entries[] = { + { "about", on_about_activated }, + { "help", on_help_activated }, + { "settings", on_settings_activated }, + { "logout", on_logout_activated }, + { "suspend", on_suspend_activated }, + { "hibernate", on_hibernate_activated }, + { "restart", on_restart_activated }, + { "shutdown", on_shutdown_activated }, + { "switch-to-screensaver", on_screensaver_activated }, + { "switch-to-greeter", on_greeter_activated } + }; + + p->actions = g_simple_action_group_new (); + + g_action_map_add_action_entries (G_ACTION_MAP(p->actions), + entries, + G_N_ELEMENTS(entries), + self); + + /* add switch-to-guest action */ + v = create_guest_switcher_state (self); + a = g_simple_action_new_stateful ("switch-to-guest", NULL, v); + g_signal_connect (a, "activate", G_CALLBACK(on_guest_activated), self); + g_simple_action_group_insert (p->actions, G_ACTION(a)); + p->guest_switcher_action = a; + + /* add switch-to-user action... parameter is the uesrname */ + v = create_user_switcher_state (self); + a = g_simple_action_new_stateful ("switch-to-user", G_VARIANT_TYPE_STRING, v); + g_signal_connect (a, "activate", G_CALLBACK(on_user_activated), self); + g_simple_action_group_insert (p->actions, G_ACTION(a)); + p->user_switcher_action = a; + + /* add the header action */ + v = g_variant_new ("(sssb)", "label", ICON_DEFAULT, "a11y", TRUE); + a = g_simple_action_new_stateful ("_header", NULL, v); + g_simple_action_group_insert (p->actions, G_ACTION(a)); + p->header_action = a; + + rebuild_now (self, SECTION_HEADER); +} + +/*** +**** +***/ + +static void +replace_section (GMenu * parent, int pos, GMenuModel * new_section) +{ + g_menu_remove (parent, pos); + g_menu_insert_section (parent, pos, NULL, new_section); + g_object_unref (G_OBJECT(new_section)); +} + +static void +rebuild_now (IndicatorSessionService * self, int sections) +{ + priv_t * p = self->priv; + struct FormMenuInfo * desktop = &p->menus[FORM_DESKTOP]; + struct FormMenuInfo * greeter = &p->menus[FORM_GREETER]; + + if (sections & SECTION_HEADER) + { + update_header_action (self); + } + + if (sections & SECTION_ADMIN) + { + replace_section (desktop->submenu, 0, create_admin_section()); + } + + if (sections & SECTION_SETTINGS) + { + replace_section (desktop->submenu, 1, create_settings_section(self)); + } + + if (sections & SECTION_SWITCH) + { + replace_section (desktop->submenu, 2, create_switch_section(self)); + update_switch_actions (self); + } + + if (sections & SECTION_SESSION) + { + replace_section (desktop->submenu, 3, create_session_section(self)); + replace_section (greeter->submenu, 0, create_session_section(self)); + } +} + +static int +rebuild_timeout_func (IndicatorSessionService * self) +{ + priv_t * p = self->priv; + rebuild_now (self, p->rebuild_flags); + p->rebuild_flags = 0; + p->rebuild_id = 0; + return G_SOURCE_REMOVE; +} + +static void +rebuild_soon (IndicatorSessionService * self, int section) +{ + priv_t * p = self->priv; + + p->rebuild_flags |= section; + + if (p->rebuild_id == 0) + { + static const int REBUILD_INTERVAL_MSEC = 500; + + p->rebuild_id = g_timeout_add (REBUILD_INTERVAL_MSEC, + (GSourceFunc)rebuild_timeout_func, + self); + } +} + +/*** +**** GDBus +***/ + +static void +on_bus_acquired (GDBusConnection * connection, + const gchar * name, + gpointer gself) +{ + int i; + guint id; + GError * err = NULL; + IndicatorSessionService * self = INDICATOR_SESSION_SERVICE(gself); + priv_t * p = self->priv; + + g_debug ("bus acquired: %s", name); + + p->conn = g_object_ref (G_OBJECT (connection)); + + /* export the actions */ + if ((id = g_dbus_connection_export_action_group (connection, + BUS_PATH, + G_ACTION_GROUP (p->actions), + &err))) + { + p->actions_export_id = id; + } + else + { + g_warning ("cannot export action group: %s", err->message); + g_clear_error (&err); + } + + /* export the menus */ + for (i=0; imenus[i]; + + if (menu->menu == NULL) + create_menu (self, i); + + if ((id = g_dbus_connection_export_menu_model (connection, + path, + G_MENU_MODEL (menu->menu), + &err))) + { + menu->export_id = id; + } + else + { + g_warning ("cannot export %s menu: %s", menu_names[i], err->message); + g_clear_error (&err); + } + + g_free (path); + } +} + +static void +unexport (IndicatorSessionService * self) +{ + int i; + priv_t * p = self->priv; + + /* unexport the menus */ + for (i=0; ipriv->menus[i].export_id; + + if (*id) + { + g_dbus_connection_unexport_menu_model (p->conn, *id); + *id = 0; + } + } + + /* unexport the actions */ + if (p->actions_export_id) + { + g_dbus_connection_unexport_action_group (p->conn, p->actions_export_id); + p->actions_export_id = 0; + } +} + +static void +on_name_lost (GDBusConnection * connection G_GNUC_UNUSED, + const gchar * name, + gpointer gself) +{ + g_debug ("%s %s name lost %s", G_STRLOC, G_STRFUNC, name); + + unexport (INDICATOR_SESSION_SERVICE (gself)); +} + +/*** +**** +***/ + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_service_init (IndicatorSessionService * self) +{ + int i; + GStrv keys; + priv_t * p; + gpointer gp; + + /* init our priv pointer */ + p = G_TYPE_INSTANCE_GET_PRIVATE (self, + INDICATOR_TYPE_SESSION_SERVICE, + IndicatorSessionServicePrivate); + p->indicator_settings = g_settings_new ("com.canonical.indicator.session"); + p->keybinding_settings = g_settings_new ("org.gnome.settings-daemon.plugins.media-keys"); + self->priv = p; + + /* init the backend objects */ + backend_get (g_cancellable_new (), &p->backend_actions, + &p->backend_users, + &p->backend_guest); + + /* init our key-to-User table */ + p->users = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + (GDestroyNotify)indicator_session_user_free); + keys = indicator_session_users_get_keys (p->backend_users); + for (i=0; keys && keys[i]; ++i) + add_user (self, keys[i]); + g_strfreev (keys); + + init_gactions (self); + + /* watch for changes in backend_users */ + gp = p->backend_users; + g_signal_connect (gp, INDICATOR_SESSION_USERS_SIGNAL_USER_ADDED, + G_CALLBACK(on_user_added), self); + g_signal_connect (gp, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, + G_CALLBACK(on_user_changed), self); + g_signal_connect (gp, INDICATOR_SESSION_USERS_SIGNAL_USER_REMOVED, + G_CALLBACK(on_user_removed), self); + g_signal_connect_swapped (gp, "notify::is-live-session", + G_CALLBACK(rebuild_switch_section_soon), self); + + /* watch for changes in backend_guest */ + gp = p->backend_guest; + g_signal_connect_swapped (gp, "notify::guest-is-active-session", + G_CALLBACK(rebuild_header_soon), self); + g_signal_connect_swapped (gp, "notify", + G_CALLBACK(rebuild_switch_section_soon), self); + + /* watch for updates in backend_actions */ + gp = p->backend_actions; + g_signal_connect_swapped (gp, "notify", + G_CALLBACK(rebuild_switch_section_soon), self); + g_signal_connect_swapped (gp, "notify", + G_CALLBACK(rebuild_session_section_soon), self); + g_signal_connect_swapped (gp, "notify::has-online-account-error", + G_CALLBACK(rebuild_header_soon), self); + g_signal_connect_swapped (gp, "notify::has-online-account-error", + G_CALLBACK(rebuild_settings_section_soon), self); + + /* watch for changes in the indicator's settings */ + gp = p->indicator_settings; + g_signal_connect_swapped (gp, "changed::suppress-logout-restart-shutdown", + G_CALLBACK(rebuild_switch_section_soon), self); + g_signal_connect_swapped (gp, "changed::suppress-logout-restart-shutdown", + G_CALLBACK(rebuild_session_section_soon), self); + g_signal_connect_swapped (gp, "changed::suppress-logout-menuitem", + G_CALLBACK(rebuild_session_section_soon), self); + g_signal_connect_swapped (gp, "changed::suppress-restart-menuitem", + G_CALLBACK(rebuild_session_section_soon), self); + g_signal_connect_swapped (gp, "changed::suppress-shutdown-menuitem", + G_CALLBACK(rebuild_session_section_soon), self); + g_signal_connect_swapped (gp, "changed::show-real-name-on-panel", + G_CALLBACK(rebuild_header_soon), self); + + /* watch for changes to the lock keybinding */ + gp = p->keybinding_settings; + g_signal_connect_swapped (gp, "changed::screensaver", + G_CALLBACK(rebuild_switch_section_soon), self); +} + +static void +my_constructed (GObject * o) +{ + GBusNameOwnerFlags owner_flags; + IndicatorSessionService * self = INDICATOR_SESSION_SERVICE(o); + + /* own the name in constructed() instead of init() so that + we'll know the value of the 'replace' property */ + owner_flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT; + if (self->priv->replace) + owner_flags |= G_BUS_NAME_OWNER_FLAGS_REPLACE; + + self->priv->own_id = g_bus_own_name (G_BUS_TYPE_SESSION, + BUS_NAME, + owner_flags, + on_bus_acquired, + NULL, + on_name_lost, + self, + NULL); +} + +/*** +**** GObject plumbing: properties +***/ + +static void +my_get_property (GObject * o, + guint property_id, + GValue * value, + GParamSpec * pspec) +{ + IndicatorSessionService * self = INDICATOR_SESSION_SERVICE (o); + + switch (property_id) + { + case PROP_REPLACE: + g_value_set_boolean (value, self->priv->replace); + break; + + case PROP_MAX_USERS: + g_value_set_uint (value, self->priv->max_users); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec); + } +} + +static void +my_set_property (GObject * o, + guint property_id, + const GValue * value G_GNUC_UNUSED, + GParamSpec * pspec) +{ + IndicatorSessionService * self = INDICATOR_SESSION_SERVICE (o); + + switch (property_id) + { + case PROP_REPLACE: + self->priv->replace = g_value_get_boolean (value); + break; + + case PROP_MAX_USERS: + self->priv->max_users = g_value_get_uint (value); + rebuild_switch_section_soon (self); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec); + } +} + +/*** +**** GObject plumbing: life cycle +***/ + +static void +my_dispose (GObject * o) +{ + int i; + IndicatorSessionService * self = INDICATOR_SESSION_SERVICE(o); + priv_t * p = self->priv; + + unexport (self); + + if (p->rebuild_id) + { + g_source_remove (p->rebuild_id); + p->rebuild_id = 0; + } + + if (p->own_id) + { + g_bus_unown_name (p->own_id); + p->own_id = 0; + } + + g_clear_pointer (&p->users, g_hash_table_destroy); + g_clear_object (&p->backend_users); + g_clear_object (&p->backend_guest); + g_clear_object (&p->backend_actions); + g_clear_object (&p->indicator_settings); + g_clear_object (&p->keybinding_settings); + g_clear_object (&p->actions); + + for (i=0; imenus[i].menu); + + g_clear_object (&p->header_action); + g_clear_object (&p->user_switcher_action); + g_clear_object (&p->guest_switcher_action); + g_clear_object (&p->conn); + + G_OBJECT_CLASS (indicator_session_service_parent_class)->dispose (o); +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_service_class_init (IndicatorSessionServiceClass * klass) +{ + GObjectClass * object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = my_dispose; + object_class->constructed = my_constructed; + object_class->get_property = my_get_property; + object_class->set_property = my_set_property; + + g_type_class_add_private (klass, sizeof (IndicatorSessionServicePrivate)); + + properties[PROP_0] = NULL; + + properties[PROP_REPLACE] = g_param_spec_boolean ("replace", + "Replace Service", + "Replace existing service", + FALSE, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + + properties[PROP_MAX_USERS] = g_param_spec_uint ("max-users", + "Max Users", + "Max visible users", + 0, INT_MAX, 12, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, PROP_LAST, properties); +} + +IndicatorSessionService * +indicator_session_service_new (gboolean replace) +{ + GObject * o = g_object_new (INDICATOR_TYPE_SESSION_SERVICE, + "replace", replace, + NULL); + + return INDICATOR_SESSION_SERVICE (o); +} diff --git a/src/service.h b/src/service.h new file mode 100644 index 0000000..2a78855 --- /dev/null +++ b/src/service.h @@ -0,0 +1,64 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef __INDICATOR_SESSION_SERVICE_H__ +#define __INDICATOR_SESSION_SERVICE_H__ + +#include +#include + +G_BEGIN_DECLS + +/* standard GObject macros */ +#define INDICATOR_TYPE_SESSION_SERVICE (indicator_session_service_get_type()) +#define INDICATOR_SESSION_SERVICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_SESSION_SERVICE, IndicatorSessionService)) +#define INDICATOR_SESSION_SERVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_TYPE_SESSION_SERVICE, IndicatorSessionServiceClass)) +#define INDICATOR_SESSION_SERVICE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), INDICATOR_TYPE_SESSION_SERVICE, IndicatorSessionServiceClass)) +#define INDICATOR_IS_SESSION_SERVICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_SESSION_SERVICE)) + +typedef struct _IndicatorSessionService IndicatorSessionService; +typedef struct _IndicatorSessionServiceClass IndicatorSessionServiceClass; +typedef struct _IndicatorSessionServicePrivate IndicatorSessionServicePrivate; + +/** + * The Indicator Session Service. + */ +struct _IndicatorSessionService +{ + /*< private >*/ + GObject parent; + IndicatorSessionServicePrivate * priv; +}; + +struct _IndicatorSessionServiceClass +{ + GObjectClass parent_class; +}; + +/*** +**** +***/ + +GType indicator_session_service_get_type (void); + +IndicatorSessionService * indicator_session_service_new (gboolean replace); + +G_END_DECLS + +#endif /* __INDICATOR_SESSION_SERVICE_H__ */ diff --git a/src/session-dbus.c b/src/session-dbus.c deleted file mode 100644 index 4ece444..0000000 --- a/src/session-dbus.c +++ /dev/null @@ -1,282 +0,0 @@ -/* -The Dbus object on the bus for the indicator. - -Copyright 2010 Canonical Ltd. - -Authors: - Ted Gould - Conor Curran - -This program 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. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . -*/ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include - -#include "session-dbus.h" -#include "shared-names.h" - -static GVariant * get_users_real_name (SessionDbus * service); -static void bus_get_cb (GObject * object, GAsyncResult * res, gpointer user_data); -static void bus_method_call (GDBusConnection * connection, const gchar * sender, const gchar * path, const gchar * interface, const gchar * method, GVariant * params, GDBusMethodInvocation * invocation, gpointer user_data); - -#include "gen-session-dbus.xml.h" - -typedef struct _SessionDbusPrivate SessionDbusPrivate; -struct _SessionDbusPrivate { - gchar * name; - GDBusConnection * bus; - GCancellable * bus_cancel; - guint dbus_registration; -}; - -/* GDBus Stuff */ -static GDBusNodeInfo * node_info = NULL; -static GDBusInterfaceInfo * interface_info = NULL; -static GDBusInterfaceVTable interface_table = { - method_call: bus_method_call, - get_property: NULL, /* No properties */ - set_property: NULL /* No properties */ -}; - -#define SESSION_DBUS_GET_PRIVATE(o) \ -(G_TYPE_INSTANCE_GET_PRIVATE ((o), SESSION_DBUS_TYPE, SessionDbusPrivate)) - -static void session_dbus_class_init (SessionDbusClass *klass); -static void session_dbus_init (SessionDbus *self); -static void session_dbus_dispose (GObject *object); -static void session_dbus_finalize (GObject *object); - -G_DEFINE_TYPE (SessionDbus, session_dbus, G_TYPE_OBJECT); - -static void -session_dbus_class_init (SessionDbusClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (SessionDbusPrivate)); - - object_class->dispose = session_dbus_dispose; - object_class->finalize = session_dbus_finalize; - - /* Setting up the DBus interfaces */ - if (node_info == NULL) { - GError * error = NULL; - - node_info = g_dbus_node_info_new_for_xml(_session_dbus, &error); - if (error != NULL) { - g_error("Unable to parse Session Service Interface description: %s", error->message); - g_error_free(error); - } - } - - if (interface_info == NULL) { - interface_info = g_dbus_node_info_lookup_interface(node_info, INDICATOR_SESSION_SERVICE_DBUS_IFACE); - - if (interface_info == NULL) { - g_error("Unable to find interface '" INDICATOR_SESSION_SERVICE_DBUS_IFACE "'"); - } - } - - return; -} - -static void -session_dbus_init (SessionDbus *self) -{ - SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(self); - - priv->name = NULL; - priv->bus = NULL; - priv->bus_cancel = NULL; - priv->dbus_registration = 0; - - priv->bus_cancel = g_cancellable_new(); - g_bus_get(G_BUS_TYPE_SESSION, - priv->bus_cancel, - bus_get_cb, - self); - - return; -} - -static void -bus_get_cb (GObject * object, GAsyncResult * res, gpointer user_data) -{ - GError * error = NULL; - GDBusConnection * connection = g_bus_get_finish(res, &error); - - if (error != NULL) { - g_error("OMG! Unable to get a connection to DBus: %s", error->message); - g_error_free(error); - return; - } - - SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(user_data); - - g_warn_if_fail(priv->bus == NULL); - priv->bus = connection; - - if (priv->bus_cancel != NULL) { - g_object_unref(priv->bus_cancel); - priv->bus_cancel = NULL; - } - - /* Now register our object on our new connection */ - priv->dbus_registration = g_dbus_connection_register_object(priv->bus, - INDICATOR_SESSION_SERVICE_DBUS_OBJECT, - interface_info, - &interface_table, - user_data, - NULL, - &error); - - if (error != NULL) { - g_error("Unable to register the object to DBus: %s", error->message); - g_error_free(error); - return; - } - - return; -} - -/* A method has been called from our dbus inteface. Figure out what it - is and dispatch it. */ -static void -bus_method_call (GDBusConnection * connection, const gchar * sender, - const gchar * path, const gchar * interface, - const gchar * method, GVariant * params, - GDBusMethodInvocation * invocation, gpointer user_data) -{ - SessionDbus * service = SESSION_DBUS (user_data); - - GVariant * retval = NULL; - - if (g_strcmp0(method, "GetUserRealName") == 0) { - retval = get_users_real_name (service); - } - else { - g_warning("Calling method '%s' on the indicator service and it's unknown", method); - } - g_dbus_method_invocation_return_value(invocation, retval); - return; -} - -static void -session_dbus_dispose (GObject *object) -{ - SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(object); - - if (priv->dbus_registration != 0) { - g_dbus_connection_unregister_object(priv->bus, priv->dbus_registration); - /* Don't care if it fails, there's nothing we can do */ - priv->dbus_registration = 0; - } - - if (priv->bus != NULL) { - g_object_unref(priv->bus); - priv->bus = NULL; - } - - if (priv->bus_cancel != NULL) { - g_cancellable_cancel(priv->bus_cancel); - g_object_unref(priv->bus_cancel); - priv->bus_cancel = NULL; - } - - G_OBJECT_CLASS (session_dbus_parent_class)->dispose (object); - return; -} - -static void -session_dbus_finalize (GObject *object) -{ - SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(object); - - g_clear_pointer (&priv->name, g_free); - - G_OBJECT_CLASS (session_dbus_parent_class)->finalize (object); - return; -} - -static GVariant * -get_users_real_name (SessionDbus * service) -{ - SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(service); - return g_variant_new ("(s)", priv->name ? priv->name : ""); -} - -SessionDbus * -session_dbus_new (void) -{ - return SESSION_DBUS(g_object_new(SESSION_DBUS_TYPE, NULL)); -} - -void -session_dbus_set_name (SessionDbus * session, const gchar * name) -{ -} - -void -session_dbus_set_users_real_name (SessionDbus * session, const gchar * name) -{ - SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(session); - GError * error = NULL; - - g_free (priv->name); - priv->name = g_strdup(name); - - if (priv->bus != NULL) { - g_dbus_connection_emit_signal (priv->bus, - NULL, - INDICATOR_SESSION_SERVICE_DBUS_OBJECT, - INDICATOR_SESSION_SERVICE_DBUS_IFACE, - "UserRealNameUpdated", - g_variant_new ("(s)", priv->name, NULL), - &error); - - if (error != NULL) { - g_warning("Unable to send UserRealNameUpdated signal: %s", error->message); - g_error_free(error); - return; - } - } - return; -} - -void session_dbus_restart_required (SessionDbus* session) -{ - SessionDbusPrivate * priv = SESSION_DBUS_GET_PRIVATE(session); - GError * error = NULL; - - if (priv->bus != NULL) { - g_debug("About to send RebootRequired signal"); - - g_dbus_connection_emit_signal (priv->bus, - NULL, - INDICATOR_SESSION_SERVICE_DBUS_OBJECT, - INDICATOR_SESSION_SERVICE_DBUS_IFACE, - "RestartRequired", - NULL, - &error); - - if (error != NULL) { - g_warning("Unable to send reboot-required signal: %s", error->message); - g_error_free(error); - } - } - -} diff --git a/src/session-dbus.h b/src/session-dbus.h deleted file mode 100644 index 7520f06..0000000 --- a/src/session-dbus.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -The Dbus object on the bus for the indicator. - -Copyright 2010 Canonical Ltd. - -Authors: - Ted Gould - -This program 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. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . -*/ - -#ifndef __SESSION_DBUS_H__ -#define __SESSION_DBUS_H__ - -#include -#include - -G_BEGIN_DECLS - -#define SESSION_DBUS_TYPE (session_dbus_get_type ()) -#define SESSION_DBUS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SESSION_DBUS_TYPE, SessionDbus)) -#define SESSION_DBUS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SESSION_DBUS_TYPE, SessionDbusClass)) -#define IS_SESSION_DBUS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SESSION_DBUS_TYPE)) -#define IS_SESSION_DBUS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SESSION_DBUS_TYPE)) -#define SESSION_DBUS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SESSION_DBUS_TYPE, SessionDbusClass)) - -typedef struct _SessionDbus SessionDbus; -typedef struct _SessionDbusClass SessionDbusClass; - -struct _SessionDbusClass { - GObjectClass parent_class; - void (*icon_updated) (SessionDbus * session, gchar * icon, gpointer user_data); -}; - -struct _SessionDbus { - GObject parent; -}; - -GType session_dbus_get_type (void); -SessionDbus * session_dbus_new (void); -void session_dbus_set_name (SessionDbus * session, const gchar * name); -void session_dbus_set_users_real_name (SessionDbus * session, const gchar * name); -void session_dbus_restart_required (SessionDbus* session); -G_END_DECLS - -#endif diff --git a/src/session-dbus.xml b/src/session-dbus.xml deleted file mode 100644 index 96e9837..0000000 --- a/src/session-dbus.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/src/session-menu-mgr.c b/src/session-menu-mgr.c deleted file mode 100644 index b618135..0000000 --- a/src/session-menu-mgr.c +++ /dev/null @@ -1,1226 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Charles Kerr - Conor Curran - -This program 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. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . -*/ - -#include "config.h" - -#include -#include /* geteuid(), getpwuid() */ - -#include -#include - -#include -#include - -#include "dbus-upower.h" -#include "session-menu-mgr.h" -#include "shared-names.h" -#include "users-service-dbus.h" -#include "online-accounts-mgr.h" - -#define DEBUG_SHOW_ALL FALSE - -#define UPOWER_ADDRESS "org.freedesktop.UPower" -#define UPOWER_PATH "/org/freedesktop/UPower" - -#define CMD_HELP "yelp" -#define CMD_INFO "gnome-control-center info" -#define CMD_SYSTEM_SETTINGS "gnome-control-center" -#ifdef HAVE_GTKLOGOUTHELPER - #define HAVE_RESTART_CMD TRUE - #define CMD_RESTART LIBEXECDIR"/gtk-logout-helper --restart" - #define CMD_LOGOUT LIBEXECDIR"/gtk-logout-helper --logout" - #define CMD_SHUTDOWN LIBEXECDIR"/gtk-logout-helper --shutdown" -#else - #define HAVE_RESTART_CMD FALSE /* hmm, no gnome-session-quit --restart? */ - #define CMD_RESTART "" - #define CMD_LOGOUT "gnome-session-quit --logout" - #define CMD_SHUTDOWN "gnome-session-quit --power-off" -#endif - -/** - * Which switch menuitem to show -- based on lockdown settings, - * greeter mode, number of users in the system, and so on. - * See get_switcher_mode() - */ -typedef enum -{ - SWITCHER_MODE_SCREENSAVER, - SWITCHER_MODE_LOCK, - SWITCHER_MODE_SWITCH, - SWITCHER_MODE_SWITCH_OR_LOCK, - SWITCHER_MODE_NONE -} -SwitcherMode; - -/** - * Creates and manages the menumodel and associated actions for the - * session menu described at . - * - * This is a pretty straightforward class: it creates the menumodel - * and listens for events that can affect the model's properties. - * - * Simple event sources, such as GSettings and a UPower DBus proxy, - * are handled here. More involved event sources are delegated to the - * UsersServiceDBus facade class. - */ -struct _SessionMenuMgr -{ - GObject parent_instance; - - DbusmenuMenuitem * top_mi; - DbusmenuMenuitem * screensaver_mi; - DbusmenuMenuitem * lock_mi; - DbusmenuMenuitem * lock_switch_mi; - DbusmenuMenuitem * guest_mi; - DbusmenuMenuitem * online_accounts_mi; - DbusmenuMenuitem * logout_mi; - DbusmenuMenuitem * suspend_mi; - DbusmenuMenuitem * hibernate_mi; - DbusmenuMenuitem * restart_mi; - DbusmenuMenuitem * shutdown_mi; - - GSList * user_menuitems; - gint user_menuitem_index; - - GSettings * lockdown_settings; - GSettings * indicator_settings; - GSettings * keybinding_settings; - - /* cached settings taken from the upower proxy */ - gboolean can_hibernate; - gboolean can_suspend; - gboolean allow_hibernate; - gboolean allow_suspend; - - gboolean greeter_mode; - - GCancellable * cancellable; - DBusUPower * upower_proxy; - SessionDbus * session_dbus; - UsersServiceDbus * users_dbus_facade; - OnlineAccountsMgr * online_accounts_mgr; -}; - -static SwitcherMode get_switcher_mode (SessionMenuMgr *); - -static void init_upower_proxy (SessionMenuMgr *); - -static void update_screensaver_shortcut (SessionMenuMgr *); -static void update_user_menuitems (SessionMenuMgr *); -static void update_session_menuitems (SessionMenuMgr *); -static void update_confirmation_labels (SessionMenuMgr *); - -static void action_func_lock (SessionMenuMgr *); -static void action_func_suspend (SessionMenuMgr *); -static void action_func_hibernate (SessionMenuMgr *); -static void action_func_switch_to_lockscreen (SessionMenuMgr *); -static void action_func_switch_to_greeter (SessionMenuMgr *); -static void action_func_switch_to_guest (SessionMenuMgr *); -static void action_func_switch_to_user (AccountsUser *); -static void action_func_spawn_async (const char * cmd); - -static gboolean is_this_guest_session (void); -static gboolean is_this_live_session (void); - -static void on_guest_logged_in_changed (UsersServiceDbus *, - SessionMenuMgr *); - -static void on_user_logged_in_changed (UsersServiceDbus *, - AccountsUser *, - SessionMenuMgr *); - -/** -*** GObject init / dispose -**/ - -G_DEFINE_TYPE (SessionMenuMgr, session_menu_mgr, G_TYPE_OBJECT); - -static void -session_menu_mgr_init (SessionMenuMgr *mgr) -{ - mgr->top_mi = dbusmenu_menuitem_new (); - - /* Lockdown settings */ - GSettings * s = g_settings_new ("org.gnome.desktop.lockdown"); - g_signal_connect_swapped (s, "changed::disable-log-out", - G_CALLBACK(update_session_menuitems), mgr); - g_signal_connect_swapped (s, "changed::disable-lock-screen", - G_CALLBACK(update_user_menuitems), mgr); - g_signal_connect_swapped (s, "changed::disable-user-switching", - G_CALLBACK(update_user_menuitems), mgr); - mgr->lockdown_settings = s; - - /* Indicator settings */ - s = g_settings_new ("com.canonical.indicator.session"); - g_signal_connect_swapped (s, "changed::suppress-logout-restart-shutdown", - G_CALLBACK(update_confirmation_labels), mgr); - g_signal_connect_swapped (s, "changed::suppress-logout-menuitem", - G_CALLBACK(update_session_menuitems), mgr); - g_signal_connect_swapped (s, "changed::suppress-restart-menuitem", - G_CALLBACK(update_session_menuitems), mgr); - g_signal_connect_swapped (s, "changed::suppress-shutdown-menuitem", - G_CALLBACK(update_session_menuitems), mgr); - mgr->indicator_settings = s; - - /* Keybinding settings */ - s = g_settings_new ("org.gnome.settings-daemon.plugins.media-keys"); - g_signal_connect_swapped (s, "changed::screensaver", - G_CALLBACK(update_screensaver_shortcut), mgr); - mgr->keybinding_settings = s; - - /* listen for user events */ - mgr->users_dbus_facade = g_object_new (USERS_SERVICE_DBUS_TYPE, NULL); - g_signal_connect_swapped (mgr->users_dbus_facade, "user-list-changed", - G_CALLBACK (update_user_menuitems), mgr); - g_signal_connect (mgr->users_dbus_facade, "user-logged-in-changed", - G_CALLBACK(on_user_logged_in_changed), mgr); - g_signal_connect (mgr->users_dbus_facade, "guest-logged-in-changed", - G_CALLBACK(on_guest_logged_in_changed), mgr); - - init_upower_proxy (mgr); - - /* Online accounts menu item */ - mgr->online_accounts_mgr = online_accounts_mgr_new (); -} - -static void -session_menu_mgr_dispose (GObject *object) -{ - SessionMenuMgr * mgr = SESSION_MENU_MGR (object); - - if (mgr->cancellable != NULL) - { - g_cancellable_cancel (mgr->cancellable); - g_clear_object (&mgr->cancellable); - } - - g_clear_object (&mgr->indicator_settings); - g_clear_object (&mgr->lockdown_settings); - g_clear_object (&mgr->keybinding_settings); - g_clear_object (&mgr->upower_proxy); - g_clear_object (&mgr->users_dbus_facade); - g_clear_object (&mgr->top_mi); - g_clear_object (&mgr->session_dbus); - g_clear_object (&mgr->online_accounts_mgr); - - g_slist_free (mgr->user_menuitems); - mgr->user_menuitems = NULL; - - G_OBJECT_CLASS (session_menu_mgr_parent_class)->dispose (object); -} - -static void -session_menu_mgr_class_init (SessionMenuMgrClass * klass) -{ - GObjectClass* object_class = G_OBJECT_CLASS (klass); - object_class->dispose = session_menu_mgr_dispose; -} - -/*** -**** UPower Proxy: -**** -**** 1. While bootstrapping, we invoke the AllowSuspend and AllowHibernate -**** methods to find out whether or not those features are allowed. -**** 2. While bootstrapping, we get the CanSuspend and CanHibernate properties -**** and also listen for property changes. -**** 3. These four values are used to set suspend and hibernate's visibility. -**** -***/ - -static void -on_upower_properties_changed (SessionMenuMgr * mgr) -{ - gboolean need_refresh = FALSE; - - if (mgr->upower_proxy != NULL) - { - gboolean b; - - /* suspend */ - b = dbus_upower_get_can_suspend (mgr->upower_proxy); - if (mgr->can_suspend != b) - { - mgr->can_suspend = b; - need_refresh = TRUE; - } - - /* hibernate */ - b = dbus_upower_get_can_hibernate (mgr->upower_proxy); - if (mgr->can_hibernate != b) - { - mgr->can_hibernate = b; - need_refresh = TRUE; - } - } - - if (need_refresh) - { - update_session_menuitems (mgr); - } -} - -static void -init_upower_proxy (SessionMenuMgr * mgr) -{ - /* default values */ - mgr->can_suspend = TRUE; - mgr->can_hibernate = TRUE; - mgr->allow_suspend = TRUE; - mgr->allow_hibernate = TRUE; - - mgr->cancellable = g_cancellable_new (); - - GError * error = NULL; - mgr->upower_proxy = dbus_upower_proxy_new_for_bus_sync ( - G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - UPOWER_ADDRESS, - UPOWER_PATH, - NULL, - &error); - if (error != NULL) - { - g_warning ("Error creating upower proxy: %s", error->message); - g_clear_error (&error); - } - else - { - dbus_upower_call_suspend_allowed_sync (mgr->upower_proxy, - &mgr->allow_suspend, - NULL, - &error); - if (error != NULL) - { - g_warning ("%s: %s", G_STRFUNC, error->message); - g_clear_error (&error); - } - - dbus_upower_call_hibernate_allowed_sync (mgr->upower_proxy, - &mgr->allow_hibernate, - NULL, - &error); - if (error != NULL) - { - g_warning ("%s: %s", G_STRFUNC, error->message); - g_clear_error (&error); - } - - g_signal_connect_swapped (mgr->upower_proxy, "changed", - G_CALLBACK(on_upower_properties_changed), mgr); - } -} - -/*** -**** Menuitem Helpers -***/ - -static inline void -mi_set_label (DbusmenuMenuitem * mi, const char * str) -{ - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_LABEL, str); -} - -static inline void -mi_set_type (DbusmenuMenuitem * mi, const char * str) -{ - dbusmenu_menuitem_property_set (mi, DBUSMENU_MENUITEM_PROP_TYPE, str); -} - -static inline void -mi_set_visible (DbusmenuMenuitem * mi, gboolean b) -{ - dbusmenu_menuitem_property_set_bool (mi, DBUSMENU_MENUITEM_PROP_VISIBLE, - b || DEBUG_SHOW_ALL); -} - -static inline void -mi_set_logged_in (DbusmenuMenuitem * mi, gboolean b) -{ - dbusmenu_menuitem_property_set_bool (mi, USER_ITEM_PROP_LOGGED_IN, b); -} - -static DbusmenuMenuitem* -mi_new_separator (void) -{ - DbusmenuMenuitem * mi = dbusmenu_menuitem_new (); - mi_set_type (mi, DBUSMENU_CLIENT_TYPES_SEPARATOR); - return mi; -} - -static DbusmenuMenuitem* -mi_new (const char * label) -{ - DbusmenuMenuitem * mi = dbusmenu_menuitem_new (); - mi_set_label (mi, label); - return mi; -} - -static void -check_online_accounts_status (SessionMenuMgr * mgr, DbusmenuMenuitem * mi) -{ - const gchar *disposition; - gboolean on_alert; - - disposition = - dbusmenu_menuitem_property_get (mi, DBUSMENU_MENUITEM_PROP_DISPOSITION); - on_alert = g_strcmp0 (disposition, DBUSMENU_MENUITEM_DISPOSITION_ALERT) == 0; - - mi_set_visible (mi, on_alert); -} - -static void -on_online_accounts_changed (SessionMenuMgr * mgr, const gchar * property, - GVariant *value, DbusmenuMenuitem *mi) -{ - if (g_strcmp0 (property, DBUSMENU_MENUITEM_PROP_DISPOSITION) == 0) - { - check_online_accounts_status(mgr, mi); - } -} - -/*** -**** Admin Menuitems -**** -***/ - -static void -build_admin_menuitems (SessionMenuMgr * mgr) -{ - if (!mgr->greeter_mode) - { - DbusmenuMenuitem * mi; - const gboolean show_settings = !mgr->greeter_mode; - - mi = mi_new (_("About This Computer")); - dbusmenu_menuitem_child_append (mgr->top_mi, mi); - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(action_func_spawn_async), CMD_INFO); - - mi = mi_new (_("Ubuntu Help")); - dbusmenu_menuitem_child_append (mgr->top_mi, mi); - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(action_func_spawn_async), CMD_HELP); - - mi = mi_new_separator (); - mi_set_visible (mi, show_settings); - dbusmenu_menuitem_child_append (mgr->top_mi, mi); - - mi = mi_new (_("System Settings\342\200\246")); - mi_set_visible (mi, show_settings); - dbusmenu_menuitem_child_append (mgr->top_mi, mi); - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(action_func_spawn_async), - CMD_SYSTEM_SETTINGS); - - mi = mgr->online_accounts_mi = - online_accounts_mgr_get_menu_item (mgr->online_accounts_mgr); - dbusmenu_menuitem_child_append (mgr->top_mi, mi); - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, - G_CALLBACK(on_online_accounts_changed), - mgr); - check_online_accounts_status (mgr, mi); - - mi = mi_new_separator (); - dbusmenu_menuitem_child_append (mgr->top_mi, mi); - } -} - -/*** -**** Session Menuitems -**** -***/ - -static void -update_session_menuitems (SessionMenuMgr * mgr) -{ - gboolean v; - GSettings * s = mgr->indicator_settings; - - v = !mgr->greeter_mode - && !is_this_live_session() - && !g_settings_get_boolean (mgr->lockdown_settings, "disable-log-out") - && !g_settings_get_boolean (s, "suppress-logout-menuitem"); - mi_set_visible (mgr->logout_mi, v); - - v = mgr->can_suspend - && mgr->allow_suspend; - mi_set_visible (mgr->suspend_mi, v); - - v = mgr->can_hibernate - && mgr->allow_hibernate; - mi_set_visible (mgr->hibernate_mi, v); - - v = HAVE_RESTART_CMD - && !g_settings_get_boolean (s, "suppress-restart-menuitem"); - mi_set_visible (mgr->restart_mi, v); - - v = !g_settings_get_boolean (s, "suppress-shutdown-menuitem"); - mi_set_visible (mgr->shutdown_mi, v); -} - -/* Update the ellipses when the confirmation setting changes. - * - * : - * "Label the menu item with a trailing ellipsis ("...") only if the - * command requires further input from the user before it can be performed." - */ -static void -update_confirmation_labels (SessionMenuMgr * mgr) -{ - const gboolean confirm_needed = !g_settings_get_boolean ( - mgr->indicator_settings, - "suppress-logout-restart-shutdown"); - - mi_set_label (mgr->logout_mi, confirm_needed ? _("Log Out\342\200\246") - : _("Log Out")); - - mi_set_label (mgr->shutdown_mi, confirm_needed ? _("Shut Down\342\200\246") - : _("Shut Down")); - - mi_set_label (mgr->restart_mi, confirm_needed ? _("Restart\342\200\246") - : _("Restart")); -} - -static void -build_session_menuitems (SessionMenuMgr* mgr) -{ - DbusmenuMenuitem * mi; - - mi = mgr->logout_mi = mi_new (_("Log Out\342\200\246")); - dbusmenu_menuitem_child_append (mgr->top_mi, mi); - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(action_func_spawn_async), CMD_LOGOUT); - - mi = mgr->suspend_mi = mi_new (_("Suspend")); - dbusmenu_menuitem_child_append (mgr->top_mi, mi); - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(action_func_suspend), mgr); - - mi = mgr->hibernate_mi = mi_new (_("Hibernate")); - dbusmenu_menuitem_child_append (mgr->top_mi, mi); - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(action_func_hibernate), mgr); - - mi = mgr->restart_mi = mi_new (_("Restart\342\200\246")); - dbusmenu_menuitem_child_append (mgr->top_mi, mi); - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(action_func_spawn_async), CMD_RESTART); - - mi = mgr->shutdown_mi = mi_new (_("Shut Down\342\200\246")); - dbusmenu_menuitem_child_append (mgr->top_mi, mi); - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(action_func_spawn_async), CMD_SHUTDOWN); - - update_confirmation_labels (mgr); - update_session_menuitems (mgr); -} - -/**** -***** User Menuitems -***** https://wiki.ubuntu.com/SystemMenu#Account-switching_items -****/ - -/* Local extensions to AccountsUser */ - -static GQuark -get_menuitem_quark (void) -{ - static GQuark q = 0; - - if (G_UNLIKELY(!q)) - { - q = g_quark_from_static_string ("menuitem"); - } - - return q; -} - -static DbusmenuMenuitem* -user_get_menuitem (AccountsUser * user) -{ - return g_object_get_qdata (G_OBJECT(user), get_menuitem_quark()); -} - -static void -user_clear_menuitem (AccountsUser * user) -{ - g_object_steal_qdata (G_OBJECT(user), get_menuitem_quark()); -} - -static void -user_set_menuitem (AccountsUser * user, DbusmenuMenuitem * mi) -{ - g_object_set_qdata (G_OBJECT(user), get_menuitem_quark(), mi); - - g_object_weak_ref (G_OBJECT(mi), (GWeakNotify)user_clear_menuitem, user); -} - -/***/ - -static GQuark -get_mgr_quark (void) -{ - static GQuark q = 0; - - if (G_UNLIKELY(!q)) - { - q = g_quark_from_static_string ("session-menu-mgr"); - } - - return q; -} - -static SessionMenuMgr* -user_get_mgr (AccountsUser * user) -{ - return g_object_get_qdata (G_OBJECT(user), get_mgr_quark()); -} - -static void -user_set_mgr (AccountsUser * user, SessionMenuMgr * mgr) -{ - g_object_set_qdata (G_OBJECT(user), get_mgr_quark(), mgr); -} - -/***/ - -static GQuark -get_collision_quark (void) -{ - static GQuark q = 0; - - if (G_UNLIKELY(!q)) - { - q = g_quark_from_static_string ("name-collision"); - } - - return q; -} - -static gboolean -user_has_name_collision (AccountsUser * u) -{ - return g_object_get_qdata (G_OBJECT(u), get_collision_quark()) != NULL; -} - -static void -user_set_name_collision (AccountsUser * u, gboolean b) -{ - g_object_set_qdata (G_OBJECT(u), get_collision_quark(), GINT_TO_POINTER(b)); -} - -/*** -**** -***/ - -static void -on_guest_logged_in_changed (UsersServiceDbus * usd, - SessionMenuMgr * mgr) -{ - if (mgr->guest_mi != NULL) - { - mi_set_logged_in (mgr->guest_mi, - users_service_dbus_is_guest_logged_in (usd)); - } -} - -/* When a user's login state changes, - update the corresponding menuitem's LOGGED_IN property */ -static void -on_user_logged_in_changed (UsersServiceDbus * usd, - AccountsUser * user, - SessionMenuMgr * mgr) -{ - DbusmenuMenuitem * mi = user_get_menuitem (user); - - if (mi != NULL) - { - mi_set_logged_in (mi, users_service_dbus_is_user_logged_in (usd, user)); - } -} - -static void -update_screensaver_shortcut (SessionMenuMgr * mgr) -{ - gchar * s = g_settings_get_string (mgr->keybinding_settings, "screensaver"); - g_debug ("%s Screensaver shortcut changed to: '%s'", G_STRLOC, s); - - if (mgr->lock_mi != NULL) - { - dbusmenu_menuitem_property_set_shortcut_string (mgr->lock_mi, s); - } - - if (mgr->lock_switch_mi != NULL) - { - dbusmenu_menuitem_property_set_shortcut_string (mgr->lock_switch_mi, s); - } - - if (mgr->screensaver_mi != NULL) - { - dbusmenu_menuitem_property_set_shortcut_string (mgr->screensaver_mi, s); - } - - g_free (s); -} - -static void -update_user_menuitem_icon (DbusmenuMenuitem * mi, AccountsUser * user) -{ - const gchar * str = accounts_user_get_icon_file (user); - - if (!str || !*str) - { - str = USER_ITEM_ICON_DEFAULT; - } - - dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_ICON, str); -} - -static void -update_user_menuitem_name (DbusmenuMenuitem * mi, AccountsUser * user) -{ - GString * gstr = g_string_new (accounts_user_get_real_name (user)); - - if (user_has_name_collision (user)) - g_string_append_printf (gstr, " (%s)", accounts_user_get_user_name(user)); - - if (!gstr->len) - g_string_assign (gstr, accounts_user_get_user_name(user)); - - dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, gstr->str); - g_string_free (gstr, TRUE); -} - -static void -on_user_property_changed (AccountsUser * user, - GParamSpec * pspec, - DbusmenuMenuitem * mi) -{ - static const char * interned_icon_file = NULL; - static const char * interned_real_name = NULL; - static const char * interned_user_name = NULL; - - if (G_UNLIKELY (interned_icon_file == NULL)) - { - interned_icon_file = g_intern_static_string ("icon-file"); - interned_user_name = g_intern_static_string ("user-name"); - interned_real_name = g_intern_static_string ("real-name"); - } - - if (pspec->name == interned_icon_file) - { - update_user_menuitem_icon (mi, user); - } - else if ((pspec->name == interned_real_name) - || (pspec->name == interned_user_name)) - { - /* name changing can affect other menuitems too by invalidating - the sort order or name collision flags... so let's rebuild */ - update_user_menuitems (user_get_mgr (user)); - } -} - -typedef struct -{ - gpointer instance; - gulong handler_id; -} -SignalHandlerData; - -/* when a user menuitem is destroyed, - it should stop listening for its UserAccount's property changes */ -static void -on_user_menuitem_destroyed (SignalHandlerData * data) -{ - g_signal_handler_disconnect (data->instance, data->handler_id); - g_free (data); -} - -static DbusmenuMenuitem* -user_menuitem_new (AccountsUser * user, SessionMenuMgr * mgr) -{ - DbusmenuMenuitem * mi = dbusmenu_menuitem_new (); - mi_set_type (mi, USER_ITEM_TYPE); - - /* set the name & icon and listen for property changes */ - update_user_menuitem_name (mi, user); - update_user_menuitem_icon (mi, user); - SignalHandlerData * hd = g_new0 (SignalHandlerData, 1); - hd->instance = user; - hd->handler_id = g_signal_connect (user, "notify", - G_CALLBACK(on_user_property_changed), mi); - g_object_weak_ref (G_OBJECT(mi), (GWeakNotify)on_user_menuitem_destroyed, hd); - - /* set the logged-in property */ - mi_set_logged_in (mi, - users_service_dbus_is_user_logged_in (mgr->users_dbus_facade, user)); - - /* set the is-current-user property */ - const gboolean is_current_user = - !g_strcmp0 (g_get_user_name(), accounts_user_get_user_name(user)); - - dbusmenu_menuitem_property_set_bool (mi, - USER_ITEM_PROP_IS_CURRENT_USER, - is_current_user); - - /* set the switch-to-user action */ - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK (action_func_switch_to_user), user); - - /* give this AccountsUser a hook back to this menuitem */ - user_set_menuitem (user, mi); - user_set_mgr (user, mgr); - - return mi; -} - -/* for sorting AccountsUsers from most to least frequently used */ -static gint -compare_users_by_login_frequency (gconstpointer a, gconstpointer b) -{ - const guint64 a_freq = accounts_user_get_login_frequency (ACCOUNTS_USER(a)); - const guint64 b_freq = accounts_user_get_login_frequency (ACCOUNTS_USER(b)); - if (a_freq > b_freq) return -1; - if (a_freq < b_freq) return 1; - return 0; -} - -/* for sorting AccountsUsers alphabetically */ -static gint -compare_users_by_username (gconstpointer ga, gconstpointer gb) -{ - AccountsUser * a = ACCOUNTS_USER(ga); - AccountsUser * b = ACCOUNTS_USER(gb); - - const int ret = g_strcmp0 (accounts_user_get_real_name (a), - accounts_user_get_real_name (b)); - - if (!ret) /* names are the same, so both have a name collision */ - { - user_set_name_collision (a, TRUE); - user_set_name_collision (b, TRUE); - } - - return ret; -} - -static gboolean -is_user_switching_allowed (SessionMenuMgr * mgr) -{ - /* maybe it's locked down */ - if (g_settings_get_boolean (mgr->lockdown_settings, "disable-user-switching")) - { - return FALSE; - } - - /* maybe the seat doesn't support activation */ - if (!users_service_dbus_can_activate_session (mgr->users_dbus_facade)) - { - return FALSE; - } - - return TRUE; -} - -static void -build_user_menuitems (SessionMenuMgr * mgr) -{ - g_return_if_fail (!mgr->greeter_mode); - - DbusmenuMenuitem * mi; - GSList * items = NULL; - gint pos = mgr->user_menuitem_index; - const char * current_real_name = NULL; - - /** - *** Start Screen Saver - *** Switch Account... - *** Lock - *** Lock / Switch Account... - **/ - - const SwitcherMode mode = get_switcher_mode (mgr); - - mi = mgr->screensaver_mi = mi_new (_("Start Screen Saver")); - mi_set_visible (mi, mode == SWITCHER_MODE_SCREENSAVER); - dbusmenu_menuitem_child_add_position (mgr->top_mi, mi, pos++); - items = g_slist_prepend (items, mi); - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK (action_func_lock), mgr); - - mi = mi_new (_("Switch User Account\342\200\246")); - mi_set_visible (mi, mode == SWITCHER_MODE_SWITCH); - dbusmenu_menuitem_child_add_position (mgr->top_mi, mi, pos++); - items = g_slist_prepend (items, mi); - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK (action_func_switch_to_greeter), mgr); - - mi = mgr->lock_mi = mi_new (_("Lock")); - mi_set_visible (mi, mode == SWITCHER_MODE_LOCK); - dbusmenu_menuitem_child_add_position (mgr->top_mi, mi, pos++); - items = g_slist_prepend (items, mi); - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK (action_func_switch_to_lockscreen), mgr); - - mi = mgr->lock_switch_mi = mi_new (_("Lock/Switch Account\342\200\246")); - mi_set_visible (mi, mode == SWITCHER_MODE_SWITCH_OR_LOCK); - dbusmenu_menuitem_child_add_position (mgr->top_mi, mi, pos++); - items = g_slist_prepend (items, mi); - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK (action_func_switch_to_lockscreen), mgr); - - const gboolean is_guest = is_this_guest_session (); - const gboolean guest_allowed = - users_service_dbus_guest_session_enabled (mgr->users_dbus_facade); - mi = mgr->guest_mi = dbusmenu_menuitem_new (); - mi_set_type (mi, USER_ITEM_TYPE); - mi_set_visible (mi, !is_guest && guest_allowed); - dbusmenu_menuitem_property_set (mi, USER_ITEM_PROP_NAME, _("Guest Session")); - dbusmenu_menuitem_child_add_position (mgr->top_mi, mi, pos++); - on_guest_logged_in_changed (mgr->users_dbus_facade, mgr); - items = g_slist_prepend (items, mi); - g_signal_connect_swapped (mi, DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK (action_func_switch_to_guest), mgr); - - if (guest_allowed && is_guest) - { - current_real_name = _("Guest"); - } - - /*** - **** Users - ***/ - - /* if we can switch to another user account, show them here */ - const char * const username = g_get_user_name(); - GList * users = users_service_dbus_get_user_list (mgr->users_dbus_facade); - - /* since we're building (or rebuilding) from scratch, - clear the name collision flags */ - GList * u; - for (u=users; u!=NULL; u=u->next) - { - AccountsUser * user = ACCOUNTS_USER(u->data); - - user_set_name_collision (user, FALSE); - - if (!g_strcmp0 (username, accounts_user_get_user_name(user))) - { - current_real_name = accounts_user_get_real_name (user); - } - } - - if (is_user_switching_allowed (mgr)) - { - /* pick the most frequently used accounts */ - const int MAX_USERS = 12; /* this limit comes from the spec */ - if (g_list_length(users) > MAX_USERS) - { - users = g_list_sort (users, compare_users_by_login_frequency); - GList * last = g_list_nth (users, MAX_USERS-1); - GList * remainder = last->next; - last->next = NULL; - remainder->prev = NULL; - g_list_free (remainder); - } - - /* Sort the users by name for display */ - users = g_list_sort (users, compare_users_by_username); - - /* Create menuitems for them */ - int i; - for (i=0, u=users; inext, i++) - { - AccountsUser * user = u->data; - DbusmenuMenuitem * mi = user_menuitem_new (user, mgr); - dbusmenu_menuitem_child_add_position (mgr->top_mi, mi, pos++); - items = g_slist_prepend (items, mi); - } - } - - g_list_free (users); - - /* separator */ - if (mode != SWITCHER_MODE_SCREENSAVER && !is_guest && guest_allowed) - { - mi = mi_new_separator (); - dbusmenu_menuitem_child_add_position (mgr->top_mi, mi, pos++); - items = g_slist_prepend (items, mi); - } - - if (current_real_name != NULL) - { - session_dbus_set_users_real_name (mgr->session_dbus, - current_real_name); - } - - update_screensaver_shortcut (mgr); - mgr->user_menuitems = items; -} - -static void -update_user_menuitems (SessionMenuMgr * mgr) -{ - /* remove any previous user menuitems */ - GSList * l; - for (l=mgr->user_menuitems; l!=NULL; l=l->next) - { - dbusmenu_menuitem_child_delete (mgr->top_mi, l->data); - } - g_slist_free (mgr->user_menuitems); - mgr->user_menuitems = NULL; - - /* add fresh user menuitems */ - if (!mgr->greeter_mode) - { - build_user_menuitems (mgr); - } -} - -/*** -**** Actions! -***/ - -static void -action_func_spawn_async (const char * cmd) -{ - GError * error = NULL; - - g_debug ("%s calling \"%s\"", G_STRFUNC, cmd); - g_spawn_command_line_async (cmd, &error); - - if (error != NULL) - { - g_warning ("Unable to execute \"%s\": %s", cmd, error->message); - g_clear_error (&error); - } -} - -/* Calling "Lock" locks the screen & goes to black. - Calling "SimulateUserActivity" afterwards shows the Lock Screen. */ -static void -lock_helper (SessionMenuMgr * mgr, gboolean show_lock_screen) -{ - if (!g_settings_get_boolean (mgr->lockdown_settings, "disable-lock-screen")) - { - GError * error = NULL; - GDBusProxy * proxy = g_dbus_proxy_new_for_bus_sync ( - G_BUS_TYPE_SESSION, - G_DBUS_PROXY_FLAGS_NONE, - NULL, - "org.gnome.ScreenSaver", - "/org/gnome/ScreenSaver", - "org.gnome.ScreenSaver", - NULL, - &error); - - if (error == NULL) - { - g_dbus_proxy_call_sync (proxy, "Lock", - NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, - &error); - } - - if ((error == NULL) && show_lock_screen) - { - g_dbus_proxy_call_sync (proxy, "SimulateUserActivity", - NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, - &error); - } - - if (error != NULL) - { - g_warning ("Error locking screen: %s", error->message); - } - - g_clear_object (&proxy); - g_clear_error (&error); - } -} - -static void -action_func_lock (SessionMenuMgr * mgr) -{ - lock_helper (mgr, FALSE); -} - -static void -action_func_switch_to_lockscreen (SessionMenuMgr * mgr) -{ - lock_helper (mgr, TRUE); -} - -static void -action_func_switch_to_greeter (SessionMenuMgr * mgr) -{ - action_func_lock (mgr); - users_service_dbus_show_greeter (mgr->users_dbus_facade); -} - -static void -action_func_switch_to_user (AccountsUser * user) -{ - SessionMenuMgr * mgr = user_get_mgr (user); - - g_return_if_fail (mgr != NULL); - - if (g_strcmp0 (g_get_user_name(), accounts_user_get_user_name(user)) != 0) - { - action_func_lock (mgr); - users_service_dbus_activate_user_session (mgr->users_dbus_facade, user); - } -} - -static void -action_func_switch_to_guest (SessionMenuMgr * mgr) -{ - action_func_lock (mgr); - users_service_dbus_activate_guest_session (mgr->users_dbus_facade); -} - -static void -action_func_suspend (SessionMenuMgr * mgr) -{ - GError * error = NULL; - - dbus_upower_call_suspend_sync (mgr->upower_proxy, - mgr->cancellable, - &error); - - if (error != NULL) - { - g_warning ("%s: %s", G_STRFUNC, error->message); - g_clear_error (&error); - } -} - -static void -action_func_hibernate (SessionMenuMgr * mgr) -{ - GError * error = NULL; - - dbus_upower_call_hibernate_sync (mgr->upower_proxy, - mgr->cancellable, - &error); - - if (error != NULL) - { - g_warning ("%s: %s", G_STRFUNC, error->message); - g_clear_error (&error); - } -} - -/*** -**** -***/ - -static gboolean -is_this_guest_session (void) -{ - /* FIXME: this test has been here awhile and seems to work, - but seems brittle to me */ - return geteuid() < 500; -} - -static gboolean -is_this_live_session (void) -{ - const struct passwd * const pw = getpwuid (geteuid()); - return (pw->pw_uid==999) && !g_strcmp0("ubuntu",pw->pw_name); -} - -static SwitcherMode -get_switcher_mode (SessionMenuMgr * mgr) -{ - SwitcherMode mode; - - const gboolean can_lock = !g_settings_get_boolean (mgr->lockdown_settings, - "disable-lock-screen"); - const gboolean can_switch = is_user_switching_allowed (mgr); - - if (!can_lock && !can_switch) /* hmm, quite an extreme lockdown */ - { - mode = SWITCHER_MODE_NONE; - } - else if (is_this_live_session()) /* live sessions can't lock or switch */ - { - mode = SWITCHER_MODE_SCREENSAVER; - } - else if (!can_switch) /* switching's locked down */ - { - mode = SWITCHER_MODE_LOCK; - } - else if (is_this_guest_session ()) /* guest sessions can't lock */ - { - mode = SWITCHER_MODE_SWITCH; - } - else /* both locking & switching are allowed */ - { - GList * l = users_service_dbus_get_user_list (mgr->users_dbus_facade); - const size_t user_count = g_list_length (l); - g_list_free (l); - - /* only show switch mode if we have users to switch to */ - mode = user_count > (is_this_guest_session() ? 0 : 1) - ? SWITCHER_MODE_SWITCH_OR_LOCK - : SWITCHER_MODE_LOCK; - } - - return mode; -} - - -/*** -**** -***/ - -SessionMenuMgr* -session_menu_mgr_new (SessionDbus * session_dbus, - gboolean greeter_mode) -{ - SessionMenuMgr* mgr = g_object_new (SESSION_TYPE_MENU_MGR, NULL); - mgr->greeter_mode = greeter_mode; - mgr->session_dbus = g_object_ref (session_dbus); - build_admin_menuitems (mgr); - const guint n = g_list_length (dbusmenu_menuitem_get_children (mgr->top_mi)); - mgr->user_menuitem_index = n; - update_user_menuitems (mgr); - build_session_menuitems (mgr); - - /* After we have the session menu items built we can look to - align them with UPower */ - on_upower_properties_changed (mgr); - - return mgr; -} - -/** - * session_menu_mgr_get_menu: - * - * Returns: (transfer none): the manager's menu. - */ -DbusmenuMenuitem * -session_menu_mgr_get_menu (SessionMenuMgr * mgr) -{ - g_return_val_if_fail (IS_SESSION_MENU_MGR(mgr), NULL); - - return mgr->top_mi; -} diff --git a/src/session-menu-mgr.h b/src/session-menu-mgr.h deleted file mode 100644 index 5a173e1..0000000 --- a/src/session-menu-mgr.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Conor Curran - -This program 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. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . -*/ - - -#ifndef _SESSION_MENU_MGR_H_ -#define _SESSION_MENU_MGR_H_ - -#include - -#include "session-dbus.h" - -G_BEGIN_DECLS - -#define SESSION_TYPE_MENU_MGR (session_menu_mgr_get_type ()) -#define SESSION_MENU_MGR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SESSION_TYPE_MENU_MGR, SessionMenuMgr)) -#define SESSION_MENU_MGR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SESSION_TYPE_MENU_MGR, SessionMenuMgrClass)) -#define IS_SESSION_MENU_MGR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SESSION_TYPE_MENU_MGR)) -#define IS_SESSION_MENU_MGR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SESSION_TYPE_MENU_MGR)) -#define SESSION_MENU_MGR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SESSION_TYPE_MENU_MGR, SessionMenuMgrClass)) - -typedef struct _SessionMenuMgrClass SessionMenuMgrClass; -typedef struct _SessionMenuMgr SessionMenuMgr; - -struct _SessionMenuMgrClass -{ - GObjectClass parent_class; -}; - -GType session_menu_mgr_get_type (void) G_GNUC_CONST; - -SessionMenuMgr* session_menu_mgr_new (SessionDbus * session_dbus, - gboolean greeter_mode); - -DbusmenuMenuitem* session_menu_mgr_get_menu (SessionMenuMgr * mgr); - - -G_END_DECLS - -#endif /* _SESSION_MENU_MGR_H_ */ diff --git a/src/session-service.c b/src/session-service.c deleted file mode 100644 index 13438d3..0000000 --- a/src/session-service.c +++ /dev/null @@ -1,96 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould - Christoph Korn - Cody Russell - Conor Curran - Charles Kerr - -This program 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. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . -*/ - -#include "config.h" - -#include -#include - -#include -#include -#include - -#include - -#include - -#include - -#include "session-dbus.h" -#include "session-menu-mgr.h" -#include "shared-names.h" -#include "users-service-dbus.h" - -static SessionDbus * session_dbus = NULL; -static GMainLoop * mainloop = NULL; - - -/* When the service interface starts to shutdown, - we should follow it. */ -void -service_shutdown (IndicatorService * service, gpointer user_data) -{ - if (mainloop != NULL) - { - g_debug ("Service shutdown"); - g_main_loop_quit (mainloop); - } -} - -static inline gboolean -is_greeter_mode (void) -{ - return !g_strcmp0 (g_getenv ("INDICATOR_GREETER_MODE"), "1"); -} - -/* Main, is well, main. It brings everything up and throws - us into the mainloop of no return. */ -int -main (int argc, char ** argv) -{ - /* Setting up i18n and gettext. - Apparently we need all of these. */ - setlocale (LC_ALL, ""); - bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); - textdomain (GETTEXT_PACKAGE); - - IndicatorService * service = indicator_service_new_version (INDICATOR_SESSION_DBUS_NAME, - INDICATOR_SESSION_DBUS_VERSION); - g_signal_connect (G_OBJECT(service), INDICATOR_SERVICE_SIGNAL_SHUTDOWN, - G_CALLBACK(service_shutdown), NULL); - - session_dbus = session_dbus_new(); - - SessionMenuMgr * menu_mgr = session_menu_mgr_new (session_dbus, is_greeter_mode()); - DbusmenuServer* server = dbusmenu_server_new (INDICATOR_SESSION_DBUS_OBJECT); - dbusmenu_server_set_root (server, session_menu_mgr_get_menu (menu_mgr)); - - mainloop = g_main_loop_new(NULL, FALSE); - g_main_loop_run(mainloop); - - return 0; -} - diff --git a/src/shared-names.h b/src/shared-names.h deleted file mode 100644 index c08f98a..0000000 --- a/src/shared-names.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -A small wrapper utility to load indicators and put them as menu items -into the gnome-panel using it's applet interface. - -Copyright 2009 Canonical Ltd. - -Authors: - Ted Gould - -This program 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. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . -*/ - -#ifndef __DBUS_SHARED_NAMES_H__ -#define __DBUS_SHARED_NAMES_H__ - -#define INDICATOR_SESSION_DBUS_NAME "com.canonical.indicator.session" -#define INDICATOR_SESSION_DBUS_OBJECT "/com/canonical/indicator/session/menu" -#define INDICATOR_SESSION_DBUS_VERSION 0 - -#define INDICATOR_SESSION_SERVICE_DBUS_OBJECT "/com/canonical/indicator/session/service" -#define INDICATOR_SESSION_SERVICE_DBUS_IFACE "com.canonical.indicator.session.service" -#define USER_ITEM_TYPE "x-canonical-user-item" -#define USER_ITEM_PROP_NAME "user-item-name" -#define USER_ITEM_PROP_LOGGED_IN "user-item-logged-in" -#define USER_ITEM_PROP_IS_CURRENT_USER "user-item-is-current-user" -#define USER_ITEM_PROP_ICON "user-item-icon-path" -#define USER_ITEM_ICON_DEFAULT "avatar-default" - -#define ICON_DEFAULT "system-devices-panel" -#define ICON_INFO "system-devices-panel-information" -#define ICON_ALERT "system-devices-panel-alert" - -/* the session indicator's settings */ -#define SESSION_SCHEMA "com.canonical.indicator.session" -#define SUPPRESS_KEY "suppress-logout-restart-shutdown" -#define LOGOUT_KEY "suppress-logout-menuitem" -#define RESTART_KEY "suppress-restart-menuitem" -#define SHUTDOWN_KEY "suppress-shutdown-menuitem" -#define SHOW_USER_MENU "user-show-menu" - - -#endif /* __DBUS_SHARED_NAMES_H__ */ diff --git a/src/upower.xml b/src/upower.xml deleted file mode 100644 index 18d5fbd..0000000 --- a/src/upower.xml +++ /dev/null @@ -1,309 +0,0 @@ - - - - - - - - The DeviceKit-power service is available via the system message - bus. To access the service, use - the org.freedesktop.UPower interface on - the /org/freedesktop/UPower object on - the D-Bus system bus service with the well-known - name org.freedesktop.UPower. - - - - -$ dbus-send --print-reply \ - --system \ - --dest=org.freedesktop.UPower \ - /org/freedesktop/UPower \ - org.freedesktop.UPower.EnumerateDevices - -method return sender=:1.386 -> dest=:1.451 reply_serial=2 - array [ - object path "/org/freedesktop/UPower/devices/line_power_AC" - object path "/org/freedesktop/UPower/devices/battery_BAT0" - ] - - - - - - - - - - - - An array of object paths for devices. - - - - - - Enumerate all power objects on the system. - - - - - - - - - - Object path of device that was added. - - - - - - Emitted when a device is added. - - - - - - - - - - Object path of device that was removed. - - - - - - Emitted when a device is removed. - - - - - - - - - - Object path of device that was changed. - - - - - - Emitted when a device changed. - - - - - - - - - - - - Emitted when one or more properties on the object changes. - - - - - - - - - - - - This signal is sent when the session is about to be suspended or - hibernated. - Session and system programs have one second to do anything required - before the sleep action is taken (such as sending out Avahi or - Jabber messages). - - - - - - - - - - - - This signal is sent when the session has just returned from - Suspend() or Hibernate(). - Session and system programs can then do anything required (such as - sending out Avahi or Jabber messages). - - - - - - - - - - - - - This method tells UPower that the Suspend() or Hibernate() method - is about to be called. - This allows UPower to emit the Suspending signal whilst - session activities are happening that have to be done before the - suspend process is started. - - - This method would typically be called by the session power - management daemon, before it locks the screen and waits for the - screen to fade to black. - The session power management component would then call Suspend() or - Hibernate() when these syncronous tasks have completed. - - - If this method is not called than nothing bad will happen and - Suspend() or Hibernate() will block for the required second. - - - - - - - - - - - - - Suspends the computer into a low power state. - System state is not preserved if the power is lost. - - - If AboutToRequestSleep() has not been called then UPower will send - the Sleeping() signal and block for one second. - - - If AboutToRequestSleep() has been called less than one second - before this method is called then UPower will block for the - remaining time to complete one second of delay. - - - - - - - - - - - TRUE if allowed, otherwise FALSE - - - - - Check if the caller has (or can get) the PolicyKit privilege to call - Suspend. - - - - - - - - - - - - - Hibernates the computer into a low power state. - System state is preserved if the power is lost. - - - If AboutToRequestSleep() has not been called then UPower will send - the Sleeping() signal and block for one second. - - - If AboutToRequestSleep() has been called less than one second - before this method is called then UPower will block for the - remaining time to complete one second of delay. - - - - - - - - - - - TRUE if allowed, otherwise FALSE - - - - - Check if the caller has (or can get) the PolicyKit privilege to call - Hibernate. - - - - - - - - - - Version of the running daemon, e.g. 002. - - - - - - Whether the system is able to suspend. - - - - - - Whether the system is able to hibernate. - - - - - - Indicates whether the system is running on battery power. - This property is provided for convenience. - - - - - - Indicates whether the system is running on battery power and if the battery is critically low. - This property is provided for convenience. - - - - - - - - Indicates if the laptop lid is closed where the display cannot be seen. - - - - - - - - - - If the system has a lid device. - - - - - - - - diff --git a/src/user-widget.c b/src/user-widget.c deleted file mode 100644 index 79b87b0..0000000 --- a/src/user-widget.c +++ /dev/null @@ -1,292 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Conor Curran - Mirco Müller - Charles Kerr - -This program 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. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . -*/ - -#ifdef HAVE_CONFIG_H - #include "config.h" -#endif - -#include - -#include - -#include "shared-names.h" -#include "user-widget.h" - - -typedef struct _UserWidgetPrivate UserWidgetPrivate; - -struct _UserWidgetPrivate -{ - DbusmenuMenuitem* twin_item; - GtkWidget* user_image; - GtkWidget* user_name; - GtkWidget* container; - GtkWidget* tick_icon; - gboolean logged_in; - gboolean sessions_active; -}; - -#define USER_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), USER_WIDGET_TYPE, UserWidgetPrivate)) - -/* Prototypes */ -static void user_widget_class_init (UserWidgetClass *klass); -static void user_widget_init (UserWidget *self); -static void user_widget_dispose (GObject *object); -static void user_widget_finalize (GObject *object); - -static void user_widget_set_twin_item (UserWidget* self, - DbusmenuMenuitem* twin_item); - -static gboolean user_widget_primitive_draw_cb_gtk_3 (GtkWidget *image, - cairo_t* cr, - gpointer user_data); - -G_DEFINE_TYPE (UserWidget, user_widget, GTK_TYPE_MENU_ITEM); - -static void -user_widget_class_init (UserWidgetClass *klass) -{ - GObjectClass * gobject_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (UserWidgetPrivate)); - - gobject_class->dispose = user_widget_dispose; - gobject_class->finalize = user_widget_finalize; -} - -static void -user_widget_init (UserWidget *self) -{ - self->priv = USER_WIDGET_GET_PRIVATE(self); - - UserWidgetPrivate * priv = self->priv; - - priv->user_image = NULL; - priv->user_name = NULL; - priv->logged_in = FALSE; - priv->sessions_active = FALSE; - priv->container = NULL; - priv->tick_icon = NULL; - - // Create the UI elements. - priv->user_image = gtk_image_new (); - gtk_misc_set_alignment(GTK_MISC(priv->user_image), 0.0, 0.0); - - priv->user_name = gtk_label_new (NULL); - - priv->container = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4); - - priv->tick_icon = gtk_image_new_from_icon_name ("account-logged-in", - GTK_ICON_SIZE_MENU); - gtk_misc_set_alignment(GTK_MISC(priv->tick_icon), 1.0, 0.5); - - // Pack it together - gtk_box_pack_start (GTK_BOX (priv->container), - priv->user_image, - FALSE, - FALSE, - 0); - gtk_box_pack_start (GTK_BOX (priv->container), - priv->user_name, - FALSE, - FALSE, - 3); - gtk_box_pack_end (GTK_BOX(priv->container), - priv->tick_icon, - FALSE, - FALSE, 5); - - gtk_widget_show_all (priv->container); - gtk_container_add (GTK_CONTAINER (self), priv->container); - gtk_widget_show_all (priv->tick_icon); - gtk_widget_set_no_show_all (priv->tick_icon, TRUE); - gtk_widget_hide (priv->tick_icon); - - - // Fetch the drawing context. - g_signal_connect_after (GTK_WIDGET(self), "draw", - G_CALLBACK(user_widget_primitive_draw_cb_gtk_3), - GTK_WIDGET(self)); -} - -static void -user_widget_dispose (GObject *object) -{ - G_OBJECT_CLASS (user_widget_parent_class)->dispose (object); -} - -// TODO tidy up image and name -static void -user_widget_finalize (GObject *object) -{ - G_OBJECT_CLASS (user_widget_parent_class)->finalize (object); -} - - -/*****************************************************************/ - -// TODO handle drawing of green check mark -static gboolean -user_widget_primitive_draw_cb_gtk_3 (GtkWidget *widget, - cairo_t* cr, - gpointer user_data) -{ - g_return_val_if_fail(IS_USER_WIDGET(user_data), FALSE); - UserWidget* meta = USER_WIDGET(user_data); - UserWidgetPrivate * priv = USER_WIDGET_GET_PRIVATE(meta); - - // Draw dot only when user is the current user. - if (dbusmenu_menuitem_property_get_bool (priv->twin_item, USER_ITEM_PROP_IS_CURRENT_USER)) - { - gdouble x, y; - GtkStyle * style = gtk_widget_get_style (widget); - - GtkAllocation allocation; - gtk_widget_get_allocation (widget, &allocation); - x = allocation.x + 13; - y = allocation.height / 2; - - cairo_arc (cr, x, y, 3.0, 0.0, 2 * G_PI); - - cairo_set_source_rgb (cr, style->fg[gtk_widget_get_state(widget)].red/65535.0, - style->fg[gtk_widget_get_state(widget)].green/65535.0, - style->fg[gtk_widget_get_state(widget)].blue/65535.0); - cairo_fill (cr); - } - - return FALSE; -} - -/*** -**** -***/ - -static void -update_icon (UserWidget * self, DbusmenuMenuitem * mi) -{ - gboolean updated = FALSE; - GtkImage * image = GTK_IMAGE(self->priv->user_image); - - /* first try the menuitem's icon property */ - const gchar * icon_name = dbusmenu_menuitem_property_get (mi, USER_ITEM_PROP_ICON); - if (icon_name != NULL) - { - int width = 18; /* arbitrary default values */ - int height = 18; - GError * err = NULL; - GdkPixbuf * pixbuf = NULL; - - /* load the image */ - gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, &height); - pixbuf = gdk_pixbuf_new_from_file_at_size (icon_name, width, height, &err); - if (err == NULL) - { - gtk_image_set_from_pixbuf (image, pixbuf); - g_object_unref (pixbuf); - updated = TRUE; - } - else - { - g_warning ("Couldn't load the image \"%s\": %s", icon_name, err->message); - g_clear_error (&err); - } - } - - /* as a fallback, use the default user icon */ - if (!updated) - { - gtk_image_set_from_icon_name (image, - USER_ITEM_ICON_DEFAULT, - GTK_ICON_SIZE_MENU); - } -} - -static void -update_logged_in (UserWidget * self, DbusmenuMenuitem * mi) -{ - const gboolean b = dbusmenu_menuitem_property_get_bool (mi, USER_ITEM_PROP_LOGGED_IN); - - g_debug ("User \"%s\" %s active sessions", - dbusmenu_menuitem_property_get (mi, USER_ITEM_PROP_NAME), - b ? "has" : "doesn't have"); - - gtk_widget_set_visible (self->priv->tick_icon, b); -} - -static void -update_name (UserWidget * self, DbusmenuMenuitem * mi) -{ - gtk_label_set_label (GTK_LABEL(self->priv->user_name), - dbusmenu_menuitem_property_get (mi, USER_ITEM_PROP_NAME)); -} - -static void -user_widget_property_update (DbusmenuMenuitem * mi, - const gchar * property, - GVariant * value, - UserWidget * self) -{ - g_return_if_fail (IS_USER_WIDGET (self)); - - if (!g_strcmp0 (property, USER_ITEM_PROP_LOGGED_IN)) - { - update_logged_in (self, mi); - } - else if (!g_strcmp0 (property, USER_ITEM_PROP_ICON)) - { - update_icon (self, mi); - } - else if (!g_strcmp0 (property, USER_ITEM_PROP_NAME)) - { - update_name (self, mi); - } - else - { - g_debug ("%s FIXME: unhandled property change %s", G_STRFUNC, property); - } -} - -static void -user_widget_set_twin_item (UserWidget * self, DbusmenuMenuitem * mi) -{ - self->priv->twin_item = mi; - - update_icon (self, mi); - update_name (self, mi); - update_logged_in (self, mi); - - g_signal_connect (G_OBJECT(mi), "property-changed", - G_CALLBACK(user_widget_property_update), self); -} - - /** - * user_widget_new: - * @item: the #DbusmenuMenuitem this widget will render. - * - * Returns: (transfer full): a new #UserWidget. - **/ -GtkWidget* -user_widget_new (DbusmenuMenuitem *item) -{ - GtkWidget* widget = g_object_new(USER_WIDGET_TYPE, NULL); - user_widget_set_twin_item ( USER_WIDGET(widget), item ); - return widget; -} diff --git a/src/user-widget.h b/src/user-widget.h deleted file mode 100644 index 0953e6c..0000000 --- a/src/user-widget.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Conor Curran - -This program 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. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . -*/ -#ifndef __USER_WIDGET_H__ -#define __USER_WIDGET_H__ - -#include -#include - -G_BEGIN_DECLS - -#define USER_WIDGET_TYPE (user_widget_get_type ()) -#define USER_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), USER_WIDGET_TYPE, UserWidget)) -#define USER_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), USER_WIDGET_TYPE, UserWidgetClass)) -#define IS_USER_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), USER_WIDGET_TYPE)) -#define IS_USER_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), USER_WIDGET_TYPE)) -#define USER_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), USER_WIDGET_TYPE, UserWidgetClass)) - -typedef struct _UserWidget UserWidget; -typedef struct _UserWidgetClass UserWidgetClass; -typedef struct _UserWidgetPrivate UserWidgetPrivate; - -struct _UserWidgetClass -{ - GtkMenuItemClass parent_class; -}; - -struct _UserWidget -{ - /*< private >*/ - GtkMenuItem parent; - UserWidgetPrivate * priv; -}; - -GType user_widget_get_type (void) G_GNUC_CONST; -GtkWidget* user_widget_new(DbusmenuMenuitem *twin_item); - -G_END_DECLS - -#endif diff --git a/src/users-service-dbus.c b/src/users-service-dbus.c deleted file mode 100644 index f12f47c..0000000 --- a/src/users-service-dbus.c +++ /dev/null @@ -1,1044 +0,0 @@ -/* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 2; tab-width: 2 -*- */ -/* - * Copyright 2009 Canonical Ltd. - * - * Authors: - * Cody Russell - * Charles Kerr - * - * This program 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranties of - * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . - */ - -#ifdef HAVE_CONFIG_H - #include "config.h" -#endif - -#include - -#include - -#include /* getpwuid() */ - -#include "dbus-accounts.h" -#include "dbus-consolekit-manager.h" -#include "dbus-consolekit-seat.h" -#include "dbus-consolekit-session.h" -#include "dbus-display-manager.h" -#include "dbus-user.h" -#include "shared-names.h" -#include "users-service-dbus.h" - -#define CK_ADDR "org.freedesktop.ConsoleKit" -#define CK_SESSION_IFACE "org.freedesktop.ConsoleKit.Session" - -/** -*** -**/ - -static void update_user_list (UsersServiceDbus * self); - -static gchar* get_seat (UsersServiceDbus * service); - -static void on_user_added (Accounts * o, - const gchar * user_object_path, - UsersServiceDbus * service); - -static void on_user_deleted (Accounts * o, - const gchar * user_object_path, - UsersServiceDbus * service); - -static void on_session_added (ConsoleKitSeat * seat, - const gchar * ssid, - UsersServiceDbus * service); - -static void on_session_removed (ConsoleKitSeat * seat, - const gchar * ssid, - UsersServiceDbus * service); - -static void on_session_list (ConsoleKitSeat * seat, - GAsyncResult * result, - UsersServiceDbus * service); - -/*** -**** Priv Struct -***/ - -struct _UsersServiceDbusPrivate -{ - gchar * seat; - gchar * guest_ssid; - - /* ssid -> AccountsUser lookup */ - GHashTable * sessions; - - /* user object path -> AccountsUser lookup */ - GHashTable * users; - - GCancellable * cancellable; - ConsoleKitSeat * seat_proxy; - ConsoleKitManager * ck_manager_proxy; - Accounts * accounts_proxy; -}; - -/*** -**** GObject -***/ - -enum -{ - USER_LIST_CHANGED, - USER_LOGGED_IN_CHANGED, - GUEST_LOGGED_IN_CHANGED, - N_SIGNALS -}; - -static guint signals[N_SIGNALS] = { 0 }; - -G_DEFINE_TYPE (UsersServiceDbus, users_service_dbus, G_TYPE_OBJECT); - -static void -users_service_dbus_dispose (GObject *object) -{ - UsersServiceDbusPrivate * priv = USERS_SERVICE_DBUS(object)->priv; - - g_clear_object (&priv->accounts_proxy); - g_clear_object (&priv->seat_proxy); - g_clear_object (&priv->ck_manager_proxy); - - if (priv->cancellable != NULL) - { - g_cancellable_cancel (priv->cancellable); - g_clear_object (&priv->cancellable); - } - - if (priv->users != NULL) - { - g_hash_table_destroy (priv->users); - priv->users = NULL; - } - - if (priv->sessions != NULL) - { - g_hash_table_destroy (priv->sessions); - priv->sessions = NULL; - } - - G_OBJECT_CLASS (users_service_dbus_parent_class)->dispose (object); -} - -static void -users_service_dbus_finalize (GObject *object) -{ - UsersServiceDbusPrivate * priv = USERS_SERVICE_DBUS(object)->priv; - - g_free (priv->guest_ssid); - g_free (priv->seat); - - G_OBJECT_CLASS (users_service_dbus_parent_class)->finalize (object); -} - -static void -users_service_dbus_class_init (UsersServiceDbusClass *klass) -{ - GObjectClass *object_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (object_class, sizeof (UsersServiceDbusPrivate)); - - object_class->dispose = users_service_dbus_dispose; - object_class->finalize = users_service_dbus_finalize; - - signals[USER_LIST_CHANGED] = g_signal_new ( - "user-list-changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (UsersServiceDbusClass, user_list_changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); - - signals[USER_LOGGED_IN_CHANGED] = g_signal_new ( - "user-logged-in-changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (UsersServiceDbusClass, user_logged_in_changed), - NULL, NULL, - g_cclosure_marshal_VOID__OBJECT, - G_TYPE_NONE, 1, G_TYPE_OBJECT); - - signals[GUEST_LOGGED_IN_CHANGED] = g_signal_new ( - "guest-logged-in-changed", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (UsersServiceDbusClass, guest_logged_in_changed), - NULL, NULL, - g_cclosure_marshal_VOID__VOID, - G_TYPE_NONE, 0); -} - -static void -users_service_dbus_init (UsersServiceDbus *self) -{ - GError * error = NULL; - - self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, - USERS_SERVICE_DBUS_TYPE, - UsersServiceDbusPrivate); - - UsersServiceDbusPrivate * p = self->priv; - - p->cancellable = g_cancellable_new (); - - /* ssid -> AccountsUser */ - p->sessions = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); - - /* user object path -> AccountsUser */ - p->users = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - g_object_unref); - - /** - *** create the consolekit manager proxy... - **/ - - p->ck_manager_proxy = console_kit_manager_proxy_new_for_bus_sync ( - G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - "org.freedesktop.ConsoleKit", - "/org/freedesktop/ConsoleKit/Manager", - NULL, - &error); - if (error != NULL) - { - g_warning ("%s: %s", G_STRLOC, error->message); - g_clear_error (&error); - } - - p->seat = get_seat (self); - - /** - *** create the consolekit seat proxy... - **/ - - if (p->seat != NULL) - { - ConsoleKitSeat * proxy = console_kit_seat_proxy_new_for_bus_sync ( - G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - "org.freedesktop.ConsoleKit", - p->seat, - NULL, - &error); - - if (error != NULL) - { - g_warning ("Failed to connect to the ConsoleKit seat: %s", error->message); - g_clear_error (&error); - } - else - { - g_signal_connect (proxy, "session-added", - G_CALLBACK (on_session_added), self); - g_signal_connect (proxy, "session-removed", - G_CALLBACK (on_session_removed), self); - console_kit_seat_call_get_sessions (proxy, p->cancellable, - (GAsyncReadyCallback)on_session_list, self); - p->seat_proxy = proxy; - } - } - - /** - *** create the accounts manager proxy... - **/ - - Accounts * proxy = accounts_proxy_new_for_bus_sync ( - G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - "org.freedesktop.Accounts", - "/org/freedesktop/Accounts", - NULL, - &error); - if (error != NULL) - { - g_warning ("%s: %s", G_STRFUNC, error->message); - g_clear_error (&error); - } - else - { - g_signal_connect (proxy, "user-added", G_CALLBACK(on_user_added), self); - g_signal_connect (proxy, "user-deleted", G_CALLBACK(on_user_deleted), self); - p->accounts_proxy = proxy; - update_user_list (self); - } -} - -/*** -**** -***/ - -static void -emit_user_list_changed (UsersServiceDbus * self) -{ - g_signal_emit (self, signals[USER_LIST_CHANGED], 0); -} - -static void -emit_user_login_changed (UsersServiceDbus * self, AccountsUser * user) -{ - g_signal_emit (self, signals[USER_LOGGED_IN_CHANGED], 0, user); -} - -static void -emit_guest_login_changed (UsersServiceDbus * self) -{ - g_signal_emit (self, signals[GUEST_LOGGED_IN_CHANGED], 0); -} - -/*** -**** -***/ - -static ConsoleKitSession* -create_consolekit_session_proxy (const char * ssid) -{ - GError * error = NULL; - - ConsoleKitSession * p = console_kit_session_proxy_new_for_bus_sync ( - G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - CK_ADDR, - ssid, - NULL, - &error); - if (error != NULL) - { - g_warning ("%s: %s", G_STRLOC, error->message); - g_error_free (error); - } - - return p; -} - -static gchar * -get_seat_from_session_proxy (ConsoleKitSession * session_proxy) -{ - gchar * seat = NULL; - - GError * error = NULL; - console_kit_session_call_get_seat_id_sync (session_proxy, - &seat, - NULL, - &error); - if (error != NULL) - { - g_debug ("%s: %s", G_STRLOC, error->message); - g_error_free (error); - } - - return seat; -} - -static gchar * -get_seat (UsersServiceDbus *service) -{ - gchar * seat = NULL; - gchar * ssid = NULL; - GError * error = NULL; - UsersServiceDbusPrivate * priv = service->priv; - - console_kit_manager_call_get_current_session_sync (priv->ck_manager_proxy, - &ssid, - NULL, - &error); - - if (error != NULL) - { - g_debug ("%s: %s", G_STRLOC, error->message); - g_error_free (error); - } - else - { - ConsoleKitSession * session = create_consolekit_session_proxy (ssid); - - if (session != NULL) - { - seat = get_seat_from_session_proxy (session); - g_object_unref (session); - } - } - - return seat; -} - -/*** -**** AccountsUser add-ons for tracking sessions -***/ - -static GHashTable* -user_get_sessions_hashset (AccountsUser * user) -{ - static GQuark q = 0; - - if (G_UNLIKELY(!q)) - { - q = g_quark_from_static_string ("sessions"); - } - - GObject * o = G_OBJECT (user); - GHashTable * h = g_object_get_qdata (o, q); - if (h == NULL) - { - h = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - g_object_set_qdata_full (o, q, h, (GDestroyNotify)g_hash_table_destroy); - } - - return h; -} - -static void -user_add_session (AccountsUser * user, const char * ssid) -{ - g_hash_table_add (user_get_sessions_hashset(user), g_strdup(ssid)); -} - -static void -user_remove_session (AccountsUser * user, const char * ssid) -{ - g_hash_table_remove (user_get_sessions_hashset(user), ssid); -} - -static guint -user_count_sessions (AccountsUser * user) -{ - return g_hash_table_size (user_get_sessions_hashset(user)); -} - -/*** -**** Users -***/ - -/* adds this user session to the user's and service's session tables */ -static void -add_user_session (UsersServiceDbus * service, - AccountsUser * user, - const gchar * ssid) -{ - ConsoleKitSession * session_proxy = create_consolekit_session_proxy (ssid); - if (session_proxy != NULL) - { - UsersServiceDbusPrivate * priv = service->priv; - gchar * seat = get_seat_from_session_proxy (session_proxy); - - /* is this session in our seat? */ - if (seat && priv->seat && !g_strcmp0 (seat, priv->seat)) - { - /* does this session have a display? */ - gchar * display = NULL; - console_kit_session_call_get_x11_display_sync (session_proxy, - &display, - NULL, NULL); - const gboolean has_display = display && *display; - g_free (display); - - if (has_display) - { - const gchar * username = accounts_user_get_user_name (user); - g_debug ("%s adding %s's session '%s' to our tables", - G_STRLOC, username, ssid); - - g_hash_table_insert (priv->sessions, - g_strdup (ssid), - g_object_ref (user)); - - user_add_session (user, ssid); - } - } - - g_free (seat); - g_object_unref (session_proxy); - } -} - -/* calls add_user_session() for each of this user's sessions */ -static void -add_user_sessions (UsersServiceDbus *self, AccountsUser * user) -{ - const guint64 uid = accounts_user_get_uid (user); - const char * username = accounts_user_get_user_name (user); - g_debug ("%s adding %s (%i)", G_STRLOC, username, (int)uid); - - GError * error = NULL; - gchar ** sessions = NULL; - console_kit_manager_call_get_sessions_for_unix_user_sync ( - self->priv->ck_manager_proxy, - uid, - &sessions, - NULL, - &error); - - if (error != NULL) - { - g_debug ("%s: %s", G_STRLOC, error->message); - g_error_free (error); - } - else if (sessions != NULL) - { - int i; - - for (i=0; sessions[i]; i++) - { - const char * const ssid = sessions[i]; - g_debug ("%s adding %s's session %s", G_STRLOC, username, ssid); - add_user_session (self, user, ssid); - } - - g_strfreev (sessions); - } -} - -/* returns true if this property is one we use */ -static gboolean -is_interesting_user_property (const char * key) -{ - return !g_strcmp0 (key, "IconFile") - || !g_strcmp0 (key, "LoginFrequency") - || !g_strcmp0 (key, "RealName") - || !g_strcmp0 (key, "Uid") - || !g_strcmp0 (key, "UserName"); -} - -static void -sync_user_properties (GDBusProxy * source, GDBusProxy * target) -{ - gchar ** keys = g_dbus_proxy_get_cached_property_names (source); - - if (keys != NULL) - { - int i; - GVariantBuilder builder; - gboolean changed = FALSE; - g_variant_builder_init (&builder, G_VARIANT_TYPE ("a{sv}")); - - for (i=0; keys[i]; i++) - { - const gchar * const key = keys[i]; - - if (is_interesting_user_property (key)) - { - GVariant * oldval = g_dbus_proxy_get_cached_property (target, key); - GVariant * newval = g_dbus_proxy_get_cached_property (source, key); - - /* all the properties we're interested in are - basic types safe for g_variant_compare()... */ - g_assert (g_variant_type_is_basic(g_variant_get_type(newval))); - - if (g_variant_compare (oldval, newval)) - { - changed = TRUE; - g_dbus_proxy_set_cached_property (target, key, newval); - g_variant_builder_add (&builder, "{sv}", key, newval); - } - - g_variant_unref (newval); - g_variant_unref (oldval); - } - } - - if (changed) - { - g_signal_emit_by_name (target, "g-properties-changed", g_variant_builder_end(&builder), keys); - } - - g_variant_builder_clear (&builder); - g_strfreev (keys); - } -} - -/** - * The AccountsUserProxy's properties aren't being updated automatically - * for some reason... the only update we get is the 'changed' signal. - * This function is a workaround to update our User object's properties. - */ -static void -on_user_changed (AccountsUser * user, UsersServiceDbus * service) -{ - AccountsUser * tmp = accounts_user_proxy_new_for_bus_sync ( - G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - "org.freedesktop.Accounts", - g_dbus_proxy_get_object_path (G_DBUS_PROXY(user)), - NULL, - NULL); - if (tmp != NULL) - { - sync_user_properties (G_DBUS_PROXY(tmp), G_DBUS_PROXY(user)); - g_object_unref (tmp); - } -} - -static void -add_user_from_object_path (UsersServiceDbus * self, - const char * user_object_path) -{ - GError * error = NULL; - - AccountsUser * user = accounts_user_proxy_new_for_bus_sync ( - G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - "org.freedesktop.Accounts", - user_object_path, - NULL, - &error); - - if (error != NULL) - { - g_warning ("%s: %s", G_STRLOC, error->message); - g_clear_error (&error); - } - else - { - AccountsUser * prev = g_hash_table_lookup (self->priv->users, user_object_path); - - if (prev != NULL) /* we've already got this user... sync its properties */ - { - sync_user_properties (G_DBUS_PROXY(user), G_DBUS_PROXY(prev)); - g_object_unref (user); - user = prev; - } - else /* ooo, we got a new user */ - { - g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self); - g_hash_table_insert (self->priv->users, g_strdup(user_object_path), user); - } - - add_user_sessions (self, user); - } -} - - -/* asks org.freedesktop.Accounts for a list of users and - * calls add_user_from_object_path() on each of those users */ -static void -update_user_list (UsersServiceDbus *self) -{ - g_return_if_fail(IS_USERS_SERVICE_DBUS(self)); - - GError * error = NULL; - char ** object_paths = NULL; - UsersServiceDbusPrivate * priv = self->priv; - - accounts_call_list_cached_users_sync (priv->accounts_proxy, - &object_paths, - NULL, - &error); - - if (error != NULL) - { - g_warning ("%s: %s", G_STRFUNC, error->message); - g_clear_error (&error); - } - else if (object_paths != NULL) - { - gint i; - - for (i=0; object_paths[i] != NULL; ++i) - { - add_user_from_object_path (self, object_paths[i]); - } - - emit_user_list_changed (self); - - g_strfreev (object_paths); - } - - g_debug ("%s finished updating the user list", G_STRLOC); -} - -static void -on_user_added (Accounts * o G_GNUC_UNUSED, - const gchar * user_path G_GNUC_UNUSED, - UsersServiceDbus * service) -{ - /* We see a new user but we might not want to list it -- - for example, lightdm shows up when we switch to the greeter. - So instead of adding the user directly here, let's ask - org.freedesktop.Accounts for a fresh list of users - because it filters out special cases. */ - update_user_list (service); -} - -static void -on_user_deleted (Accounts * o G_GNUC_UNUSED, - const gchar * user_path, - UsersServiceDbus * service) -{ - AccountsUser * user = g_hash_table_lookup (service->priv->users, user_path); - - if (user != NULL) - { - GObject * o = g_object_ref (G_OBJECT(user)); - g_hash_table_remove (service->priv->users, user_path); - emit_user_list_changed (service); - g_object_unref (o); - } -} - -static AccountsUser * -find_user_from_username (UsersServiceDbus * self, - const gchar * username) -{ - AccountsUser * match = NULL; - - g_return_val_if_fail (IS_USERS_SERVICE_DBUS(self), match); - - gpointer user; - GHashTableIter iter; - g_hash_table_iter_init (&iter, self->priv->users); - while (!match && g_hash_table_iter_next (&iter, NULL, &user)) - { - if (!g_strcmp0 (username, accounts_user_get_user_name (user))) - { - match = user; - } - } - - return match; -} - -/*** -**** Sessions -***/ - -static void -on_session_removed (ConsoleKitSeat * seat_proxy, - const gchar * ssid, - UsersServiceDbus * service) -{ - g_return_if_fail (IS_USERS_SERVICE_DBUS (service)); - - UsersServiceDbusPrivate * priv = service->priv; - g_debug ("%s %s() session removed %s", G_STRLOC, G_STRFUNC, ssid); - - if (!g_strcmp0 (ssid, priv->guest_ssid)) - { - g_debug ("%s removing guest session %s", G_STRLOC, ssid); - g_clear_pointer (&priv->guest_ssid, g_free); - emit_guest_login_changed (service); - } - else - { - AccountsUser * user = g_hash_table_lookup (priv->sessions, ssid); - if (user == NULL) - { - g_debug ("%s we're not tracking ssid %s", G_STRLOC, ssid); - } - else - { - GObject * o = g_object_ref (G_OBJECT(user)); - g_hash_table_remove (service->priv->users, ssid); - user_remove_session (user, ssid); - emit_user_login_changed (service, user); - g_object_unref (o); - } - } -} - -static gchar* -get_unix_username_from_ssid (UsersServiceDbus * self, - const gchar * ssid) -{ - gchar * username = NULL; - - ConsoleKitSession * session_proxy = create_consolekit_session_proxy (ssid); - if (session_proxy != NULL) - { - guint uid = 0; - GError * error = NULL; - console_kit_session_call_get_unix_user_sync (session_proxy, - &uid, - NULL, &error); - if (error != NULL) - { - g_warning ("%s: %s", G_STRLOC, error->message); - g_clear_error (&error); - } - else - { - errno = 0; - const struct passwd * pwent = getpwuid (uid); - if (pwent == NULL) - { - g_warning ("Failed to lookup user id %d: %s", (int)uid, g_strerror(errno)); - } - else - { - username = g_strdup (pwent->pw_name); - } - } - - g_object_unref (session_proxy); - } - - return username; -} - -static gboolean -is_guest_username (const char * username) -{ - if (!g_strcmp0 (username, "guest")) - return TRUE; - - if (username && g_str_has_prefix (username, "guest-")) - return TRUE; - - return FALSE; -} - -/* If the new session belongs to 'guest', update our guest_ssid. - Otherwise, call add_user_session() to update our session tables */ -static void -on_session_added (ConsoleKitSeat * seat_proxy G_GNUC_UNUSED, - const gchar * ssid, - UsersServiceDbus * service) -{ - g_return_if_fail (IS_USERS_SERVICE_DBUS(service)); - - gchar * username = get_unix_username_from_ssid (service, ssid); - g_debug ("%s %s() username %s has new session %s", G_STRLOC, G_STRFUNC, username, ssid); - - if (is_guest_username (username)) - { - /* handle guest as a special case -- it's not in the GDM - user tables and there isn't be an AccountsUser for it */ - g_debug("Found guest session: %s", ssid); - g_free (service->priv->guest_ssid); - service->priv->guest_ssid = g_strdup (ssid); - emit_guest_login_changed (service); - } - else - { - AccountsUser * user = find_user_from_username (service, username); - - if (user != NULL) - { - add_user_session (service, user, ssid); - emit_user_login_changed (service, user); - } - } - - g_free (username); -} - -/* Receives a list of sessions and calls on_session_added() for each of them */ -static void -on_session_list (ConsoleKitSeat * seat_proxy, - GAsyncResult * result, - UsersServiceDbus * self) -{ - GError * error = NULL; - gchar ** sessions = NULL; - g_debug ("%s bootstrapping the session list", G_STRLOC); - - console_kit_seat_call_get_sessions_finish (seat_proxy, - &sessions, - result, - &error); - - if (error != NULL) - { - g_debug ("%s: %s", G_STRLOC, error->message); - g_error_free (error); - } - else if (sessions != NULL) - { - int i; - - for (i=0; sessions[i]; i++) - { - g_debug ("%s adding initial session '%s'", G_STRLOC, sessions[i]); - on_session_added (seat_proxy, sessions[i], self); - } - - g_strfreev (sessions); - } - - g_debug ("%s done bootstrapping the session list", G_STRLOC); -} - -static DisplayManagerSeat * -create_display_proxy (UsersServiceDbus * self) -{ - const gchar * const seat = g_getenv ("XDG_SEAT_PATH"); - g_debug ("%s creating a DisplayManager proxy for seat %s", G_STRLOC, seat); - - GError * error = NULL; - DisplayManagerSeat * p = display_manager_seat_proxy_new_for_bus_sync ( - G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_NONE, - "org.freedesktop.DisplayManager", - seat, - NULL, - &error); - - if (error != NULL) - { - g_warning ("%s: %s", G_STRLOC, error->message); - g_error_free (error); - } - - return p; -} - -/*** -**** Public API -***/ - -/** - * users_service_dbus_get_user_list: - * - * Returns: (transfer container): a list of AccountsUser objects - */ -GList * -users_service_dbus_get_user_list (UsersServiceDbus * self) -{ - g_return_val_if_fail(IS_USERS_SERVICE_DBUS(self), NULL); - - return g_hash_table_get_values (self->priv->users); -} - -/** - * users_service_dbus_show_greeter: - * - * Ask the Display Mnaager to switch to the greeter screen. - */ -void -users_service_dbus_show_greeter (UsersServiceDbus * self) -{ - DisplayManagerSeat * dp; - - g_return_if_fail (IS_USERS_SERVICE_DBUS(self)); - - dp = create_display_proxy (self); - if (dp != NULL) - { - display_manager_seat_call_switch_to_greeter_sync (dp, NULL, NULL); - g_clear_object (&dp); - } -} - -/** - * users_service_dbus_activate_guest_session: - * - * Activates the guest account. - */ -void -users_service_dbus_activate_guest_session (UsersServiceDbus * self) -{ - DisplayManagerSeat * dp; - - g_return_if_fail (IS_USERS_SERVICE_DBUS(self)); - - dp = create_display_proxy (self); - if (dp != NULL) - { - display_manager_seat_call_switch_to_guest_sync (dp, "", NULL, NULL); - g_clear_object (&dp); - } -} - -/** - * users_service_dbus_activate_user_session: - * - * Activates a specific user. - */ -void -users_service_dbus_activate_user_session (UsersServiceDbus * self, - AccountsUser * user) -{ - DisplayManagerSeat * dp; - - g_return_if_fail (IS_USERS_SERVICE_DBUS(self)); - - dp = create_display_proxy (self); - if (dp != NULL) - { - const char * const username = accounts_user_get_user_name (user); - display_manager_seat_call_switch_to_user_sync (dp, username, "", NULL, NULL); - g_clear_object (&dp); - } -} - -/** - * users_service_dbus_guest_session_enabled: - * - * Tells whether or not guest sessions are allowed. - */ -gboolean -users_service_dbus_guest_session_enabled (UsersServiceDbus * self) -{ - DisplayManagerSeat * dp; - gboolean enabled = FALSE; - - g_return_val_if_fail (IS_USERS_SERVICE_DBUS(self), enabled); - - dp = create_display_proxy (self); - if (dp != NULL) - { - enabled = display_manager_seat_get_has_guest_account (dp); - g_clear_object (&dp); - } - - return enabled; -} - -gboolean -users_service_dbus_can_activate_session (UsersServiceDbus * self) -{ - gboolean can_activate = FALSE; - - g_return_val_if_fail (IS_USERS_SERVICE_DBUS(self), can_activate); - - GError * error = NULL; - console_kit_seat_call_can_activate_sessions_sync (self->priv->seat_proxy, - &can_activate, - NULL, - &error); - if (error != NULL) - { - g_warning ("%s: %s", G_STRLOC, error->message); - g_error_free (error); - } - - return can_activate; -} - -gboolean -users_service_dbus_is_guest_logged_in (UsersServiceDbus * self) -{ - g_return_val_if_fail (IS_USERS_SERVICE_DBUS(self), FALSE); - - return self->priv->guest_ssid != NULL; -} - -gboolean -users_service_dbus_is_user_logged_in (UsersServiceDbus * self, - AccountsUser * user) -{ - g_return_val_if_fail (IS_USERS_SERVICE_DBUS(self), FALSE); - g_return_val_if_fail (IS_ACCOUNTS_USER(user), FALSE); - - return user_count_sessions (user) > 0; -} diff --git a/src/users-service-dbus.h b/src/users-service-dbus.h deleted file mode 100644 index 0f082c3..0000000 --- a/src/users-service-dbus.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2009 Canonical Ltd. - * - * Authors: - * Cody Russell - * Charles Kerr - * - * This program 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranties of - * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . - */ - -#ifndef __USERS_SERVICE_DBUS_H__ -#define __USERS_SERVICE_DBUS_H__ - -#include -#include - -#include "dbus-user.h" /* for AccountsUser */ - -G_BEGIN_DECLS - -#define USERS_SERVICE_DBUS_TYPE (users_service_dbus_get_type ()) -#define USERS_SERVICE_DBUS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), USERS_SERVICE_DBUS_TYPE, UsersServiceDbus)) -#define IS_USERS_SERVICE_DBUS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), USERS_SERVICE_DBUS_TYPE)) - -typedef struct _UsersServiceDbus UsersServiceDbus; -typedef struct _UsersServiceDbusClass UsersServiceDbusClass; -typedef struct _UsersServiceDbusPrivate UsersServiceDbusPrivate; - -/** - * A facade class which interacts with multiple DBus services to - * track info which is useful to the interactor's user menu: - * - * 1. A list of users to add to the user menu. - * - * Each user is an AccountsUser object, which is a GDBusProxy - * to an org.freedesktop.Accounts.User object. - * - * We initially build this list by calling org.freedesktop.Accounts' - * GetCachedUsers method. We also monitor o.f.Accounts' UserAdded - * and UserDeleted and update the list accordingly. - * - * 2. Track which users currently have X sessions. - * This is used for the menuitems' USER_ITEM_PROP_LOGGED_IN property. - * - * We initially build this list by calling org.freedesktop.ConsoleKit.Seat's - * GetDevices method. We also monitor the seat for SessionAdded and - * SessionRemoved and update the list accordingly. - * - * 3. Provide an API for user switching and guest sessions. - * These are typically pass-through functions to GDBusProxies. - * - */ -struct _UsersServiceDbus -{ - /*< private >*/ - GObject parent; - UsersServiceDbusPrivate * priv; -}; - -struct _UsersServiceDbusClass -{ - GObjectClass parent_class; - - /* Signals */ - void (* user_list_changed) (UsersServiceDbus*, gpointer); - void (* user_logged_in_changed) (UsersServiceDbus*, AccountsUser*, gpointer); - void (* guest_logged_in_changed) (UsersServiceDbus*, gpointer); -}; - -GType users_service_dbus_get_type (void) G_GNUC_CONST; - -GList * users_service_dbus_get_user_list (UsersServiceDbus * self); - -gboolean users_service_dbus_is_guest_logged_in (UsersServiceDbus * self); -gboolean users_service_dbus_is_user_logged_in (UsersServiceDbus * self, - AccountsUser * user); - -void users_service_dbus_show_greeter (UsersServiceDbus * self); -gboolean users_service_dbus_guest_session_enabled (UsersServiceDbus * self); -gboolean users_service_dbus_can_activate_session (UsersServiceDbus * self); -void users_service_dbus_activate_guest_session (UsersServiceDbus * self); -void users_service_dbus_activate_user_session (UsersServiceDbus * self, - AccountsUser * user); - -G_END_DECLS - -#endif diff --git a/src/users.c b/src/users.c new file mode 100644 index 0000000..4b9c0ad --- /dev/null +++ b/src/users.c @@ -0,0 +1,198 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include "users.h" + +/* signals enum */ +enum +{ + USER_ADDED, + USER_REMOVED, + USER_CHANGED, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + +G_DEFINE_TYPE (IndicatorSessionUsers, indicator_session_users, G_TYPE_OBJECT) + +enum +{ + PROP_0, + PROP_IS_LIVE_SESSION, + PROP_LAST +}; + +static GParamSpec *properties[PROP_LAST]; + +static void +my_get_property (GObject * o, + guint property_id, + GValue * value, + GParamSpec * pspec) +{ + IndicatorSessionUsers * self = INDICATOR_SESSION_USERS (o); + + switch (property_id) + { + case PROP_IS_LIVE_SESSION: + g_value_set_boolean (value, indicator_session_users_is_live_session (self)); + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (o, property_id, pspec); + } +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_users_class_init (IndicatorSessionUsersClass * klass) +{ + GObjectClass * object_class; + const GParamFlags flags = G_PARAM_READABLE | G_PARAM_STATIC_STRINGS; + + object_class = G_OBJECT_CLASS (klass); + object_class->get_property = my_get_property; + + signals[USER_ADDED] = g_signal_new (INDICATOR_SESSION_USERS_SIGNAL_USER_ADDED, + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (IndicatorSessionUsersClass, user_added), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); + + signals[USER_REMOVED] = g_signal_new (INDICATOR_SESSION_USERS_SIGNAL_USER_REMOVED, + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (IndicatorSessionUsersClass, user_removed), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); + + signals[USER_CHANGED] = g_signal_new (INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (IndicatorSessionUsersClass, user_changed), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); + + + properties[PROP_IS_LIVE_SESSION] = + g_param_spec_boolean (INDICATOR_SESSION_USERS_PROP_IS_LIVE_SESSION, + "Is Live Session", + "Whether or this is a 'live session', such as booting from a live CD", + FALSE, flags); + + g_object_class_install_properties (object_class, PROP_LAST, properties); + +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_users_init (IndicatorSessionUsers * self G_GNUC_UNUSED) +{ +} + +/*** +**** Virtual Functions +***/ + +GStrv +indicator_session_users_get_keys (IndicatorSessionUsers * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_USERS (self), NULL); + + return INDICATOR_SESSION_USERS_GET_CLASS (self)->get_keys (self); +} + +IndicatorSessionUser * +indicator_session_users_get_user (IndicatorSessionUsers * self, + const char * key) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_USERS (self), NULL); + + return INDICATOR_SESSION_USERS_GET_CLASS (self)->get_user (self, key); +} + +void +indicator_session_users_activate_user (IndicatorSessionUsers * self, + const char * key) +{ + g_return_if_fail (INDICATOR_IS_SESSION_USERS (self)); + + INDICATOR_SESSION_USERS_GET_CLASS (self)->activate_user (self, key); +} + +gboolean +indicator_session_users_is_live_session (IndicatorSessionUsers * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_USERS (self), FALSE); + + return INDICATOR_SESSION_USERS_GET_CLASS (self)->is_live_session (self); +} + +void +indicator_session_user_free (IndicatorSessionUser * user) +{ + g_return_if_fail (user != NULL); + + g_free (user->real_name); + g_free (user->user_name); + g_free (user->icon_file); + g_free (user); +} + +/*** +**** Signal Convenience +***/ + +void +indicator_session_users_added (IndicatorSessionUsers * self, const char * key) +{ + g_return_if_fail (INDICATOR_IS_SESSION_USERS (self)); + + g_signal_emit (self, signals[USER_ADDED], 0, key); +} + +void +indicator_session_users_removed (IndicatorSessionUsers * self, const char * key) +{ + g_return_if_fail (INDICATOR_IS_SESSION_USERS (self)); + + g_signal_emit (self, signals[USER_REMOVED], 0, key); +} + +void +indicator_session_users_changed (IndicatorSessionUsers * self, const char * key) +{ + g_return_if_fail (INDICATOR_IS_SESSION_USERS (self)); + + g_signal_emit (self, signals[USER_CHANGED], 0, key); +} + +void +indicator_session_users_notify_is_live_session (IndicatorSessionUsers * self) +{ + g_return_if_fail (INDICATOR_IS_SESSION_USERS (self)); + + g_object_notify_by_pspec (G_OBJECT(self), properties[PROP_IS_LIVE_SESSION]); +} + diff --git a/src/users.h b/src/users.h new file mode 100644 index 0000000..31ee39e --- /dev/null +++ b/src/users.h @@ -0,0 +1,146 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef __USERS_H__ +#define __USERS_H__ + +#include +#include + +G_BEGIN_DECLS + +#define INDICATOR_TYPE_SESSION_USERS (indicator_session_users_get_type()) +#define INDICATOR_SESSION_USERS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_SESSION_USERS, IndicatorSessionUsers)) +#define INDICATOR_SESSION_USERS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_TYPE_SESSION_USERS, IndicatorSessionUsersClass)) +#define INDICATOR_SESSION_USERS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), INDICATOR_TYPE_SESSION_USERS, IndicatorSessionUsersClass)) +#define INDICATOR_IS_SESSION_USERS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_SESSION_USERS)) + + +typedef struct _IndicatorSessionUser IndicatorSessionUser; +typedef struct _IndicatorSessionUsers IndicatorSessionUsers; +typedef struct _IndicatorSessionUsersClass IndicatorSessionUsersClass; + +/** + * A base class for monitoring the system's users and active sessions. + * Use backend.h's get_backend() to get an instance. + */ +struct _IndicatorSessionUsers +{ + /*< private >*/ + GObject parent; +}; + +struct _IndicatorSessionUser +{ + gboolean is_current_user; + gboolean is_logged_in; + guint uid; + guint64 login_frequency; + gchar * user_name; + gchar * real_name; + gchar * icon_file; +}; + +/* signal keys */ +#define INDICATOR_SESSION_USERS_SIGNAL_USER_ADDED "user-added" +#define INDICATOR_SESSION_USERS_SIGNAL_USER_REMOVED "user-removed" +#define INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED "user-changed" + +/* property keys */ +#define INDICATOR_SESSION_USERS_PROP_IS_LIVE_SESSION "is-live-session" + +struct _IndicatorSessionUsersClass +{ + GObjectClass parent_class; + + /* signals */ + + void (* user_added) (IndicatorSessionUsers * self, + const gchar * key); + + void (* user_removed) (IndicatorSessionUsers * self, + const gchar * key); + + void (* user_changed) (IndicatorSessionUsers * self, + const gchar * key); + + + /* pure virtual functions */ + + gboolean (* is_live_session) (IndicatorSessionUsers * self); + + + GStrv (* get_keys) (IndicatorSessionUsers * self); + + IndicatorSessionUser * (* get_user) (IndicatorSessionUsers * self, + const gchar * key); + + void ( * activate_user) (IndicatorSessionUsers * self, + const gchar * key); +}; + +/*** +**** +***/ + +GType indicator_session_users_get_type (void); + +/* emits the "user-added" signal */ +void indicator_session_users_added (IndicatorSessionUsers * self, + const gchar * key); + +/* emits the "user-removed" signal */ +void indicator_session_users_removed (IndicatorSessionUsers * self, + const gchar * key); + +/* emits the "user-changed" signal */ +void indicator_session_users_changed (IndicatorSessionUsers * self, + const gchar * key); + +/* notify listeners of a change to the 'is-live-session' property */ +void indicator_session_users_notify_is_live_session (IndicatorSessionUsers * self); + + + +/*** +**** +***/ + +gboolean indicator_session_users_is_live_session (IndicatorSessionUsers * users); + +/* get a list of user keys */ +GStrv indicator_session_users_get_keys (IndicatorSessionUsers * users); + +/* get information about a particular user. + call indicator_session_user_free() when done with the returned struct. */ +IndicatorSessionUser * +indicator_session_users_get_user (IndicatorSessionUsers * users, + const gchar * key); + +/* frees a IndicatorSessionUser struct */ +void indicator_session_user_free (IndicatorSessionUser * user); + +/* activate to a different session */ +void indicator_session_users_activate_user (IndicatorSessionUsers * self, + const char * key); + + +G_END_DECLS + +#endif diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..45ab69f --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,53 @@ +# build the necessary schemas +set_directory_properties (PROPERTIES + ADDITIONAL_MAKE_CLEAN_FILES gschemas.compiled) +set_source_files_properties (gschemas.compiled GENERATED) + +# GSettings: +# compile the schemas our tests use (indicator-session's, lockdown, media-keys) +# into a gschemas.compiled file in this directory, and help the tests to find +# that file by setting -DSCHEMA_DIR +set (SCHEMA_DIR ${CMAKE_CURRENT_BINARY_DIR}) +add_definitions(-DSCHEMA_DIR="${SCHEMA_DIR}") +execute_process (COMMAND ${PKG_CONFIG_EXECUTABLE} gio-2.0 --variable glib_compile_schemas + OUTPUT_VARIABLE COMPILE_SCHEMA_EXECUTABLE + OUTPUT_STRIP_TRAILING_WHITESPACE) +add_custom_command (OUTPUT gschemas.compiled + DEPENDS ${CMAKE_BINARY_DIR}/data/com.canonical.indicator.session.gschema.xml + ${CMAKE_SOURCE_DIR}/tests/com.canonical.indicator.session.backendmock.gschema.xml + ${CMAKE_SOURCE_DIR}/tests/org.gnome.desktop.lockdown.gschema.xml + ${CMAKE_SOURCE_DIR}/tests/org.gnome.settings-daemon.plugins.media-keys.gschema.xml + COMMAND cp -f ${CMAKE_BINARY_DIR}/data/*gschema.xml ${SCHEMA_DIR} + COMMAND cp -f ${CMAKE_SOURCE_DIR}/tests/*gschema.xml ${SCHEMA_DIR} + COMMAND ${COMPILE_SCHEMA_EXECUTABLE} ${SCHEMA_DIR}) + +# DBus Activation +configure_file (indicator-session.service.in indicator-session.service) +add_definitions(-DINDICATOR_SERVICE_DIR="${CMAKE_CURRENT_BINARY_DIR}") + +# look for hearder in our src dir, and also in the directories where we autogenerate files... +include_directories (${CMAKE_SOURCE_DIR}/src) +include_directories (${CMAKE_CURRENT_BINARY_DIR} ${SERVICE_INCLUDE_DIRS}) + +# backendmock +add_library (backendmock STATIC + backend-mock-actions.c + backend-mock-actions.h + backend-mock.c + backend-mock.h + backend-mock-guest.c + backend-mock-guest.h + backend-mock-users.c + backend-mock-users.h) +set_target_properties (backendmock PROPERTIES COMPILE_FLAGS " ${CC_WARNING_ARGS}") + +# test-service +add_executable (test-service + test-service.cc + gschemas.compiled) +set_target_properties (test-service PROPERTIES COMPILE_FLAGS " ${CC_WARNING_ARGS}") +add_test (test-service test-service) +add_dependencies (test-service libindicatorsessionservice backendmock) +target_link_libraries (test-service libindicatorsessionservice backendmock gtest ${SERVICE_LIBRARIES} ${GTEST_LIBS}) + +add_subdirectory (backend-dbus) diff --git a/tests/Makefile.am b/tests/Makefile.am deleted file mode 100644 index 071f684..0000000 --- a/tests/Makefile.am +++ /dev/null @@ -1,51 +0,0 @@ -TESTS = -CLEANFILES = -BUILT_SOURCES = -check_PROGRAMS = - -integrationcheckdir = . -integrationcheck_PROGRAMS = - -### -### -### - -# stock UMB tests on user-visible strings -include $(srcdir)/Makefile.am.strings - -check_LIBRARIES = libgtest.a -nodist_libgtest_a_SOURCES = \ - $(GTEST_SOURCE)/gtest-all.cc \ - $(GTEST_SOURCE)/gtest_main.cc - -AM_CPPFLAGS = $(GTEST_CPPFLAGS) -I${top_srcdir}/src -Wall -Werror -AM_CXXFLAGS = $(GTEST_CXXFLAGS) - -### -### -### - -BUILT_SOURCES += gschemas.compiled -CLEANFILES += gschemas.compiled -gschemas.compiled: Makefile - $(AM_V_at) cp -f $(top_builddir)/data/*gschema.xml . - $(AM_V_GEN) $(GLIB_COMPILE_SCHEMAS) --targetdir=. . - - -integrationcheck: - ./test-service - -integrationcheck_PROGRAMS += test-service -test_service_SOURCES = test-service.cc -test_service_LDADD = \ - $(TEST_SERVICE_LIBS) \ - $(XORG_GTEST_LDFLAGS) \ - libgtest.a -test_service_CPPFLAGS = \ - -DSCHEMA_DIR="\"$(top_builddir)/tests/\"" \ - -DINDICATOR_SERVICE_DIR="\"$(abs_builddir)\"" \ - -DINDICATOR_SERVICE_PATH="\"$(top_builddir)/src/indicator-session-service\"" \ - $(TEST_SERVICE_CFLAGS) \ - $(AM_CPPFLAGS) - - diff --git a/tests/Makefile.am.strings b/tests/Makefile.am.strings deleted file mode 100644 index 26a23a8..0000000 --- a/tests/Makefile.am.strings +++ /dev/null @@ -1,38 +0,0 @@ -TESTS += \ - test-ellipsis \ - test-space-ellipsis \ - test-ascii-quotes - -##### -# Tests for there being proper ellipsis instead of three periods in a row -##### -test-ellipsis: $(top_srcdir)/po - @echo "#!/bin/bash" > $@ - @echo "(cd $(top_srcdir)/po && make $(GETTEXT_PACKAGE).pot)" >> $@ - @echo "grep -c -e \"^msgid.*\.\.\.\\\"\" $(top_srcdir)/po/$(GETTEXT_PACKAGE).pot > /dev/null && echo \"Ellipsis found in user visible strings\" >&2 && exit 1" >> $@ - @echo "exit 0" >> $@ - @chmod +x $@ - -##### -# Tests for there being a space before an ellipsis -##### -test-space-ellipsis: $(top_srcdir)/po - @echo "#!/bin/bash" > $@ - @echo "(cd $(top_srcdir)/po && make $(GETTEXT_PACKAGE).pot)" >> $@ - @echo "grep -c -e \"^msgid.* …\\\"\" $(top_srcdir)/po/$(GETTEXT_PACKAGE).pot > /dev/null && echo \"Space before ellipsis found in user visible strings\" >&2 && exit 1" >> $@ - @echo "exit 0" >> $@ - @chmod +x $@ - -##### -# Tests for ASCII quote types -##### -test-ascii-quotes: $(top_srcdir)/po - @echo "#!/bin/bash" > $@ - @echo "(cd $(top_srcdir)/po && make $(GETTEXT_PACKAGE).pot)" >> $@ - @echo "grep -c -e \"^msgid \\\".*'.*\\\"\" $(top_srcdir)/po/$(GETTEXT_PACKAGE).pot > /dev/null && echo \"ASCII apostrophy found in user visible strings\" >&2 && exit 1" >> $@ - @echo "grep -c -e \"^msgid \\\".*\\\".*\\\"\" $(top_srcdir)/po/$(GETTEXT_PACKAGE).pot > /dev/null && echo \"ASCII quote found in user visible strings\" >&2 && exit 1" >> $@ - @echo "grep -c -e \"^msgid \\\".*\\\`.*\\\"\" $(top_srcdir)/po/$(GETTEXT_PACKAGE).pot > /dev/null && echo \"ASCII backtick found in user visible strings\" >&2 && exit 1" >> $@ - @echo "exit 0" >> $@ - @chmod +x $@ - -CLEANFILES += $(TESTS) diff --git a/tests/backend-dbus/CMakeLists.txt b/tests/backend-dbus/CMakeLists.txt new file mode 100644 index 0000000..7cd7030 --- /dev/null +++ b/tests/backend-dbus/CMakeLists.txt @@ -0,0 +1,62 @@ +# build libgtest +add_library (gtest STATIC + ${GTEST_SOURCE_DIR}/gtest-all.cc + ${GTEST_SOURCE_DIR}/gtest_main.cc) +set_target_properties (gtest PROPERTIES INCLUDE_DIRECTORIES + ${GTEST_INCLUDE_DIR}) + +# build desktopmock +add_library (desktopmock STATIC + mock-accounts.cc + mock-accounts.h + mock-consolekit-manager.cc + mock-consolekit-manager.h + mock-consolekit-seat.cc + mock-consolekit-seat.h + mock-consolekit-session.cc + mock-consolekit-session.h + mock-display-manager-seat.cc + mock-display-manager-seat.h + mock-end-session-dialog.cc + mock-end-session-dialog.h + mock-object.cc + mock-object.h + mock-screen-saver.cc + mock-screen-saver.h + mock-session-manager.cc + mock-session-manager.h + mock-upower.cc + mock-upower.h + mock-user.cc + mock-user.h + mock-webcredentials.cc + mock-webcredentials.h) + +include_directories (${SERVICE_INCLUDE_DIRS}) +include_directories (${CMAKE_SOURCE_DIR}/src) +include_directories (${CMAKE_BINARY_DIR}/src) +include_directories (${CMAKE_SOURCE_DIR}/tests) + +# test the Actions class +add_executable (test-actions + test-actions.cc) +add_test (test-actions test-actions) +set_tests_properties (test-actions PROPERTIES COMPILE_FLAGS "${SERVICE_CFLAGS}") +target_link_libraries (test-actions desktopmock backenddbus libindicatorsessionservice gtest ${SERVICE_LDFLAGS} ${GTEST_LIBS} ${GCOV_LIBS}) + +# test the Guest class +add_executable (test-guest + test-guest.cc) +add_test (test-guest test-guest) +set_tests_properties (test-guest PROPERTIES COMPILE_FLAGS "${SERVICE_CFLAGS}") +target_link_libraries (test-guest desktopmock backenddbus libindicatorsessionservice gtest ${SERVICE_LDFLAGS} ${GTEST_LIBS} ${GCOV_LIBS}) + +# test the Users class +add_executable (test-users + test-users.cc) +add_test (test-users test-users) +set_tests_properties (test-users PROPERTIES COMPILE_FLAGS "${SERVICE_CFLAGS}") +target_link_libraries (test-users desktopmock backenddbus libindicatorsessionservice gtest ${SERVICE_LDFLAGS} ${GTEST_LIBS} ${GCOV_LIBS}) + + + diff --git a/tests/backend-dbus/gtest-mock-dbus-fixture.h b/tests/backend-dbus/gtest-mock-dbus-fixture.h new file mode 100644 index 0000000..5c4e312 --- /dev/null +++ b/tests/backend-dbus/gtest-mock-dbus-fixture.h @@ -0,0 +1,130 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include "gtest-dbus-fixture.h" + +#include "mock-accounts.h" +#include "mock-consolekit-manager.h" +#include "mock-consolekit-seat.h" +#include "mock-consolekit-session.h" +#include "mock-display-manager-seat.h" +#include "mock-end-session-dialog.h" +#include "mock-screen-saver.h" +#include "mock-session-manager.h" +#include "mock-upower.h" +#include "mock-user.h" +#include "mock-webcredentials.h" + +/*** +**** +***/ + +class GTestMockDBusFixture: public GTestDBusFixture +{ + private: + + typedef GTestDBusFixture super; + + protected: + + MockScreenSaver * screen_saver; + MockSessionManager * session_manager; + MockDisplayManagerSeat * dm_seat; + MockAccounts * accounts; + MockConsoleKitSession * ck_session; + MockConsoleKitSeat * ck_seat; + MockConsoleKitManager * ck_manager; + MockUPower * upower; + MockEndSessionDialog * end_session_dialog; + MockWebcredentials * webcredentials; + + protected: + + virtual void SetUp () + { + super :: SetUp (); + + webcredentials = new MockWebcredentials (loop, conn); + end_session_dialog = new MockEndSessionDialog (loop, conn); + session_manager = new MockSessionManager (loop, conn); + screen_saver = new MockScreenSaver (loop, conn); + upower = new MockUPower (loop, conn); + dm_seat = new MockDisplayManagerSeat (loop, conn); + g_setenv ("XDG_SEAT_PATH", dm_seat->path(), TRUE); + dm_seat->set_guest_allowed (false); + accounts = build_accounts_mock (); + ck_manager = new MockConsoleKitManager (loop, conn); + ck_seat = new MockConsoleKitSeat (loop, conn, true); + MockUser * user = accounts->find_by_username ("msmith"); + ck_session = ck_seat->add_session_by_user (user); + ck_manager->add_seat (ck_seat); + dm_seat->set_consolekit_seat (ck_seat); + dm_seat->switch_to_user (user->username()); + ASSERT_EQ (ck_session, ck_manager->current_session()); + } + + protected: + + virtual void TearDown () + { + delete accounts; + delete ck_manager; + delete dm_seat; + delete upower; + delete screen_saver; + delete session_manager; + delete end_session_dialog; + delete webcredentials; + + super :: TearDown (); + } + + private: + + MockAccounts * build_accounts_mock () + { + struct { + guint64 login_frequency; + const gchar * user_name; + const gchar * real_name; + } users[] = { + { 134, "whartnell", "First Doctor" }, + { 119, "ptroughton", "Second Doctor" }, + { 128, "jpertwee", "Third Doctor" }, + { 172, "tbaker", "Fourth Doctor" }, + { 69, "pdavison", "Fifth Doctor" }, + { 31, "cbaker", "Sixth Doctor" }, + { 42, "smccoy", "Seventh Doctor" }, + { 1, "pmcgann", "Eigth Doctor" }, + { 13, "ceccleston", "Ninth Doctor" }, + { 47, "dtennant", "Tenth Doctor" }, + { 34, "msmith", "Eleventh Doctor" }, + { 1, "rhurndall", "First Doctor" } + }; + + MockAccounts * a = new MockAccounts (loop, conn); + for (int i=0, n=G_N_ELEMENTS(users); iadd_user (new MockUser (loop, conn, + users[i].user_name, + users[i].real_name, + users[i].login_frequency)); + return a; + } +}; + diff --git a/tests/backend-dbus/mock-accounts.cc b/tests/backend-dbus/mock-accounts.cc new file mode 100644 index 0000000..2a0e7e7 --- /dev/null +++ b/tests/backend-dbus/mock-accounts.cc @@ -0,0 +1,156 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include "mock-accounts.h" +#include "mock-user.h" + +namespace +{ + const char * const DBUS_ACCOUNTS_NAME = "org.freedesktop.Accounts"; + + const char * const DBUS_ACCOUNTS_PATH = "/org/freedesktop/Accounts"; +} + +/*** +**** +***/ + +void +MockAccounts :: add_user (MockUser * user) +{ + g_assert (my_users.count(user) == 0); + + my_users.insert (user); + my_uid_to_user[user->uid()] = user; + my_path_to_user[user->path()] = user; + my_username_to_user[user->username()] = user; + + accounts_emit_user_added (my_skeleton, user->path()); +} + +void +MockAccounts :: remove_user (MockUser * user) +{ + g_assert (my_users.count(user) == 1); + + my_users.erase (user); + my_uid_to_user.erase (user->uid()); + my_path_to_user.erase (user->path()); + my_username_to_user.erase (user->username()); + + accounts_emit_user_deleted (my_skeleton, user->path()); +} + +MockUser * +MockAccounts :: find_by_uid (guint64 uid) +{ + const uid_to_user_t::iterator it (my_uid_to_user.find(uid)); + + if (it != my_uid_to_user.end()) + return it->second; + + g_warn_if_reached (); + return 0; +} + +MockUser * +MockAccounts :: find_by_path (const char * path) +{ + const path_to_user_t::iterator it (my_path_to_user.find(path)); + + if (it != my_path_to_user.end()) + return it->second; + + g_warn_if_reached (); + return 0; +} + +MockUser * +MockAccounts :: find_by_username (const char * username) +{ + const username_to_user_t::iterator it (my_username_to_user.find(username)); + + if (it != my_path_to_user.end()) + return it->second; + + g_warn_if_reached (); + return 0; +} + +/*** +**** +***/ + +gboolean +MockAccounts :: on_find_user_by_id_static (Accounts * a, + GDBusMethodInvocation * invocation, + guint64 uid, + gpointer gself) +{ + MockUser * user = static_cast(gself)->find_by_uid (uid); + accounts_complete_find_user_by_id (a, invocation, user ? user->path() : ""); + return true; +} + +gboolean +MockAccounts :: on_list_cached_users_static (Accounts * a, + GDBusMethodInvocation * invocation, + gpointer gself) +{ + int i; + const char ** paths; + const users_t& users = static_cast(gself)->my_users; + + i = 0; + paths = g_new0 (const char*, users.size() + 1); + for (users_t::iterator it(users.begin()), + end(users.end()); it!=end; ++it) + paths[i++] = (*it)->path(); + accounts_complete_list_cached_users (a, invocation, paths); + g_free (paths); + + return true; +} + +/*** +**** +***/ + +MockAccounts :: MockAccounts (GMainLoop * loop, + GDBusConnection * bus_connection): + MockObject (loop, bus_connection, DBUS_ACCOUNTS_NAME, DBUS_ACCOUNTS_PATH), + my_skeleton (accounts_skeleton_new ()) +{ + g_signal_connect (my_skeleton, "handle-list-cached-users", + G_CALLBACK(on_list_cached_users_static), this); + g_signal_connect (my_skeleton, "handle-find-user-by-id", + G_CALLBACK(on_find_user_by_id_static), this); + + set_skeleton (G_DBUS_INTERFACE_SKELETON(my_skeleton)); +} + +MockAccounts :: ~MockAccounts () +{ + for (users_t::iterator it(my_users.begin()), + end(my_users.end()); it!=end; ++it) + delete *it; + + g_signal_handlers_disconnect_by_data (my_skeleton, this); + g_clear_object (&my_skeleton); +} diff --git a/tests/backend-dbus/mock-accounts.h b/tests/backend-dbus/mock-accounts.h new file mode 100644 index 0000000..95da102 --- /dev/null +++ b/tests/backend-dbus/mock-accounts.h @@ -0,0 +1,74 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef MOCK_ACCOUNTS_H +#define MOCK_ACCOUNTS_H + +#include +#include +#include +#include "mock-object.h" +#include "backend-dbus/dbus-accounts.h" // struct Accounts + +class MockUser; + +class MockAccounts: public MockObject +{ + public: + + MockAccounts (GMainLoop * loop, + GDBusConnection * bus_connection); + virtual ~MockAccounts (); + + void add_user (MockUser * user); + void remove_user (MockUser * user); + size_t size() const { return my_users.size(); } + MockUser * find_by_uid (guint64 uid); + MockUser * find_by_path (const char * path); + MockUser * find_by_username (const char * username); + + private: + + Accounts * my_skeleton; + + typedef std::set users_t; + users_t my_users; + + typedef std::map uid_to_user_t; + uid_to_user_t my_uid_to_user; + + typedef std::map path_to_user_t; + path_to_user_t my_path_to_user; + + typedef std::map username_to_user_t; + username_to_user_t my_username_to_user; + + private: + + static gboolean on_find_user_by_id_static (Accounts *, + GDBusMethodInvocation *, + guint64, + gpointer); + + static gboolean on_list_cached_users_static (Accounts *, + GDBusMethodInvocation *, + gpointer); +}; + +#endif // #ifndef MOCK_ACCOUNTS_H diff --git a/tests/backend-dbus/mock-consolekit-manager.cc b/tests/backend-dbus/mock-consolekit-manager.cc new file mode 100644 index 0000000..40f9bf9 --- /dev/null +++ b/tests/backend-dbus/mock-consolekit-manager.cc @@ -0,0 +1,156 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include "mock-consolekit-manager.h" +#include "mock-consolekit-seat.h" +#include "mock-consolekit-session.h" + +namespace +{ + const char * CONSOLEKIT_MANAGER_NAME = "org.freedesktop.ConsoleKit"; + + const char * CONSOLEKIT_MANAGER_PATH = "/org/freedesktop/ConsoleKit/Manager"; + + void on_active_session_changed (ConsoleKitSeat * o G_GNUC_UNUSED, + const gchar * new_ssid, + gpointer ssid) + { + *static_cast(ssid) = new_ssid; + } +} + +/*** +**** +***/ + +gboolean +MockConsoleKitManager :: on_get_current_session (ConsoleKitManager * m, + GDBusMethodInvocation * inv, + gpointer gself) +{ + MockConsoleKitManager * self = static_cast(gself); + const std::string& ssid = self->my_current_ssid; + console_kit_manager_complete_get_current_session (m, inv, ssid.c_str()); + return true; +} + +gboolean +MockConsoleKitManager :: on_get_seats (ConsoleKitManager * m, + GDBusMethodInvocation * inv, + gpointer gself) +{ + int i; + char ** sids; + const seats_t& seats = static_cast(gself)->my_seats; + + i = 0; + sids = g_new0 (char*, seats.size()+1); + for (seats_t::const_iterator it(seats.begin()), + end(seats.end()); it!=end; ++it) + sids[i++] = (char*) (*it)->path(); + console_kit_manager_complete_get_seats (m, inv, sids); + g_strfreev (sids); + + return true; +} + +gboolean +MockConsoleKitManager :: handle_restart (ConsoleKitManager * ckm, + GDBusMethodInvocation * inv, + gpointer gself) +{ + static_cast(gself)->my_last_action = Restart; + console_kit_manager_complete_restart (ckm, inv); + return true; +} + +gboolean +MockConsoleKitManager :: handle_stop (ConsoleKitManager * ckm, + GDBusMethodInvocation * inv, + gpointer gself) +{ + static_cast(gself)->my_last_action = Shutdown; + console_kit_manager_complete_stop (ckm, inv); + return true; +} + +/*** +**** +***/ + +MockConsoleKitSession * +MockConsoleKitManager :: current_session () +{ + MockConsoleKitSession * ret = 0; + + for (seats_t::iterator it(my_seats.begin()), + end(my_seats.end()); it!=end; ++it) + if ((ret = (*it)->find (my_current_ssid.c_str()))) + break; + + return ret; +} + +void +MockConsoleKitManager :: add_seat (MockConsoleKitSeat * seat) +{ + g_assert (my_seats.count(seat) == 0); + + my_seats.insert (seat); + + console_kit_manager_emit_seat_added (my_skeleton, seat->sid()); + + g_signal_connect (seat->skeleton(), "active-session-changed", + G_CALLBACK(on_active_session_changed), &my_current_ssid); +} + +/*** +**** +***/ + +MockConsoleKitManager :: MockConsoleKitManager (GMainLoop * loop, + GDBusConnection * conn): + MockObject (loop, conn, CONSOLEKIT_MANAGER_NAME, CONSOLEKIT_MANAGER_PATH), + my_skeleton (console_kit_manager_skeleton_new ()), + my_last_action (None) +{ + g_signal_connect (my_skeleton, "handle-get-current-session", + G_CALLBACK(on_get_current_session), this); + g_signal_connect (my_skeleton, "handle-get-seats", + G_CALLBACK(on_get_seats), this); + g_signal_connect (my_skeleton, "handle-stop", + G_CALLBACK(handle_stop), this); + g_signal_connect (my_skeleton, "handle-restart", + G_CALLBACK(handle_restart), this); + + set_skeleton (G_DBUS_INTERFACE_SKELETON(my_skeleton)); +} + +MockConsoleKitManager :: ~MockConsoleKitManager () +{ + for (seats_t::iterator it(my_seats.begin()); it!=my_seats.end(); ++it) + { + MockConsoleKitSeat * seat = *it; + g_signal_handlers_disconnect_by_data (seat->skeleton(), &my_current_ssid); + delete seat; + } + + g_signal_handlers_disconnect_by_data (my_skeleton, this); + g_clear_object (&my_skeleton); +} diff --git a/tests/backend-dbus/mock-consolekit-manager.h b/tests/backend-dbus/mock-consolekit-manager.h new file mode 100644 index 0000000..c5942b2 --- /dev/null +++ b/tests/backend-dbus/mock-consolekit-manager.h @@ -0,0 +1,77 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef MOCK_CONSOLEKIT_MANAGER_H +#define MOCK_CONSOLEKIT_MANAGER_H + +#include +#include +#include "mock-object.h" +#include "backend-dbus/dbus-consolekit-manager.h" + +class MockConsoleKitSession; +class MockConsoleKitSeat; + +class MockConsoleKitManager: public MockObject +{ + public: + + MockConsoleKitManager (GMainLoop * loop, + GDBusConnection * bus_connection); + virtual ~MockConsoleKitManager (); + + void add_seat (MockConsoleKitSeat * seat); + + MockConsoleKitSession * current_session (); + + public: + + enum Action { None, Shutdown, Restart }; + + Action last_action () const { return my_last_action; } + + void clear_last_action () { my_last_action = None; } + + private: + + typedef std::set seats_t; + seats_t my_seats; + + ConsoleKitManager * my_skeleton; + + std::string my_current_ssid; + + Action my_last_action; + + static gboolean on_get_current_session (ConsoleKitManager *, + GDBusMethodInvocation *, + gpointer ); + static gboolean on_get_seats (ConsoleKitManager *, + GDBusMethodInvocation *, + gpointer ); + static gboolean handle_restart (ConsoleKitManager *, + GDBusMethodInvocation *, + gpointer); + static gboolean handle_stop (ConsoleKitManager *, + GDBusMethodInvocation *, + gpointer); + +}; + +#endif // #ifndef MOCK_CONSOLEKIT_MANAGER_H diff --git a/tests/backend-dbus/mock-consolekit-seat.cc b/tests/backend-dbus/mock-consolekit-seat.cc new file mode 100644 index 0000000..ce1fbad --- /dev/null +++ b/tests/backend-dbus/mock-consolekit-seat.cc @@ -0,0 +1,220 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include "mock-consolekit-seat.h" + +#include "mock-object.h" +#include "mock-consolekit-session.h" +#include "mock-user.h" + +namespace +{ + const char * CONSOLEKIT_BUS_NAME = "org.freedesktop.ConsoleKit"; + + std::string next_unique_sid () + { + static int id = 1; + + char * tmp; + std::string ret; + + tmp = g_strdup_printf ("/org/freedesktop/ConsoleKit/Seat%d", id++); + ret = tmp; + g_free (tmp); + return ret; + } +} + +/*** +**** +***/ + +void +MockConsoleKitSeat :: activate_session (MockConsoleKitSession * session) +{ + g_assert (my_sessions.count(session) == 1); + + const char * ssid = session->ssid (); + if (my_active_ssid != ssid) + { + my_active_ssid = ssid; + console_kit_seat_emit_active_session_changed (my_skeleton, ssid); + } +} + +void +MockConsoleKitSeat :: switch_to_guest () +{ + for (sessions_t::iterator it(my_sessions.begin()), + end(my_sessions.end()); it!=end; ++it) + { + MockConsoleKitSession * session (*it); + + if (session->user()->is_guest()) + { + activate_session (*it); + return; + } + } + + g_warn_if_reached (); +} + +void +MockConsoleKitSeat :: switch_to_user (const char * username) +{ + for (sessions_t::iterator it(my_sessions.begin()), + end(my_sessions.end()); it!=end; ++it) + { + MockConsoleKitSession * session (*it); + + if (!g_strcmp0 (username, session->user()->username())) + { + activate_session (*it); + return; + } + } + + g_warn_if_reached (); +} + +/*** +**** +***/ + +MockConsoleKitSession * +MockConsoleKitSeat :: add_session_by_user (MockUser * mu) +{ + g_assert (mu != 0); + + MockConsoleKitSession * session; + + session = new MockConsoleKitSession (my_loop, my_bus_connection); + session->set_user (mu); + add_session (session); + return session; +} + +void +MockConsoleKitSeat :: add_session (MockConsoleKitSession * session) +{ + g_assert (my_sessions.count(session) == 0); + + my_sessions.insert (session); + session->set_sid (path()); + console_kit_seat_emit_session_added (my_skeleton, session->ssid()); +} + +void +MockConsoleKitSeat :: remove_session (MockConsoleKitSession * session) +{ + g_assert (my_sessions.count(session) == 1); + + my_sessions.erase (session); + session->set_sid (""); + console_kit_seat_emit_session_removed (my_skeleton, session->ssid()); +} + +/*** +**** Handlers +***/ + +gboolean +MockConsoleKitSeat :: on_can_activate_sessions (ConsoleKitSeat * cks, + GDBusMethodInvocation * inv, + gpointer gself) +{ + bool b = static_cast(gself)->my_can_activate_sessions; + console_kit_seat_complete_can_activate_sessions (cks, inv, b); + return true; +} + +gboolean +MockConsoleKitSeat :: on_get_active_session (ConsoleKitSeat * cks, + GDBusMethodInvocation * invoke, + gpointer gself) +{ + std::string ssid = static_cast(gself)->my_active_ssid; + console_kit_seat_complete_get_active_session (cks, invoke, ssid.c_str()); + return true; +} + +gboolean +MockConsoleKitSeat :: on_get_sessions (ConsoleKitSeat * cks, + GDBusMethodInvocation * inv, + gpointer gself) +{ + int i; + const char ** paths; + sessions_t& sessions = static_cast(gself)->my_sessions; + + i = 0; + paths = g_new0 (const char*, sessions.size() + 1); + for (sessions_t::iterator it(sessions.begin()), + end(sessions.end()); it!=end; ++it) + paths[i++] = (*it)->path(); + + g_debug ("returning a list of %d sessions", i); + console_kit_seat_complete_get_sessions (cks, inv, paths); + g_free (paths); + + return true; +} + +MockConsoleKitSession * +MockConsoleKitSeat :: find (const char * ssid) +{ + for (sessions_t::iterator it(my_sessions.begin()), + end(my_sessions.end()); it!=end; ++it) + if (!g_strcmp0 ((*it)->path(), ssid)) + return *it; + + return 0; +} + +/*** +**** Life Cycle +***/ + +MockConsoleKitSeat :: MockConsoleKitSeat (GMainLoop * loop, + GDBusConnection * bus_connection, + bool can_activate_sessions): + MockObject (loop, bus_connection, CONSOLEKIT_BUS_NAME, next_unique_sid()), + my_skeleton (console_kit_seat_skeleton_new ()), + my_can_activate_sessions (can_activate_sessions) +{ + g_signal_connect (my_skeleton, "handle-get-active-session", + G_CALLBACK(on_get_active_session), this); + g_signal_connect (my_skeleton, "handle-get-sessions", + G_CALLBACK(on_get_sessions), this); + g_signal_connect (my_skeleton, "handle-can-activate-sessions", + G_CALLBACK(on_can_activate_sessions), this); + + set_skeleton (G_DBUS_INTERFACE_SKELETON(my_skeleton)); +} + +MockConsoleKitSeat :: ~MockConsoleKitSeat () +{ + for (sessions_t::iterator it(my_sessions.begin()), + end(my_sessions.end()); it!=end; ++it) + delete *it; + + g_signal_handlers_disconnect_by_data (my_skeleton, this); + g_clear_object (&my_skeleton); +} diff --git a/tests/backend-dbus/mock-consolekit-seat.h b/tests/backend-dbus/mock-consolekit-seat.h new file mode 100644 index 0000000..aa52276 --- /dev/null +++ b/tests/backend-dbus/mock-consolekit-seat.h @@ -0,0 +1,75 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef MOCK_CONSOLEKIT_SEAT_H +#define MOCK_CONSOLEKIT_SEAT_H + +#include +#include +#include "backend-dbus/dbus-consolekit-seat.h" +#include "mock-object.h" + +class MockUser; +class MockConsoleKitSession; + +class MockConsoleKitSeat: public MockObject +{ + public: + + MockConsoleKitSeat (GMainLoop * loop, + GDBusConnection * bus_connection, + bool can_activate_sessions); + virtual ~MockConsoleKitSeat (); + + const char * sid() { return path(); } + MockConsoleKitSession * add_session_by_user (MockUser * user); + void add_session (MockConsoleKitSession * session); + void remove_session (MockConsoleKitSession * session); + void activate_session (MockConsoleKitSession * session); + void switch_to_guest (); + void switch_to_user (const char * username); + bool can_activate_sessions () const { return my_can_activate_sessions; } + MockConsoleKitSession * find (const char * ssid); + + private: + + static gboolean on_get_active_session (ConsoleKitSeat * cks, + GDBusMethodInvocation * inv, + gpointer gself); + static gboolean on_get_sessions (ConsoleKitSeat * cks, + GDBusMethodInvocation * inv, + gpointer gself); + static gboolean on_can_activate_sessions (ConsoleKitSeat * cks, + GDBusMethodInvocation * inv, + gpointer gself); + + + private: + + ConsoleKitSeat * my_skeleton; + + std::string my_active_ssid; + + typedef std::set sessions_t; + sessions_t my_sessions; + bool my_can_activate_sessions; + +}; + +#endif // #ifndef MOCK_CONSOLEKIT_SEAT_H diff --git a/tests/backend-dbus/mock-consolekit-session.cc b/tests/backend-dbus/mock-consolekit-session.cc new file mode 100644 index 0000000..2f39411 --- /dev/null +++ b/tests/backend-dbus/mock-consolekit-session.cc @@ -0,0 +1,113 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include "mock-consolekit-session.h" +#include "mock-user.h" + +namespace +{ + const char * const DEFAULT_X11_DISPLAY = ":0:0"; + + const char * const CONSOLEKIT_NAME = "org.freedesktop.ConsoleKit"; + + std::string next_unique_ssid () + { + static int id = 333; // arbitrary + + char * tmp; + std::string ret; + + tmp = g_strdup_printf ("/org/freedesktop/ConsoleKit/Session%d", id++); + ret = tmp; + g_free (tmp); + return ret; + } +} + +void +MockConsoleKitSession :: set_user (MockUser * user) +{ + my_user = user; +} + +/*** +**** +***/ + +gboolean +MockConsoleKitSession :: on_get_seat_id_static (ConsoleKitSession * cks, + GDBusMethodInvocation * inv, + gpointer gself) +{ + const std::string& sid = static_cast(gself)->my_sid; + g_debug ("%s %s returning seat id of %s", G_STRLOC, G_STRFUNC, sid.c_str()); + console_kit_session_complete_get_seat_id (cks, inv, sid.c_str()); + return true; +} + +gboolean +MockConsoleKitSession :: on_get_unix_user_static (ConsoleKitSession * cks, + GDBusMethodInvocation * inv, + gpointer gself) +{ + MockUser * user = static_cast(gself)->my_user; + g_debug ("%s %s returning uid of %u", G_STRLOC, G_STRFUNC, user->uid()); + console_kit_session_complete_get_unix_user (cks, inv, user->uid()); + return true; +} + +gboolean +MockConsoleKitSession :: on_get_x11_display (ConsoleKitSession * cks, + GDBusMethodInvocation * inv, + gpointer gself) +{ + MockConsoleKitSession * self = static_cast(gself); + const char * x11 = self->x11_display(); + g_debug ("%s %s returning x11 display '%s'", G_STRLOC, G_STRFUNC, x11); + console_kit_session_complete_get_x11_display (cks, inv, x11); + return true; +} + +/*** +**** +***/ + +MockConsoleKitSession :: MockConsoleKitSession (GMainLoop * loop, + GDBusConnection * conn): + MockObject (loop, conn, CONSOLEKIT_NAME, next_unique_ssid ()), + my_skeleton (console_kit_session_skeleton_new ()), + my_x11_display (DEFAULT_X11_DISPLAY), + my_user (0) +{ + g_signal_connect (my_skeleton, "handle-get-seat-id", + G_CALLBACK(on_get_seat_id_static), this); + g_signal_connect (my_skeleton, "handle-get-unix-user", + G_CALLBACK(on_get_unix_user_static), this); + g_signal_connect (my_skeleton, "handle-get-x11-display", + G_CALLBACK(on_get_x11_display), this); + + set_skeleton (G_DBUS_INTERFACE_SKELETON(my_skeleton)); +} + +MockConsoleKitSession :: ~MockConsoleKitSession () +{ + const int n = g_signal_handlers_disconnect_by_data (my_skeleton, this); + g_assert (n == 3); + g_clear_object (&my_skeleton); +} diff --git a/tests/backend-dbus/mock-consolekit-session.h b/tests/backend-dbus/mock-consolekit-session.h new file mode 100644 index 0000000..7759f72 --- /dev/null +++ b/tests/backend-dbus/mock-consolekit-session.h @@ -0,0 +1,65 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef MOCK_CONSOLEKIT_SESSION_H +#define MOCK_CONSOLEKIT_SESSION_H + +#include +#include "mock-object.h" +#include "backend-dbus/dbus-consolekit-session.h" + +class MockUser; + +class MockConsoleKitSession: public MockObject +{ + public: + + MockConsoleKitSession (GMainLoop * loop, + GDBusConnection * bus_connection); + virtual ~MockConsoleKitSession (); + + MockUser * user () { return my_user; } + void set_user (MockUser * user); + const char * ssid () { return path(); } + void set_sid (const std::string& sid) { my_sid = sid; } + const char * x11_display() { return my_x11_display.c_str(); } + void set_x11_display (const std::string& x) { my_x11_display = x; } + + private: + + static gboolean on_get_seat_id_static (ConsoleKitSession *, + GDBusMethodInvocation *, + gpointer); + static gboolean on_get_unix_user_static (ConsoleKitSession *, + GDBusMethodInvocation *, + gpointer); + static gboolean on_get_x11_display (ConsoleKitSession *, + GDBusMethodInvocation *, + gpointer); + + + private: + + ConsoleKitSession * my_skeleton; + std::string my_sid; + std::string my_x11_display; + MockUser * my_user; +}; + +#endif // #ifndef MOCK_CONSOLEKIT_SESSION_H diff --git a/tests/backend-dbus/mock-display-manager-seat.cc b/tests/backend-dbus/mock-display-manager-seat.cc new file mode 100644 index 0000000..9f30ae1 --- /dev/null +++ b/tests/backend-dbus/mock-display-manager-seat.cc @@ -0,0 +1,140 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include "mock-display-manager-seat.h" +#include "mock-consolekit-seat.h" + +namespace +{ + const char * const DISPLAY_MANAGER_NAME = "org.freedesktop.DisplayManager"; + + std::string + next_unique_path () + { + static int id = 12; // arbitrary; doesn't matter + + char * tmp; + std::string ret; + + tmp = g_strdup_printf ("/org/freedesktop/DisplayManager/Seat%d", id++); + ret = tmp; + g_free (tmp); + return ret; + } +} + +/*** +**** +***/ + +void +MockDisplayManagerSeat :: switch_to_greeter () +{ + my_last_action = GREETER; +} + +gboolean +MockDisplayManagerSeat :: handle_switch_to_greeter (DisplayManagerSeat * o, + GDBusMethodInvocation * inv, + gpointer gself) +{ + static_cast(gself)->switch_to_greeter (); + display_manager_seat_complete_switch_to_greeter (o, inv); + return true; +} + +void +MockDisplayManagerSeat :: set_guest_allowed (bool b) +{ + display_manager_seat_set_has_guest_account (my_skeleton, b); +} + +gboolean +MockDisplayManagerSeat :: handle_switch_to_guest (DisplayManagerSeat * o, + GDBusMethodInvocation * inv, + const gchar * session_name G_GNUC_UNUSED, + gpointer gself) +{ + static_cast(gself)->switch_to_guest (); + display_manager_seat_complete_switch_to_guest (o, inv); + return true; +} + +void +MockDisplayManagerSeat :: switch_to_guest () +{ + g_assert (my_ck_seat != 0); + + my_last_action = GUEST; + my_ck_seat->switch_to_guest (); +} + +gboolean +MockDisplayManagerSeat :: handle_switch_to_user (DisplayManagerSeat * o, + GDBusMethodInvocation * inv, + const gchar * username, + const gchar * session_name G_GNUC_UNUSED, + gpointer gself) +{ + static_cast(gself)->switch_to_user (username); + display_manager_seat_complete_switch_to_user (o, inv); + return true; +} + +void +MockDisplayManagerSeat :: switch_to_user (const char * username) +{ + g_assert (my_ck_seat != 0); + + my_last_action = USER; + my_ck_seat->switch_to_user (username); +} + +void +MockDisplayManagerSeat :: set_consolekit_seat (MockConsoleKitSeat * seat) +{ + my_ck_seat = seat; +} + +/*** +**** +***/ + +MockDisplayManagerSeat :: MockDisplayManagerSeat (GMainLoop * loop, + GDBusConnection * connection): + MockObject (loop, connection, DISPLAY_MANAGER_NAME, next_unique_path()), + my_skeleton (display_manager_seat_skeleton_new ()), + my_ck_seat (0), + my_last_action (NONE) +{ + g_signal_connect (my_skeleton, "handle-switch-to-guest", + G_CALLBACK(handle_switch_to_guest), this); + g_signal_connect (my_skeleton, "handle-switch-to-user", + G_CALLBACK(handle_switch_to_user), this); + g_signal_connect (my_skeleton, "handle-switch-to-greeter", + G_CALLBACK(handle_switch_to_greeter), this); + + set_skeleton (G_DBUS_INTERFACE_SKELETON(my_skeleton)); +} + +MockDisplayManagerSeat :: ~MockDisplayManagerSeat () +{ + g_signal_handlers_disconnect_by_data (my_skeleton, this); + g_clear_object (&my_skeleton); +} diff --git a/tests/backend-dbus/mock-display-manager-seat.h b/tests/backend-dbus/mock-display-manager-seat.h new file mode 100644 index 0000000..b0ea415 --- /dev/null +++ b/tests/backend-dbus/mock-display-manager-seat.h @@ -0,0 +1,72 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef MOCK_DISPLAY_MANAGER_SEAT_H +#define MOCK_DISPLAY_MANAGER_SEAT_H + +#include "mock-object.h" // parent class +#include "backend-dbus/dbus-display-manager.h" + +class MockConsoleKitSeat; + +class MockDisplayManagerSeat: public MockObject +{ + public: + + MockDisplayManagerSeat (GMainLoop * loop, + GDBusConnection * bus_connection); + virtual ~MockDisplayManagerSeat (); + + void set_guest_allowed (bool b); + + void set_consolekit_seat (MockConsoleKitSeat * ck_seat); + + void switch_to_guest (); + + void switch_to_greeter (); + + void switch_to_user (const char * username); + + public: + + enum Action { NONE, GUEST, GREETER, USER }; + + Action last_action () const { return my_last_action; } + + private: + + static gboolean handle_switch_to_greeter (DisplayManagerSeat *o, + GDBusMethodInvocation *inv, + gpointer gself); + static gboolean handle_switch_to_guest (DisplayManagerSeat *o, + GDBusMethodInvocation *inv, + const gchar *session_name, + gpointer gself); + static gboolean handle_switch_to_user (DisplayManagerSeat * o, + GDBusMethodInvocation * inv, + const gchar * username, + const gchar * session_name, + gpointer gself); + + DisplayManagerSeat * my_skeleton; + MockConsoleKitSeat * my_ck_seat; + Action my_last_action; +}; + +#endif // #ifndef MOCK_DISPLAY_MANAGER_SEAT_H diff --git a/tests/backend-dbus/mock-end-session-dialog.cc b/tests/backend-dbus/mock-end-session-dialog.cc new file mode 100644 index 0000000..e289a83 --- /dev/null +++ b/tests/backend-dbus/mock-end-session-dialog.cc @@ -0,0 +1,89 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include "mock-end-session-dialog.h" + +#if 0 +gboolean +MockEndSessionDialog :: handle_lock (GnomeScreenSaver * ss, + GDBusMethodInvocation * inv, + gpointer gself) +{ + static_cast(gself)->my_last_action = Lock; + gnome_screen_saver_complete_lock (ss, inv); + return true; +} + +gboolean +MockEndSessionDialog :: handle_simulate_user_activity (GnomeScreenSaver * ss, + GDBusMethodInvocation * inv, + gpointer gself) +{ + static_cast(gself)->my_last_action = UserActivity; + gnome_screen_saver_complete_simulate_user_activity (ss, inv); + return true; +} +#endif + +gboolean +MockEndSessionDialog :: handle_open (EndSessionDialog * object, + GDBusMethodInvocation * invocation, + guint arg_type, + guint arg_timestamp, + guint arg_seconds_to_stay_open, + const gchar * const * inhibitor_paths, + gpointer gself) +{ + static_cast(gself)->my_isOpen = true; + end_session_dialog_complete_open (object, invocation); + return true; +} + +/*** +**** +***/ + +namespace +{ + const char * const MY_NAME = "com.canonical.Unity"; + const char * const MY_PATH = "/org/gnome/SessionManager/EndSessionDialog"; +} + +MockEndSessionDialog :: MockEndSessionDialog (GMainLoop * loop, + GDBusConnection * bus_connection): + MockObject (loop, bus_connection, MY_NAME, MY_PATH), + my_isOpen (false), + my_skeleton (end_session_dialog_skeleton_new ()) +{ + g_signal_connect (my_skeleton, "handle-open", + G_CALLBACK(handle_open), this); +#if 0 + g_signal_connect (my_skeleton, "handle-lock", + G_CALLBACK(handle_lock), this); + g_signal_connect (my_skeleton, "handle-simulate-user-activity", + G_CALLBACK(handle_simulate_user_activity), this); +#endif + + set_skeleton (G_DBUS_INTERFACE_SKELETON(my_skeleton)); +} + +MockEndSessionDialog :: ~MockEndSessionDialog () +{ + g_clear_object (&my_skeleton); +} diff --git a/tests/backend-dbus/mock-end-session-dialog.h b/tests/backend-dbus/mock-end-session-dialog.h new file mode 100644 index 0000000..468715c --- /dev/null +++ b/tests/backend-dbus/mock-end-session-dialog.h @@ -0,0 +1,67 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef MOCK_END_SESSION_DIALOG_H +#define MOCK_END_SESSION_DIALOG_H + +#include "mock-object.h" // parent class +#include "backend-dbus/dbus-end-session-dialog.h" // EndSessionDialog + +class MockEndSessionDialog: public MockObject +{ + public: + + MockEndSessionDialog (GMainLoop * loop, + GDBusConnection * bus_connection); + virtual ~MockEndSessionDialog (); + + bool is_open () const { return my_isOpen; } + + void cancel () { my_isOpen = false; end_session_dialog_emit_canceled (my_skeleton); } + void confirm_logout () { my_isOpen = false; end_session_dialog_emit_confirmed_logout (my_skeleton); } + void confirm_reboot () { my_isOpen = false; end_session_dialog_emit_confirmed_reboot (my_skeleton); } + void confirm_shutdown () { my_isOpen = false; end_session_dialog_emit_confirmed_shutdown (my_skeleton); } + void close () { my_isOpen = false; end_session_dialog_emit_closed (my_skeleton); } + + private: + + EndSessionDialog * my_skeleton; + + bool my_isOpen; + + static gboolean handle_open (EndSessionDialog *, + GDBusMethodInvocation *, + guint, + guint, + guint, + const gchar * const *, + gpointer); + + +#if 0 + static gboolean handle_lock (GnomeScreenSaver *, + GDBusMethodInvocation *, + gpointer); + static gboolean handle_simulate_user_activity (GnomeScreenSaver *, + GDBusMethodInvocation *, + gpointer); +#endif +}; + +#endif diff --git a/tests/backend-dbus/mock-object.cc b/tests/backend-dbus/mock-object.cc new file mode 100644 index 0000000..af9330b --- /dev/null +++ b/tests/backend-dbus/mock-object.cc @@ -0,0 +1,122 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include +#include + +#include "mock-object.h" + +namespace +{ + const int TIMEOUT_SECONDS = 5; + + gboolean on_timeout_reached (gpointer loop) + { + g_main_loop_quit (static_cast(loop)); + return G_SOURCE_REMOVE; + } + + void on_name_acquired (GDBusConnection * connection G_GNUC_UNUSED, + const char * name G_GNUC_UNUSED, + gpointer loop) + { + //g_debug ("name '%s' acquired", name); + g_main_loop_quit (static_cast(loop)); + } + + void on_name_lost (GDBusConnection * connection G_GNUC_UNUSED, + const char * name G_GNUC_UNUSED, + gpointer loop) + { + //g_debug ("name '%s' lost", name); + g_main_loop_quit (static_cast(loop)); + } +} + +void +MockObject :: set_skeleton (GDBusInterfaceSkeleton * skeleton) +{ + g_assert (skeleton != NULL); + g_assert (my_skeleton == NULL); + g_assert (g_variant_is_object_path (my_object_path.c_str())); + g_assert (my_owner_id == 0); + + my_skeleton = G_DBUS_INTERFACE_SKELETON (g_object_ref (skeleton)); + + GError * err = NULL; + g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON(my_skeleton), + my_bus_connection, + my_object_path.c_str(), + &err); + g_assert_no_error (err); + + my_owner_id = g_bus_own_name_on_connection (my_bus_connection, + my_object_name.c_str(), + G_BUS_NAME_OWNER_FLAGS_NONE, + on_name_acquired, + on_name_lost, + my_loop, + NULL); + + // wait for the name to be acquired or timeout, whichever comes first + const guint timeout_id = g_timeout_add_seconds (TIMEOUT_SECONDS, + on_timeout_reached, + my_loop); + g_main_loop_run (my_loop); + g_assert (g_main_context_find_source_by_id (NULL, timeout_id) != NULL); + g_source_remove (timeout_id); +} + +/*** +**** +***/ + +MockObject :: MockObject (GMainLoop * loop, + GDBusConnection * bus_connection, + const std::string & object_name, + const std::string & object_path): + my_owner_id (0), + my_loop (g_main_loop_ref (loop)), + my_bus_connection (G_DBUS_CONNECTION (g_object_ref (bus_connection))), + my_object_name (object_name), + my_object_path (object_path), + my_skeleton (0) +{ +} + +MockObject :: ~MockObject () +{ + g_main_loop_unref (my_loop); + + if (my_owner_id != 0) + { + g_bus_unown_name (my_owner_id); + + my_owner_id = 0; + } + + if (my_skeleton) + { + g_dbus_interface_skeleton_unexport (my_skeleton); + + g_clear_object (&my_skeleton); + } + + g_clear_object (&my_bus_connection); +} diff --git a/tests/backend-dbus/mock-object.h b/tests/backend-dbus/mock-object.h new file mode 100644 index 0000000..8dc7070 --- /dev/null +++ b/tests/backend-dbus/mock-object.h @@ -0,0 +1,62 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef MOCK_OBJECT_H +#define MOCK_OBJECT_H + +#include + +#include +#include + +class MockObject +{ + public: + + MockObject (GMainLoop * loop, + GDBusConnection * bus_connection, + const std::string & object_name, + const std::string & object_path); + + virtual ~MockObject (); + + const char * name() const { return my_object_name.c_str(); } + const char * path() const { return my_object_path.c_str(); } + + GDBusInterfaceSkeleton * skeleton() { return my_skeleton; } + + protected: + + guint my_owner_id; + GMainLoop * my_loop; + GDBusConnection * my_bus_connection; + const std::string my_object_name; + const std::string my_object_path; + GDBusInterfaceSkeleton * my_skeleton; + + void set_skeleton (GDBusInterfaceSkeleton * skeleton); + + private: + // safeguard to make sure we don't copy-by-value... + // this object's holding a handful of pointers + MockObject (const MockObject& rhs); + MockObject& operator= (const MockObject& rhs); +}; + +#endif diff --git a/tests/backend-dbus/mock-screen-saver.cc b/tests/backend-dbus/mock-screen-saver.cc new file mode 100644 index 0000000..1d3bb11 --- /dev/null +++ b/tests/backend-dbus/mock-screen-saver.cc @@ -0,0 +1,71 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include "mock-screen-saver.h" + + +gboolean +MockScreenSaver :: handle_lock (GnomeScreenSaver * ss, + GDBusMethodInvocation * inv, + gpointer gself) +{ + static_cast(gself)->my_last_action = Lock; + gnome_screen_saver_complete_lock (ss, inv); + return true; +} + +gboolean +MockScreenSaver :: handle_simulate_user_activity (GnomeScreenSaver * ss, + GDBusMethodInvocation * inv, + gpointer gself) +{ + static_cast(gself)->my_last_action = UserActivity; + gnome_screen_saver_complete_simulate_user_activity (ss, inv); + return true; +} + +/*** +**** +***/ + +namespace +{ + const char * const SCREENSAVER_NAME = "org.gnome.ScreenSaver"; + const char * const SCREENSAVER_PATH = "/org/gnome/ScreenSaver"; + +} + +MockScreenSaver :: MockScreenSaver (GMainLoop * loop, + GDBusConnection * bus_connection): + MockObject (loop, bus_connection, SCREENSAVER_NAME, SCREENSAVER_PATH), + my_skeleton (gnome_screen_saver_skeleton_new ()), + my_last_action (None) +{ + g_signal_connect (my_skeleton, "handle-lock", + G_CALLBACK(handle_lock), this); + g_signal_connect (my_skeleton, "handle-simulate-user-activity", + G_CALLBACK(handle_simulate_user_activity), this); + + set_skeleton (G_DBUS_INTERFACE_SKELETON(my_skeleton)); +} + +MockScreenSaver :: ~MockScreenSaver () +{ + g_clear_object (&my_skeleton); +} diff --git a/tests/backend-dbus/mock-screen-saver.h b/tests/backend-dbus/mock-screen-saver.h new file mode 100644 index 0000000..c57a4c6 --- /dev/null +++ b/tests/backend-dbus/mock-screen-saver.h @@ -0,0 +1,53 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef MOCK_SCREENSAVER_H +#define MOCK_SCREENSAVER_H + +#include "mock-object.h" // parent class +#include "backend-dbus/gnome-screen-saver.h" // GnomeScreenSaver + +class MockScreenSaver: public MockObject +{ + public: + + MockScreenSaver (GMainLoop * loop, + GDBusConnection * bus_connection); + virtual ~MockScreenSaver (); + + public: + + enum Action { None, Lock, UserActivity }; + Action last_action () { return my_last_action; } + + private: + + GnomeScreenSaver * my_skeleton; + Action my_last_action; + + static gboolean handle_lock (GnomeScreenSaver *, + GDBusMethodInvocation *, + gpointer); + static gboolean handle_simulate_user_activity (GnomeScreenSaver *, + GDBusMethodInvocation *, + gpointer); + +}; + +#endif diff --git a/tests/backend-dbus/mock-session-manager.cc b/tests/backend-dbus/mock-session-manager.cc new file mode 100644 index 0000000..7a4ce87 --- /dev/null +++ b/tests/backend-dbus/mock-session-manager.cc @@ -0,0 +1,66 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include "mock-session-manager.h" + +gboolean +MockSessionManager :: handle_logout (GnomeSessionManager * gsm, + GDBusMethodInvocation * inv, + guint arg, + gpointer gself) +{ + Action action; + switch (arg) { + case 0: action = LogoutNormal; break; + case 1: action = LogoutQuiet; break; + case 2: action = LogoutForce; break; + default: action = None; break; + } + static_cast(gself)->my_last_action = action; + gnome_session_manager_complete_logout (gsm, inv); + return true; +} + + /*** +**** +***/ + +namespace +{ + const char * const SESSION_MANAGER_NAME = "org.gnome.SessionManager"; + const char * const SESSION_MANAGER_PATH = "/org/gnome/SessionManager"; + +} + +MockSessionManager :: MockSessionManager (GMainLoop * loop, + GDBusConnection * bus_connection): + MockObject (loop, bus_connection, SESSION_MANAGER_NAME, SESSION_MANAGER_PATH), + my_skeleton (gnome_session_manager_skeleton_new ()), + my_last_action (None) +{ + g_signal_connect (my_skeleton, "handle-logout", + G_CALLBACK(handle_logout), this); + + set_skeleton (G_DBUS_INTERFACE_SKELETON(my_skeleton)); +} + +MockSessionManager :: ~MockSessionManager () +{ + g_clear_object (&my_skeleton); +} diff --git a/tests/backend-dbus/mock-session-manager.h b/tests/backend-dbus/mock-session-manager.h new file mode 100644 index 0000000..6a21277 --- /dev/null +++ b/tests/backend-dbus/mock-session-manager.h @@ -0,0 +1,50 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef MOCK_SESSION_MANAGER_H +#define MOCK_SESSION_MANAGER_H + +#include "mock-object.h" // parent class +#include "backend-dbus/gnome-session-manager.h" // GnomeSessionManager + +class MockSessionManager: public MockObject +{ + public: + + MockSessionManager (GMainLoop * loop, + GDBusConnection * bus_connection); + virtual ~MockSessionManager (); + + public: + + enum Action { None, LogoutNormal, LogoutQuiet, LogoutForce }; + Action last_action () { return my_last_action; } + + private: + + GnomeSessionManager * my_skeleton; + Action my_last_action; + + static gboolean handle_logout (GnomeSessionManager *, + GDBusMethodInvocation *, + guint, + gpointer); +}; + +#endif diff --git a/tests/backend-dbus/mock-upower.cc b/tests/backend-dbus/mock-upower.cc new file mode 100644 index 0000000..65757b3 --- /dev/null +++ b/tests/backend-dbus/mock-upower.cc @@ -0,0 +1,103 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include "mock-upower.h" + + +gboolean +MockUPower :: handle_suspend (UPower * upower, + GDBusMethodInvocation * inv, + gpointer gself) +{ + static_cast(gself)->my_last_action = Suspend; + upower_complete_suspend (upower, inv); + return true; +} + +gboolean +MockUPower :: handle_hibernate (UPower * upower, + GDBusMethodInvocation * inv, + gpointer gself) +{ + static_cast(gself)->my_last_action = Hibernate; + upower_complete_hibernate (upower, inv); + return true; +} + +gboolean +MockUPower :: handle_suspend_allowed (UPower * upower, + GDBusMethodInvocation * inv, + gpointer gself) +{ + const bool allowed = static_cast(gself)->my_can_suspend; + upower_complete_suspend_allowed (upower, inv, allowed); + return true; +} + +gboolean +MockUPower :: handle_hibernate_allowed (UPower * upower, + GDBusMethodInvocation * inv, + gpointer gself) +{ + const bool allowed = static_cast(gself)->my_can_hibernate; + upower_complete_hibernate_allowed (upower, inv, allowed); + return true; +} + +/*** +**** +***/ + +namespace +{ + const char * const UPOWER_NAME = "org.freedesktop.UPower"; + const char * const UPOWER_PATH = "/org/freedesktop/UPower"; + +} + +MockUPower :: MockUPower (GMainLoop * loop, + GDBusConnection * bus_connection): + MockObject (loop, bus_connection, UPOWER_NAME, UPOWER_PATH), + my_skeleton (upower_skeleton_new ()), + my_can_suspend (true), + my_can_hibernate (true), + my_suspend_allowed (true), + my_hibernate_allowed (true), + my_last_action (None) +{ + //set_can_hibernate (false); + //set_can_suspend (true); + + g_signal_connect (my_skeleton, "handle-suspend", + G_CALLBACK(handle_suspend), this); + g_signal_connect (my_skeleton, "handle-suspend-allowed", + G_CALLBACK(handle_suspend_allowed), this); + + g_signal_connect (my_skeleton, "handle-hibernate", + G_CALLBACK(handle_hibernate), this); + g_signal_connect (my_skeleton, "handle-hibernate-allowed", + G_CALLBACK(handle_hibernate_allowed), this); + + set_skeleton (G_DBUS_INTERFACE_SKELETON(my_skeleton)); +} + +MockUPower :: ~MockUPower () +{ + g_clear_object (&my_skeleton); +} diff --git a/tests/backend-dbus/mock-upower.h b/tests/backend-dbus/mock-upower.h new file mode 100644 index 0000000..351d0f7 --- /dev/null +++ b/tests/backend-dbus/mock-upower.h @@ -0,0 +1,72 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef MOCK_UPOWER_H +#define MOCK_UPOWER_H + +#include "mock-object.h" // parent class +#include "backend-dbus/dbus-upower.h" // UPower + +class MockUPower: public MockObject +{ + public: + + MockUPower (GMainLoop * loop, + GDBusConnection * bus_connection); + virtual ~MockUPower (); + + void set_can_suspend (bool b) { upower_set_can_suspend (my_skeleton, b); } + void set_can_hibernate (bool b) { upower_set_can_hibernate (my_skeleton, b); } + + bool suspend_allowed () const { return my_suspend_allowed; } + bool hibernate_allowed () const { return my_suspend_allowed; } + bool can_suspend () const { return upower_get_can_suspend (my_skeleton); } + bool can_hibernate () const { return upower_get_can_hibernate (my_skeleton); } + + public: + + enum Action { None, Suspend, Hibernate }; + Action last_action () { return my_last_action; } + + private: + + UPower * my_skeleton; + bool my_can_suspend; + bool my_can_hibernate; + bool my_suspend_allowed; + bool my_hibernate_allowed; + Action my_last_action; + + static gboolean handle_suspend_allowed (UPower *, + GDBusMethodInvocation *, + gpointer); + static gboolean handle_suspend (UPower *, + GDBusMethodInvocation *, + gpointer); + + static gboolean handle_hibernate_allowed (UPower *, + GDBusMethodInvocation *, + gpointer); + static gboolean handle_hibernate (UPower *, + GDBusMethodInvocation *, + gpointer); + +}; + +#endif diff --git a/tests/backend-dbus/mock-user.cc b/tests/backend-dbus/mock-user.cc new file mode 100644 index 0000000..abf2e21 --- /dev/null +++ b/tests/backend-dbus/mock-user.cc @@ -0,0 +1,131 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include "mock-user.h" + +/*** +**** +***/ + +const char * +MockUser :: username () const +{ + return accounts_user_get_user_name (my_skeleton); +} + +const char * +MockUser :: realname () const +{ + return accounts_user_get_real_name (my_skeleton); +} + +void +MockUser :: set_realname (const char * realname) +{ + accounts_user_set_real_name (my_skeleton, realname); + accounts_user_emit_changed (my_skeleton); +} + +guint +MockUser :: uid () const +{ + return accounts_user_get_uid (my_skeleton); +} + +guint64 +MockUser :: login_frequency () const +{ + return accounts_user_get_login_frequency (my_skeleton); +} + +#if 0 +bool +MockUser :: system_account() const +{ + return accounts_user_get_system_account (my_skeleton); +} +#endif + +void +MockUser :: set_system_account (gboolean b) +{ + accounts_user_set_system_account (my_skeleton, b); +} + +bool +MockUser :: is_guest () const +{ + // a guest will look like this: + // username:[guest-jjbEVV] realname:[Guest] system:[1] + return accounts_user_get_system_account (my_skeleton) + && !g_ascii_strcasecmp (accounts_user_get_real_name(my_skeleton), "Guest"); +} + +/*** +**** +***/ + +namespace +{ + const char * const DBUS_ACCOUNTS_NAME = "org.freedesktop.Accounts"; + + static guint next_uid = 1000; + + std::string path_for_uid (guint uid) + { + char * tmp; + std::string ret; + const char * const DBUS_ACCOUNTS_PATH = "/org/freedesktop/Accounts"; + tmp = g_strdup_printf ("%s/User%u", DBUS_ACCOUNTS_PATH, uid); + ret = tmp; + g_free (tmp); + return ret; + } +} + +guint +MockUser :: get_next_uid () +{ + return next_uid++; +} + + +MockUser :: MockUser (GMainLoop * loop, + GDBusConnection * bus_connection, + const char * userName, + const char * realName, + guint64 login_frequency, + guint uid_): + MockObject (loop, bus_connection, DBUS_ACCOUNTS_NAME, path_for_uid(uid_)), + my_skeleton (accounts_user_skeleton_new ()) +{ + accounts_user_set_uid (my_skeleton, uid_); + accounts_user_set_user_name (my_skeleton, userName); + accounts_user_set_real_name (my_skeleton, realName); + accounts_user_set_login_frequency (my_skeleton, login_frequency); + accounts_user_set_system_account (my_skeleton, false); + + set_skeleton (G_DBUS_INTERFACE_SKELETON(my_skeleton)); +} + +MockUser :: ~MockUser () +{ + g_signal_handlers_disconnect_by_data (my_skeleton, this); + g_clear_object (&my_skeleton); +} diff --git a/tests/backend-dbus/mock-user.h b/tests/backend-dbus/mock-user.h new file mode 100644 index 0000000..c1d3d0f --- /dev/null +++ b/tests/backend-dbus/mock-user.h @@ -0,0 +1,57 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef MOCK_USER_H +#define MOCK_USER_H + +#include "mock-object.h" // parent class +#include "backend-dbus/dbus-user.h" // AccountsUser + +class MockUser: public MockObject +{ + protected: + + static guint get_next_uid (); + + public: + + MockUser (GMainLoop * loop, + GDBusConnection * bus_connection, + const char * userName, + const char * realName, + guint64 login_frequency, + guint uid = get_next_uid()); + virtual ~MockUser (); + + const char * username () const; + const char * realname () const; + void set_realname (const char *); + guint uid () const; + guint64 login_frequency () const; + //bool system_account() const; + + bool is_guest() const; + void set_system_account (gboolean b); + + private: + + AccountsUser * my_skeleton; +}; + +#endif diff --git a/tests/backend-dbus/mock-webcredentials.cc b/tests/backend-dbus/mock-webcredentials.cc new file mode 100644 index 0000000..44fa8ac --- /dev/null +++ b/tests/backend-dbus/mock-webcredentials.cc @@ -0,0 +1,54 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include "mock-webcredentials.h" + +namespace +{ + const char * const MY_NAME = "com.canonical.indicators.webcredentials"; + const char * const MY_PATH = "/com/canonical/indicators/webcredentials"; +} + +MockWebcredentials :: MockWebcredentials (GMainLoop * loop, + GDBusConnection * bus_connection): + MockObject (loop, bus_connection, MY_NAME, MY_PATH), + my_skeleton (webcredentials_skeleton_new ()) +{ + //set_can_hibernate (false); + //set_can_suspend (true); + +#if 0 + g_signal_connect (my_skeleton, "handle-suspend", + G_CALLBACK(handle_suspend), this); + g_signal_connect (my_skeleton, "handle-suspend-allowed", + G_CALLBACK(handle_suspend_allowed), this); + + g_signal_connect (my_skeleton, "handle-hibernate", + G_CALLBACK(handle_hibernate), this); + g_signal_connect (my_skeleton, "handle-hibernate-allowed", + G_CALLBACK(handle_hibernate_allowed), this); +#endif + + set_skeleton (G_DBUS_INTERFACE_SKELETON(my_skeleton)); +} + +MockWebcredentials :: ~MockWebcredentials () +{ + g_clear_object (&my_skeleton); +} diff --git a/tests/backend-dbus/mock-webcredentials.h b/tests/backend-dbus/mock-webcredentials.h new file mode 100644 index 0000000..212ca76 --- /dev/null +++ b/tests/backend-dbus/mock-webcredentials.h @@ -0,0 +1,42 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef MOCK_WEBCREDENTIALS_H +#define MOCK_WEBCREDENTIALS_H + +#include "mock-object.h" // parent class +#include "backend-dbus/dbus-webcredentials.h" // Webcredentials + +class MockWebcredentials: public MockObject +{ + public: + + MockWebcredentials (GMainLoop * loop, + GDBusConnection * bus_connection); + virtual ~MockWebcredentials (); + + bool has_error () const { return webcredentials_get_error_status (my_skeleton); } + bool set_error (bool b) const { webcredentials_set_error_status (my_skeleton, b); } + + private: + + Webcredentials * my_skeleton; +}; + +#endif diff --git a/tests/backend-dbus/test-actions.cc b/tests/backend-dbus/test-actions.cc new file mode 100644 index 0000000..f79c913 --- /dev/null +++ b/tests/backend-dbus/test-actions.cc @@ -0,0 +1,454 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include "gtest-mock-dbus-fixture.h" + +#include "backend.h" +#include "backend-dbus/backend-dbus.h" + +/*** +**** +***/ + +class Actions: public GTestMockDBusFixture +{ + private: + + typedef GTestMockDBusFixture super; + + protected: + + GCancellable * cancellable; + IndicatorSessionActions * actions; + + virtual void SetUp () + { + super :: SetUp (); + + // init 'actions' + cancellable = g_cancellable_new (); + actions = 0; + backend_get (cancellable, &actions, NULL, NULL); + g_assert (actions != 0); + wait_msec (100); + } + + virtual void TearDown () + { + g_cancellable_cancel (cancellable); + g_clear_object (&cancellable); + g_clear_object (&actions); + + super :: TearDown (); + } +}; + +/*** +**** +***/ + +TEST_F (Actions, HelloWorld) +{ + ASSERT_TRUE (true); +} + +namespace +{ + static gboolean toggle_can_switch (gpointer settings) + { + const char * key = "disable-user-switching"; + gboolean b = g_settings_get_boolean (G_SETTINGS(settings), key); + g_settings_set_boolean (G_SETTINGS(settings), key, !b); + return G_SOURCE_REMOVE; + } +} + +TEST_F (Actions, CanSwitch) +{ + const char * schema_id = "org.gnome.desktop.lockdown"; + const char * settings_key = "disable-user-switching"; + GSettings * s = g_settings_new (schema_id); + + for (int i=0; i<3; ++i) + { + bool b; + gboolean b2; + + b = ck_seat->can_activate_sessions() && !g_settings_get_boolean (s, settings_key); + ASSERT_EQ (b, indicator_session_actions_can_switch (actions)); + g_object_get (actions, INDICATOR_SESSION_ACTIONS_PROP_CAN_SWITCH, &b2, NULL); + ASSERT_EQ (b, b2); + + g_idle_add (toggle_can_switch, s); + wait_for_signal (actions, "notify::" INDICATOR_SESSION_ACTIONS_PROP_CAN_SWITCH); + } + + g_object_unref (s); +} + +namespace +{ + static gboolean toggle_can_lock (gpointer settings) + { + const char * key = "disable-lock-screen"; + gboolean b = g_settings_get_boolean (G_SETTINGS(settings), key); + g_settings_set_boolean (G_SETTINGS(settings), key, !b); + return G_SOURCE_REMOVE; + } +} + +TEST_F (Actions, CanLock) +{ + const char * schema_id = "org.gnome.desktop.lockdown"; + const char * settings_key = "disable-lock-screen"; + GSettings * s = g_settings_new (schema_id); + + for (int i=0; i<3; ++i) + { + bool b; + gboolean b2; + + b = g_settings_get_boolean (s, settings_key); + ASSERT_EQ (b, !indicator_session_actions_can_lock (actions)); + g_object_get (actions, INDICATOR_SESSION_ACTIONS_PROP_CAN_LOCK, &b2, NULL); + ASSERT_EQ (b, !b2); + + g_idle_add (toggle_can_lock, s); + wait_for_signal (actions, "notify::" INDICATOR_SESSION_ACTIONS_PROP_CAN_LOCK); + } + + g_object_unref (s); +} + +namespace +{ + static gboolean toggle_can_logout (gpointer settings) + { + const char * key = "disable-log-out"; + gboolean b = g_settings_get_boolean (G_SETTINGS(settings), key); + g_settings_set_boolean (G_SETTINGS(settings), key, !b); + return G_SOURCE_REMOVE; + } +} + +TEST_F (Actions, CanLogout) +{ + const char * schema_id = "org.gnome.desktop.lockdown"; + const char * settings_key = "disable-log-out"; + GSettings * s = g_settings_new (schema_id); + + for (int i=0; i<3; ++i) + { + bool b; + gboolean b2; + + b = g_settings_get_boolean (s, settings_key); + ASSERT_EQ (b, !indicator_session_actions_can_logout (actions)); + g_object_get (actions, INDICATOR_SESSION_ACTIONS_PROP_CAN_LOGOUT, &b2, NULL); + ASSERT_EQ (b, !b2); + + g_idle_add (toggle_can_logout, s); + wait_for_signal (actions, "notify::" INDICATOR_SESSION_ACTIONS_PROP_CAN_LOGOUT); + } + + g_object_unref (s); +} + +TEST_F (Actions, CanSuspend) +{ + bool b; + bool can; + bool allowed; + gboolean b2; + + can = upower->can_suspend (); + allowed = upower->suspend_allowed (); + b = can && allowed; + + ASSERT_EQ (b, indicator_session_actions_can_suspend (actions)); + g_object_get (actions, INDICATOR_SESSION_ACTIONS_PROP_CAN_SUSPEND, &b2, NULL); + ASSERT_EQ (b, b2); + + for (int i=0; i<2; ++i) + { + can = !can; + b = can && allowed; + + upower->set_can_suspend (can); + wait_for_signal (actions, "notify::" INDICATOR_SESSION_ACTIONS_PROP_CAN_SUSPEND); + ASSERT_EQ (b, indicator_session_actions_can_suspend (actions)); + g_object_get (actions, INDICATOR_SESSION_ACTIONS_PROP_CAN_SUSPEND, &b2, NULL); + ASSERT_EQ (b, b2); + } +} + +TEST_F (Actions, CanHibernate) +{ + bool b; + bool can; + bool allowed; + gboolean b2; + + can = upower->can_hibernate (); + allowed = upower->hibernate_allowed (); + b = can && allowed; + + ASSERT_EQ (b, indicator_session_actions_can_hibernate (actions)); + g_object_get (actions, INDICATOR_SESSION_ACTIONS_PROP_CAN_HIBERNATE, &b2, NULL); + ASSERT_EQ (b, b2); + +#if 0 + for (int i=0; i<2; ++i) + { + b = !b; + upower->set_can_hibernate (b); + wait_for_signal (actions, "notify::" INDICATOR_SESSION_ACTIONS_PROP_CAN_HIBERNATE); + ASSERT_EQ (b, indicator_session_actions_can_hibernate (actions)); + g_object_get (actions, INDICATOR_SESSION_ACTIONS_PROP_CAN_HIBERNATE, &b2, NULL); + ASSERT_EQ (b, b2); + } +#endif +} + +TEST_F (Actions, Restart) +{ + ASSERT_EQ (MockConsoleKitManager::None, ck_manager->last_action()); + + // confirm that user is prompted + // and that no action is taken when the user cancels the dialog + indicator_session_actions_restart (actions); + wait_msec (50); + ASSERT_TRUE (end_session_dialog->is_open()); + end_session_dialog->cancel(); + wait_msec (50); + ASSERT_EQ (MockConsoleKitManager::None, ck_manager->last_action()); + + // confirm that user is prompted + // and that no action is taken when the user cancels the dialog + indicator_session_actions_restart (actions); + wait_msec (50); + ASSERT_TRUE (end_session_dialog->is_open ()); + end_session_dialog->confirm_reboot (); + wait_msec (100); + ASSERT_EQ (MockConsoleKitManager::Restart, ck_manager->last_action()); + + // confirm that we try to restart w/o prompting + // if the EndSessionDialog isn't available + delete end_session_dialog; + end_session_dialog = 0; + ck_manager->clear_last_action (); + ASSERT_EQ (MockConsoleKitManager::None, ck_manager->last_action()); + wait_msec (50); + indicator_session_actions_restart (actions); + wait_msec (50); + ASSERT_EQ (MockConsoleKitManager::Restart, ck_manager->last_action()); +} + +TEST_F (Actions, Shutdown) +{ + ASSERT_EQ (MockConsoleKitManager::None, ck_manager->last_action()); + + // confirm that user is prompted + // and that no action is taken when the user cancels the dialog + indicator_session_actions_shutdown (actions); + wait_msec (50); + ASSERT_TRUE (end_session_dialog->is_open()); + end_session_dialog->cancel(); + wait_msec (50); + ASSERT_EQ (MockConsoleKitManager::None, ck_manager->last_action()); + + // confirm that user is prompted + // and that no action is taken when the user cancels the dialog + indicator_session_actions_shutdown (actions); + wait_msec (50); + ASSERT_TRUE (end_session_dialog->is_open ()); + end_session_dialog->confirm_shutdown (); + wait_msec (100); + ASSERT_EQ (MockConsoleKitManager::Shutdown, ck_manager->last_action()); + + // confirm that we try to shutdown w/o prompting + // if the EndSessionDialog isn't available + delete end_session_dialog; + end_session_dialog = 0; + ck_manager->clear_last_action (); + wait_msec (50); + indicator_session_actions_shutdown (actions); + wait_msec (50); + ASSERT_EQ (MockConsoleKitManager::Shutdown, ck_manager->last_action()); +} + +TEST_F (Actions, Logout) +{ + ASSERT_EQ (MockConsoleKitManager::None, ck_manager->last_action()); + + // confirm that user is prompted + // and that no action is taken when the user cancels the dialog + indicator_session_actions_logout (actions); + wait_msec (50); + ASSERT_TRUE (end_session_dialog->is_open()); + end_session_dialog->cancel(); + wait_msec (50); + ASSERT_EQ (MockSessionManager::None, session_manager->last_action ()); + + // confirm that user is prompted + // and that no action is taken when the user cancels the dialog + indicator_session_actions_shutdown (actions); + wait_msec (50); + ASSERT_TRUE (end_session_dialog->is_open ()); + end_session_dialog->confirm_logout (); + wait_msec (100); + ASSERT_EQ (MockSessionManager::LogoutQuiet, session_manager->last_action ()); + + // confirm that we try to call SessionManager::LogoutNormal + // if the EndSessionDialog isn't available + delete end_session_dialog; + end_session_dialog = 0; + wait_msec (50); + indicator_session_actions_logout (actions); + wait_msec (50); + ASSERT_EQ (MockSessionManager::LogoutNormal, session_manager->last_action ()); +} + +TEST_F (Actions, Suspend) +{ + ASSERT_EQ (MockUPower::None, upower->last_action()); + indicator_session_actions_suspend (actions); + wait_msec (50); + ASSERT_EQ (MockUPower::Suspend, upower->last_action()); +} + +TEST_F (Actions, Hibernate) +{ + ASSERT_EQ (MockUPower::None, upower->last_action()); + indicator_session_actions_hibernate (actions); + wait_msec (50); + ASSERT_EQ (MockUPower::Hibernate, upower->last_action()); +} + +TEST_F (Actions, SwitchToScreensaver) +{ + ASSERT_EQ (MockScreenSaver::None, screen_saver->last_action()); + indicator_session_actions_switch_to_screensaver (actions); + wait_msec (50); + ASSERT_EQ (MockScreenSaver::Lock, screen_saver->last_action()); +} + +TEST_F (Actions, SwitchToGreeter) +{ + ASSERT_NE (MockDisplayManagerSeat::GREETER, dm_seat->last_action()); + indicator_session_actions_switch_to_greeter (actions); + wait_msec (50); + ASSERT_EQ (MockDisplayManagerSeat::GREETER, dm_seat->last_action()); +} + +TEST_F (Actions, SwitchToGuest) +{ + // allow guests + dm_seat->set_guest_allowed (true); + MockUser * guest_user; + MockConsoleKitSession * guest_ck_session; + + // set up a guest + guest_user = new MockUser (loop, conn, "guest-zzbEVV", "Guest", 10); + guest_user->set_system_account (true); + accounts->add_user (guest_user); + guest_ck_session = ck_seat->add_session_by_user (guest_user); + + // try to switch to guest + indicator_session_actions_switch_to_guest (actions); + wait_for_signal (ck_seat->skeleton(), "active-session-changed"); + ASSERT_EQ (guest_ck_session, ck_manager->current_session()); + wait_msec (50); +} + +TEST_F (Actions, SwitchToUsername) +{ + const char * const dr1_username = "whartnell"; + const char * const dr2_username = "ptroughton"; + MockUser * dr1_user; + MockUser * dr2_user; + MockConsoleKitSession * dr1_session; + MockConsoleKitSession * dr2_session; + + dr1_user = accounts->find_by_username (dr1_username); + dr1_session = ck_seat->add_session_by_user (dr1_user); + + dr2_user = accounts->find_by_username (dr2_username); + dr2_session = ck_seat->add_session_by_user (dr2_user); + + indicator_session_actions_switch_to_username (actions, dr1_username); + wait_for_signal (ck_seat->skeleton(), "active-session-changed"); + ASSERT_EQ (dr1_session, ck_manager->current_session()); + wait_msec (50); + + indicator_session_actions_switch_to_username (actions, dr2_username); + wait_for_signal (ck_seat->skeleton(), "active-session-changed"); + ASSERT_EQ (dr2_session, ck_manager->current_session()); + wait_msec (50); + + indicator_session_actions_switch_to_username (actions, dr1_username); + wait_for_signal (ck_seat->skeleton(), "active-session-changed"); + ASSERT_EQ (dr1_session, ck_manager->current_session()); + wait_msec (50); +} + +TEST_F (Actions, HasOnlineAccountError) +{ + bool b; + gboolean gb; + + b = webcredentials->has_error (); + ASSERT_EQ (b, indicator_session_actions_has_online_account_error (actions)); + g_object_get (actions, INDICATOR_SESSION_ACTIONS_PROP_HAS_ONLINE_ACCOUNT_ERROR, &gb, NULL); + ASSERT_EQ (b, gb); + + b = !b; + webcredentials->set_error (b); + wait_msec (50); + ASSERT_EQ (b, indicator_session_actions_has_online_account_error (actions)); + g_object_get (actions, INDICATOR_SESSION_ACTIONS_PROP_HAS_ONLINE_ACCOUNT_ERROR, &gb, NULL); + ASSERT_EQ (b, gb); + + b = !b; + webcredentials->set_error (b); + wait_msec (50); + ASSERT_EQ (b, indicator_session_actions_has_online_account_error (actions)); + g_object_get (actions, INDICATOR_SESSION_ACTIONS_PROP_HAS_ONLINE_ACCOUNT_ERROR, &gb, NULL); + ASSERT_EQ (b, gb); +} + +TEST_F (Actions, CanPrompt) +{ + gboolean b; + + ASSERT_TRUE (indicator_session_actions_can_prompt (actions)); + + delete end_session_dialog; + end_session_dialog = 0; + wait_msec (50); + ASSERT_FALSE (indicator_session_actions_can_prompt (actions)); + g_object_get (actions, INDICATOR_SESSION_ACTIONS_PROP_CAN_PROMPT, &b, NULL); + ASSERT_FALSE (b); + + end_session_dialog = new MockEndSessionDialog (loop, conn); + wait_msec (50); + ASSERT_TRUE (indicator_session_actions_can_prompt (actions)); + g_object_get (actions, INDICATOR_SESSION_ACTIONS_PROP_CAN_PROMPT, &b, NULL); + ASSERT_TRUE (b); +} diff --git a/tests/backend-dbus/test-guest.cc b/tests/backend-dbus/test-guest.cc new file mode 100644 index 0000000..db55dd1 --- /dev/null +++ b/tests/backend-dbus/test-guest.cc @@ -0,0 +1,192 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include "gtest-mock-dbus-fixture.h" + +#include "backend.h" +#include "backend-dbus/backend-dbus.h" + +/*** +**** +***/ + +class Guest: public GTestMockDBusFixture +{ + private: + + typedef GTestMockDBusFixture super; + + protected: + + GCancellable * cancellable; + IndicatorSessionGuest * guest; + + virtual void SetUp () + { + super :: SetUp (); + + // get the guest-dbus + cancellable = g_cancellable_new (); + guest = 0; + backend_get (cancellable, NULL, NULL, &guest); + wait_msec (100); + + // test the default state + ASSERT_TRUE (guest != 0); + ASSERT_FALSE (indicator_session_guest_is_allowed (guest)); + ASSERT_FALSE (indicator_session_guest_is_logged_in (guest)); + ASSERT_FALSE (indicator_session_guest_is_active (guest)); + } + + virtual void TearDown () + { + g_cancellable_cancel (cancellable); + g_clear_object (&cancellable); + g_clear_object (&guest); + + super :: TearDown (); + } + + protected: + + void add_mock_guest (MockUser *& guest_user, + MockConsoleKitSession *& guest_session) + { + guest_user = new MockUser (loop, conn, "guest-jjbEVV", "Guest", 10); + guest_user->set_system_account (true); + accounts->add_user (guest_user); + guest_session = new MockConsoleKitSession (loop, conn); + guest_session->set_user (guest_user); + ck_seat->add_session (guest_session); + } +}; + +/** + * Confirms that the Fixture's SetUp() and TearDown() work + */ +TEST_F (Guest, HelloWorld) +{ + ASSERT_TRUE (true); +} + +/** + * Toggle in the DM whether or not guests are allowed. + * Confirm that "guest" reflects the changes. + */ +TEST_F (Guest, Allowed) +{ + dm_seat->set_guest_allowed (true); + wait_for_signal (guest, "notify::guest-is-allowed"); + ASSERT_TRUE (indicator_session_guest_is_allowed (guest)); + ASSERT_FALSE (indicator_session_guest_is_logged_in (guest)); + ASSERT_FALSE (indicator_session_guest_is_active (guest)); + + dm_seat->set_guest_allowed (false); + wait_for_signal (guest, "notify::guest-is-allowed"); + ASSERT_FALSE (indicator_session_guest_is_allowed (guest)); + ASSERT_FALSE (indicator_session_guest_is_logged_in (guest)); + ASSERT_FALSE (indicator_session_guest_is_active (guest)); +} + +/** + * Have a guest user log in & out. + * Confirm that "guest" reflects the changes. + */ +TEST_F (Guest, Login) +{ + gboolean b; + + dm_seat->set_guest_allowed (true); + + // Log a Guest in + // And confirm that guest's is_login changes to true + MockUser * guest_user; + MockConsoleKitSession * guest_session; + add_mock_guest (guest_user, guest_session); + wait_for_signal (guest, "notify::guest-is-logged-in"); + ASSERT_TRUE (indicator_session_guest_is_allowed (guest)); + ASSERT_TRUE (indicator_session_guest_is_logged_in (guest)); + g_object_get (guest, INDICATOR_SESSION_GUEST_PROPERTY_LOGGED_IN, &b,NULL); + ASSERT_TRUE (b); + ASSERT_FALSE (indicator_session_guest_is_active (guest)); + + // Log the Guest User out + // and confirm that guest's is_login changes to false + ck_seat->remove_session (guest_session); + accounts->remove_user (guest_user); + delete guest_user; + delete guest_session; + wait_for_signal (guest, "notify::guest-is-logged-in"); + ASSERT_TRUE (indicator_session_guest_is_allowed (guest)); + ASSERT_FALSE (indicator_session_guest_is_logged_in (guest)); + g_object_get (guest, INDICATOR_SESSION_GUEST_PROPERTY_LOGGED_IN, &b,NULL); + ASSERT_FALSE (b); + ASSERT_FALSE (indicator_session_guest_is_active (guest)); +} + +/** + * Activate a Guest session, then activate a different session. + * Confirm that "guest" reflects the changes. + */ +TEST_F (Guest, Active) +{ + gboolean b; + + dm_seat->set_guest_allowed (true); + MockUser * guest_user; + MockConsoleKitSession * guest_session; + add_mock_guest (guest_user, guest_session); + + // Activate the guest session + // and confirm that guest's is_active changes to true + ck_seat->activate_session (guest_session); + wait_for_signal (guest, "notify::guest-is-active-session"); + ASSERT_TRUE (indicator_session_guest_is_allowed (guest)); + ASSERT_TRUE (indicator_session_guest_is_logged_in (guest)); + ASSERT_TRUE (indicator_session_guest_is_active (guest)); + g_object_get (guest, INDICATOR_SESSION_GUEST_PROPERTY_ACTIVE, &b,NULL); + ASSERT_TRUE (b); + + // Activate a non-guest session + // and confirm that guest's is_active changes to false + ck_seat->activate_session (ck_session); + wait_for_signal (guest, "notify::guest-is-active-session"); + ASSERT_TRUE (indicator_session_guest_is_allowed (guest)); + ASSERT_TRUE (indicator_session_guest_is_logged_in (guest)); + ASSERT_FALSE (indicator_session_guest_is_active (guest)); + g_object_get (guest, INDICATOR_SESSION_GUEST_PROPERTY_ACTIVE, &b,NULL); + ASSERT_FALSE (b); +} + +/** + * Activate a guest session using the "guest" API. + * Confirm that the guest session gets activated on the bus. + */ +TEST_F (Guest, Activate) +{ + dm_seat->set_guest_allowed (true); + MockUser * guest_user; + MockConsoleKitSession * guest_session; + add_mock_guest (guest_user, guest_session); + + indicator_session_guest_switch_to_guest (guest); + wait_for_signal (ck_seat->skeleton(), "active-session-changed"); + ASSERT_EQ (guest_session, ck_manager->current_session()); + wait_msec (50); +} diff --git a/tests/backend-dbus/test-users.cc b/tests/backend-dbus/test-users.cc new file mode 100644 index 0000000..bd0547d --- /dev/null +++ b/tests/backend-dbus/test-users.cc @@ -0,0 +1,377 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include "gtest-mock-dbus-fixture.h" + +#include "backend.h" +#include "backend-dbus/backend-dbus.h" + +/*** +**** +***/ + +class Users: public GTestMockDBusFixture +{ + private: + + typedef GTestMockDBusFixture super; + + protected: + + GCancellable * cancellable; + IndicatorSessionUsers * users; + + virtual void SetUp () + { + super :: SetUp (); + + init_event_keys (0); + + // init 'users' + cancellable = g_cancellable_new (); + users = 0; + backend_get (cancellable, NULL, &users, NULL); + g_assert (users != 0); + wait_msec (100); + } + + virtual void TearDown () + { + g_cancellable_cancel (cancellable); + g_clear_object (&cancellable); + g_clear_object (&users); + + super :: TearDown (); + } + + protected: + + void compare_user (const IndicatorSessionUser * isu, + MockUser * mu, + bool is_logged_in, + bool is_current_user) + { + ASSERT_TRUE (isu != 0); + ASSERT_TRUE (mu != 0); + + ASSERT_EQ (mu->uid(), isu->uid); + ASSERT_EQ (mu->login_frequency(), isu->login_frequency); + ASSERT_STREQ (mu->username(), isu->user_name); + ASSERT_STREQ (mu->realname(), isu->real_name); + ASSERT_EQ (is_logged_in, isu->is_logged_in); + ASSERT_EQ (is_current_user, isu->is_current_user); + // FIXME: test icon file? + } + + void compare_user (const std::string & key, + MockUser * mu, + bool is_logged_in, + bool is_current_user) + { + IndicatorSessionUser * isu; + isu = indicator_session_users_get_user (users, key.c_str()); + compare_user (isu, mu, is_logged_in, is_current_user); + indicator_session_user_free (isu); + } + + private: + + void init_event_keys (size_t n) + { + expected_event_count = n; + event_keys.clear(); + } + + static gboolean + wait_for_signals__timeout (gpointer name) + { + g_error ("%s: timed out waiting for signal '%s'", G_STRLOC, (char*)name); + return G_SOURCE_REMOVE; + } + + static void + wait_for_signals__event (IndicatorSessionUser * u G_GNUC_UNUSED, + const char * key, + gpointer gself) + { + Users * self = static_cast(gself); + + self->event_keys.push_back (key); + + if (self->event_keys.size() == self->expected_event_count) + g_main_loop_quit (self->loop); + } + + protected: + + std::vector event_keys; + size_t expected_event_count; + + void wait_for_signals (gpointer o, const gchar * name, size_t n) + { + const int timeout_seconds = 5; // arbitrary + + init_event_keys (n); + + guint handler_id = g_signal_connect (o, name, + G_CALLBACK(wait_for_signals__event), + this); + gulong timeout_id = g_timeout_add_seconds (timeout_seconds, + wait_for_signals__timeout, + (gpointer)name); + g_main_loop_run (loop); + g_source_remove (timeout_id); + g_signal_handler_disconnect (o, handler_id); + } +}; + +/*** +**** +***/ + +/** + * Confirm that the fixture's SetUp() and TearDown() work + */ +TEST_F (Users, HelloWorld) +{ + ASSERT_TRUE (true); +} + + +/** + * Confirm that 'users' can get the cached users from our Mock Accounts + */ +TEST_F (Users, InitialUsers) +{ + const guint logged_in_uid = ck_session->user()->uid(); + GStrv keys = indicator_session_users_get_keys (users); + + ASSERT_EQ (12, g_strv_length (keys)); + + for (int i=0; keys && keys[i]; ++i) + { + MockUser * mu = accounts->find_by_path (keys[i]); + const bool is_logged_in = mu->uid() == logged_in_uid; + const bool is_current_user = mu->uid() == logged_in_uid; + compare_user (keys[i], mu, is_logged_in, is_current_user); + } + + g_strfreev (keys); +} + +/** + * Confirm that 'users' can tell when a new user is added + */ +TEST_F (Users, UserAdded) +{ + MockUser * mu; + + mu = new MockUser (loop, conn, "pcushing", "Peter Cushing", 2); + accounts->add_user (mu); + ASSERT_EQ (0, event_keys.size()); + wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_ADDED, 1); + ASSERT_EQ (1, event_keys.size()); + ASSERT_STREQ (mu->path(), event_keys[0].c_str()); + + compare_user (event_keys[0], mu, false, false); +} + +/** + * Confirm that 'users' can tell when a user is removed + */ +TEST_F (Users, UserRemoved) +{ + MockUser * mu; + + mu = accounts->find_by_username ("pdavison"); + accounts->remove_user (mu); + ASSERT_EQ (0, event_keys.size()); + wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_REMOVED, 1); + ASSERT_EQ (1, event_keys.size()); + ASSERT_STREQ (mu->path(), event_keys[0].c_str()); + + GStrv keys = indicator_session_users_get_keys (users); + ASSERT_EQ (11, g_strv_length (keys)); + g_strfreev (keys); + + ASSERT_TRUE (indicator_session_users_get_user (users, mu->path()) == NULL); + + delete mu; +} + +/** + * Confirm that 'users' notices when a user's real name changes + */ +TEST_F (Users, RealnameChanged) +{ + MockUser * mu; + + mu = accounts->find_by_username ("pdavison"); + const char * const realname = "Peter M. G. Moffett"; + mu->set_realname (realname); + ASSERT_NE (mu->realname(), realname); + ASSERT_STREQ (mu->realname(), realname); + wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 1); + ASSERT_EQ (1, event_keys.size()); + ASSERT_STREQ (mu->path(), event_keys[0].c_str()); + compare_user (mu->path(), mu, false, false); +} + +/** + * Confirm that 'users' notices when users log in and out + */ +TEST_F (Users, LogInLogOut) +{ + // The fist doctor logs in. + // Confirm that 'users' notices. + MockUser * mu = accounts->find_by_username ("whartnell"); + compare_user (mu->path(), mu, false, false); + MockConsoleKitSession * session = ck_seat->add_session_by_user (mu); + wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 1); + ASSERT_STREQ (mu->path(), event_keys[0].c_str()); + compare_user (mu->path(), mu, true, false); + + // The fist doctor logs out. + // Confirm that 'users' notices. + ck_seat->remove_session (session); + wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 1); + ASSERT_EQ (1, event_keys.size()); + ASSERT_STREQ (mu->path(), event_keys[0].c_str()); + compare_user (event_keys[0], mu, false, false); + + delete session; +} + +/** + * Confirm that 'users' notices when the active session changes + */ +TEST_F (Users, ActivateSession) +{ + // The fist doctor logs in. + // Confirm that 'users' notices. + MockUser * mu = accounts->find_by_username ("whartnell"); + compare_user (mu->path(), mu, false, false); + MockConsoleKitSession * session = ck_seat->add_session_by_user (mu); + wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 1); + ASSERT_STREQ (mu->path(), event_keys[0].c_str()); + compare_user (mu->path(), mu, true, false); + + // activate the first doctor's session. + // confirm that 'users' sees he's active and that ck_session isn't. + // this should come in the form of two 'user-changed' events + ck_seat->activate_session (session); + wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 2); + ASSERT_EQ (2, event_keys.size()); + compare_user (event_keys[0], ck_session->user(), true, false); + compare_user (event_keys[1], mu, true, true); + + // switch back to the previous + // confirm that 'users' sees it's active and the first doctor's session isn't + // this should come in the form of two 'user-changed' events + ck_seat->activate_session (ck_session); + wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 2); + ASSERT_EQ (2, event_keys.size()); + compare_user (event_keys[0], mu, true, false); + compare_user (event_keys[1], ck_session->user(), true, true); +} + +/** + * Confirm that we can change the active session via users' API. + * This is nearly the same as ActivateSession but uses users' API + */ +TEST_F (Users, ActivateUser) +{ + // The fist doctor logs in. + // Confirm that 'users' notices. + MockUser * mu = accounts->find_by_username ("whartnell"); + compare_user (mu->path(), mu, false, false); + MockConsoleKitSession * session = ck_seat->add_session_by_user (mu); + wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 1); + ASSERT_STREQ (mu->path(), event_keys[0].c_str()); + compare_user (mu->path(), mu, true, false); + + // activate the first doctor's session. + // confirm that 'users' sees he's active and that ck_session isn't. + // this should come in the form of two 'user-changed' events + indicator_session_users_activate_user (users, mu->path()); + ck_seat->activate_session (session); + wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 2); + ASSERT_EQ (2, event_keys.size()); + compare_user (event_keys[0], ck_session->user(), true, false); + compare_user (event_keys[1], mu, true, true); + + // switch back to the previous + // confirm that 'users' sees it's active and the first doctor's session isn't + // this should come in the form of two 'user-changed' events + indicator_session_users_activate_user (users, ck_session->user()->path()); + ck_seat->activate_session (ck_session); + wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 2); + ASSERT_EQ (2, event_keys.size()); + compare_user (event_keys[0], mu, true, false); + compare_user (event_keys[1], ck_session->user(), true, true); +} + +/** + * Confirm that adding a Guest doesn't show up in the users list + */ +TEST_F (Users, UnwantedGuest) +{ + GStrv keys; + + keys = indicator_session_users_get_keys (users); + const size_t n = g_strv_length (keys); + g_strfreev (keys); + + MockUser * mu = new MockUser (loop, conn, "guest-jjbEVV", "Guest", 1); + mu->set_system_account (true); + accounts->add_user (mu); + wait_msec (50); + + keys = indicator_session_users_get_keys (users); + ASSERT_EQ (n, g_strv_length (keys)); + g_strfreev (keys); +} + + +/** + * Confirm that we can detect live sessions + */ +TEST_F (Users, LiveSession) +{ + gboolean b; + + // not initially a live session + ASSERT_FALSE (indicator_session_users_is_live_session (users)); + g_object_get (users, INDICATOR_SESSION_USERS_PROP_IS_LIVE_SESSION, &b, NULL); + ASSERT_FALSE (b); + + // now add the criteria for a live session + MockUser * live_user = new MockUser (loop, conn, "ubuntu", "Ubuntu", 1, 999); + live_user->set_system_account (true); + accounts->add_user (live_user); + MockConsoleKitSession * session = ck_seat->add_session_by_user (live_user); + wait_msec (100); + ck_seat->activate_session (session); + wait_for_signal (users, "notify::"INDICATOR_SESSION_USERS_PROP_IS_LIVE_SESSION); + + // confirm the backend thinks it's a live session + ASSERT_TRUE (indicator_session_users_is_live_session (users)); + g_object_get (users, INDICATOR_SESSION_USERS_PROP_IS_LIVE_SESSION, &b, NULL); + ASSERT_TRUE (b); +} diff --git a/tests/backend-mock-actions.c b/tests/backend-mock-actions.c new file mode 100644 index 0000000..121c7ba --- /dev/null +++ b/tests/backend-mock-actions.c @@ -0,0 +1,229 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include +#include + +#include "backend-mock.h" +#include "backend-mock-actions.h" + +G_DEFINE_TYPE (IndicatorSessionActionsMock, + indicator_session_actions_mock, + INDICATOR_TYPE_SESSION_ACTIONS) + +/*** +**** Virtual Functions +***/ + +static gboolean +my_can_lock (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + return g_settings_get_boolean (mock_settings, "can-lock"); +} + +static gboolean +my_can_logout (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + return g_settings_get_boolean (mock_settings, "can-logout"); +} + +static gboolean +my_can_switch (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + return g_settings_get_boolean (mock_settings, "can-switch-sessions"); +} + +static gboolean +my_can_suspend (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + return g_settings_get_boolean (mock_settings, "can-suspend"); +} + +static gboolean +my_can_hibernate (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + return g_settings_get_boolean (mock_settings, "can-hibernate"); +} + +static void +my_logout (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + g_settings_set_string (mock_settings, "last-command", "logout"); +} + +static void +my_suspend (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + g_settings_set_string (mock_settings, "last-command", "suspend"); +} + +static void +my_hibernate (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + g_settings_set_string (mock_settings, "last-command", "hibernate"); +} + +static void +my_restart (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + g_settings_set_string (mock_settings, "last-command", "restart"); +} + +static void +my_shutdown (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + g_settings_set_string (mock_settings, "last-command", "shutdown"); +} + +static void +my_switch_to_screensaver (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + g_settings_set_string (mock_settings, "last-command", "switch-to-screensaver"); +} + +static void +my_switch_to_greeter (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + g_settings_set_string (mock_settings, "last-command", "switch-to-greeter"); +} + +static void +my_switch_to_guest (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + g_settings_set_string (mock_settings, "last-command", "switch-to-guest"); +} + +static void +my_switch_to_username (IndicatorSessionActions * self G_GNUC_UNUSED, + const char * username) +{ + gchar * str = g_strdup_printf ("switch-to-user::%s", username); + g_settings_set_string (mock_settings, "last-command", str); +} + +static void +my_help (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + g_settings_set_string (mock_settings, "last-command", "help"); +} + +static void +my_about (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + g_settings_set_string (mock_settings, "last-command", "about"); +} + +static void +my_settings (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + g_settings_set_string (mock_settings, "last-command", "settings"); +} + +static gboolean +my_can_prompt (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + return g_settings_get_boolean (mock_settings, "can-prompt"); +} + +static gboolean +my_has_online_account_error (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + return g_settings_get_boolean (mock_settings, "has-online-account-error"); +} + +static void +my_dispose (GObject * o) +{ + G_OBJECT_CLASS (indicator_session_actions_mock_parent_class)->dispose (o); +} + +static void +my_finalize (GObject * o) +{ + G_OBJECT_CLASS (indicator_session_actions_mock_parent_class)->finalize (o); +} + +/*** +**** GObject Boilerplate +***/ + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_actions_mock_class_init (IndicatorSessionActionsMockClass * klass) +{ + GObjectClass * object_class; + IndicatorSessionActionsClass * actions_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->dispose = my_dispose; + object_class->finalize = my_finalize; + + actions_class = INDICATOR_SESSION_ACTIONS_CLASS (klass); + actions_class->can_lock = my_can_lock; + actions_class->can_logout = my_can_logout; + actions_class->can_switch = my_can_switch; + actions_class->can_suspend = my_can_suspend; + actions_class->can_hibernate = my_can_hibernate; + actions_class->can_prompt = my_can_prompt; + actions_class->has_online_account_error = my_has_online_account_error; + actions_class->logout = my_logout; + actions_class->suspend = my_suspend; + actions_class->hibernate = my_hibernate; + actions_class->restart = my_restart; + actions_class->shutdown = my_shutdown; + actions_class->settings = my_settings; + actions_class->help = my_help; + actions_class->about = my_about; + actions_class->switch_to_screensaver = my_switch_to_screensaver; + actions_class->switch_to_greeter = my_switch_to_greeter; + actions_class->switch_to_guest = my_switch_to_guest; + actions_class->switch_to_username = my_switch_to_username; +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_actions_mock_init (IndicatorSessionActionsMock * self) +{ + g_signal_connect_swapped (mock_settings, "changed::can-lock", + G_CALLBACK(indicator_session_actions_notify_can_lock), self); + g_signal_connect_swapped (mock_settings, "changed::can-logout", + G_CALLBACK(indicator_session_actions_notify_can_logout), self); + g_signal_connect_swapped (mock_settings, "changed::can-switch-sessions", + G_CALLBACK(indicator_session_actions_notify_can_switch), self); + g_signal_connect_swapped (mock_settings, "changed::can-suspend", + G_CALLBACK(indicator_session_actions_notify_can_suspend), self); + g_signal_connect_swapped (mock_settings, "changed::can-hibernate", + G_CALLBACK(indicator_session_actions_notify_can_hibernate), self); + g_signal_connect_swapped (mock_settings, "changed::can-prompt", + G_CALLBACK(indicator_session_actions_notify_can_prompt), self); + g_signal_connect_swapped (mock_settings, "changed::has-online-account-error", + G_CALLBACK(indicator_session_actions_notify_has_online_account_error), self); +} + +/*** +**** Public +***/ + +IndicatorSessionActions * +indicator_session_actions_mock_new (void) +{ + gpointer o = g_object_new (INDICATOR_TYPE_SESSION_ACTIONS_MOCK, NULL); + + return INDICATOR_SESSION_ACTIONS (o); +} diff --git a/tests/backend-mock-actions.h b/tests/backend-mock-actions.h new file mode 100644 index 0000000..bd9ed47 --- /dev/null +++ b/tests/backend-mock-actions.h @@ -0,0 +1,61 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef __INDICATOR_SESSION_ACTIONS_MOCK_H__ +#define __INDICATOR_SESSION_ACTIONS_MOCK_H__ + +#include +#include + +#include "actions.h" /* parent class */ + +G_BEGIN_DECLS + +#define INDICATOR_TYPE_SESSION_ACTIONS_MOCK (indicator_session_actions_mock_get_type()) +#define INDICATOR_SESSION_ACTIONS_MOCK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_SESSION_ACTIONS_MOCK, IndicatorSessionActionsMock)) +#define INDICATOR_SESSION_ACTIONS_MOCK_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_TYPE_SESSION_ACTIONS_MOCK, IndicatorSessionActionsMockClass)) +#define INDICATOR_IS_SESSION_ACTIONS_MOCK(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_SESSION_ACTIONS_MOCK)) + +typedef struct _IndicatorSessionActionsMock IndicatorSessionActionsMock; +typedef struct _IndicatorSessionActionsMockPriv IndicatorSessionActionsMockPriv; +typedef struct _IndicatorSessionActionsMockClass IndicatorSessionActionsMockClass; + +/** + * An implementation of IndicatorSessionActions that gets its user information + * from org.freedesktop.ConsoleKit and org.freedesktop.Accounts over DBus. + */ +struct _IndicatorSessionActionsMock +{ + /*< private >*/ + IndicatorSessionActions parent; + IndicatorSessionActionsMockPriv * priv; +}; + +struct _IndicatorSessionActionsMockClass +{ + IndicatorSessionActionsClass parent_class; +}; + +GType indicator_session_actions_mock_get_type (void); + +IndicatorSessionActions * indicator_session_actions_mock_new (void); + +G_END_DECLS + +#endif /* __INDICATOR_SESSION_ACTIONS_MOCK_H__ */ diff --git a/tests/backend-mock-guest.c b/tests/backend-mock-guest.c new file mode 100644 index 0000000..0428783 --- /dev/null +++ b/tests/backend-mock-guest.c @@ -0,0 +1,129 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include + +#include "backend-mock-guest.h" + +struct _IndicatorSessionGuestMockPriv +{ + gboolean guest_is_active; + gboolean guest_is_logged_in; + gboolean guest_is_allowed; +}; + +typedef IndicatorSessionGuestMockPriv priv_t; + +G_DEFINE_TYPE (IndicatorSessionGuestMock, + indicator_session_guest_mock, + INDICATOR_TYPE_SESSION_GUEST) + +/*** +**** Virtual Functions +***/ + +static void +my_dispose (GObject * o) +{ + G_OBJECT_CLASS (indicator_session_guest_mock_parent_class)->dispose (o); +} + +static void +my_finalize (GObject * o) +{ + G_OBJECT_CLASS (indicator_session_guest_mock_parent_class)->finalize (o); +} + +static gboolean +my_is_allowed (IndicatorSessionGuest * self) +{ + return INDICATOR_SESSION_GUEST_MOCK(self)->priv->guest_is_allowed; +} + +static gboolean +my_is_logged_in (IndicatorSessionGuest * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_GUEST_MOCK(self), FALSE); + + return INDICATOR_SESSION_GUEST_MOCK(self)->priv->guest_is_logged_in; +} + +static gboolean +my_is_active (IndicatorSessionGuest * self) +{ + return INDICATOR_SESSION_GUEST_MOCK(self)->priv->guest_is_active; +} + +static void +my_switch_to_guest (IndicatorSessionGuest * self) +{ + g_message ("%s %s FIXME", G_STRLOC, G_STRFUNC); +} + +/*** +**** GObject Boilerplate +***/ + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_guest_mock_class_init (IndicatorSessionGuestMockClass * klass) +{ + GObjectClass * object_class; + IndicatorSessionGuestClass * guest_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->dispose = my_dispose; + object_class->finalize = my_finalize; + + guest_class = INDICATOR_SESSION_GUEST_CLASS (klass); + guest_class->is_allowed = my_is_allowed; + guest_class->is_logged_in = my_is_logged_in; + guest_class->is_active = my_is_active; + guest_class->switch_to_guest = my_switch_to_guest; + + g_type_class_add_private (klass, sizeof (IndicatorSessionGuestMockPriv)); +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_guest_mock_init (IndicatorSessionGuestMock * self) +{ + priv_t * p; + + p = G_TYPE_INSTANCE_GET_PRIVATE (self, + INDICATOR_TYPE_SESSION_GUEST_MOCK, + IndicatorSessionGuestMockPriv); + self->priv = p; + + p->guest_is_allowed = TRUE; + p->guest_is_active = FALSE; + p->guest_is_logged_in = FALSE; +} + +/*** +**** Public +***/ + +IndicatorSessionGuest * +indicator_session_guest_mock_new (void) +{ + gpointer o = g_object_new (INDICATOR_TYPE_SESSION_GUEST_MOCK, NULL); + + return INDICATOR_SESSION_GUEST (o); +} diff --git a/tests/backend-mock-guest.h b/tests/backend-mock-guest.h new file mode 100644 index 0000000..db6ce86 --- /dev/null +++ b/tests/backend-mock-guest.h @@ -0,0 +1,61 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef __GUEST_MOCK_H__ +#define __GUEST_MOCK_H__ + +#include +#include + +#include "guest.h" /* parent class */ + +G_BEGIN_DECLS + +#define INDICATOR_TYPE_SESSION_GUEST_MOCK (indicator_session_guest_mock_get_type()) +#define INDICATOR_SESSION_GUEST_MOCK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_SESSION_GUEST_MOCK, IndicatorSessionGuestMock)) +#define INDICATOR_SESSION_GUEST_MOCK_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_TYPE_SESSION_GUEST_MOCK, IndicatorSessionGuestMockClass)) +#define INDICATOR_IS_SESSION_GUEST_MOCK(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_SESSION_GUEST_MOCK)) + +typedef struct _IndicatorSessionGuestMock IndicatorSessionGuestMock; +typedef struct _IndicatorSessionGuestMockPriv IndicatorSessionGuestMockPriv; +typedef struct _IndicatorSessionGuestMockClass IndicatorSessionGuestMockClass; + +/** + * An implementation of IndicatorSessionGuest that gets its user information + * from org.freedesktop.ConsoleKit and org.freedesktop.Accounts over DBus. + */ +struct _IndicatorSessionGuestMock +{ + /*< private >*/ + IndicatorSessionGuest parent; + IndicatorSessionGuestMockPriv * priv; +}; + +struct _IndicatorSessionGuestMockClass +{ + IndicatorSessionGuestClass parent_class; +}; + +GType indicator_session_guest_mock_get_type (void); + +IndicatorSessionGuest * indicator_session_guest_mock_new (void); + +G_END_DECLS + +#endif diff --git a/tests/backend-mock-users.c b/tests/backend-mock-users.c new file mode 100644 index 0000000..d9ab5a8 --- /dev/null +++ b/tests/backend-mock-users.c @@ -0,0 +1,189 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include "backend-mock.h" +#include "backend-mock-users.h" + +struct _IndicatorSessionUsersMockPriv +{ + GHashTable * users; +}; + +typedef IndicatorSessionUsersMockPriv priv_t; + +G_DEFINE_TYPE (IndicatorSessionUsersMock, + indicator_session_users_mock, + INDICATOR_TYPE_SESSION_USERS) + +/*** +**** +***/ + +static void +my_dispose (GObject * o) +{ + G_OBJECT_CLASS (indicator_session_users_mock_parent_class)->dispose (o); +} + +static void +my_finalize (GObject * o) +{ + priv_t * p = INDICATOR_SESSION_USERS_MOCK (o)->priv; + + g_hash_table_destroy (p->users); + + G_OBJECT_CLASS (indicator_session_users_mock_parent_class)->finalize (o); +} + +static gboolean +my_is_live_session (IndicatorSessionUsers * users G_GNUC_UNUSED) +{ + return g_settings_get_boolean (mock_settings, "is-live-session"); +} + +static void +my_activate_user (IndicatorSessionUsers * users, const char * key) +{ + g_message ("%s %s users %p key %s FIXME", G_STRLOC, G_STRFUNC, (void*)users, key); +} + +static GStrv +my_get_keys (IndicatorSessionUsers * users) +{ + int i; + priv_t * p; + gchar ** keys; + GHashTableIter iter; + gpointer key; + + g_return_val_if_fail (INDICATOR_IS_SESSION_USERS_MOCK(users), NULL); + p = INDICATOR_SESSION_USERS_MOCK (users)->priv; + + i = 0; + keys = g_new (gchar*, g_hash_table_size(p->users)+1); + g_hash_table_iter_init (&iter, p->users); + while (g_hash_table_iter_next (&iter, &key, NULL)) + keys[i++] = g_strdup (key); + keys[i] = NULL; + + return keys; +} + +static IndicatorSessionUser * +my_get_user (IndicatorSessionUsers * self, const gchar * key) +{ + priv_t * p; + const IndicatorSessionUser * src; + IndicatorSessionUser * ret = NULL; + + g_return_val_if_fail (INDICATOR_IS_SESSION_USERS_MOCK(self), NULL); + p = INDICATOR_SESSION_USERS_MOCK (self)->priv; + + if ((src = g_hash_table_lookup (p->users, key))) + { + ret = g_new0 (IndicatorSessionUser, 1); + ret->is_current_user = src->is_current_user; + ret->is_logged_in = src->is_logged_in; + ret->uid = src->uid; + ret->login_frequency = src->login_frequency; + ret->user_name = g_strdup (src->user_name); + ret->real_name = g_strdup (src->real_name); + ret->icon_file = g_strdup (src->icon_file); + } + + return ret; +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_users_mock_class_init (IndicatorSessionUsersMockClass * klass) +{ + GObjectClass * object_class; + IndicatorSessionUsersClass * users_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->dispose = my_dispose; + object_class->finalize = my_finalize; + + users_class = INDICATOR_SESSION_USERS_CLASS (klass); + users_class->is_live_session = my_is_live_session; + users_class->get_keys = my_get_keys; + users_class->get_user = my_get_user; + users_class->activate_user = my_activate_user; + + g_type_class_add_private (klass, sizeof (IndicatorSessionUsersMockPriv)); +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_users_mock_init (IndicatorSessionUsersMock * self) +{ + priv_t * p; + + p = G_TYPE_INSTANCE_GET_PRIVATE (self, + INDICATOR_TYPE_SESSION_USERS_MOCK, + IndicatorSessionUsersMockPriv); + self->priv = p; + + p->users = g_hash_table_new_full (g_str_hash, + g_str_equal, + g_free, + (GDestroyNotify)indicator_session_user_free); + + g_signal_connect_swapped (mock_settings, "changed::is-live-session", + G_CALLBACK(indicator_session_users_notify_is_live_session), self); +} + +/*** +**** Public +***/ + +IndicatorSessionUsers * +indicator_session_users_mock_new (void) +{ + gpointer o = g_object_new (INDICATOR_TYPE_SESSION_USERS_MOCK, NULL); + + return INDICATOR_SESSION_USERS (o); +} + + +void +indicator_session_users_mock_add_user (IndicatorSessionUsersMock * self, + const char * key, + IndicatorSessionUser * user) +{ + g_return_if_fail (INDICATOR_IS_SESSION_USERS_MOCK (self)); + g_return_if_fail (key && *key); + g_return_if_fail (user != NULL); + + g_hash_table_insert (self->priv->users, g_strdup(key), user); + indicator_session_users_added (INDICATOR_SESSION_USERS (self), key); +} + +void +indicator_session_users_mock_remove_user (IndicatorSessionUsersMock * self, + const char * key) +{ + g_return_if_fail (INDICATOR_IS_SESSION_USERS_MOCK (self)); + g_return_if_fail (key && *key); + + g_hash_table_remove (self->priv->users, key); + indicator_session_users_removed (INDICATOR_SESSION_USERS (self), key); +} + diff --git a/tests/backend-mock-users.h b/tests/backend-mock-users.h new file mode 100644 index 0000000..c7e11d3 --- /dev/null +++ b/tests/backend-mock-users.h @@ -0,0 +1,70 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef __USERS_MOCK_H__ +#define __USERS_MOCK_H__ + +#include +#include + +#include "users.h" /* parent class */ + +G_BEGIN_DECLS + +#define INDICATOR_TYPE_SESSION_USERS_MOCK (indicator_session_users_mock_get_type()) +#define INDICATOR_SESSION_USERS_MOCK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), INDICATOR_TYPE_SESSION_USERS_MOCK, IndicatorSessionUsersMock)) +#define INDICATOR_SESSION_USERS_MOCK_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), INDICATOR_TYPE_SESSION_USERS_MOCK, IndicatorSessionUsersMockClass)) +#define INDICATOR_IS_SESSION_USERS_MOCK(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), INDICATOR_TYPE_SESSION_USERS_MOCK)) + +typedef struct _IndicatorSessionUsersMock IndicatorSessionUsersMock; +typedef struct _IndicatorSessionUsersMockPriv IndicatorSessionUsersMockPriv; +typedef struct _IndicatorSessionUsersMockClass IndicatorSessionUsersMockClass; + +/** + * An implementation of IndicatorSessionUsers that gets its user information + * from org.freedesktop.ConsoleKit and org.freedesktop.Accounts over DBus. + */ +struct _IndicatorSessionUsersMock +{ + /*< private >*/ + IndicatorSessionUsers parent; + IndicatorSessionUsersMockPriv * priv; +}; + +struct _IndicatorSessionUsersMockClass +{ + IndicatorSessionUsersClass parent_class; +}; + +GType indicator_session_users_mock_get_type (void); + +IndicatorSessionUsers * indicator_session_users_mock_new (void); + +void indicator_session_users_mock_add_user (IndicatorSessionUsersMock * self, + const char * key, + IndicatorSessionUser * user); + +void indicator_session_users_mock_remove_user (IndicatorSessionUsersMock * self, + const char * key); + + + +G_END_DECLS + +#endif diff --git a/tests/backend-mock.c b/tests/backend-mock.c new file mode 100644 index 0000000..48d7de4 --- /dev/null +++ b/tests/backend-mock.c @@ -0,0 +1,44 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include "backend-mock.h" +#include "backend-mock-actions.h" +#include "backend-mock-guest.h" +#include "backend-mock-users.h" + +GSettings * mock_settings = NULL; +IndicatorSessionActions * mock_actions = NULL; +IndicatorSessionUsers * mock_users = NULL; +IndicatorSessionGuest * mock_guest = NULL; + +void +backend_get (GCancellable * cancellable G_GNUC_UNUSED, + IndicatorSessionActions ** setme_actions, + IndicatorSessionUsers ** setme_users, + IndicatorSessionGuest ** setme_guest) +{ + if (setme_actions != NULL) + *setme_actions = g_object_ref (mock_actions); + + if (setme_users != NULL) + *setme_users = g_object_ref (mock_users); + + if (setme_guest != NULL) + *setme_guest = g_object_ref (mock_guest); +} diff --git a/tests/backend-mock.h b/tests/backend-mock.h new file mode 100644 index 0000000..d80a185 --- /dev/null +++ b/tests/backend-mock.h @@ -0,0 +1,38 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef __BACKEND_MOCK_H__ +#define __BACKEND_MOCK_H__ + +#include /* GCancellable */ + +#include "actions.h" +#include "guest.h" +#include "users.h" + +G_BEGIN_DECLS + +extern GSettings * mock_settings; +extern IndicatorSessionActions * mock_actions; +extern IndicatorSessionUsers * mock_users; +extern IndicatorSessionGuest * mock_guest; + +G_END_DECLS + +#endif diff --git a/tests/com.canonical.indicator.session.backendmock.gschema.xml b/tests/com.canonical.indicator.session.backendmock.gschema.xml new file mode 100644 index 0000000..34479df --- /dev/null +++ b/tests/com.canonical.indicator.session.backendmock.gschema.xml @@ -0,0 +1,41 @@ + + + + + '' + The last command activated + + + false + Has online account error + + + true + Is hibernation allowed? + + + true + Is suspending allowed? + + + true + Is logging out allowed? + + + true + Is locking the session allowed? + + + true + Is switching sessions allowed? + + + true + Do we have a way of prompting for confirmation? + + + false + Is this a session running on a live CD? + + + diff --git a/tests/com.canonical.indicator.session.gschema.xml b/tests/com.canonical.indicator.session.gschema.xml new file mode 100644 index 0000000..76b2be3 --- /dev/null +++ b/tests/com.canonical.indicator.session.gschema.xml @@ -0,0 +1,32 @@ + + + + + false + Suppress the dialog to confirm logout, restart and shutdown action + Whether or not to show confirmation dialogs for logout, restart and shutdown actions. + + + false + Remove the Log Out item from the session menu + Makes it so that the logout button doesn’t show in the session menu. + + + false + Remove the Restart item from the session menu + Makes it so that the restart button doesn’t show in the session menu. + + + false + Remove the shutdown item from the session menu + Makes it so that the shutdown button doesn’t show in the session menu. + + + false + Determine the visibility of the User's real name on the panel + Allow for the Removal of the users name from the panel + + + + + \ No newline at end of file diff --git a/tests/gtest-dbus-fixture.h b/tests/gtest-dbus-fixture.h new file mode 100644 index 0000000..e6cd9c7 --- /dev/null +++ b/tests/gtest-dbus-fixture.h @@ -0,0 +1,134 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include +#include + +#include + +/*** +**** +***/ + +class GTestDBusFixture : public ::testing::Test +{ + private: + + static void + on_bus_opened (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) + { + GTestDBusFixture * self = static_cast(gself); + + GError * err = 0; + self->conn = g_bus_get_finish (res, &err); + g_assert_no_error (err); + + g_main_loop_quit (self->loop); + } + + static void + on_bus_closed (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) + { + GTestDBusFixture * self = static_cast(gself); + + GError * err = 0; + g_dbus_connection_close_finish (self->conn, res, &err); + g_assert_no_error (err); + + g_main_loop_quit (self->loop); + } + + static gboolean + wait_for_signal__timeout (gpointer name) + { + g_error ("%s: timed out waiting for signal '%s'", G_STRLOC, (char*)name); + return G_SOURCE_REMOVE; + } + + protected: + + virtual void SetUp () + { + conn = 0; + test_dbus = 0; + loop = 0; + + g_setenv ("GSETTINGS_SCHEMA_DIR", SCHEMA_DIR, TRUE); + g_setenv ("GSETTINGS_BACKEND", "memory", TRUE); + g_debug ("SCHEMA_DIR is %s", SCHEMA_DIR); + + // pull up a test dbus + loop = g_main_loop_new (NULL, FALSE); + test_dbus = g_test_dbus_new (G_TEST_DBUS_NONE); + g_test_dbus_add_service_dir (test_dbus, INDICATOR_SERVICE_DIR); + g_debug ("INDICATOR_SERVICE_DIR is %s", INDICATOR_SERVICE_DIR); + g_test_dbus_up (test_dbus); + const char * address; + address = g_test_dbus_get_bus_address (test_dbus); + g_setenv ("DBUS_SYSTEM_BUS_ADDRESS", address, TRUE); + g_debug ("test_dbus's address is %s", address); + + // wait for the GDBusConnection before returning + g_bus_get (G_BUS_TYPE_SYSTEM, NULL, on_bus_opened, this); + g_main_loop_run (loop); + } + + virtual void TearDown() + { + // close the bus connection + g_dbus_connection_close (conn, NULL, on_bus_closed, this); + g_main_loop_run (loop); + g_clear_object (&conn); + + // tear down the test dbus + g_test_dbus_down (test_dbus); + g_clear_object (&test_dbus); + + g_clear_pointer (&loop, g_main_loop_unref); + } + + /* convenience func to loop while waiting for a GObject's signal */ + void wait_for_signal (gpointer o, const gchar * signal) + { + const int timeout_seconds = 5; // arbitrary + + // wait for the signal or for timeout, whichever comes first + guint handler_id = g_signal_connect_swapped (o, signal, + G_CALLBACK(g_main_loop_quit), + loop); + gulong timeout_id = g_timeout_add_seconds (timeout_seconds, + wait_for_signal__timeout, + loop); + g_main_loop_run (loop); + g_source_remove (timeout_id); + g_signal_handler_disconnect (o, handler_id); + } + + /* convenience func to loop for N msec */ + void wait_msec (int msec) + { + guint id = g_timeout_add (msec, (GSourceFunc)g_main_loop_quit, loop); + g_main_loop_run (loop); + g_source_remove (id); + } + + GMainLoop * loop; + GTestDBus * test_dbus; + GDBusConnection * conn; +}; diff --git a/tests/indicator-session.service.in b/tests/indicator-session.service.in index 80aab0d..fb3798a 100644 --- a/tests/indicator-session.service.in +++ b/tests/indicator-session.service.in @@ -1,3 +1,3 @@ [D-BUS Service] -Name=com.canonical.indicator.session -Exec=@abs_top_builddir@/src/indicator-session-service +Name=com.canonical.indicator.session-test +Exec=${CMAKE_BINARY_DIR}/src/indicator-session-service --mock diff --git a/tests/test-service.cc b/tests/test-service.cc index b1ca5bc..058fc3d 100644 --- a/tests/test-service.cc +++ b/tests/test-service.cc @@ -17,70 +17,329 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#include -#include -#include - -#include - -#include "shared-names.h" +#include "gtest-dbus-fixture.h" +#include "service.h" +#include "backend-mock.h" +#include "backend-mock-users.h" +#include "backend-mock-guest.h" +#include "backend-mock-actions.h" /*** **** ***/ -#define INDICATOR_SERVICE_OBJECT_PATH "/org/ayatana/indicator/service" -#define INDICATOR_SERVICE_INTERFACE_NAME "org.ayatana.indicator.service" +#if 0 +namespace +{ + void + dump_menu_model (GMenuModel * model, int depth) + { + GString * indent = g_string_new_len (" ", (depth*4)); + const int n = g_menu_model_get_n_items (model); + g_message ("%s depth[%d] menu model[%p] has %d items", indent->str, depth, (void*)model, n); + + for (int i=0; istr, depth, (void*)model, i, name, str); + g_free (str); + g_variant_unref (attribute_value); + } + g_clear_object (&attribute_iter); + + GMenuLinkIter * link_iter = g_menu_model_iterate_item_links (model, i); + while (g_menu_link_iter_get_next (link_iter, &name, &link_value)) + { + g_message ("%s depth[%d] menu model[%p] item[%d] attribute key[%s] model[%p]", indent->str, depth, (void*)model, i, name, (void*)link_value); + dump_menu_model (link_value, depth+1); + g_object_unref (link_value); + } + g_clear_object (&link_iter); + } + g_string_free (indent, TRUE); + } +} +#endif -class ClientTest : public ::testing::Test + +/* cppcheck-suppress noConstructor */ +class ServiceTest: public GTestDBusFixture { + typedef GTestDBusFixture super; + + enum { TIME_LIMIT_SEC = 10 }; + + private: + + static void on_name_appeared (GDBusConnection * connection G_GNUC_UNUSED, + const gchar * name G_GNUC_UNUSED, + const gchar * name_owner G_GNUC_UNUSED, + gpointer gself) + { + g_main_loop_quit (static_cast(gself)->loop); + } + + GSList * menu_references; + + bool any_item_changed; + + static void on_items_changed (GMenuModel * model G_GNUC_UNUSED, + gint position G_GNUC_UNUSED, + gint removed G_GNUC_UNUSED, + gint added G_GNUC_UNUSED, + gpointer any_item_changed) + { + *((gboolean*)any_item_changed) = true; + } + + protected: + + void activate_subtree (GMenuModel * model) + { + // query the GDBusMenuModel for information to activate it + int n = g_menu_model_get_n_items (model); + if (!n) + { + // give the model a moment to populate its info + wait_msec (100); + n = g_menu_model_get_n_items (model); + } + + // keep a ref so that it stays activated + menu_references = g_slist_prepend (menu_references, g_object_ref(model)); + + g_signal_connect (model, "items-changed", G_CALLBACK(on_items_changed), &any_item_changed); + + // recurse + for (int i=0; i= TIME_LIMIT_SEC; + } + + void wait_for_has_action (const char * name) + { + while (!g_action_group_has_action (G_ACTION_GROUP(action_group), name) && !times_up()) + wait_msec (50); + + ASSERT_FALSE (times_up()); + ASSERT_TRUE (g_action_group_has_action (G_ACTION_GROUP(action_group), name)); + } - virtual void SetUp() + void wait_for_menu_resync (void) { - test_dbus = NULL; - session_bus = NULL; - main_loop = NULL; + any_item_changed = false; + while (!times_up() && !any_item_changed) + wait_msec (50); + sync_menu (); + } + + protected: + + void check_last_command_is (const char * expected) + { + char * str = g_settings_get_string (mock_settings, "last-command"); + ASSERT_STREQ (expected, str); + g_free (str); + } - static bool first_run = true; - if (first_run) + void test_simple_action (const char * action_name) + { + wait_for_has_action (action_name); + + g_action_group_activate_action (G_ACTION_GROUP (action_group), action_name, NULL); + wait_for_signal (mock_settings, "changed::last-command"); + check_last_command_is (action_name); + } + + protected: + + bool find_menu_item_for_action (const char * action_key, GMenuModel ** setme, int * item_index) + { + bool success = false; + + for (GSList * l=menu_references; !success && (l!=NULL); l=l->next) { - g_setenv ("INDICATOR_SERVICE_SHUTDOWN_TIMEOUT", "1000", TRUE); - g_unsetenv ("INDICATOR_ALLOW_NO_WATCHERS"); - g_unsetenv ("INDICATOR_SERVICE_REPLACE_MODE"); - g_setenv ("GSETTINGS_SCHEMA_DIR", SCHEMA_DIR, TRUE); - g_setenv ("GSETTINGS_BACKEND", "memory", TRUE); - first_run = false; + GMenuModel * mm = G_MENU_MODEL (l->data); + const int n = g_menu_model_get_n_items (mm); + + for (int i=0; !success && iref_count); + if (expected_a11y != NULL) + ASSERT_STREQ (expected_a11y, a11y); + + // the session menu is always visible... + ASSERT_TRUE (visible); + + g_variant_unref (variant); } - // undo SetUp - virtual void TearDown() + void check_label (const char * expected_label, GMenuModel * model, int pos) { - g_clear_object (&session_bus); - g_debug (G_STRLOC" tearing down the bus"); - g_test_dbus_down (test_dbus); - g_clear_object (&test_dbus); - g_clear_pointer (&main_loop, g_main_loop_unref); + char * label = NULL; + ASSERT_TRUE (g_menu_model_get_item_attribute (model, pos, G_MENU_ATTRIBUTE_LABEL, "s", &label)); + ASSERT_STREQ (expected_label, label); + g_free (label); } }; @@ -88,58 +347,438 @@ class ClientTest : public ::testing::Test **** ***/ +#if 0 +TEST_F (ServiceTest, HelloWorld) +{ + ASSERT_TRUE (true); +} +#endif + +TEST_F (ServiceTest, About) +{ + test_simple_action ("about"); +} + +TEST_F (ServiceTest, Help) +{ + test_simple_action ("help"); +} + +TEST_F (ServiceTest, Hibernate) +{ + test_simple_action ("hibernate"); +} + +TEST_F (ServiceTest, Settings) +{ + test_simple_action ("settings"); +} + +TEST_F (ServiceTest, Logout) +{ + test_simple_action ("logout"); +} + +TEST_F (ServiceTest, Shutdown) +{ + test_simple_action ("shutdown"); +} + +TEST_F (ServiceTest, Restart) +{ + test_simple_action ("restart"); +} + +TEST_F (ServiceTest, SwitchToScreensaver) +{ + test_simple_action ("switch-to-screensaver"); +} + +TEST_F (ServiceTest, SwitchToGuest) +{ + test_simple_action ("switch-to-guest"); +} + +TEST_F (ServiceTest, SwitchToGreeter) +{ + test_simple_action ("switch-to-greeter"); +} + +TEST_F (ServiceTest, Suspend) +{ + test_simple_action ("suspend"); +} + +#if 0 +namespace +{ + gboolean + find_menu_item_for_action (GMenuModel * top, const char * action_key, GMenuModel ** setme, int * item_index) + { + gboolean success = FALSE; + const int n = g_menu_model_get_n_items (top); + + for (int i=0; !success && imessage); - g_clear_error (&error); - } - - name = NULL; - g_variant_get (result, "(&s)", &name); - ASSERT_STREQ (g_get_real_name(), name); - g_clear_pointer (&result, g_variant_unref); - - // call IndicatorService's Shutdown() method for a clean exit - result = g_dbus_connection_call_sync (session_bus, - INDICATOR_SESSION_DBUS_NAME, - "/org/ayatana/indicator/service", - "org.ayatana.indicator.service", - "Shutdown", NULL, - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, NULL, NULL); - g_clear_pointer (&result, g_variant_unref); +TEST_F (ServiceTest, DefaultMenuItems) +{ + ASSERT_TRUE (find_menu_item_for_action ("indicator.about", NULL, NULL)); + ASSERT_TRUE (find_menu_item_for_action ("indicator.help", NULL, NULL)); + ASSERT_TRUE (find_menu_item_for_action ("indicator.settings", NULL, NULL)); + ASSERT_TRUE (find_menu_item_for_action ("indicator.switch-to-greeter", NULL, NULL)); + ASSERT_TRUE (find_menu_item_for_action ("indicator.switch-to-guest", NULL, NULL)); + ASSERT_TRUE (find_menu_item_for_action ("indicator.logout", NULL, NULL)); + ASSERT_TRUE (find_menu_item_for_action ("indicator.suspend", NULL, NULL)); + ASSERT_TRUE (find_menu_item_for_action ("indicator.hibernate", NULL, NULL)); + ASSERT_TRUE (find_menu_item_for_action ("indicator.restart", NULL, NULL)); + ASSERT_TRUE (find_menu_item_for_action ("indicator.shutdown", NULL, NULL)); +} + +TEST_F (ServiceTest, OnlineAccountError) +{ + bool err; + int pos = -1; + GMenuModel * model = 0; + const char * const error_key = "has-online-account-error"; + + // check the initial default header state + check_header ("", "system-devices-panel", "System"); + + // check that the menuitems' existence matches the error flag + err = g_settings_get_boolean (mock_settings, error_key); + ASSERT_FALSE (err); + ASSERT_EQ (err, find_menu_item_for_action ("indicator.online-accounts", &model, &pos)); + g_clear_object (&model); + + // now toggle the error flag + err = !err; + g_settings_set_boolean (mock_settings, error_key, err); + + // wait for the _header action and error menuitem to update + wait_for_menu_resync (); + + // check that the menuitems' existence matches the error flag + ASSERT_TRUE (g_settings_get_boolean (mock_settings, error_key)); + ASSERT_TRUE (find_menu_item_for_action ("indicator.online-accounts", &model, &pos)); + g_clear_object (&model); + + // check that the header's icon and a11y adjusted to the error state + check_header ("", "system-devices-panel-alert", "System (Attention Required)"); + + // cleanup + g_settings_reset (mock_settings, error_key); +} + +namespace +{ + gboolean set_live_session_to_true (gpointer unused G_GNUC_UNUSED) + { + const char * const live_session_key = "is-live-session"; + g_settings_set_boolean (mock_settings, live_session_key, true); + return G_SOURCE_REMOVE; + } +} + +TEST_F (ServiceTest, LiveSession) +{ + gboolean b; + const char * const live_session_key = "is-live-session"; + + // default BackendMock is not a live session + ASSERT_FALSE (g_settings_get_boolean (mock_settings, live_session_key)); + g_object_get (mock_users, INDICATOR_SESSION_USERS_PROP_IS_LIVE_SESSION, &b, NULL); + ASSERT_FALSE (b); + + // confirm that we can see live sessions + g_idle_add (set_live_session_to_true, NULL); + wait_for_signal (mock_users, "notify::" INDICATOR_SESSION_USERS_PROP_IS_LIVE_SESSION); + ASSERT_TRUE (g_settings_get_boolean (mock_settings, live_session_key)); + wait_msec (50); + g_object_get (mock_users, INDICATOR_SESSION_USERS_PROP_IS_LIVE_SESSION, &b, NULL); + ASSERT_TRUE (b); + + // cleanup + g_settings_reset (mock_settings, live_session_key); +} + + +TEST_F (ServiceTest, User) +{ + const char * const error_key = "has-online-account-error"; + const char * const show_name_key = "show-real-name-on-panel"; + + const struct { + guint64 login_frequency; + const gchar * user_name; + const gchar * real_name; + } account_info[] = { + { 134, "whartnell", "First Doctor" }, + { 119, "ptroughton", "Second Doctor" }, + { 128, "jpertwee", "Third Doctor" }, + { 172, "tbaker", "Fourth Doctor" }, + { 69, "pdavison", "Fifth Doctor" }, + { 31, "cbaker", "Sixth Doctor" }, + { 42, "smccoy", "Seventh Doctor" }, + { 1, "pmcgann", "Eigth Doctor" }, + { 13, "ceccleston", "Ninth Doctor" }, + { 47, "dtennant", "Tenth Doctor" }, + { 34, "msmith", "Eleventh Doctor" }, + { 1, "rhurndall", "First Doctor" } + }; + + // Find the switcher menu model. + // In BackendMock's default setup, it will only two menuitems: greeter & guest + int pos = 0; + GMenuModel * switch_menu = 0; + ASSERT_TRUE (find_menu_item_for_action ("indicator.switch-to-greeter", &switch_menu, &pos)); + ASSERT_EQ (0, pos); + ASSERT_EQ (2, g_menu_model_get_n_items (switch_menu)); + g_clear_object (&switch_menu); + + // now add some users + IndicatorSessionUser * users[12]; + for (int i=0; i<12; ++i) + users[i] = 0; + for (int i=0; i<5; ++i) + { + IndicatorSessionUser * u = g_new0 (IndicatorSessionUser, 1); + u->is_current_user = false; + u->is_logged_in = false; + u->uid = 101 + i; + u->login_frequency = account_info[i].login_frequency; + u->user_name = g_strdup (account_info[i].user_name); + u->real_name = g_strdup (account_info[i].real_name); + indicator_session_users_mock_add_user (INDICATOR_SESSION_USERS_MOCK(mock_users), u->user_name, u); + users[i] = u; + } + + wait_for_menu_resync (); + + // now there should be 7 menuitems: greeter + guest + the five doctors + ASSERT_TRUE (find_menu_item_for_action ("indicator.switch-to-greeter", &switch_menu, &pos)); + ASSERT_EQ (0, pos); + ASSERT_EQ (7, g_menu_model_get_n_items (switch_menu)); + // confirm that the doctor names are sorted + check_label ("Fifth Doctor", switch_menu, 2); + check_label ("First Doctor", switch_menu, 3); + check_label ("Fourth Doctor", switch_menu, 4); + check_label ("Second Doctor", switch_menu, 5); + check_label ("Third Doctor", switch_menu, 6); + g_clear_object (&switch_menu); + + // now remove a couple of 'em + indicator_session_users_mock_remove_user (INDICATOR_SESSION_USERS_MOCK(mock_users), account_info[3].user_name); + indicator_session_users_mock_remove_user (INDICATOR_SESSION_USERS_MOCK(mock_users), account_info[4].user_name); + + wait_for_menu_resync (); + + // now there should be 5 menuitems: greeter + guest + the three doctors + ASSERT_TRUE (find_menu_item_for_action ("indicator.switch-to-greeter", &switch_menu, &pos)); + ASSERT_EQ (0, pos); + ASSERT_EQ (5, g_menu_model_get_n_items (switch_menu)); + // confirm that the doctor names are sorted + check_label ("First Doctor", switch_menu, 2); + check_label ("Second Doctor", switch_menu, 3); + check_label ("Third Doctor", switch_menu, 4); + g_clear_object (&switch_menu); + + // now let's have the third one be the current user + users[2]->is_current_user = true; + users[2]->is_logged_in = true; + indicator_session_users_changed (mock_users, users[2]->user_name); + + wait_for_menu_resync (); + + // now there should be 5 menuitems: greeter + guest + the three doctors + ASSERT_TRUE (find_menu_item_for_action ("indicator.switch-to-greeter", &switch_menu, &pos)); + ASSERT_EQ (0, pos); + ASSERT_EQ (5, g_menu_model_get_n_items (switch_menu)); + g_clear_object (&switch_menu); + + // oh hey, while we've got an active user let's check the header + ASSERT_FALSE (g_settings_get_boolean (indicator_settings, show_name_key)); + ASSERT_FALSE (g_settings_get_boolean (mock_settings, error_key)); + check_header ("", "system-devices-panel", "System"); + g_settings_set_boolean (indicator_settings, show_name_key, true); + wait_for_signal (action_group, "action-state-changed"); + check_header ("Third Doctor", "system-devices-panel", "System, Third Doctor"); + g_settings_set_boolean (mock_settings, error_key, true); + wait_for_signal (action_group, "action-state-changed"); + check_header ("Third Doctor", "system-devices-panel-alert", "System, Third Doctor (Attention Required)"); + g_settings_reset (mock_settings, error_key); + g_settings_reset (indicator_settings, show_name_key); + wait_for_menu_resync (); + + // try setting the max user count to 2... + // since troughton has the fewest logins, he should get culled + g_object_set (service, "max-users", 2, NULL); + guint max_users; + g_object_get (service, "max-users", &max_users, NULL); + ASSERT_EQ (2, max_users); + wait_for_menu_resync (); + ASSERT_TRUE (find_menu_item_for_action ("indicator.switch-to-greeter", &switch_menu, &pos)); + ASSERT_EQ (0, pos); + ASSERT_EQ (4, g_menu_model_get_n_items (switch_menu)); + check_label ("First Doctor", switch_menu, 2); + check_label ("Third Doctor", switch_menu, 3); + g_clear_object (&switch_menu); + + // add some more, test sorting and culling. + // add in all the doctors, but only show 7, and make msmith the current session + g_object_set (service, "max-users", 7, NULL); + g_object_get (service, "max-users", &max_users, NULL); + ASSERT_EQ (7, max_users); + for (int i=3; i<12; ++i) + { + IndicatorSessionUser * u = g_new0 (IndicatorSessionUser, 1); + u->is_current_user = false; + u->is_logged_in = false; + u->uid = 101 + i; + u->login_frequency = account_info[i].login_frequency; + u->user_name = g_strdup (account_info[i].user_name); + u->real_name = g_strdup (account_info[i].real_name); + indicator_session_users_mock_add_user (INDICATOR_SESSION_USERS_MOCK(mock_users), u->user_name, u); + users[i] = u; + } + users[2]->is_current_user = false; + indicator_session_users_changed (mock_users, users[2]->user_name); + users[10]->is_current_user = true; + users[10]->is_logged_in = true; + indicator_session_users_changed (mock_users, users[10]->user_name); + wait_for_menu_resync (); + ASSERT_TRUE (find_menu_item_for_action ("indicator.switch-to-greeter", &switch_menu, &pos)); + ASSERT_EQ (0, pos); + ASSERT_EQ (9, g_menu_model_get_n_items (switch_menu)); + check_label ("Eleventh Doctor", switch_menu, 2); + check_label ("Fifth Doctor", switch_menu, 3); + check_label ("First Doctor", switch_menu, 4); + check_label ("Fourth Doctor", switch_menu, 5); + check_label ("Second Doctor", switch_menu, 6); + check_label ("Tenth Doctor", switch_menu, 7); + check_label ("Third Doctor", switch_menu, 8); + g_clear_object (&switch_menu); + + // now switch to one of the doctors + g_action_group_activate_action (G_ACTION_GROUP(action_group), + "switch-to-user", + g_variant_new_string("tbaker")); + wait_for_signal (mock_settings, "changed::last-command"); + check_last_command_is ("switch-to-user::tbaker"); } diff --git a/trim-lcov.py b/trim-lcov.py new file mode 100755 index 0000000..78613d3 --- /dev/null +++ b/trim-lcov.py @@ -0,0 +1,53 @@ +#!/usr/bin/python + +# This script removes branch and/or line coverage data for lines that +# contain a particular substring. +# +# In the interest of "fairness" it removes all branch or coverage data +# when a match is found -- not just negative data. It is therefore +# likely that running this script will actually reduce the total number +# of lines and branches that are marked as covered (in absolute terms). +# +# This script intentionally avoids checking for errors. Any exceptions +# will trigger make to fail. +# +# Author: Ryan Lortie + +import sys + +line_suppress = ['g_assert_not_reached'] +branch_suppress = ['g_assert', 'g_return_if_fail', 'g_clear_object', 'g_clear_pointer', 'g_return_val_if_fail', 'G_DEFINE_TYPE'] + +def check_suppress(suppressions, source, data): + line, _, rest = data.partition(',') + line = int(line) - 1 + + assert line < len(source) + + for suppression in suppressions: + if suppression in source[line]: + return True + + return False + +source = [] +for line in sys.stdin: + line = line[:-1] + + keyword, _, rest = line.partition(':') + + # Source file + if keyword == 'SF': + source = file(rest).readlines() + + # Branch coverage data + elif keyword == 'BRDA': + if check_suppress(branch_suppress, source, rest): + continue + + # Line coverage data + elif keyword == 'DA': + if check_suppress(line_suppress, source, rest): + continue + + print line -- cgit v1.2.3 From 2d7bf142998a28e1970c61bf63d6435eb4d4ac1e Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 22 Mar 2013 16:53:58 -0500 Subject: copyediting: grammar --- README | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README b/README index 8834cc2..420541e 100644 --- a/README +++ b/README @@ -7,10 +7,10 @@ For instructions on building and running built-in tests, see the INSTALL file. Notes for Client Renderers -------------------------- -Indicator-Session has two custom types: the Guest menuitem and User menuitems. -Referencing the spec at ,https://wiki.ubuntu.com/SystemMenu.>, both have four -visual components: (1) an Active Session Mark and the user's (2) icon, -(3) name, and (4) Logged In Mark. +Indicator-Session has two custom menuitems: the Guest and User switchers. +As per the https://wiki.ubuntu.com/SystemMenu specification, both need four +visual components: (1) an Active Session Mark, the user's (2) icon, (3) name, +and (4) a Logged In Mark. == User menuitems can be recognized by their "indicator.switch-to-user" action. Their four visual components are determined by: @@ -30,8 +30,8 @@ visual components: (1) an Active Session Mark and the user's (2) icon, an array of usernames. If the array contains the username in this menuitem's "target" attribute, show the Logged In Mark. -== Guest menuitems can be recognized by their "indicator.switch-to-guest" action. - Its four visual components is determined by: +== The Guest switcher can be recognized by its "indicator.switch-to-guest" + action. Its four visual components are determined by: 1. You can test for the Active Session Mark by checking the action's state. The state is a dictionary whose "is-active" key yields a boolean. -- cgit v1.2.3 From c8ce514661476c027c2bd8b9f8c000810e105e67 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 22 Mar 2013 16:57:58 -0500 Subject: add top-level cmake files to the repo --- CMakeLists.txt | 71 +++++++++++++++++++ cmake/FindIntltool.cmake | 23 ++++++ cmake/GCov.cmake | 50 +++++++++++++ cmake/GSettings.cmake | 108 ++++++++++++++++++++++++++++ cmake/Gettext.cmake | 179 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 431 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 cmake/FindIntltool.cmake create mode 100644 cmake/GCov.cmake create mode 100644 cmake/GSettings.cmake create mode 100644 cmake/Gettext.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..9f8f026 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,71 @@ +project (indicator-session C CXX) +set (PROJECT_VERSION "13.10.1") +cmake_minimum_required (VERSION 2.8.9) +list (APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) + +option (full_warnings "Full compiler warnings." ON) +option (enable_tests "Build the package's automatic tests." ON) +option (enable_lcov "Generate lcov code coverage reports." ON) + +set (ARCHIVE_NAME ${CMAKE_PROJECT_NAME}-${PROJECT_VERSION}) +set (CC_WARNING_ARGS " -Wall -pedantic -Wextra -Wno-missing-field-initializers") + +# +# Check for glib/gio +# + +include (FindPkgConfig) +pkg_check_modules (SERVICE REQUIRED + glib-2.0>=2.35.4 + gio-unix-2.0>=2.25.11) +include_directories (${SERVICE_INCLUDE_DIRS}) + +# +# Testing / Coverage +# + +if (${enable_tests}) + set (GTEST_SOURCE_DIR /usr/src/gtest/src) + set (GTEST_INCLUDE_DIR ${GTEST_SOURCE_DIR}/..) + set (GTEST_LIBS -lpthread) + enable_testing () + if (${enable_lcov}) + include(cmake/GCov.cmake) + endif () +endif () + +# +# Custom Targets +# + +add_custom_target (dist + COMMAND bzr export --root=${ARCHIVE_NAME} ${CMAKE_BINARY_DIR}/${ARCHIVE_NAME}.tar.gz + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) + +add_custom_target (clean-coverage + COMMAND find ${CMAKE_BINARY_DIR} -name '*.gcda' | xargs rm -f) + +add_custom_target (cppcheck COMMAND cppcheck --enable=all -q --error-exitcode=2 --inline-suppr + ${CMAKE_SOURCE_DIR}/src + ${CMAKE_SOURCE_DIR}/test) + +# +# +# + + +add_definitions (-DGETTEXT_PACKAGE=\"indicator-session\") +add_definitions (-DPACKAGE_NAME=\"indicator-session\") +add_definitions (-DGNOMELOCALEDIR=\"@CMAKE_INSTALL_PREFIX@/share/locale\") + +# +# Directories +# + +include_directories(${CMAKE_CURRENT_BINARY_DIR}/src) + +add_subdirectory(src) +add_subdirectory(data) +if (${enable_tests}) + add_subdirectory(tests) +endif () diff --git a/cmake/FindIntltool.cmake b/cmake/FindIntltool.cmake new file mode 100644 index 0000000..45318c4 --- /dev/null +++ b/cmake/FindIntltool.cmake @@ -0,0 +1,23 @@ +# FindIntltool.cmake +# +# Jim Nelson +# Copyright 2012 Yorba Foundation + +find_program (INTLTOOL_MERGE_EXECUTABLE intltool-merge) + +if (INTLTOOL_MERGE_EXECUTABLE) + set (INTLTOOL_MERGE_FOUND TRUE) +else (INTLTOOL_MERGE_EXECUTABLE) + set (INTLTOOL_MERGE_FOUND FALSE) +endif (INTLTOOL_MERGE_EXECUTABLE) + +if (INTLTOOL_MERGE_FOUND) + macro (INTLTOOL_MERGE_DESKTOP desktop_id po_dir) + add_custom_target (geary.desktop ALL + ${INTLTOOL_MERGE_EXECUTABLE} --desktop-style ${CMAKE_SOURCE_DIR}/${po_dir} + ${CMAKE_CURRENT_SOURCE_DIR}/${desktop_id}.desktop.in ${desktop_id}.desktop + ) + install (FILES ${CMAKE_CURRENT_BINARY_DIR}/geary.desktop DESTINATION /usr/share/applications) + endmacro (INTLTOOL_MERGE_DESKTOP desktop_id po_dir) +endif (INTLTOOL_MERGE_FOUND) + diff --git a/cmake/GCov.cmake b/cmake/GCov.cmake new file mode 100644 index 0000000..8df10ee --- /dev/null +++ b/cmake/GCov.cmake @@ -0,0 +1,50 @@ +if (CMAKE_BUILD_TYPE MATCHES coverage) + set(GCOV_FLAGS "${GCOV_FLAGS} --coverage") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCOV_FLAGS}") + set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${GCOV_FLAGS}") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${GCOV_FLAGS}") + set(GCOV_LIBS ${GCOV_LIBS} gcov) + + find_program(GCOVR_EXECUTABLE gcovr HINTS ${GCOVR_ROOT} "${GCOVR_ROOT}/bin") + if (NOT GCOVR_EXECUTABLE) + message(STATUS "Gcovr binary was not found, can not generate XML coverage info.") + else () + message(STATUS "Gcovr found, can generate XML coverage info.") + add_custom_target (coverage-xml + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMAND "${GCOVR_EXECUTABLE}" --exclude="test.*" -x -r "${CMAKE_SOURCE_DIR}" + --object-directory=${CMAKE_BINARY_DIR} -o coverage.xml) + endif() + + find_program(LCOV_EXECUTABLE lcov HINTS ${LCOV_ROOT} "${GCOVR_ROOT}/bin") + find_program(GENHTML_EXECUTABLE genhtml HINTS ${GENHTML_ROOT}) + if (NOT LCOV_EXECUTABLE) + message(STATUS "Lcov binary was not found, can not generate HTML coverage info.") + else () + if(NOT GENHTML_EXECUTABLE) + message(STATUS "Genthml binary not found, can not generate HTML coverage info.") + else() + message(STATUS "Lcov and genhtml found, can generate HTML coverage info.") + add_custom_target (coverage-html + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + COMMAND "${CMAKE_CTEST_COMMAND}" --force-new-ctest-process --verbose + COMMAND "${LCOV_EXECUTABLE}" --directory ${CMAKE_BINARY_DIR} --capture | ${CMAKE_SOURCE_DIR}/trim-lcov.py > dconf-lcov.info + COMMAND LANG=C "${GENHTML_EXECUTABLE}" --prefix ${CMAKE_BINARY_DIR} --output-directory lcov-html --legend --show-details dconf-lcov.info + COMMAND ${CMAKE_COMMAND} -E echo "" + COMMAND ${CMAKE_COMMAND} -E echo "file://${CMAKE_BINARY_DIR}/lcov-html/index.html" + COMMAND ${CMAKE_COMMAND} -E echo "") + #COMMAND "${LCOV_EXECUTABLE}" --directory ${CMAKE_BINARY_DIR} --capture --output-file coverage.info --no-checksum + #COMMAND "${GENHTML_EXECUTABLE}" --prefix ${CMAKE_BINARY_DIR} --output-directory coveragereport --title "Code Coverage" --legend --show-details coverage.info + #COMMAND ${CMAKE_COMMAND} -E echo "\\#define foo \\\"bar\\\"" + #) + endif() + endif() +endif() + + + #$(MAKE) $(AM_MAKEFLAGS) check + #lcov --directory $(top_builddir) --capture --test-name dconf | $(top_srcdir)/trim-lcov.py > dconf-lcov.info + #LANG=C genhtml --prefix $(top_builddir) --output-directory lcov-html --legend --show-details dconf-lcov.info + #@echo + #@echo " file://$(abs_top_builddir)/lcov-html/index.html" + #@echo diff --git a/cmake/GSettings.cmake b/cmake/GSettings.cmake new file mode 100644 index 0000000..5902baa --- /dev/null +++ b/cmake/GSettings.cmake @@ -0,0 +1,108 @@ +# GSettings.cmake +# Originally based on CMake macros written for Marlin +# Updated by Yorba for newer versions of GLib. +# +# NOTE: This module does an in-place compilation of GSettings; the +# resulting gschemas.compiled file will end up in the same +# source folder as the original schema(s). + +option(GSETTINGS_COMPILE "Compile GSettings schemas. Can be disabled for packaging reasons." ON) +option(GSETTINGS_COMPILE_IN_PLACE "Compile GSettings schemas in the build folder. This is used for running an appliction without installing the GSettings systemwide. The application will need to set GSETTINGS_SCHEMA_DIR" ON) + +if (GSETTINGS_COMPILE) + message(STATUS "GSettings schemas will be compiled.") +endif () + +if (GSETTINGS_COMPILE_IN_PLACE) + message(STATUS "GSettings schemas will be compiled in-place.") +endif () + +macro(add_schemas GSETTINGS_TARGET SCHEMA_DIRECTORY) + set(PKG_CONFIG_EXECUTABLE pkg-config) + + # Locate all schema files. + file(GLOB all_schema_files + "${SCHEMA_DIRECTORY}/*.gschema.xml" + ) + + # Find the GLib path for schema installation + execute_process( + COMMAND + ${PKG_CONFIG_EXECUTABLE} + glib-2.0 + --variable prefix + OUTPUT_VARIABLE + _glib_prefix + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + set(GSETTINGS_DIR "${_glib_prefix}/share/glib-2.0/schemas/" CACHE INTERNAL "") + + # Fetch path for schema compiler from pkg-config + execute_process( + COMMAND + ${PKG_CONFIG_EXECUTABLE} + gio-2.0 + --variable + glib_compile_schemas + OUTPUT_VARIABLE + _glib_compile_schemas + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + set(glib_schema_compiler ${_glib_compile_schemas} CACHE INTERNAL "") + + if (GSETTINGS_COMPILE_IN_PLACE) + set(COMPILE_IN_PLACE_DIR ${CMAKE_BINARY_DIR}/gsettings) + add_custom_command( + TARGET + ${GSETTINGS_TARGET} + COMMAND + ${CMAKE_COMMAND} -E make_directory "${COMPILE_IN_PLACE_DIR}" + ) + + # Copy all schemas to the build folder. + foreach(schema_file ${all_schema_files}) + add_custom_command( + TARGET + ${GSETTINGS_TARGET} + COMMAND + ${CMAKE_COMMAND} -E copy "${schema_file}" "${COMPILE_IN_PLACE_DIR}" + COMMENT "Copying schema ${schema_file} to ${COMPILE_IN_PLACE_DIR}" + ) + endforeach() + + # Compile schema in-place. + add_custom_command( + TARGET + ${GSETTINGS_TARGET} + COMMAND + ${glib_schema_compiler} ${COMPILE_IN_PLACE_DIR} + COMMENT "Compiling schemas in folder: ${COMPILE_IN_PLACE_DIR}" + ) + endif () + + # Install and recompile schemas + message(STATUS "GSettings schemas will be installed into ${GSETTINGS_DIR}") + + install( + FILES + ${all_schema_files} + DESTINATION + ${GSETTINGS_DIR} + OPTIONAL + ) + + if (GSETTINGS_COMPILE) + install( + CODE + "message (STATUS \"Compiling GSettings schemas\")" + ) + + install( + CODE + "execute_process (COMMAND ${glib_schema_compiler} ${GSETTINGS_DIR})" + ) + endif () +endmacro(add_schemas) + diff --git a/cmake/Gettext.cmake b/cmake/Gettext.cmake new file mode 100644 index 0000000..9be4742 --- /dev/null +++ b/cmake/Gettext.cmake @@ -0,0 +1,179 @@ +# Gettext support: Create/Update pot file and +# +# To use: INCLUDE(Gettext) +# +# Most of the gettext support code is from FindGettext.cmake of cmake, +# but it is included here because: +# +# 1. Some system like RHEL5 does not have FindGettext.cmake +# 2. Bug of GETTEXT_CREATE_TRANSLATIONS make it unable to be include in 'All' +# 3. It does not support xgettext +# +#=================================================================== +# Constants: +# XGETTEXT_OPTIONS_DEFAULT: Default xgettext option: +#=================================================================== +# Variables: +# XGETTEXT_OPTIONS: Options pass to xgettext +# Default: XGETTEXT_OPTIONS_DEFAULT +# GETTEXT_MSGMERGE_EXECUTABLE: the full path to the msgmerge tool. +# GETTEXT_MSGFMT_EXECUTABLE: the full path to the msgfmt tool. +# GETTEXT_FOUND: True if gettext has been found. +# XGETTEXT_EXECUTABLE: the full path to the xgettext. +# XGETTEXT_FOUND: True if xgettext has been found. +# +#=================================================================== +# Macros: +# GETTEXT_CREATE_POT(potFile +# [OPTION xgettext_options] +# SRC list_of_source_file_that_contains_msgid +# ) +# +# Generate .pot file. +# OPTION xgettext_options: Override XGETTEXT_OPTIONS +# +# * Produced targets: pot_file +# +#------------------------------------------------------------------- +# GETTEXT_CREATE_TRANSLATIONS ( outputFile [ALL] locale1 ... localeN +# [COMMENT comment] ) +# +# This will create a target "translations" which will convert the +# given input po files into the binary output mo file. If the +# ALL option is used, the translations will also be created when +# building the default target. +# +# * Produced targets: translations +#------------------------------------------------------------------- + +FIND_PROGRAM(GETTEXT_MSGMERGE_EXECUTABLE msgmerge) +FIND_PROGRAM(GETTEXT_MSGFMT_EXECUTABLE msgfmt) +FIND_PROGRAM(GETTEXT_MSGCAT_EXECUTABLE msgcat) +FIND_PROGRAM(XGETTEXT_EXECUTABLE xgettext) + +SET(XGETTEXT_OPTIONS_DEFAULT + --language=C --keyword=_ --keyword=N_ --keyword=C_:1c,2 --keyword=NC_:1c,2 -s + --escape --add-comments="/" --package-name=${PROJECT_NAME} --package-version=${VERSION}) + +IF (GETTEXT_MSGMERGE_EXECUTABLE AND GETTEXT_MSGFMT_EXECUTABLE AND GETTEXT_MSGCAT_EXECUTABLE) + SET(GETTEXT_FOUND TRUE) +ELSE (GETTEXT_MSGMERGE_EXECUTABLE AND GETTEXT_MSGFMT_EXECUTABLE) + SET(GETTEXT_FOUND FALSE) + IF (GetText_REQUIRED) + MESSAGE(FATAL_ERROR "GetText not found") + ENDIF (GetText_REQUIRED) +ENDIF (GETTEXT_MSGMERGE_EXECUTABLE AND GETTEXT_MSGFMT_EXECUTABLE AND GETTEXT_MSGCAT_EXECUTABLE) + +IF(XGETTEXT_EXECUTABLE) + SET(XGETTEXT_FOUND TRUE) +ELSE(XGETTEXT_EXECUTABLE) + MESSAGE(STATUS "xgettext not found.") + SET(XGETTTEXT_FOUND FALSE) +ENDIF(XGETTEXT_EXECUTABLE) + +IF(NOT DEFINED XGETTEXT_OPTIONS) + SET(XGETTEXT_OPTIONS ${XGETTEXT_OPTIONS_DEFAULT}) +ENDIF(NOT DEFINED XGETTEXT_OPTIONS) + +IF(XGETTEXT_FOUND) + MACRO(GETTEXT_CREATE_POT _potFile _pot_options ) + SET(_xgettext_options_list) + SET(_src_list) + SET(_src_list_abs) + SET(_glade_list) + SET(_glade_list_abs) + SET(_stage "SRC") + FOREACH(_pot_option ${_pot_options} ${ARGN}) + IF(_pot_option STREQUAL "OPTION") + SET(_stage "OPTION") + ELSEIF(_pot_option STREQUAL "SRC") + SET(_stage "SRC") + ELSEIF(_pot_option STREQUAL "GLADE") + SET(_stage "GLADE") + ELSE(_pot_option STREQUAL "OPTION") + IF(_stage STREQUAL "OPTION") + SET(_xgettext_options_list ${_xgettext_options_list} ${_pot_option}) + ELSEIF(_stage STREQUAL "GLADE") + FILE(RELATIVE_PATH _relFile ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/${_pot_option}) + GET_FILENAME_COMPONENT(_absFile ${_pot_option} ABSOLUTE) + SET(_glade_list ${_glade_list} ${_relFile}) + SET(_glade_list_abs ${_glade_list_abs} ${_absFile}) + ELSEIF(_stage STREQUAL "SRC") + FILE(RELATIVE_PATH _relFile ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/${_pot_option}) + GET_FILENAME_COMPONENT(_absFile ${_pot_option} ABSOLUTE) + SET(_src_list ${_src_list} ${_relFile}) + SET(_src_list_abs ${_src_list_abs} ${_absFile}) + ENDIF(_stage STREQUAL "OPTION") + ENDIF(_pot_option STREQUAL "OPTION") + ENDFOREACH(_pot_option ${_pot_options} ${ARGN}) + + IF (_xgettext_options_list) + SET(_xgettext_options ${_xgettext_options_list}) + ELSE(_xgettext_options_list) + SET(_xgettext_options ${XGETTEXT_OPTIONS}) + ENDIF(_xgettext_options_list) + + #MESSAGE("${XGETTEXT_EXECUTABLE} ${_xgettext_options_list} -o ${_potFile} ${_src_list}") + ADD_CUSTOM_COMMAND(OUTPUT pot_file + COMMAND ${XGETTEXT_EXECUTABLE} ${_xgettext_options} -o ${_potFile} ${_src_list} + DEPENDS ${_src_list_abs} ${GLADE_FILES} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) + + ADD_CUSTOM_TARGET(pot_file + COMMAND ${XGETTEXT_EXECUTABLE} ${_xgettext_options_list} -o _source.pot ${_src_list} + COMMAND ${XGETTEXT_EXECUTABLE} --language=Glade --omit-header -o _glade.pot ${_glade_list} + COMMAND ${GETTEXT_MSGCAT_EXECUTABLE} -o ${_potFile} --use-first _source.pot _glade.pot + DEPENDS ${_src_list_abs} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMENT "Extract translatable messages to ${_potFile}" + ) + ENDMACRO(GETTEXT_CREATE_POT _potFile _pot_options) + + + MACRO(GETTEXT_CREATE_TRANSLATIONS _potFile _firstLang) + SET(_gmoFiles) + GET_FILENAME_COMPONENT(_potBasename ${_potFile} NAME_WE) + GET_FILENAME_COMPONENT(_absPotFile ${_potFile} ABSOLUTE) + + SET(_addToAll) + SET(_is_comment FALSE) + + FOREACH (_currentLang ${_firstLang} ${ARGN}) + IF(_currentLang STREQUAL "ALL") + SET(_addToAll "ALL") + ELSEIF(_currentLang STREQUAL "COMMENT") + SET(_is_comment TRUE) + ELSEIF(_is_comment) + SET(_is_comment FALSE) + SET(_comment ${_currentLang}) + ELSE() + SET(_lang ${_currentLang}) + GET_FILENAME_COMPONENT(_absFile ${_currentLang}.po ABSOLUTE) + GET_FILENAME_COMPONENT(_abs_PATH ${_absFile} PATH) + SET(_gmoFile ${CMAKE_CURRENT_BINARY_DIR}/${_lang}.mo) + + #MESSAGE("_absFile=${_absFile} _abs_PATH=${_abs_PATH} _lang=${_lang} curr_bin=${CMAKE_CURRENT_BINARY_DIR}") + ADD_CUSTOM_COMMAND( + OUTPUT ${_gmoFile} + COMMAND ${GETTEXT_MSGMERGE_EXECUTABLE} --quiet --update --backup=none -s ${_absFile} ${_absPotFile} + COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} -o ${_gmoFile} ${_absFile} + DEPENDS ${_absPotFile} ${_absFile} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + ) + + INSTALL(FILES ${_gmoFile} DESTINATION share/locale/${_lang}/LC_MESSAGES RENAME ${_potBasename}.mo) + SET(_gmoFiles ${_gmoFiles} ${_gmoFile}) + ENDIF() + ENDFOREACH (_currentLang ) + + IF(DEFINED _comment) + ADD_CUSTOM_TARGET(translations ${_addToAll} DEPENDS ${_gmoFiles} COMMENT ${_comment}) + ELSE(DEFINED _comment) + ADD_CUSTOM_TARGET(translations ${_addToAll} DEPENDS ${_gmoFiles}) + ENDIF(DEFINED _comment) + ENDMACRO(GETTEXT_CREATE_TRANSLATIONS ) +ENDIF(XGETTEXT_FOUND) + + + -- cgit v1.2.3 From d782f784d486fd726a870fb9c03e49bd6ef6877c Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 22 Mar 2013 16:59:19 -0500 Subject: add data/CMakeLists.txt to the repo --- data/CMakeLists.txt | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 data/CMakeLists.txt diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt new file mode 100644 index 0000000..7d213b2 --- /dev/null +++ b/data/CMakeLists.txt @@ -0,0 +1,23 @@ +# schema +configure_file (com.canonical.indicator.session.gschema.xml.in + com.canonical.indicator.session.gschema.xml) +include (GSettings) +add_schemas(clinica-schemas ${CMAKE_SOURCE_DIR}/data/com.canonical.indicator.session.gschema.xml) + +# .service file +include (GNUInstallDirs) +configure_file (indicator-session.service.in indicator-session.service) + +# .indicator file +# (NOOP) +# +# FIXME install files +#install(FILES +#${CMAKE_CURRENT_BINARY_DIR}/indicator-datetime.service +#DESTINATION share/indicator-datetime # FIXME to be the real install dir. +#) +# +#install(FILES +#datetime-dialog.ui +#DESTINATION share/indicatore-datetime # FIXME this too. +#) -- cgit v1.2.3 From ca4b40ade7f432d98c21ac499a0de63244b1c3cc Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sat, 23 Mar 2013 10:04:13 -0500 Subject: use pete woods' hud cmake code for the build.sh script to check for Ninja and to move the gdbus-codegen macros into a resuable file in the cmake/ directory. --- CMakeLists.txt | 66 ++++++++++------------- build.sh | 18 +++++++ cmake/GdbusCodegen.cmake | 36 +++++++++++++ src/backend-dbus/CMakeLists.txt | 115 +++++++++++++++------------------------- 4 files changed, 125 insertions(+), 110 deletions(-) create mode 100755 build.sh create mode 100644 cmake/GdbusCodegen.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f8f026..feb332c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,43 +1,35 @@ project (indicator-session C CXX) -set (PROJECT_VERSION "13.10.1") cmake_minimum_required (VERSION 2.8.9) + list (APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) -option (full_warnings "Full compiler warnings." ON) +set (PROJECT_VERSION "13.10.1") +set (PACKAGE ${CMAKE_PROJECT_NAME}) +set (GETTEXT_PACKAGE ${CMAKE_PROJECT_NAME}) + option (enable_tests "Build the package's automatic tests." ON) +option (full_warnings "Full compiler warnings." ON) option (enable_lcov "Generate lcov code coverage reports." ON) -set (ARCHIVE_NAME ${CMAKE_PROJECT_NAME}-${PROJECT_VERSION}) -set (CC_WARNING_ARGS " -Wall -pedantic -Wextra -Wno-missing-field-initializers") - -# -# Check for glib/gio -# +find_package(PkgConfig REQUIRED) include (FindPkgConfig) +include (GdbusCodegen) +include (GSettings) + +add_definitions( -DGETTEXT_PACKAGE="${GETTEXT_PACKAGE}" ) +add_definitions (-DGNOMELOCALEDIR=\"@CMAKE_INSTALL_PREFIX@/share/locale\") + pkg_check_modules (SERVICE REQUIRED glib-2.0>=2.35.4 gio-unix-2.0>=2.25.11) include_directories (${SERVICE_INCLUDE_DIRS}) -# -# Testing / Coverage -# +set (CC_WARNING_ARGS " -Wall -pedantic -Wextra -Wno-missing-field-initializers") -if (${enable_tests}) - set (GTEST_SOURCE_DIR /usr/src/gtest/src) - set (GTEST_INCLUDE_DIR ${GTEST_SOURCE_DIR}/..) - set (GTEST_LIBS -lpthread) - enable_testing () - if (${enable_lcov}) - include(cmake/GCov.cmake) - endif () -endif () -# -# Custom Targets -# +set (ARCHIVE_NAME ${CMAKE_PROJECT_NAME}-${PROJECT_VERSION}) add_custom_target (dist COMMAND bzr export --root=${ARCHIVE_NAME} ${CMAKE_BINARY_DIR}/${ARCHIVE_NAME}.tar.gz WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) @@ -47,25 +39,21 @@ add_custom_target (clean-coverage add_custom_target (cppcheck COMMAND cppcheck --enable=all -q --error-exitcode=2 --inline-suppr ${CMAKE_SOURCE_DIR}/src - ${CMAKE_SOURCE_DIR}/test) - -# -# -# + ${CMAKE_SOURCE_DIR}/tests) +include_directories (${CMAKE_CURRENT_SOURCE_DIR}/src) +include_directories (${CMAKE_CURRENT_BINARY_DIR}/src) -add_definitions (-DGETTEXT_PACKAGE=\"indicator-session\") -add_definitions (-DPACKAGE_NAME=\"indicator-session\") -add_definitions (-DGNOMELOCALEDIR=\"@CMAKE_INSTALL_PREFIX@/share/locale\") - -# -# Directories -# +add_subdirectory (src) +add_subdirectory (data) -include_directories(${CMAKE_CURRENT_BINARY_DIR}/src) - -add_subdirectory(src) -add_subdirectory(data) if (${enable_tests}) + set (GTEST_SOURCE_DIR /usr/src/gtest/src) + set (GTEST_INCLUDE_DIR ${GTEST_SOURCE_DIR}/..) + set (GTEST_LIBS -lpthread) + enable_testing () + if (${enable_lcov}) + include(cmake/GCov.cmake) + endif () add_subdirectory(tests) endif () diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..173ff8c --- /dev/null +++ b/build.sh @@ -0,0 +1,18 @@ +#! /bin/bash +set -e + +mkdir -p build + +if [ -f "/usr/bin/ninja" ] ; then + EXTRA_ARGS="-G Ninja" + BUILD_COMMAND="ninja" +else + BUILD_COMMAND="make" +fi + +echo "Using $BUILD_COMMAND to build" +( + cd build + cmake .. $EXTRA_ARGS -DCMAKE_INSTALL_PREFIX=../../install -Dlocal_install=ON + $BUILD_COMMAND +) diff --git a/cmake/GdbusCodegen.cmake b/cmake/GdbusCodegen.cmake new file mode 100644 index 0000000..ddb2995 --- /dev/null +++ b/cmake/GdbusCodegen.cmake @@ -0,0 +1,36 @@ +cmake_minimum_required(VERSION 2.6) +if(POLICY CMP0011) + cmake_policy(SET CMP0011 NEW) +endif(POLICY CMP0011) + +find_program(GDBUS_CODEGEN NAMES gdbus-codegen DOC "gdbus-codegen executable") +if(NOT GDBUS_CODEGEN) + message(FATAL_ERROR "Excutable gdbus-codegen not found") +endif() + +macro(add_gdbus_codegen outfiles name prefix service_xml) + add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${name}.h" "${CMAKE_CURRENT_BINARY_DIR}/${name}.c" + COMMAND "${GDBUS_CODEGEN}" + --interface-prefix "${prefix}" + --generate-c-code "${name}" + "${service_xml}" + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${ARGN} "${service_xml}" + ) + list(APPEND ${outfiles} "${CMAKE_CURRENT_BINARY_DIR}/${name}.c") +endmacro(add_gdbus_codegen) + +macro(add_gdbus_codegen_with_namespace outfiles name prefix namespace service_xml) + add_custom_command( + OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${name}.h" "${CMAKE_CURRENT_BINARY_DIR}/${name}.c" + COMMAND "${GDBUS_CODEGEN}" + --interface-prefix "${prefix}" + --generate-c-code "${name}" + --c-namespace "${namespace}" + "${service_xml}" + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${ARGN} "${service_xml}" + ) + list(APPEND ${outfiles} "${CMAKE_CURRENT_BINARY_DIR}/${name}.c") +endmacro(add_gdbus_codegen_with_namespace) diff --git a/src/backend-dbus/CMakeLists.txt b/src/backend-dbus/CMakeLists.txt index a477cfe..dd928cc 100644 --- a/src/backend-dbus/CMakeLists.txt +++ b/src/backend-dbus/CMakeLists.txt @@ -1,86 +1,59 @@ -# autogenerate source code files for our DBus proxies -function(gdbus_codegen XML_FILE INTERFACE_PREFIX SOURCE_PREFIX) +set(BACKEND_GENERATED_SOURCES +) - set (SRC_C, ${SOURCE_PREFIX}.c) - set (SRC_H, ${SOURCE_PREFIX}.h) +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-display-manager + org.freedesktop + ${CMAKE_CURRENT_SOURCE_DIR}/display-manager.xml) - # check for the app - find_program (GDBUS_CODEGEN_EXECUTABLE NAMES gdbus-codegen DOC "gdbus-codegen executable") - if(NOT GDBUS_CODEGEN_EXECUTABLE) - message(FATAL_ERROR "Executable gdbus-codegen not found") - endif() +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-webcredentials + com.canonical.indicators + ${CMAKE_CURRENT_SOURCE_DIR}/com.canonical.indicators.webcredentials.xml) - # generate the code - add_custom_command ( - OUTPUT ${SOURCE_PREFIX}.c ${SOURCE_PREFIX}.h - COMMAND gdbus-codegen ARGS --interface-prefix ${INTERFACE_PREFIX} --generate-c-code ${SOURCE_PREFIX} ${CMAKE_CURRENT_SOURCE_DIR}/${XML_FILE} - DEPENDS ${XML_FILE}) +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-accounts + org.freedesktop + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.Accounts.xml) + +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-user + org.freedesktop + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.Accounts.User.xml) - # update our variables - set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${SRC_C}) - set_property (DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${SRC_H}) - set_property (SOURCE ${SRC_C} ${SRC_H} PROPERTY GENERATED) +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-consolekit-manager + org.freedesktop + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.ConsoleKit.Manager.xml) - # cleanup - unset (SRC_C) - unset (SRC_H) +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-consolekit-seat + org.freedesktop + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.ConsoleKit.Seat.xml) -endfunction(gdbus_codegen) -gdbus_codegen ("display-manager.xml" "org.freedesktop" "dbus-display-manager") -gdbus_codegen ("com.canonical.indicators.webcredentials.xml" "com.canonical.indicators" "dbus-webcredentials") -gdbus_codegen ("org.freedesktop.Accounts.xml" "org.freedesktop" "dbus-accounts") -gdbus_codegen ("org.freedesktop.Accounts.User.xml" "org.freedesktop" "dbus-user") -gdbus_codegen ("org.freedesktop.ConsoleKit.Manager.xml" "org.freedesktop" "dbus-consolekit-manager") -gdbus_codegen ("org.freedesktop.ConsoleKit.Seat.xml" "org.freedesktop" "dbus-consolekit-seat") -gdbus_codegen ("org.freedesktop.ConsoleKit.Session.xml" "org.freedesktop" "dbus-consolekit-session") -gdbus_codegen ("org.gnome.ScreenSaver.xml" "org" "gnome-screen-saver") -gdbus_codegen ("org.gnome.SessionManager.xml" "org" "gnome-session-manager") -gdbus_codegen ("org.gnome.SessionManager.EndSessionDialog.xml" "org.gnome.SessionManager" "dbus-end-session-dialog") -gdbus_codegen ("upower.xml" "org.freedesktop" "dbus-upower") +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-consolekit-session + org.freedesktop + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.ConsoleKit.Session.xml) + +add_gdbus_codegen (BACKEND_GENERATED_SOURCES gnome-screen-saver + org + ${CMAKE_CURRENT_SOURCE_DIR}/org.gnome.ScreenSaver.xml) + +add_gdbus_codegen (BACKEND_GENERATED_SOURCES gnome-session-manager + org + ${CMAKE_CURRENT_SOURCE_DIR}/org.gnome.SessionManager.xml) + +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-end-session-dialog + org.gnome.SessionManager + ${CMAKE_CURRENT_SOURCE_DIR}/org.gnome.SessionManager.EndSessionDialog.xml) + +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-upower + org.freedesktop + ${CMAKE_CURRENT_SOURCE_DIR}/upower.xml) + +set (SOURCES actions.c backend-dbus.c guest.c users.c utils.c) # add warnings/coverage info on handwritten files # but not the autogenerated ones... -set_source_files_properties (actions.c - backend-dbus.c - guest.c - users.c - utils.c +set_source_files_properties (${SOURCES} PROPERTIES COMPILE_FLAGS " -g ${CC_WARNING_ARGS} ${GCOV_FLAGS}") # add the bin dir to our include path s.t. our code can find the autogenerated header files include_directories (${CMAKE_CURRENT_BINARY_DIR} ${SERVICE_INCLUDE_DIRS}) -add_library (backenddbus STATIC - gnome-screen-saver.c - gnome-screen-saver.h - gnome-session-manager.c - gnome-session-manager.h - dbus-display-manager.c - dbus-display-manager.h - dbus-consolekit-manager.c - dbus-consolekit-manager.h - dbus-consolekit-seat.c - dbus-consolekit-seat.h - dbus-consolekit-session.c - dbus-consolekit-session.h - dbus-accounts.c - dbus-accounts.h - dbus-upower.c - dbus-upower.h - dbus-user.c - dbus-user.h - dbus-webcredentials.c - dbus-webcredentials.h - dbus-end-session-dialog.c - dbus-end-session-dialog.h - actions.c - actions.h - backend-dbus.c - backend-dbus.h - guest.c - guest.h - users.c - users.h - utils.c - utils.h) +add_library (backenddbus STATIC ${SOURCES} ${BACKEND_GENERATED_SOURCES}) -- cgit v1.2.3 From 78e8c39d7fb8cb50b7a3cf3cca088f2b5e433166 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sat, 23 Mar 2013 16:25:21 -0500 Subject: Add Translations.cmake for i18n files --- CMakeLists.txt | 1 + INSTALL | 1 + cmake/Gettext.cmake | 179 ----------------------------------------------- cmake/Translations.cmake | 41 +++++++++++ po/CMakeLists.txt | 3 + po/LINGUAS | 99 -------------------------- po/POTFILES.in | 14 ---- 7 files changed, 46 insertions(+), 292 deletions(-) delete mode 100644 cmake/Gettext.cmake create mode 100644 cmake/Translations.cmake create mode 100644 po/CMakeLists.txt delete mode 100644 po/LINGUAS delete mode 100644 po/POTFILES.in diff --git a/CMakeLists.txt b/CMakeLists.txt index feb332c..5f04214 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,6 +46,7 @@ include_directories (${CMAKE_CURRENT_BINARY_DIR}/src) add_subdirectory (src) add_subdirectory (data) +add_subdirectory (po) if (${enable_tests}) set (GTEST_SOURCE_DIR /usr/src/gtest/src) diff --git a/INSTALL b/INSTALL index ef5d8e5..1ca082b 100644 --- a/INSTALL +++ b/INSTALL @@ -18,6 +18,7 @@ Build dependencies ------------------ List of packages required to build and test the code: +- gettext (gettext 0.18.1.1-10ubuntu3 or later) - glib (libglib2.0, 2.35.4 or later) - cmake (cmake, 2.8.9 or later) - gcovr (gcovr, 2.4 or later) diff --git a/cmake/Gettext.cmake b/cmake/Gettext.cmake deleted file mode 100644 index 9be4742..0000000 --- a/cmake/Gettext.cmake +++ /dev/null @@ -1,179 +0,0 @@ -# Gettext support: Create/Update pot file and -# -# To use: INCLUDE(Gettext) -# -# Most of the gettext support code is from FindGettext.cmake of cmake, -# but it is included here because: -# -# 1. Some system like RHEL5 does not have FindGettext.cmake -# 2. Bug of GETTEXT_CREATE_TRANSLATIONS make it unable to be include in 'All' -# 3. It does not support xgettext -# -#=================================================================== -# Constants: -# XGETTEXT_OPTIONS_DEFAULT: Default xgettext option: -#=================================================================== -# Variables: -# XGETTEXT_OPTIONS: Options pass to xgettext -# Default: XGETTEXT_OPTIONS_DEFAULT -# GETTEXT_MSGMERGE_EXECUTABLE: the full path to the msgmerge tool. -# GETTEXT_MSGFMT_EXECUTABLE: the full path to the msgfmt tool. -# GETTEXT_FOUND: True if gettext has been found. -# XGETTEXT_EXECUTABLE: the full path to the xgettext. -# XGETTEXT_FOUND: True if xgettext has been found. -# -#=================================================================== -# Macros: -# GETTEXT_CREATE_POT(potFile -# [OPTION xgettext_options] -# SRC list_of_source_file_that_contains_msgid -# ) -# -# Generate .pot file. -# OPTION xgettext_options: Override XGETTEXT_OPTIONS -# -# * Produced targets: pot_file -# -#------------------------------------------------------------------- -# GETTEXT_CREATE_TRANSLATIONS ( outputFile [ALL] locale1 ... localeN -# [COMMENT comment] ) -# -# This will create a target "translations" which will convert the -# given input po files into the binary output mo file. If the -# ALL option is used, the translations will also be created when -# building the default target. -# -# * Produced targets: translations -#------------------------------------------------------------------- - -FIND_PROGRAM(GETTEXT_MSGMERGE_EXECUTABLE msgmerge) -FIND_PROGRAM(GETTEXT_MSGFMT_EXECUTABLE msgfmt) -FIND_PROGRAM(GETTEXT_MSGCAT_EXECUTABLE msgcat) -FIND_PROGRAM(XGETTEXT_EXECUTABLE xgettext) - -SET(XGETTEXT_OPTIONS_DEFAULT - --language=C --keyword=_ --keyword=N_ --keyword=C_:1c,2 --keyword=NC_:1c,2 -s - --escape --add-comments="/" --package-name=${PROJECT_NAME} --package-version=${VERSION}) - -IF (GETTEXT_MSGMERGE_EXECUTABLE AND GETTEXT_MSGFMT_EXECUTABLE AND GETTEXT_MSGCAT_EXECUTABLE) - SET(GETTEXT_FOUND TRUE) -ELSE (GETTEXT_MSGMERGE_EXECUTABLE AND GETTEXT_MSGFMT_EXECUTABLE) - SET(GETTEXT_FOUND FALSE) - IF (GetText_REQUIRED) - MESSAGE(FATAL_ERROR "GetText not found") - ENDIF (GetText_REQUIRED) -ENDIF (GETTEXT_MSGMERGE_EXECUTABLE AND GETTEXT_MSGFMT_EXECUTABLE AND GETTEXT_MSGCAT_EXECUTABLE) - -IF(XGETTEXT_EXECUTABLE) - SET(XGETTEXT_FOUND TRUE) -ELSE(XGETTEXT_EXECUTABLE) - MESSAGE(STATUS "xgettext not found.") - SET(XGETTTEXT_FOUND FALSE) -ENDIF(XGETTEXT_EXECUTABLE) - -IF(NOT DEFINED XGETTEXT_OPTIONS) - SET(XGETTEXT_OPTIONS ${XGETTEXT_OPTIONS_DEFAULT}) -ENDIF(NOT DEFINED XGETTEXT_OPTIONS) - -IF(XGETTEXT_FOUND) - MACRO(GETTEXT_CREATE_POT _potFile _pot_options ) - SET(_xgettext_options_list) - SET(_src_list) - SET(_src_list_abs) - SET(_glade_list) - SET(_glade_list_abs) - SET(_stage "SRC") - FOREACH(_pot_option ${_pot_options} ${ARGN}) - IF(_pot_option STREQUAL "OPTION") - SET(_stage "OPTION") - ELSEIF(_pot_option STREQUAL "SRC") - SET(_stage "SRC") - ELSEIF(_pot_option STREQUAL "GLADE") - SET(_stage "GLADE") - ELSE(_pot_option STREQUAL "OPTION") - IF(_stage STREQUAL "OPTION") - SET(_xgettext_options_list ${_xgettext_options_list} ${_pot_option}) - ELSEIF(_stage STREQUAL "GLADE") - FILE(RELATIVE_PATH _relFile ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR}/${_pot_option}) - GET_FILENAME_COMPONENT(_absFile ${_pot_option} ABSOLUTE) - SET(_glade_list ${_glade_list} ${_relFile}) - SET(_glade_list_abs ${_glade_list_abs} ${_absFile}) - ELSEIF(_stage STREQUAL "SRC") - FILE(RELATIVE_PATH _relFile ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/${_pot_option}) - GET_FILENAME_COMPONENT(_absFile ${_pot_option} ABSOLUTE) - SET(_src_list ${_src_list} ${_relFile}) - SET(_src_list_abs ${_src_list_abs} ${_absFile}) - ENDIF(_stage STREQUAL "OPTION") - ENDIF(_pot_option STREQUAL "OPTION") - ENDFOREACH(_pot_option ${_pot_options} ${ARGN}) - - IF (_xgettext_options_list) - SET(_xgettext_options ${_xgettext_options_list}) - ELSE(_xgettext_options_list) - SET(_xgettext_options ${XGETTEXT_OPTIONS}) - ENDIF(_xgettext_options_list) - - #MESSAGE("${XGETTEXT_EXECUTABLE} ${_xgettext_options_list} -o ${_potFile} ${_src_list}") - ADD_CUSTOM_COMMAND(OUTPUT pot_file - COMMAND ${XGETTEXT_EXECUTABLE} ${_xgettext_options} -o ${_potFile} ${_src_list} - DEPENDS ${_src_list_abs} ${GLADE_FILES} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - ) - - ADD_CUSTOM_TARGET(pot_file - COMMAND ${XGETTEXT_EXECUTABLE} ${_xgettext_options_list} -o _source.pot ${_src_list} - COMMAND ${XGETTEXT_EXECUTABLE} --language=Glade --omit-header -o _glade.pot ${_glade_list} - COMMAND ${GETTEXT_MSGCAT_EXECUTABLE} -o ${_potFile} --use-first _source.pot _glade.pot - DEPENDS ${_src_list_abs} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - COMMENT "Extract translatable messages to ${_potFile}" - ) - ENDMACRO(GETTEXT_CREATE_POT _potFile _pot_options) - - - MACRO(GETTEXT_CREATE_TRANSLATIONS _potFile _firstLang) - SET(_gmoFiles) - GET_FILENAME_COMPONENT(_potBasename ${_potFile} NAME_WE) - GET_FILENAME_COMPONENT(_absPotFile ${_potFile} ABSOLUTE) - - SET(_addToAll) - SET(_is_comment FALSE) - - FOREACH (_currentLang ${_firstLang} ${ARGN}) - IF(_currentLang STREQUAL "ALL") - SET(_addToAll "ALL") - ELSEIF(_currentLang STREQUAL "COMMENT") - SET(_is_comment TRUE) - ELSEIF(_is_comment) - SET(_is_comment FALSE) - SET(_comment ${_currentLang}) - ELSE() - SET(_lang ${_currentLang}) - GET_FILENAME_COMPONENT(_absFile ${_currentLang}.po ABSOLUTE) - GET_FILENAME_COMPONENT(_abs_PATH ${_absFile} PATH) - SET(_gmoFile ${CMAKE_CURRENT_BINARY_DIR}/${_lang}.mo) - - #MESSAGE("_absFile=${_absFile} _abs_PATH=${_abs_PATH} _lang=${_lang} curr_bin=${CMAKE_CURRENT_BINARY_DIR}") - ADD_CUSTOM_COMMAND( - OUTPUT ${_gmoFile} - COMMAND ${GETTEXT_MSGMERGE_EXECUTABLE} --quiet --update --backup=none -s ${_absFile} ${_absPotFile} - COMMAND ${GETTEXT_MSGFMT_EXECUTABLE} -o ${_gmoFile} ${_absFile} - DEPENDS ${_absPotFile} ${_absFile} - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - ) - - INSTALL(FILES ${_gmoFile} DESTINATION share/locale/${_lang}/LC_MESSAGES RENAME ${_potBasename}.mo) - SET(_gmoFiles ${_gmoFiles} ${_gmoFile}) - ENDIF() - ENDFOREACH (_currentLang ) - - IF(DEFINED _comment) - ADD_CUSTOM_TARGET(translations ${_addToAll} DEPENDS ${_gmoFiles} COMMENT ${_comment}) - ELSE(DEFINED _comment) - ADD_CUSTOM_TARGET(translations ${_addToAll} DEPENDS ${_gmoFiles}) - ENDIF(DEFINED _comment) - ENDMACRO(GETTEXT_CREATE_TRANSLATIONS ) -ENDIF(XGETTEXT_FOUND) - - - diff --git a/cmake/Translations.cmake b/cmake/Translations.cmake new file mode 100644 index 0000000..476fb37 --- /dev/null +++ b/cmake/Translations.cmake @@ -0,0 +1,41 @@ +# Translations.cmake, CMake macros written for Marlin, feel free to re-use them + +macro(add_translations_directory NLS_PACKAGE) + add_custom_target (i18n ALL COMMENT “Building i18n messages.”) + find_program (MSGFMT_EXECUTABLE msgfmt) + file (GLOB PO_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.po) + foreach (PO_INPUT ${PO_FILES}) + get_filename_component (PO_INPUT_BASE ${PO_INPUT} NAME_WE) + set (MO_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PO_INPUT_BASE}.mo) + add_custom_command (TARGET i18n COMMAND ${MSGFMT_EXECUTABLE} -o ${MO_OUTPUT} ${PO_INPUT}) + + install (FILES ${MO_OUTPUT} DESTINATION + share/locale/${PO_INPUT_BASE}/LC_MESSAGES + RENAME ${NLS_PACKAGE}.mo) + endforeach (PO_INPUT ${PO_FILES}) +endmacro(add_translations_directory) + + +macro(add_translations_catalog NLS_PACKAGE) + add_custom_target (pot COMMENT “Building translation catalog.”) + find_program (XGETTEXT_EXECUTABLE xgettext) + + + set(C_SOURCE "") + + foreach(FILES_INPUT ${ARGN}) + file (GLOB_RECURSE SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/${FILES_INPUT}/*.c) + foreach(C_FILE ${SOURCE_FILES}) + set(C_SOURCE ${C_SOURCE} ${C_FILE}) + endforeach() + file (GLOB_RECURSE SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/${FILES_INPUT}/*.vala) + foreach(C_FILE ${SOURCE_FILES}) + set(C_SOURCE ${C_SOURCE} ${C_FILE}) + endforeach() + endforeach() + + add_custom_command (TARGET pot COMMAND + ${XGETTEXT_EXECUTABLE} -d ${NLS_PACKAGE} -o ${CMAKE_CURRENT_SOURCE_DIR}/${NLS_PACKAGE}.pot + ${VALA_SOURCE} ${C_SOURCE} --keyword="_" --keyword="N_" --from-code=UTF-8 + ) +endmacro() diff --git a/po/CMakeLists.txt b/po/CMakeLists.txt new file mode 100644 index 0000000..8325f6e --- /dev/null +++ b/po/CMakeLists.txt @@ -0,0 +1,3 @@ +include (Translations) +add_translations_directory ("${GETTEXT_PACKAGE}") +add_translations_catalog ("${GETTEXT_PACKAGE}" ../src/) diff --git a/po/LINGUAS b/po/LINGUAS deleted file mode 100644 index 2f49802..0000000 --- a/po/LINGUAS +++ /dev/null @@ -1,99 +0,0 @@ -af -am -an -ar -ast -az -be -bg -bn -bo -br -bs -ca -ca@valencia -crh -csb -cs -cv -cy -da -de -dv -el -en_AU -en_CA -en_GB -eo -es -et -eu -fa -fi -fr -fur -fy -gd -gl -gu -gv -he -hi -hr -hu -hy -id -is -it -ja -ka -kk -km -kn -ko -ku -ky -lb -lt -lv -mg -mk -ml -mr -ms -my -nb -ne -nl -nn -ny -oc -os -pa -pl -pt_BR -pt -ro -ru -sc -sd -si -sk -sl -sq -sr -sv -ta_LK -ta -te -th -tr -tt -ug -uk -ur -vec -vi -zh_CN -zh_HK -zh_TW diff --git a/po/POTFILES.in b/po/POTFILES.in deleted file mode 100644 index f2cafb0..0000000 --- a/po/POTFILES.in +++ /dev/null @@ -1,14 +0,0 @@ -[encoding: UTF-8] -data/com.canonical.indicator.session.gschema.xml.in -data/extra-sessions/classic-desktop.desktop.in.in -src/dialog.c -src/gen-session-dbus.xml.c -src/gtk-logout-helper.c -src/indicator-session.c -src/online-accounts-mgr.c -src/session-dbus.c -src/session-menu-mgr.c -src/session-service.c -src/users-service-dbus.c -src/user-widget.c - -- cgit v1.2.3 From 4a8c2566e3114cb30e0c79b48859e5325c1f448b Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 25 Mar 2013 15:06:43 -0500 Subject: remove unused session-dbus.xml; this is a leftover from the GTK+ indicator --- src/backend-dbus/session-dbus.xml | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 src/backend-dbus/session-dbus.xml diff --git a/src/backend-dbus/session-dbus.xml b/src/backend-dbus/session-dbus.xml deleted file mode 100644 index 96e9837..0000000 --- a/src/backend-dbus/session-dbus.xml +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - -- cgit v1.2.3 From 5f9911a74ef23da8d8bc9ba5b6488da964470178 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 25 Mar 2013 15:07:21 -0500 Subject: In INSTALL, document the DBus runtime dependencies --- INSTALL | 78 ++++++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 46 insertions(+), 32 deletions(-) diff --git a/INSTALL b/INSTALL index 1ca082b..2920993 100644 --- a/INSTALL +++ b/INSTALL @@ -14,53 +14,67 @@ # along with this program. If not, see . # -Build dependencies ------------------- +Compile-time build dependencies +------------------------------- + - gettext (gettext 0.18.1.1-10ubuntu3 or later) + - glib (libglib2.0, 2.35.4 or later) + - cmake (cmake, 2.8.9 or later) + - gcovr (gcovr, 2.4 or later) + - lcov (lcov, 1.9 or later) + - google test (libgtest-dev, 1.6.0 or later) + - cppcheck (cppcheck) -List of packages required to build and test the code: -- gettext (gettext 0.18.1.1-10ubuntu3 or later) -- glib (libglib2.0, 2.35.4 or later) -- cmake (cmake, 2.8.9 or later) -- gcovr (gcovr, 2.4 or later) -- lcov (lcov, 1.9 or later) -- google test (libgtest-dev, 1.6.0 or later) -- cppcheck (cppcheck) +Runtime DBus dependencies +------------------------- + - com.canonical.indicators.webcredentials + - org.freedesktop.Accounts + - org.freedesktop.Accounts.User + - org.freedesktop.ConsoleKit.Manager + - org.freedesktop.ConsoleKit.Seat + - org.freedesktop.ConsoleKit.Session + - org.freedesktop.DisplayManager.Seat + - org.freedesktop.UPower + - org.gnome.ScreenSaver + - org.gnome.SessionManager + - org.gnome.SessionManager.EndSessionDialog Building the code ----------------- - The simplest case is: - - $ cd indicator-session-X.Y.Z - $ mkdir build - $ cd build - $ cmake .. - $ make + $ cd indicator-session-X.Y.Z + $ mkdir build + $ cd build + $ cmake .. + $ make Running the tests ----------------- - - $ cd indicator-session-X.Y.Z - $ mkdir build - $ cd build - $ cmake .. - $ make - $ make test - $ make cppcheck + $ cd indicator-session-X.Y.Z + $ mkdir build + $ cd build + $ cmake .. + $ make + $ make test + $ make cppcheck Generating Test Coverage Reports -------------------------------- - - $ cd indicator-session-X.Y.Z - $ mkdir build-coverage - $ cd build-coverage - $ cmake -DCMAKE_BUILD_TYPE=coverage .. - $ make - $ make coverage-html + $ cd indicator-session-X.Y.Z + $ mkdir build-coverage + $ cd build-coverage + $ cmake -DCMAKE_BUILD_TYPE=coverage .. + $ make + $ make coverage-html Installation ------------ +what gets installed +LC_ALL=C /usr/bin/intltool-merge -x -u --no-translations com.canonical.indicator.session.gschema.xml.in com.canonical.indicator.session.gschema.xml + + + + FIXME: not tested To get files that form part of an installation, run a "make install" in the build directory. By default, this installs them in the "install" -- cgit v1.2.3 From 4bc93061f407194434de187ea55a0317af4b71ac Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 26 Mar 2013 15:52:55 -0500 Subject: remove unnecessary G_GNUC_UNUSED --- src/service.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/service.c b/src/service.c index 1345681..8e2921e 100644 --- a/src/service.c +++ b/src/service.c @@ -1082,7 +1082,7 @@ my_get_property (GObject * o, static void my_set_property (GObject * o, guint property_id, - const GValue * value G_GNUC_UNUSED, + const GValue * value, GParamSpec * pspec) { IndicatorSessionService * self = INDICATOR_SESSION_SERVICE (o); -- cgit v1.2.3 From 066872fb191ba3b79d1387a10f0b8be948d2d488 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 18 Apr 2013 09:49:09 -0500 Subject: remove unnecessary signal (SIGPIPE, SIG_IGN) --- src/main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main.c b/src/main.c index ff5997b..17b50b4 100644 --- a/src/main.c +++ b/src/main.c @@ -66,8 +66,6 @@ main (int argc, char ** argv) GMainLoop * loop; IndicatorSessionService * service; - signal (SIGPIPE, SIG_IGN); - /* boilerplate i18n */ setlocale (LC_ALL, ""); bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); -- cgit v1.2.3 From d87fb5d14091b22eaf6226dc8f9656bd6d514571 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 18 Apr 2013 10:10:17 -0500 Subject: where appropriate, use g_menu_append() to save a few lines. --- src/service.c | 62 +++++++++++++---------------------------------------------- 1 file changed, 13 insertions(+), 49 deletions(-) diff --git a/src/service.c b/src/service.c index 8e2921e..e62250e 100644 --- a/src/service.c +++ b/src/service.c @@ -277,18 +277,10 @@ static GMenuModel * create_admin_section (void) { GMenu * menu; - GMenuItem * item; menu = g_menu_new (); - - item = g_menu_item_new (_("About This Computer"), "indicator.about"); - g_menu_append_item (menu, item); - g_object_unref (G_OBJECT(item)); - - item = g_menu_item_new (_("Ubuntu Help"), "indicator.help"); - g_menu_append_item (menu, item); - g_object_unref (G_OBJECT(item)); - + g_menu_append (menu, _("About This Computer"), "indicator.about"); + g_menu_append (menu, _("Ubuntu Help"), "indicator.help"); return G_MENU_MODEL (menu); } @@ -296,21 +288,12 @@ static GMenuModel * create_settings_section (IndicatorSessionService * self) { GMenu * menu; - GMenuItem * item; priv_t * p = self->priv; menu = g_menu_new (); - - item = g_menu_item_new (_("System Settings\342\200\246"), "indicator.settings"); - g_menu_append_item (menu, item); - g_object_unref (G_OBJECT(item)); - + g_menu_append (menu, _("System Settings\342\200\246"), "indicator.settings"); if (indicator_session_actions_has_online_account_error (p->backend_actions)) - { - item = g_menu_item_new (_("Online Accounts\342\200\246"), "indicator.online-accounts"); - g_menu_append_item (menu, item); - g_object_unref (G_OBJECT(item)); - } + g_menu_append (menu, _("Online Accounts\342\200\246"), "indicator.online-accounts"); return G_MENU_MODEL (menu); } @@ -478,11 +461,7 @@ create_switch_section (IndicatorSessionService * self) g_object_unref (G_OBJECT(item)); if (indicator_session_guest_is_allowed (p->backend_guest)) - { - item = g_menu_item_new (_("Guest Session"), "indicator.switch-to-guest"); - g_menu_append_item (menu, item); - g_object_unref (G_OBJECT(item)); - } + g_menu_append (menu, _("Guest Session"), "indicator.switch-to-guest"); /* build an array of all the users we know of */ users = g_ptr_array_new (); @@ -519,7 +498,6 @@ static GMenuModel * create_session_section (IndicatorSessionService * self) { GMenu * menu; - GMenuItem * item; const priv_t * const p = self->priv; GSettings * const s = p->indicator_settings; const gboolean ellipsis = use_ellipsis (self); @@ -528,40 +506,26 @@ create_session_section (IndicatorSessionService * self) if (indicator_session_actions_can_logout (p->backend_actions) && !g_settings_get_boolean (s, "suppress-logout-menuitem")) { - item = g_menu_item_new (ellipsis ? _("Log Out\342\200\246") - : _("Log Out"), "indicator.logout"); - g_menu_append_item (menu, item); - g_object_unref (G_OBJECT(item)); + const char * label = ellipsis ? _("Log Out\342\200\246") : _("Log Out"); + g_menu_append (menu, label, "indicator.logout"); } if (indicator_session_actions_can_suspend (p->backend_actions)) - { - item = g_menu_item_new (_("Suspend"), "indicator.suspend"); - g_menu_append_item (menu, item); - g_object_unref (G_OBJECT(item)); - } + g_menu_append (menu, _("Suspend"), "indicator.suspend"); if (indicator_session_actions_can_hibernate (p->backend_actions)) - { - item = g_menu_item_new (_("Hibernate"), "indicator.hibernate"); - g_menu_append_item (menu, item); - g_object_unref (G_OBJECT(item)); - } + g_menu_append (menu, _("Hibernate"), "indicator.hibernate"); if (!g_settings_get_boolean (s, "suppress-restart-menuitem")) { - item = g_menu_item_new (ellipsis ? _("Restart\342\200\246") - : _("Restart"), "indicator.restart"); - g_menu_append_item (menu, item); - g_object_unref (G_OBJECT(item)); + const char * label = ellipsis ? _("Restart\342\200\246") : _("Restart"); + g_menu_append (menu, label, "indicator.restart"); } if (!g_settings_get_boolean (s, "suppress-shutdown-menuitem")) { - item = g_menu_item_new (ellipsis ? _("Shutdown\342\200\246") - : _("Shutdown"), "indicator.shutdown"); - g_menu_append_item (menu, item); - g_object_unref (G_OBJECT(item)); + const char * label = ellipsis ? _("Shutdown\342\200\246") : _("Shutdown"); + g_menu_append (menu, label, "indicator.shutdown"); } return G_MENU_MODEL (menu); -- cgit v1.2.3 From 033cc134729679757e96715e32e0d517143ef49e Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 18 Apr 2013 10:26:20 -0500 Subject: add a small comment explaining replace_section() --- src/service.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/service.c b/src/service.c index e62250e..2206621 100644 --- a/src/service.c +++ b/src/service.c @@ -741,8 +741,13 @@ init_gactions (IndicatorSessionService * self) **** ***/ +/** + * A small helper function for rebuild_now(). + * - removes the previous section + * - adds and unrefs the new section + */ static void -replace_section (GMenu * parent, int pos, GMenuModel * new_section) +rebuild_section (GMenu * parent, int pos, GMenuModel * new_section) { g_menu_remove (parent, pos); g_menu_insert_section (parent, pos, NULL, new_section); @@ -763,24 +768,24 @@ rebuild_now (IndicatorSessionService * self, int sections) if (sections & SECTION_ADMIN) { - replace_section (desktop->submenu, 0, create_admin_section()); + rebuild_section (desktop->submenu, 0, create_admin_section()); } if (sections & SECTION_SETTINGS) { - replace_section (desktop->submenu, 1, create_settings_section(self)); + rebuild_section (desktop->submenu, 1, create_settings_section(self)); } if (sections & SECTION_SWITCH) { - replace_section (desktop->submenu, 2, create_switch_section(self)); + rebuild_section (desktop->submenu, 2, create_switch_section(self)); update_switch_actions (self); } if (sections & SECTION_SESSION) { - replace_section (desktop->submenu, 3, create_session_section(self)); - replace_section (greeter->submenu, 0, create_session_section(self)); + rebuild_section (desktop->submenu, 3, create_session_section(self)); + rebuild_section (greeter->submenu, 0, create_session_section(self)); } } -- cgit v1.2.3 From d79745bdb2e9bbd02e162a5209de9f227d1dbbc3 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 18 Apr 2013 10:29:50 -0500 Subject: in rebuild_soon(), add a comment explaining the 500 msec interval --- src/service.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/service.c b/src/service.c index 2206621..2a10290 100644 --- a/src/service.c +++ b/src/service.c @@ -808,6 +808,10 @@ rebuild_soon (IndicatorSessionService * self, int section) if (p->rebuild_id == 0) { + /* Change events seem to come over the bus in small bursts. This msec + value is an arbitrary number that tries to be large enough to fold + multiple events into a single rebuild, but small enough that the + user won't notice any lag. */ static const int REBUILD_INTERVAL_MSEC = 500; p->rebuild_id = g_timeout_add (REBUILD_INTERVAL_MSEC, -- cgit v1.2.3 From 67218e58889b101ceb5a50bcb40c37045fb2855d Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 18 Apr 2013 11:13:03 -0500 Subject: indicator-session-service should exit when it loses ownership of its name on the bus. --- src/main.c | 9 +++++++++ src/service.c | 23 ++++++++++++++++++++++- src/service.h | 7 +++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 17b50b4..4511fce 100644 --- a/src/main.c +++ b/src/main.c @@ -60,6 +60,13 @@ parse_command_line (int * argc, char *** argv) **** ***/ +static void +on_name_lost (gpointer instance, gpointer loop) +{ + g_debug ("exiting: service couldn't acquire or lost ownership of busname"); + g_main_loop_quit ((GMainLoop*)loop); +} + int main (int argc, char ** argv) { @@ -76,6 +83,8 @@ main (int argc, char ** argv) /* run */ service = indicator_session_service_new (replace); loop = g_main_loop_new (NULL, FALSE); + g_signal_connect (service, INDICATOR_SESSION_SERVICE_SIGNAL_NAME_LOST, + G_CALLBACK(on_name_lost), loop); g_main_loop_run (loop); /* cleanup */ diff --git a/src/service.c b/src/service.c index 2a10290..bcd88ff 100644 --- a/src/service.c +++ b/src/service.c @@ -37,6 +37,15 @@ G_DEFINE_TYPE (IndicatorSessionService, indicator_session_service, G_TYPE_OBJECT) +/* signals enum */ +enum +{ + NAME_LOST, + LAST_SIGNAL +}; + +static guint signals[LAST_SIGNAL] = { 0 }; + enum { PROP_0, @@ -910,9 +919,13 @@ on_name_lost (GDBusConnection * connection G_GNUC_UNUSED, const gchar * name, gpointer gself) { + IndicatorSessionService * self = INDICATOR_SESSION_SERVICE (gself); + g_debug ("%s %s name lost %s", G_STRLOC, G_STRFUNC, name); - unexport (INDICATOR_SESSION_SERVICE (gself)); + unexport (self); + + g_signal_emit (self, signals[NAME_LOST], 0, NULL); } /*** @@ -1133,6 +1146,14 @@ indicator_session_service_class_init (IndicatorSessionServiceClass * klass) g_type_class_add_private (klass, sizeof (IndicatorSessionServicePrivate)); + signals[NAME_LOST] = g_signal_new (INDICATOR_SESSION_SERVICE_SIGNAL_NAME_LOST, + G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (IndicatorSessionServiceClass, name_lost), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + properties[PROP_0] = NULL; properties[PROP_REPLACE] = g_param_spec_boolean ("replace", diff --git a/src/service.h b/src/service.h index 2a78855..3fad6bf 100644 --- a/src/service.h +++ b/src/service.h @@ -36,6 +36,9 @@ typedef struct _IndicatorSessionService IndicatorSessionService; typedef struct _IndicatorSessionServiceClass IndicatorSessionServiceClass; typedef struct _IndicatorSessionServicePrivate IndicatorSessionServicePrivate; +/* signal keys */ +#define INDICATOR_SESSION_SERVICE_SIGNAL_NAME_LOST "name-lost" + /** * The Indicator Session Service. */ @@ -49,6 +52,10 @@ struct _IndicatorSessionService struct _IndicatorSessionServiceClass { GObjectClass parent_class; + + /* signals */ + + void (* name_lost)(IndicatorSessionService * self); }; /*** -- cgit v1.2.3 From 348a5c53f4ca0d1ee197bc0822f0c8d712cd8972 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 18 Apr 2013 11:19:05 -0500 Subject: in indicator_session_service_init(), don't leak a GCancellable --- src/service.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/service.c b/src/service.c index bcd88ff..14d41cd 100644 --- a/src/service.c +++ b/src/service.c @@ -108,6 +108,7 @@ struct _IndicatorSessionServicePrivate guint rebuild_id; int rebuild_flags; GDBusConnection * conn; + GCancellable * cancellable; gboolean replace; }; @@ -950,9 +951,10 @@ indicator_session_service_init (IndicatorSessionService * self) self->priv = p; /* init the backend objects */ - backend_get (g_cancellable_new (), &p->backend_actions, - &p->backend_users, - &p->backend_guest); + p->cancellable = g_cancellable_new (); + backend_get (p->cancellable, &p->backend_actions, + &p->backend_users, + &p->backend_guest); /* init our key-to-User table */ p->users = g_hash_table_new_full (g_str_hash, @@ -1102,6 +1104,12 @@ my_dispose (GObject * o) unexport (self); + if (p->cancellable != NULL) + { + g_cancellable_cancel (p->cancellable); + g_clear_object (&p->cancellable); + } + if (p->rebuild_id) { g_source_remove (p->rebuild_id); -- cgit v1.2.3 From 75d79800ffbc0bdc8598b2b34164c4dabc9888c8 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 18 Apr 2013 11:25:13 -0500 Subject: in the service's dispose() function, unown the busname before unexporting the actions and menus. --- src/service.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/service.c b/src/service.c index 14d41cd..9a4e561 100644 --- a/src/service.c +++ b/src/service.c @@ -1102,6 +1102,12 @@ my_dispose (GObject * o) IndicatorSessionService * self = INDICATOR_SESSION_SERVICE(o); priv_t * p = self->priv; + if (p->own_id) + { + g_bus_unown_name (p->own_id); + p->own_id = 0; + } + unexport (self); if (p->cancellable != NULL) @@ -1116,12 +1122,6 @@ my_dispose (GObject * o) p->rebuild_id = 0; } - if (p->own_id) - { - g_bus_unown_name (p->own_id); - p->own_id = 0; - } - g_clear_pointer (&p->users, g_hash_table_destroy); g_clear_object (&p->backend_users); g_clear_object (&p->backend_guest); -- cgit v1.2.3 From 6ff4e525b7f1a090450b3ff40cff082888250323 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 18 Apr 2013 11:33:20 -0500 Subject: remove #if 0 code --- src/backend-dbus/guest.c | 34 ---------------------------------- src/backend-dbus/users.c | 26 -------------------------- 2 files changed, 60 deletions(-) diff --git a/src/backend-dbus/guest.c b/src/backend-dbus/guest.c index 516ba00..1559aa8 100644 --- a/src/backend-dbus/guest.c +++ b/src/backend-dbus/guest.c @@ -379,30 +379,6 @@ set_display_manager_seat (IndicatorSessionGuestDbus * self, DisplayManagerSeat * } } -#if 0 -static void -on_display_manager_seat_proxy_ready (GObject * o, GAsyncResult * res, gpointer gself) -{ - GError * err; - DisplayManagerSeat * seat; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - err = NULL; - seat = display_manager_seat_proxy_new_for_bus_finish (res, &err); - if (err != NULL) - { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); - g_error_free (err); - } - else - { - set_display_manager_seat (INDICATOR_SESSION_GUEST_DBUS(gself), seat); - } - - g_clear_object (&seat); -} -#endif - static void on_switch_to_guest_done (GObject * o, GAsyncResult * res, gpointer unused G_GNUC_UNUSED) { @@ -529,16 +505,6 @@ indicator_session_guest_dbus_init (IndicatorSessionGuestDbus * self) IndicatorSessionGuestDbusPriv); p->cancellable = g_cancellable_new (); self->priv = p; - -#if 0 - display_manager_seat_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - "org.freedesktop.DisplayManager", - g_getenv ("XDG_SEAT_PATH"), - self->priv->cancellable, - on_display_manager_seat_proxy_ready, - self); -#endif } /*** diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 4798d33..34e0c97 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -229,21 +229,6 @@ set_account_manager (IndicatorSessionUsersDbus * self, Accounts * a) } } -#if 0 -static void -create_accounts_proxy (IndicatorSessionUsersDbus * self) -{ - const char * name = "org.freedesktop.Accounts"; - const char * path = "/org/freedesktop/Accounts"; - GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES; - - accounts_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - flags, name, path, - self->priv->cancellable, - on_accounts_proxy_ready, self); -} -#endif - /** * SEAT / SESSION TRACKING * @@ -771,17 +756,6 @@ indicator_session_users_dbus_init (IndicatorSessionUsersDbus * self) p->uid_to_sessions = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, (GDestroyNotify)g_hash_table_destroy); - -#if 0 - console_kit_manager_proxy_new_for_bus ( - G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - "org.freedesktop.ConsoleKit", - "/org/freedesktop/ConsoleKit/Manager", - p->cancellable, - on_console_kit_manager_proxy_ready, - self); -#endif } /*** -- cgit v1.2.3 From 22a20308a602d2bbe7343c43564ee34a734ec4bc Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 18 Apr 2013 11:38:24 -0500 Subject: remove unnecessary dependencies from debian/control --- debian/control | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/debian/control b/debian/control index 458ffef..7e4b609 100644 --- a/debian/control +++ b/debian/control @@ -6,17 +6,11 @@ Build-Depends: debhelper (>= 9), dh-autoreconf, dh-translations, intltool, - gnome-common, libgtest-dev, - libxorg-gtest-dev, libdbustest1-dev, dbus-test-runner, - libgtk-3-dev, libglib2.0-dev (>= 2.35.4), - gnome-doc-utils, - libindicator3-dev (>= 0.3.90), - libdbusmenu-glib-dev (>= 0.5.90), - libdbusmenu-gtk3-dev (>= 0.5.90), + gnome-doc-utils Standards-Version: 3.9.3 Homepage: https://launchpad.net/indicator-session # If you aren't a member of ~indicator-applet-developers but need to upload -- cgit v1.2.3 From 29befc58e1f1fd61d4d6d1a6db024d32182f7488 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 18 Apr 2013 11:41:22 -0500 Subject: g_object_unref doesn't need a G_OBJECT() cast --- src/service.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/service.c b/src/service.c index 9a4e561..2e42bd0 100644 --- a/src/service.c +++ b/src/service.c @@ -468,7 +468,7 @@ create_switch_section (IndicatorSessionService * self) g_menu_item_set_attribute (item, "accel", "s", str); g_free (str); g_menu_append_item (menu, item); - g_object_unref (G_OBJECT(item)); + g_object_unref (item); if (indicator_session_guest_is_allowed (p->backend_guest)) g_menu_append (menu, _("Guest Session"), "indicator.switch-to-guest"); @@ -496,7 +496,7 @@ create_switch_section (IndicatorSessionService * self) item = g_menu_item_new (u->real_name, NULL); g_menu_item_set_action_and_target (item, "indicator.switch-to-user", "s", u->user_name); g_menu_append_item (menu, item); - g_object_unref (G_OBJECT(item)); + g_object_unref (item); } /* cleanup */ @@ -571,19 +571,19 @@ create_menu (IndicatorSessionService * self, int form_factor) for (i=0; ipriv->menus[form_factor].menu = menu; self->priv->menus[form_factor].submenu = submenu; @@ -761,7 +761,7 @@ rebuild_section (GMenu * parent, int pos, GMenuModel * new_section) { g_menu_remove (parent, pos); g_menu_insert_section (parent, pos, NULL, new_section); - g_object_unref (G_OBJECT(new_section)); + g_object_unref (new_section); } static void -- cgit v1.2.3 From 460b015be860290cf06e9e08a99a51c52c770717 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 18 Apr 2013 12:24:58 -0500 Subject: better documentation for indicator_session_users_get_keys() and indicator_session_users_get_user() --- src/users.h | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/users.h b/src/users.h index 31ee39e..f2d7404 100644 --- a/src/users.h +++ b/src/users.h @@ -124,11 +124,21 @@ void indicator_session_users_notify_is_live_session (IndicatorSessionUsers * sel gboolean indicator_session_users_is_live_session (IndicatorSessionUsers * users); -/* get a list of user keys */ +/** + * Get a list of user keys. + * + * Return value: (transfer full): a NULL-terminated array of user keys. + * Free with g_strfreev() when done. + */ GStrv indicator_session_users_get_keys (IndicatorSessionUsers * users); -/* get information about a particular user. - call indicator_session_user_free() when done with the returned struct. */ +/** + * Get information about a particular user. + * + * Return value: (transfer full): an IndicatorSessionUser struct + * populated with information about the specified user. + * Free with indicator_session_user_free() when done. + */ IndicatorSessionUser * indicator_session_users_get_user (IndicatorSessionUsers * users, const gchar * key); -- cgit v1.2.3 From 6729218076bdfebfc5b5c48742abb72a3a899314 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 18 Apr 2013 12:30:14 -0500 Subject: refer to profiles as profiles instead of forms. --- src/service.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/service.c b/src/service.c index 2e42bd0..d912176 100644 --- a/src/service.c +++ b/src/service.c @@ -67,18 +67,18 @@ enum enum { - FORM_DESKTOP, - FORM_GREETER, - N_FORMS + PROFILE_DESKTOP, + PROFILE_GREETER, + N_PROFILES }; -static const char * const menu_names[N_FORMS] = +static const char * const menu_names[N_PROFILES] = { "desktop", "desktop_greeter" }; -struct FormMenuInfo +struct ProfileMenuInfo { /* the root level -- the header is the only child of this */ GMenu * menu; @@ -100,7 +100,7 @@ struct _IndicatorSessionServicePrivate GSettings * keybinding_settings; GSimpleActionGroup * actions; guint actions_export_id; - struct FormMenuInfo menus[N_FORMS]; + struct ProfileMenuInfo menus[N_PROFILES]; GSimpleAction * header_action; GSimpleAction * user_switcher_action; GSimpleAction * guest_switcher_action; @@ -542,7 +542,7 @@ create_session_section (IndicatorSessionService * self) } static void -create_menu (IndicatorSessionService * self, int form_factor) +create_menu (IndicatorSessionService * self, int profile) { GMenu * menu; GMenu * submenu; @@ -551,17 +551,17 @@ create_menu (IndicatorSessionService * self, int form_factor) int i; int n = 0; - g_assert (0<=form_factor && form_factorpriv->menus[form_factor].menu == NULL); + g_assert (0<=profile && profilepriv->menus[profile].menu == NULL); - if (form_factor == FORM_DESKTOP) + if (profile == PROFILE_DESKTOP) { sections[n++] = create_admin_section (); sections[n++] = create_settings_section (self); sections[n++] = create_switch_section (self); sections[n++] = create_session_section (self); } - else if (form_factor == FORM_GREETER) + else if (profile == PROFILE_GREETER) { sections[n++] = create_session_section (self); } @@ -585,8 +585,8 @@ create_menu (IndicatorSessionService * self, int form_factor) g_menu_append_item (menu, header); g_object_unref (header); - self->priv->menus[form_factor].menu = menu; - self->priv->menus[form_factor].submenu = submenu; + self->priv->menus[profile].menu = menu; + self->priv->menus[profile].submenu = submenu; } /*** @@ -768,8 +768,8 @@ static void rebuild_now (IndicatorSessionService * self, int sections) { priv_t * p = self->priv; - struct FormMenuInfo * desktop = &p->menus[FORM_DESKTOP]; - struct FormMenuInfo * greeter = &p->menus[FORM_GREETER]; + struct ProfileMenuInfo * desktop = &p->menus[PROFILE_DESKTOP]; + struct ProfileMenuInfo * greeter = &p->menus[PROFILE_GREETER]; if (sections & SECTION_HEADER) { @@ -864,10 +864,10 @@ on_bus_acquired (GDBusConnection * connection, } /* export the menus */ - for (i=0; imenus[i]; + struct ProfileMenuInfo * menu = &p->menus[i]; if (menu->menu == NULL) create_menu (self, i); @@ -896,7 +896,7 @@ unexport (IndicatorSessionService * self) priv_t * p = self->priv; /* unexport the menus */ - for (i=0; ipriv->menus[i].export_id; @@ -1130,7 +1130,7 @@ my_dispose (GObject * o) g_clear_object (&p->keybinding_settings); g_clear_object (&p->actions); - for (i=0; imenus[i].menu); g_clear_object (&p->header_action); -- cgit v1.2.3 From 08be3e1b81cb6ba58073929be8121acb37078680 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 18 Apr 2013 12:41:55 -0500 Subject: add session.indicator to data/ --- data/session.indicator | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 data/session.indicator diff --git a/data/session.indicator b/data/session.indicator new file mode 100644 index 0000000..b5f6802 --- /dev/null +++ b/data/session.indicator @@ -0,0 +1,4 @@ +[Indicator Service] +Name=indicator-session +BusName=com.canonical.indicator.session-test +ObjectPath=/com/canonical/indicator/session -- cgit v1.2.3 From 2babf3e334649031a4e8fff308358f6974ceb155 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Thu, 23 May 2013 18:48:56 -0400 Subject: Set x-canonical-type for user and guest menu items --- README | 4 ++-- src/service.c | 11 ++++++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/README b/README index 420541e..29a135f 100644 --- a/README +++ b/README @@ -12,7 +12,7 @@ As per the https://wiki.ubuntu.com/SystemMenu specification, both need four visual components: (1) an Active Session Mark, the user's (2) icon, (3) name, and (4) a Logged In Mark. -== User menuitems can be recognized by their "indicator.switch-to-user" action. +== User menuitems have "x-canonical-type" set to "indicator.user-menu-item" Their four visual components are determined by: 1. You can test for the Action Session Mark by checking the action's state. @@ -30,7 +30,7 @@ and (4) a Logged In Mark. an array of usernames. If the array contains the username in this menuitem's "target" attribute, show the Logged In Mark. -== The Guest switcher can be recognized by its "indicator.switch-to-guest" +== The Guest switcher has "x-canonical-type" set to "indicator.guest-menu-item" action. Its four visual components are determined by: 1. You can test for the Active Session Mark by checking the action's state. diff --git a/src/service.c b/src/service.c index d912176..59728d1 100644 --- a/src/service.c +++ b/src/service.c @@ -471,7 +471,15 @@ create_switch_section (IndicatorSessionService * self) g_object_unref (item); if (indicator_session_guest_is_allowed (p->backend_guest)) - g_menu_append (menu, _("Guest Session"), "indicator.switch-to-guest"); + { + GMenuItem *item; + + item = g_menu_item_new (_("Guest Session"), "indicator.switch-to-guest"); + g_menu_item_set_attribute (item, "x-canonical-type", "s", "indicator.guest-menu-item"); + g_menu_append_item (menu, item); + + g_object_unref (item); + } /* build an array of all the users we know of */ users = g_ptr_array_new (); @@ -495,6 +503,7 @@ create_switch_section (IndicatorSessionService * self) const IndicatorSessionUser * u = g_ptr_array_index (users, i); item = g_menu_item_new (u->real_name, NULL); g_menu_item_set_action_and_target (item, "indicator.switch-to-user", "s", u->user_name); + g_menu_item_set_attribute (item, "x-canonical-type", "s", "indicator.user-menu-item"); g_menu_append_item (menu, item); g_object_unref (item); } -- cgit v1.2.3 From c84cb6dac25783131ee21fba453db1d6fc708f59 Mon Sep 17 00:00:00 2001 From: Jeremy Bicha Date: Fri, 14 Jun 2013 22:03:59 -0400 Subject: recommend gnome-screensaver --- debian/control | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/debian/control b/debian/control index f65df35..b9ffa9f 100644 --- a/debian/control +++ b/debian/control @@ -32,7 +32,8 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, systemd-services, gnome-settings-daemon, -Recommends: indicator-applet (>= 0.2) | indicator-renderer, +Recommends: indicator-applet (>= 0.2) | indicator-renderer, + gnome-screensaver Suggests: lightdm Description: indicator showing session management, status and user switching This indicator is designed to be placed on the right side of a panel and -- cgit v1.2.3 From 1f747c84219f55374aa65c8483c026435b659553 Mon Sep 17 00:00:00 2001 From: Mathieu Trudel-Lapierre Date: Mon, 17 Jun 2013 09:42:46 -0400 Subject: Fix linking with gtest, which expects pthreads. --- tests/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index 071f684..f4f853e 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -39,8 +39,8 @@ integrationcheck_PROGRAMS += test-service test_service_SOURCES = test-service.cc test_service_LDADD = \ $(TEST_SERVICE_LIBS) \ - $(XORG_GTEST_LDFLAGS) \ - libgtest.a + libgtest.a \ + $(XORG_GTEST_LDFLAGS) test_service_CPPFLAGS = \ -DSCHEMA_DIR="\"$(top_builddir)/tests/\"" \ -DINDICATOR_SERVICE_DIR="\"$(abs_builddir)\"" \ -- cgit v1.2.3 From 963589405fd798d1327fbc454eb7c31c54f760bb Mon Sep 17 00:00:00 2001 From: Automatic PS uploader Date: Wed, 19 Jun 2013 02:01:26 +0000 Subject: Releasing 12.10.5daily13.06.19-0ubuntu1, based on r393 --- debian/changelog | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/debian/changelog b/debian/changelog index 32a029d..ef1cd53 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,16 @@ +indicator-session (12.10.5daily13.06.19-0ubuntu1) saucy; urgency=low + + [ Mathieu Trudel-Lapierre ] + * Fix linking with pthreads for gtest. + + [ Jeremy Bicha ] + * recommend gnome-screensaver for the Lock Screen feature. + + [ Ubuntu daily release ] + * Automatic snapshot from revision 393 + + -- Ubuntu daily release Wed, 19 Jun 2013 02:01:25 +0000 + indicator-session (12.10.5daily13.05.06.1-0ubuntu1) saucy; urgency=low [ Iain Lane ] -- cgit v1.2.3 From a4c536391abbd2057ddbcd8d0bc83a9e67de3273 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 19 Jun 2013 18:16:25 -0500 Subject: in service.c, remove unnecesssary locale #include --- src/service.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/service.c b/src/service.c index d912176..7852adf 100644 --- a/src/service.c +++ b/src/service.c @@ -17,8 +17,6 @@ * with this program. If not, see . */ -#include - #include #include -- cgit v1.2.3 From 093aed6a5e8c35bfe5a3e187fed3e293e2d12183 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 19 Jun 2013 18:16:56 -0500 Subject: in our async callbacks, don't call g_warning() if the task was cancelled by the client --- src/backend-dbus/actions.c | 13 +++---------- src/backend-dbus/guest.c | 30 ++++++++++++++++-------------- src/backend-dbus/users.c | 28 +++++++++++++++++++++------- src/backend-dbus/utils.c | 28 ++++++++++++++++++---------- 4 files changed, 58 insertions(+), 41 deletions(-) diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index 8994710..bc196f2 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -68,7 +68,9 @@ log_and_clear_error (GError ** err, const char * loc, const char * func) { if (*err) { - g_warning ("%s %s: %s", loc, func, (*err)->message); + if (!g_error_matches (*err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", loc, func, (*err)->message); + g_clear_error (err); } } @@ -591,14 +593,6 @@ my_dispose (GObject * o) G_OBJECT_CLASS (indicator_session_actions_dbus_parent_class)->dispose (o); } -static void -my_finalize (GObject * o) -{ - /*IndicatorSessionActionsDbus * u = INDICATOR_SESSION_ACTIONS_DBUS (o);*/ - - G_OBJECT_CLASS (indicator_session_actions_dbus_parent_class)->finalize (o); -} - /*** **** GObject Boilerplate ***/ @@ -612,7 +606,6 @@ indicator_session_actions_dbus_class_init (IndicatorSessionActionsDbusClass * kl object_class = G_OBJECT_CLASS (klass); object_class->dispose = my_dispose; - object_class->finalize = my_finalize; actions_class = INDICATOR_SESSION_ACTIONS_CLASS (klass); actions_class->can_lock = my_can_lock; diff --git a/src/backend-dbus/guest.c b/src/backend-dbus/guest.c index 1559aa8..317152d 100644 --- a/src/backend-dbus/guest.c +++ b/src/backend-dbus/guest.c @@ -95,7 +95,9 @@ on_active_uid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gse if (err != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); } else @@ -140,7 +142,10 @@ on_active_session_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gp if (err != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + + g_error_free (err); } else { @@ -253,7 +258,9 @@ on_user_proxy_ready (GObject * o G_GNUC_UNUSED, if (err != NULL) { - g_warning ("%s: %s", G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s: %s", G_STRFUNC, err->message); + g_error_free (err); } else if (is_guest (user)) @@ -290,7 +297,9 @@ on_user_list_ready (GObject * o, GAsyncResult * res, gpointer gself) accounts_call_list_cached_users_finish (ACCOUNTS(o), &paths, res, &err); if (err != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); } else @@ -389,7 +398,9 @@ on_switch_to_guest_done (GObject * o, GAsyncResult * res, gpointer unused G_GNUC display_manager_seat_call_switch_to_guest_finish (DISPLAY_MANAGER_SEAT(o), res, &err); if (err != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); } } @@ -418,14 +429,6 @@ my_dispose (GObject * o) G_OBJECT_CLASS (indicator_session_guest_dbus_parent_class)->dispose (o); } -static void -my_finalize (GObject * o) -{ - /*IndicatorSessionGuestDbus * u = INDICATOR_SESSION_GUEST_DBUS (o);*/ - - G_OBJECT_CLASS (indicator_session_guest_dbus_parent_class)->finalize (o); -} - static gboolean my_is_allowed (IndicatorSessionGuest * self) { @@ -483,7 +486,6 @@ indicator_session_guest_dbus_class_init (IndicatorSessionGuestDbusClass * klass) object_class = G_OBJECT_CLASS (klass); object_class->dispose = my_dispose; - object_class->finalize = my_finalize; guest_class = INDICATOR_SESSION_GUEST_CLASS (klass); guest_class->is_allowed = my_is_allowed; diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 34e0c97..6d9ada6 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -154,7 +154,9 @@ on_user_proxy_ready (GObject * o G_GNUC_UNUSED, user = accounts_user_proxy_new_for_bus_finish (res, &err); if (err != NULL) { - g_warning ("%s: %s", G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s: %s", G_STRFUNC, err->message); + g_error_free (err); } else @@ -187,7 +189,9 @@ on_user_list_ready (GObject * o, GAsyncResult * res, gpointer gself) accounts_call_list_cached_users_finish (ACCOUNTS(o), &paths, res, &err); if (err != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); } else @@ -317,7 +321,9 @@ on_session_proxy_uid_ready (GObject * o, console_kit_session_call_get_unix_user_finish (session, &uid, res, &err); if (err != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); } else if (uid) @@ -347,7 +353,9 @@ on_session_x11_display_ready (GObject * o, console_kit_session_call_get_x11_display_finish (session, &gui, res, &err); if (err != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); } else @@ -378,7 +386,9 @@ on_session_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer session = console_kit_session_proxy_new_finish (res, &err); if (err != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); } else if (session != NULL) @@ -417,7 +427,9 @@ on_session_list_ready (GObject * o, GAsyncResult * res, gpointer gself) &sessions, res, &err); if (err != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); } else @@ -508,7 +520,9 @@ on_seat_active_session_ready (GObject * o, GAsyncResult * res, gpointer gself) console_kit_seat_call_get_active_session_finish (seat, &ssid, res, &err); if (err != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); } else if (ssid != NULL) diff --git a/src/backend-dbus/utils.c b/src/backend-dbus/utils.c index 86a5e5a..c8abc2b 100644 --- a/src/backend-dbus/utils.c +++ b/src/backend-dbus/utils.c @@ -91,7 +91,8 @@ on_user_proxy_ready (GObject * o G_GNUC_UNUSED, if (data->error != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } else { @@ -112,7 +113,8 @@ on_user_path_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdat if (data->error != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } else if (path != NULL) { @@ -141,7 +143,8 @@ on_uid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) console_kit_session_call_get_unix_user_finish (data->current_session, &uid, res, &data->error); if (data->error != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } else if (uid) { @@ -165,7 +168,7 @@ on_seat_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gda data->current_seat = console_kit_seat_proxy_new_for_bus_finish (res, &data->error); - if (data->error != NULL) + if (data->error && !g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); finish_callback (data); @@ -182,7 +185,8 @@ on_sid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) if (data->error != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } else if (sid != NULL) { @@ -210,7 +214,8 @@ on_session_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer data->current_session = console_kit_session_proxy_new_finish (res, &data->error); if (data->error != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } else { @@ -243,7 +248,8 @@ on_current_session_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointe &data->error); if (data->error != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } else if (ssid) { @@ -275,7 +281,8 @@ on_display_manager_seat_proxy_ready (GObject * o G_GNUC_UNUSED, if (data->error != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } else if (seat != NULL) { @@ -302,7 +309,8 @@ on_console_kit_manager_proxy_ready (GObject * o G_GNUC_UNUSED, if (data->error != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } else { @@ -330,7 +338,7 @@ on_accounts_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer { data->account_manager = accounts_proxy_new_for_bus_finish (res, &data->error); - if (data->error != NULL) + if (data->error && !g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); } -- cgit v1.2.3 From 0c5a240c6fb66d4b2dd620c81d48a065bedeb7f7 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 19 Jun 2013 18:22:32 -0500 Subject: silence unused variable warning --- tests/backend-mock-guest.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/backend-mock-guest.c b/tests/backend-mock-guest.c index 0428783..b04c805 100644 --- a/tests/backend-mock-guest.c +++ b/tests/backend-mock-guest.c @@ -71,7 +71,7 @@ my_is_active (IndicatorSessionGuest * self) } static void -my_switch_to_guest (IndicatorSessionGuest * self) +my_switch_to_guest (IndicatorSessionGuest * self G_GNUC_UNUSED) { g_message ("%s %s FIXME", G_STRLOC, G_STRFUNC); } -- cgit v1.2.3 From 4df0aceb48e9b3d6c77f6e06c7acde89747ff878 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 19 Jun 2013 18:27:08 -0500 Subject: use the production dbus name --- data/com.canonical.indicator.session | 10 ++++++++++ data/session.indicator | 4 ---- src/service.c | 3 +-- tests/test-service.cc | 6 +++--- 4 files changed, 14 insertions(+), 9 deletions(-) create mode 100644 data/com.canonical.indicator.session delete mode 100644 data/session.indicator diff --git a/data/com.canonical.indicator.session b/data/com.canonical.indicator.session new file mode 100644 index 0000000..fce3554 --- /dev/null +++ b/data/com.canonical.indicator.session @@ -0,0 +1,10 @@ +[Indicator Service] +Name=indicator-session +ObjectPath=/com/canonical/indicator/session + +[desktop] +ObjectPath=/com/canonical/indicator/session/desktop + +[greeter] +ObjectPath=/com/canonical/indicator/session/greeter + diff --git a/data/session.indicator b/data/session.indicator deleted file mode 100644 index b5f6802..0000000 --- a/data/session.indicator +++ /dev/null @@ -1,4 +0,0 @@ -[Indicator Service] -Name=indicator-session -BusName=com.canonical.indicator.session-test -ObjectPath=/com/canonical/indicator/session diff --git a/src/service.c b/src/service.c index 7852adf..862028b 100644 --- a/src/service.c +++ b/src/service.c @@ -23,8 +23,7 @@ #include "backend.h" #include "service.h" -/* FIXME: remove -test */ -#define BUS_NAME "com.canonical.indicator.session-test" +#define BUS_NAME "com.canonical.indicator.session" #define BUS_PATH "/com/canonical/indicator/session" #define ICON_DEFAULT "system-devices-panel" diff --git a/tests/test-service.cc b/tests/test-service.cc index 058fc3d..76dcd75 100644 --- a/tests/test-service.cc +++ b/tests/test-service.cc @@ -170,7 +170,7 @@ class ServiceTest: public GTestDBusFixture // wait for the service to show up on the bus const guint watch_id = g_bus_watch_name_on_connection (conn, - "com.canonical.indicator.session-test", + "com.canonical.indicator.session", G_BUS_NAME_WATCHER_FLAGS_NONE, on_name_appeared, // quits the loop NULL, this, NULL); @@ -182,10 +182,10 @@ class ServiceTest: public GTestDBusFixture // get the actions & menus that the service exported. action_group = g_dbus_action_group_get (conn, - "com.canonical.indicator.session-test", + "com.canonical.indicator.session", "/com/canonical/indicator/session"); menu_model = g_dbus_menu_model_get (conn, - "com.canonical.indicator.session-test", + "com.canonical.indicator.session", "/com/canonical/indicator/session/desktop"); // the actions are added asynchronously, so wait for the actions if (!g_action_group_has_action (G_ACTION_GROUP(action_group), "about")) -- cgit v1.2.3 From bb645114401d22af45b14294697e1e294cf52e34 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 19 Jun 2013 18:31:27 -0500 Subject: add short-term TODO --- TODO | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 TODO diff --git a/TODO b/TODO new file mode 100644 index 0000000..a9feedc --- /dev/null +++ b/TODO @@ -0,0 +1,8 @@ +code + - fix deprecated/dead APIs use in backend + +cmake + - add cmake rule to install .indicator file + - add cmake rule to install dbus service file + - icon installation + - test schema installation -- cgit v1.2.3 From fab2853f35eb108988b5ddb16cd9f6e43de79773 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 20 Jun 2013 13:54:41 -0500 Subject: remove the --replace command-line argument and property as we're using upstart for that --- src/main.c | 42 +++++------------------------------------- src/service.c | 41 +++-------------------------------------- src/service.h | 2 +- tests/test-service.cc | 7 +------ 4 files changed, 10 insertions(+), 82 deletions(-) diff --git a/src/main.c b/src/main.c index 4511fce..8df5e60 100644 --- a/src/main.c +++ b/src/main.c @@ -29,46 +29,16 @@ **** ***/ -static gboolean replace = FALSE; - -static void -parse_command_line (int * argc, char *** argv) -{ - GError * error; - GOptionContext * option_context; - - static GOptionEntry entries[] = - { - { "replace", 'r', 0, G_OPTION_ARG_NONE, &replace, "Replace the currently-running service", NULL }, - { NULL } - }; - - error = NULL; - option_context = g_option_context_new ("- indicator-session service"); - g_option_context_add_main_entries (option_context, entries, GETTEXT_PACKAGE); - if (!g_option_context_parse (option_context, argc, argv, &error)) - { - g_print ("option parsing failed: %s\n", error->message); - g_error_free (error); - exit (EXIT_FAILURE); - } - - g_option_context_free (option_context); -} - -/*** -**** -***/ - static void on_name_lost (gpointer instance, gpointer loop) { - g_debug ("exiting: service couldn't acquire or lost ownership of busname"); - g_main_loop_quit ((GMainLoop*)loop); + g_warning ("exiting: service couldn't acquire, or lost ownership of, busname"); + + g_main_loop_quit (loop); } int -main (int argc, char ** argv) +main (int argc G_GNUC_UNUSED, char ** argv G_GNUC_UNUSED) { GMainLoop * loop; IndicatorSessionService * service; @@ -78,10 +48,8 @@ main (int argc, char ** argv) bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR); textdomain (GETTEXT_PACKAGE); - parse_command_line (&argc, &argv); - /* run */ - service = indicator_session_service_new (replace); + service = indicator_session_service_new (); loop = g_main_loop_new (NULL, FALSE); g_signal_connect (service, INDICATOR_SESSION_SERVICE_SIGNAL_NAME_LOST, G_CALLBACK(on_name_lost), loop); diff --git a/src/service.c b/src/service.c index 862028b..83bfeaa 100644 --- a/src/service.c +++ b/src/service.c @@ -46,7 +46,6 @@ static guint signals[LAST_SIGNAL] = { 0 }; enum { PROP_0, - PROP_REPLACE, PROP_MAX_USERS, PROP_LAST }; @@ -106,8 +105,6 @@ struct _IndicatorSessionServicePrivate int rebuild_flags; GDBusConnection * conn; GCancellable * cancellable; - - gboolean replace; }; typedef IndicatorSessionServicePrivate priv_t; @@ -1013,23 +1010,10 @@ indicator_session_service_init (IndicatorSessionService * self) gp = p->keybinding_settings; g_signal_connect_swapped (gp, "changed::screensaver", G_CALLBACK(rebuild_switch_section_soon), self); -} - -static void -my_constructed (GObject * o) -{ - GBusNameOwnerFlags owner_flags; - IndicatorSessionService * self = INDICATOR_SESSION_SERVICE(o); - - /* own the name in constructed() instead of init() so that - we'll know the value of the 'replace' property */ - owner_flags = G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT; - if (self->priv->replace) - owner_flags |= G_BUS_NAME_OWNER_FLAGS_REPLACE; self->priv->own_id = g_bus_own_name (G_BUS_TYPE_SESSION, BUS_NAME, - owner_flags, + G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT, on_bus_acquired, NULL, on_name_lost, @@ -1051,10 +1035,6 @@ my_get_property (GObject * o, switch (property_id) { - case PROP_REPLACE: - g_value_set_boolean (value, self->priv->replace); - break; - case PROP_MAX_USERS: g_value_set_uint (value, self->priv->max_users); break; @@ -1074,10 +1054,6 @@ my_set_property (GObject * o, switch (property_id) { - case PROP_REPLACE: - self->priv->replace = g_value_get_boolean (value); - break; - case PROP_MAX_USERS: self->priv->max_users = g_value_get_uint (value); rebuild_switch_section_soon (self); @@ -1145,7 +1121,6 @@ indicator_session_service_class_init (IndicatorSessionServiceClass * klass) GObjectClass * object_class = G_OBJECT_CLASS (klass); object_class->dispose = my_dispose; - object_class->constructed = my_constructed; object_class->get_property = my_get_property; object_class->set_property = my_set_property; @@ -1161,14 +1136,6 @@ indicator_session_service_class_init (IndicatorSessionServiceClass * klass) properties[PROP_0] = NULL; - properties[PROP_REPLACE] = g_param_spec_boolean ("replace", - "Replace Service", - "Replace existing service", - FALSE, - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_STATIC_STRINGS); - properties[PROP_MAX_USERS] = g_param_spec_uint ("max-users", "Max Users", "Max visible users", @@ -1181,11 +1148,9 @@ indicator_session_service_class_init (IndicatorSessionServiceClass * klass) } IndicatorSessionService * -indicator_session_service_new (gboolean replace) +indicator_session_service_new (void) { - GObject * o = g_object_new (INDICATOR_TYPE_SESSION_SERVICE, - "replace", replace, - NULL); + GObject * o = g_object_new (INDICATOR_TYPE_SESSION_SERVICE, NULL); return INDICATOR_SESSION_SERVICE (o); } diff --git a/src/service.h b/src/service.h index 3fad6bf..fa870e5 100644 --- a/src/service.h +++ b/src/service.h @@ -64,7 +64,7 @@ struct _IndicatorSessionServiceClass GType indicator_session_service_get_type (void); -IndicatorSessionService * indicator_session_service_new (gboolean replace); +IndicatorSessionService * indicator_session_service_new (void); G_END_DECLS diff --git a/tests/test-service.cc b/tests/test-service.cc index 76dcd75..57b4221 100644 --- a/tests/test-service.cc +++ b/tests/test-service.cc @@ -161,12 +161,7 @@ class ServiceTest: public GTestDBusFixture // Start an IndicatorSessionService and wait for it to appear on the bus. // This way our calls to g_dbus_*_get() in the next paragraph won't activate // a second copy of the service... - service = indicator_session_service_new (true); - - // confirm that the property got set - gboolean replace = FALSE; - g_object_get (service, "replace", &replace, NULL); - ASSERT_TRUE (replace); + service = indicator_session_service_new (); // wait for the service to show up on the bus const guint watch_id = g_bus_watch_name_on_connection (conn, -- cgit v1.2.3 From 22e72bb60a789ba3a48aff737c8816908695b408 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 20 Jun 2013 14:13:28 -0500 Subject: install the .indicator file into the unity/indicators/ dir --- data/CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index 7d213b2..c00b8db 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -9,8 +9,9 @@ include (GNUInstallDirs) configure_file (indicator-session.service.in indicator-session.service) # .indicator file -# (NOOP) -# +install(FILES com.canonical.indicator.session + DESTINATION ${CMAKE_INSTALL_PREFIX}/share/unity/indicators) + # FIXME install files #install(FILES #${CMAKE_CURRENT_BINARY_DIR}/indicator-datetime.service -- cgit v1.2.3 From a5fb857ee48a9022eb1e6c9ea04e0aeff80f445b Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 20 Jun 2013 14:43:23 -0500 Subject: cmake work: properly generate and install the .service file for dbus activation --- CMakeLists.txt | 18 +++++++++++++++++- TODO | 4 ++-- build.sh | 2 +- data/CMakeLists.txt | 12 ++++++------ data/indicator-session.service.in | 2 +- 5 files changed, 27 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f04214..f656cb4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,9 +10,10 @@ set (GETTEXT_PACKAGE ${CMAKE_PROJECT_NAME}) option (enable_tests "Build the package's automatic tests." ON) option (full_warnings "Full compiler warnings." ON) option (enable_lcov "Generate lcov code coverage reports." ON) - +option (LOCAL_INSTALL "Support local installation." OFF) find_package(PkgConfig REQUIRED) +include (GNUInstallDirs) include (FindPkgConfig) include (GdbusCodegen) include (GSettings) @@ -44,6 +45,21 @@ add_custom_target (cppcheck COMMAND cppcheck --enable=all -q --error-exitcode=2 include_directories (${CMAKE_CURRENT_SOURCE_DIR}/src) include_directories (${CMAKE_CURRENT_BINARY_DIR}/src) +# Workaround for libexecdir on debian +if (EXISTS "/etc/debian_version") + set(CMAKE_INSTALL_LIBEXECDIR ${CMAKE_INSTALL_LIBDIR}) + set(CMAKE_INSTALL_FULL_LIBEXECDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBEXECDIR}") +endif() +message("Installing libexec files to ${CMAKE_INSTALL_FULL_LIBEXECDIR}") + +if(${LOCAL_INSTALL}) + set(DBUSSERVICEDIR "${CMAKE_INSTALL_DATADIR}/dbus-1/services/") +else() + EXEC_PROGRAM(${PKG_CONFIG_EXECUTABLE} ARGS dbus-1 --variable session_bus_services_dir OUTPUT_VARIABLE DBUSSERVICEDIR ) +endif() +message("Installing DBus services to ${DBUSSERVICEDIR}") + + add_subdirectory (src) add_subdirectory (data) add_subdirectory (po) diff --git a/TODO b/TODO index f47802a..56c6a68 100644 --- a/TODO +++ b/TODO @@ -4,7 +4,7 @@ code - fix deprecated/dead APIs use in backend cmake - - add cmake rule to install .indicator file - - add cmake rule to install dbus service file + x add cmake rule to install .indicator file + x add cmake rule to install dbus service file - icon installation - test schema installation diff --git a/build.sh b/build.sh index 173ff8c..c98285e 100755 --- a/build.sh +++ b/build.sh @@ -13,6 +13,6 @@ fi echo "Using $BUILD_COMMAND to build" ( cd build - cmake .. $EXTRA_ARGS -DCMAKE_INSTALL_PREFIX=../../install -Dlocal_install=ON + cmake .. $EXTRA_ARGS -DCMAKE_INSTALL_PREFIX=../../install -DLOCAL_INSTALL=ON -DCMAKE_BUILD_TYPE=Debug $BUILD_COMMAND ) diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index c00b8db..84fe66c 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -5,18 +5,18 @@ include (GSettings) add_schemas(clinica-schemas ${CMAKE_SOURCE_DIR}/data/com.canonical.indicator.session.gschema.xml) # .service file -include (GNUInstallDirs) -configure_file (indicator-session.service.in indicator-session.service) +set(SERVICE_NAME "indicator-session.service") +set(SERVICE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${SERVICE_NAME}") +set(pkglibexecdir "${CMAKE_INSTALL_FULL_LIBEXECDIR}/indicator-session") +configure_file ("${CMAKE_CURRENT_SOURCE_DIR}/${SERVICE_NAME}.in" "${SERVICE_PATH}") +install (FILES ${SERVICE_PATH} + DESTINATION ${DBUSSERVICEDIR}) # .indicator file install(FILES com.canonical.indicator.session DESTINATION ${CMAKE_INSTALL_PREFIX}/share/unity/indicators) # FIXME install files -#install(FILES -#${CMAKE_CURRENT_BINARY_DIR}/indicator-datetime.service -#DESTINATION share/indicator-datetime # FIXME to be the real install dir. -#) # #install(FILES #datetime-dialog.ui diff --git a/data/indicator-session.service.in b/data/indicator-session.service.in index a4d10a1..e520e20 100644 --- a/data/indicator-session.service.in +++ b/data/indicator-session.service.in @@ -1,3 +1,3 @@ [D-BUS Service] Name=com.canonical.indicator.session -Exec=@libexecdir@/indicator-session-service +Exec=@pkglibexecdir@/indicator-session-service -- cgit v1.2.3 From 6def7fceae5ea55e6d44ede05146f6a95add317c Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 20 Jun 2013 17:31:07 -0500 Subject: install .schema.xml and indicator-session-service in the right places. --- CMakeLists.txt | 3 +- TODO | 2 + cmake/GSettings.cmake | 108 ----------------------------------------------- cmake/UseGSettings.cmake | 43 +++++++++++++++++++ data/CMakeLists.txt | 66 ++++++++++++++++++----------- src/CMakeLists.txt | 7 +-- 6 files changed, 93 insertions(+), 136 deletions(-) delete mode 100644 cmake/GSettings.cmake create mode 100644 cmake/UseGSettings.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index f656cb4..d90d6c9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,7 +16,7 @@ find_package(PkgConfig REQUIRED) include (GNUInstallDirs) include (FindPkgConfig) include (GdbusCodegen) -include (GSettings) +include (UseGSettings) add_definitions( -DGETTEXT_PACKAGE="${GETTEXT_PACKAGE}" ) add_definitions (-DGNOMELOCALEDIR=\"@CMAKE_INSTALL_PREFIX@/share/locale\") @@ -51,6 +51,7 @@ if (EXISTS "/etc/debian_version") set(CMAKE_INSTALL_FULL_LIBEXECDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBEXECDIR}") endif() message("Installing libexec files to ${CMAKE_INSTALL_FULL_LIBEXECDIR}") +set (PROJECT_LIBEXECDIR "${CMAKE_INSTALL_FULL_LIBEXECDIR}/${CMAKE_PROJECT_NAME}") if(${LOCAL_INSTALL}) set(DBUSSERVICEDIR "${CMAKE_INSTALL_DATADIR}/dbus-1/services/") diff --git a/TODO b/TODO index 56c6a68..3d79bab 100644 --- a/TODO +++ b/TODO @@ -6,5 +6,7 @@ code cmake x add cmake rule to install .indicator file x add cmake rule to install dbus service file + x add cmake rule to install indicator-session-service + x gsettings schema validation - icon installation - test schema installation diff --git a/cmake/GSettings.cmake b/cmake/GSettings.cmake deleted file mode 100644 index 5902baa..0000000 --- a/cmake/GSettings.cmake +++ /dev/null @@ -1,108 +0,0 @@ -# GSettings.cmake -# Originally based on CMake macros written for Marlin -# Updated by Yorba for newer versions of GLib. -# -# NOTE: This module does an in-place compilation of GSettings; the -# resulting gschemas.compiled file will end up in the same -# source folder as the original schema(s). - -option(GSETTINGS_COMPILE "Compile GSettings schemas. Can be disabled for packaging reasons." ON) -option(GSETTINGS_COMPILE_IN_PLACE "Compile GSettings schemas in the build folder. This is used for running an appliction without installing the GSettings systemwide. The application will need to set GSETTINGS_SCHEMA_DIR" ON) - -if (GSETTINGS_COMPILE) - message(STATUS "GSettings schemas will be compiled.") -endif () - -if (GSETTINGS_COMPILE_IN_PLACE) - message(STATUS "GSettings schemas will be compiled in-place.") -endif () - -macro(add_schemas GSETTINGS_TARGET SCHEMA_DIRECTORY) - set(PKG_CONFIG_EXECUTABLE pkg-config) - - # Locate all schema files. - file(GLOB all_schema_files - "${SCHEMA_DIRECTORY}/*.gschema.xml" - ) - - # Find the GLib path for schema installation - execute_process( - COMMAND - ${PKG_CONFIG_EXECUTABLE} - glib-2.0 - --variable prefix - OUTPUT_VARIABLE - _glib_prefix - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - - set(GSETTINGS_DIR "${_glib_prefix}/share/glib-2.0/schemas/" CACHE INTERNAL "") - - # Fetch path for schema compiler from pkg-config - execute_process( - COMMAND - ${PKG_CONFIG_EXECUTABLE} - gio-2.0 - --variable - glib_compile_schemas - OUTPUT_VARIABLE - _glib_compile_schemas - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - - set(glib_schema_compiler ${_glib_compile_schemas} CACHE INTERNAL "") - - if (GSETTINGS_COMPILE_IN_PLACE) - set(COMPILE_IN_PLACE_DIR ${CMAKE_BINARY_DIR}/gsettings) - add_custom_command( - TARGET - ${GSETTINGS_TARGET} - COMMAND - ${CMAKE_COMMAND} -E make_directory "${COMPILE_IN_PLACE_DIR}" - ) - - # Copy all schemas to the build folder. - foreach(schema_file ${all_schema_files}) - add_custom_command( - TARGET - ${GSETTINGS_TARGET} - COMMAND - ${CMAKE_COMMAND} -E copy "${schema_file}" "${COMPILE_IN_PLACE_DIR}" - COMMENT "Copying schema ${schema_file} to ${COMPILE_IN_PLACE_DIR}" - ) - endforeach() - - # Compile schema in-place. - add_custom_command( - TARGET - ${GSETTINGS_TARGET} - COMMAND - ${glib_schema_compiler} ${COMPILE_IN_PLACE_DIR} - COMMENT "Compiling schemas in folder: ${COMPILE_IN_PLACE_DIR}" - ) - endif () - - # Install and recompile schemas - message(STATUS "GSettings schemas will be installed into ${GSETTINGS_DIR}") - - install( - FILES - ${all_schema_files} - DESTINATION - ${GSETTINGS_DIR} - OPTIONAL - ) - - if (GSETTINGS_COMPILE) - install( - CODE - "message (STATUS \"Compiling GSettings schemas\")" - ) - - install( - CODE - "execute_process (COMMAND ${glib_schema_compiler} ${GSETTINGS_DIR})" - ) - endif () -endmacro(add_schemas) - diff --git a/cmake/UseGSettings.cmake b/cmake/UseGSettings.cmake new file mode 100644 index 0000000..3d8ae1c --- /dev/null +++ b/cmake/UseGSettings.cmake @@ -0,0 +1,43 @@ +# GSettings.cmake, CMake macros written for Marlin, feel free to re-use them. + +option (GSETTINGS_LOCALINSTALL "Install GSettings Schemas locally instead of to the GLib prefix" ${LOCAL_INSTALL}) + +option (GSETTINGS_COMPILE "Compile GSettings Schemas after installation" ${GSETTINGS_LOCALINSTALL}) + +if(GSETTINGS_LOCALINSTALL) + message(STATUS "GSettings schemas will be installed locally.") +endif() + +if(GSETTINGS_COMPILE) + message(STATUS "GSettings shemas will be compiled.") +endif() + +macro(add_schema SCHEMA_NAME) + + set(PKG_CONFIG_EXECUTABLE pkg-config) + # Have an option to not install the schema into where GLib is + if (GSETTINGS_LOCALINSTALL) + SET (GSETTINGS_DIR "${CMAKE_INSTALL_PREFIX}/share/glib-2.0/schemas/") + else (GSETTINGS_LOCALINSTALL) + execute_process (COMMAND ${PKG_CONFIG_EXECUTABLE} glib-2.0 --variable prefix OUTPUT_VARIABLE _glib_prefix OUTPUT_STRIP_TRAILING_WHITESPACE) + SET (GSETTINGS_DIR "${_glib_prefix}/share/glib-2.0/schemas/") + endif (GSETTINGS_LOCALINSTALL) + + # Run the validator and error if it fails + execute_process (COMMAND ${PKG_CONFIG_EXECUTABLE} gio-2.0 --variable glib_compile_schemas OUTPUT_VARIABLE _glib_comple_schemas OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process (COMMAND ${_glib_comple_schemas} --dry-run --schema-file=${SCHEMA_NAME} ERROR_VARIABLE _schemas_invalid OUTPUT_STRIP_TRAILING_WHITESPACE) + + if (_schemas_invalid) + message (SEND_ERROR "Schema validation error: ${_schemas_invalid}") + endif (_schemas_invalid) + + # Actually install and recomple schemas + message (STATUS "GSettings schemas will be installed into ${GSETTINGS_DIR}") + install (FILES ${SCHEMA_NAME} DESTINATION ${GSETTINGS_DIR} OPTIONAL) + + if (GSETTINGS_COMPILE) + install (CODE "message (STATUS \"Compiling GSettings schemas\")") + install (CODE "execute_process (COMMAND ${_glib_comple_schemas} ${GSETTINGS_DIR})") + endif () +endmacro() + diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index 84fe66c..d8f338b 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -1,24 +1,42 @@ -# schema -configure_file (com.canonical.indicator.session.gschema.xml.in - com.canonical.indicator.session.gschema.xml) -include (GSettings) -add_schemas(clinica-schemas ${CMAKE_SOURCE_DIR}/data/com.canonical.indicator.session.gschema.xml) - -# .service file -set(SERVICE_NAME "indicator-session.service") -set(SERVICE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${SERVICE_NAME}") -set(pkglibexecdir "${CMAKE_INSTALL_FULL_LIBEXECDIR}/indicator-session") -configure_file ("${CMAKE_CURRENT_SOURCE_DIR}/${SERVICE_NAME}.in" "${SERVICE_PATH}") -install (FILES ${SERVICE_PATH} - DESTINATION ${DBUSSERVICEDIR}) - -# .indicator file -install(FILES com.canonical.indicator.session - DESTINATION ${CMAKE_INSTALL_PREFIX}/share/unity/indicators) - -# FIXME install files -# -#install(FILES -#datetime-dialog.ui -#DESTINATION share/indicatore-datetime # FIXME this too. -#) +## +## GSettings schema +## + +set (SCHEMA_NAME "com.canonical.indicator.session.gschema.xml") +set (SCHEMA_PATH "${CMAKE_CURRENT_BINARY_DIR}/${SCHEMA_NAME}") +set (SCHEMA_PATH_IN "${CMAKE_CURRENT_SOURCE_DIR}/${SCHEMA_NAME}.in") + +# generate the .xml file using intltool +set (ENV{LC_ALL} "C") +execute_process (COMMAND intltool-merge -x -u --no-translations ${SCHEMA_PATH_IN} ${SCHEMA_PATH}) + +# let UseGSettings do the rest +add_schema (${SCHEMA_PATH}) + + +## +## DBus Service File +## + +set (SERVICE_NAME "${CMAKE_PROJECT_NAME}.service") +set (SERVICE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${SERVICE_NAME}") +set (SERVICE_PATH_IN "${CMAKE_CURRENT_SOURCE_DIR}/${SERVICE_NAME}.in") + +# build it +set (pkglibexecdir "${PROJECT_LIBEXECDIR}") +configure_file ("${SERVICE_PATH_IN}" "${SERVICE_PATH}") + +# install it +install (FILES ${SERVICE_PATH} DESTINATION ${DBUSSERVICEDIR}) + + +## +## Unity Indicator File +## + +set (UNITY_INDICATOR_NAME "com.canonical.indicator.session") +set (UNITY_INDICATOR_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${UNITY_INDICATOR_NAME}") +set (UNITY_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/share/unity") + +install (FILES ${UNITY_INDICATOR_PATH} DESTINATION "${UNITY_INSTALL_PREFIX}/indicators") + diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index efa704c..7b65629 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -14,6 +14,7 @@ set_target_properties (libindicatorsessionservice PROPERTIES COMPILE_FLAGS " -g include_directories(${SERVICE_INCLUDE_DIRS}) link_directories(${SERVICE_LIBRARY_DIRS}) -add_executable (indicator-session-service main.c) -target_link_libraries (indicator-session-service libindicatorsessionservice backenddbus ${SERVICE_LIBRARIES} ${GCOV_LIBS}) - +set (SERVICE_EXEC "indicator-session-service") +add_executable (${SERVICE_EXEC} main.c) +target_link_libraries (${SERVICE_EXEC} libindicatorsessionservice backenddbus ${SERVICE_LIBRARIES} ${GCOV_LIBS}) +install (TARGETS ${SERVICE_EXEC} RUNTIME DESTINATION ${PROJECT_LIBEXECDIR}) -- cgit v1.2.3 From 452ac8d007d55ef282546c0ee3871bf50dd49917 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 20 Jun 2013 18:06:06 -0500 Subject: add cmake rules to install the icon files --- TODO | 2 +- data/CMakeLists.txt | 15 +++++++++++++++ data/Makefile.am | 27 --------------------------- data/icons/16x16/Makefile.am | 1 - data/icons/16x16/actions/Makefile.am | 9 --------- data/icons/16x16/status/Makefile.am | 7 ------- data/icons/22x22/Makefile.am | 1 - data/icons/22x22/actions/Makefile.am | 9 --------- data/icons/22x22/status/Makefile.am | 7 ------- data/icons/24x24/Makefile.am | 1 - data/icons/24x24/actions/Makefile.am | 9 --------- data/icons/24x24/status/Makefile.am | 7 ------- data/icons/32x32/Makefile.am | 1 - data/icons/32x32/actions/Makefile.am | 8 -------- data/icons/32x32/status/Makefile.am | 7 ------- data/icons/Makefile.am | 15 --------------- data/icons/scalable/Makefile.am | 1 - data/icons/scalable/actions/Makefile.am | 9 --------- data/icons/scalable/status/Makefile.am | 7 ------- 19 files changed, 16 insertions(+), 127 deletions(-) delete mode 100644 data/Makefile.am delete mode 100644 data/icons/16x16/Makefile.am delete mode 100644 data/icons/16x16/actions/Makefile.am delete mode 100644 data/icons/16x16/status/Makefile.am delete mode 100644 data/icons/22x22/Makefile.am delete mode 100644 data/icons/22x22/actions/Makefile.am delete mode 100644 data/icons/22x22/status/Makefile.am delete mode 100644 data/icons/24x24/Makefile.am delete mode 100644 data/icons/24x24/actions/Makefile.am delete mode 100644 data/icons/24x24/status/Makefile.am delete mode 100644 data/icons/32x32/Makefile.am delete mode 100644 data/icons/32x32/actions/Makefile.am delete mode 100644 data/icons/32x32/status/Makefile.am delete mode 100644 data/icons/Makefile.am delete mode 100644 data/icons/scalable/Makefile.am delete mode 100644 data/icons/scalable/actions/Makefile.am delete mode 100644 data/icons/scalable/status/Makefile.am diff --git a/TODO b/TODO index 3d79bab..178bb97 100644 --- a/TODO +++ b/TODO @@ -8,5 +8,5 @@ cmake x add cmake rule to install dbus service file x add cmake rule to install indicator-session-service x gsettings schema validation - - icon installation + x icon installation - test schema installation diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index d8f338b..de6942d 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -40,3 +40,18 @@ set (UNITY_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/share/unity") install (FILES ${UNITY_INDICATOR_PATH} DESTINATION "${UNITY_INSTALL_PREFIX}/indicators") + +## +## Icons +## + +if(${LOCAL_INSTALL}) + set (ICON_PREFIX "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/libindicator/icons/") +else() + EXEC_PROGRAM(${PKG_CONFIG_EXECUTABLE} ARGS indicator3-0.4 --variable iconsdir OUTPUT_VARIABLE ICON_PREFIX) +endif() +set (ICON_DIR "${ICON_PREFIX}/hicolor") +message ("Installing icons to ${ICON_DIR}") +install (DIRECTORY icons + DESTINATION ${ICON_DIR} + FILES_MATCHING PATTERN "*.png" PATTERN "*.svg") diff --git a/data/Makefile.am b/data/Makefile.am deleted file mode 100644 index 27b5ea2..0000000 --- a/data/Makefile.am +++ /dev/null @@ -1,27 +0,0 @@ -SUBDIRS = \ - icons \ - extra-sessions - -dbus_servicesdir = $(DBUSSERVICEDIR) -service_in_files = indicator-session.service.in -dbus_services_DATA = $(service_in_files:.service.in=.service) - -%.service: %.service.in - sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@ - -@INTLTOOL_SCHEMAS_RULE@ -@INTLTOOL_XML_NOMERGE_RULE@ - -@GSETTINGS_RULES@ -gsettings_SCHEMAS = com.canonical.indicator.session.gschema.xml - -convertdir = $(datadir)/GConf/gsettings -dist_convert_DATA = indicator-session.convert - -EXTRA_DIST = \ - $(service_in_files) \ - $(gsettings_SCHEMAS:.xml=.xml.in) - -CLEANFILES = \ - $(dbus_services_DATA) \ - $(gsettings_SCHEMAS) diff --git a/data/icons/16x16/Makefile.am b/data/icons/16x16/Makefile.am deleted file mode 100644 index c163076..0000000 --- a/data/icons/16x16/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -SUBDIRS = actions status diff --git a/data/icons/16x16/actions/Makefile.am b/data/icons/16x16/actions/Makefile.am deleted file mode 100644 index 5aa276c..0000000 --- a/data/icons/16x16/actions/Makefile.am +++ /dev/null @@ -1,9 +0,0 @@ - -iconsdir = $(INDICATORICONSDIR)/hicolor/16x16/actions - -icons_DATA = \ - system-shutdown.png \ - system-restart.png \ - system-log-out.png - -EXTRA_DIST = $(icons_DATA) diff --git a/data/icons/16x16/status/Makefile.am b/data/icons/16x16/status/Makefile.am deleted file mode 100644 index c0af60e..0000000 --- a/data/icons/16x16/status/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ - -iconsdir = $(INDICATORICONSDIR)/hicolor/16x16/status - -icons_DATA = \ - account-logged-in.png - -EXTRA_DIST = $(icons_DATA) diff --git a/data/icons/22x22/Makefile.am b/data/icons/22x22/Makefile.am deleted file mode 100644 index c163076..0000000 --- a/data/icons/22x22/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -SUBDIRS = actions status diff --git a/data/icons/22x22/actions/Makefile.am b/data/icons/22x22/actions/Makefile.am deleted file mode 100644 index 73cdd09..0000000 --- a/data/icons/22x22/actions/Makefile.am +++ /dev/null @@ -1,9 +0,0 @@ - -iconsdir = $(INDICATORICONSDIR)/hicolor/22x22/actions - -icons_DATA = \ - system-shutdown.png \ - system-restart.png \ - system-log-out.png - -EXTRA_DIST = $(icons_DATA) diff --git a/data/icons/22x22/status/Makefile.am b/data/icons/22x22/status/Makefile.am deleted file mode 100644 index 1ce0fa1..0000000 --- a/data/icons/22x22/status/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ - -iconsdir = $(INDICATORICONSDIR)/hicolor/22x22/status - -icons_DATA = \ - account-logged-in.png - -EXTRA_DIST = $(icons_DATA) diff --git a/data/icons/24x24/Makefile.am b/data/icons/24x24/Makefile.am deleted file mode 100644 index c163076..0000000 --- a/data/icons/24x24/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -SUBDIRS = actions status diff --git a/data/icons/24x24/actions/Makefile.am b/data/icons/24x24/actions/Makefile.am deleted file mode 100644 index 55c63d1..0000000 --- a/data/icons/24x24/actions/Makefile.am +++ /dev/null @@ -1,9 +0,0 @@ - -iconsdir = $(INDICATORICONSDIR)/hicolor/24x24/actions - -icons_DATA = \ - system-shutdown.png \ - system-restart.png \ - system-log-out.png - -EXTRA_DIST = $(icons_DATA) diff --git a/data/icons/24x24/status/Makefile.am b/data/icons/24x24/status/Makefile.am deleted file mode 100644 index 4fa065a..0000000 --- a/data/icons/24x24/status/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ - -iconsdir = $(INDICATORICONSDIR)/hicolor/24x24/status - -icons_DATA = \ - account-logged-in.png - -EXTRA_DIST = $(icons_DATA) diff --git a/data/icons/32x32/Makefile.am b/data/icons/32x32/Makefile.am deleted file mode 100644 index c163076..0000000 --- a/data/icons/32x32/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -SUBDIRS = actions status diff --git a/data/icons/32x32/actions/Makefile.am b/data/icons/32x32/actions/Makefile.am deleted file mode 100644 index 74c2c8d..0000000 --- a/data/icons/32x32/actions/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ - -iconsdir = $(INDICATORICONSDIR)/hicolor/32x32/actions - -icons_DATA = \ - system-restart.png \ - system-log-out.png - -EXTRA_DIST = $(icons_DATA) diff --git a/data/icons/32x32/status/Makefile.am b/data/icons/32x32/status/Makefile.am deleted file mode 100644 index b852725..0000000 --- a/data/icons/32x32/status/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ - -iconsdir = $(INDICATORICONSDIR)/hicolor/32x32/status - -icons_DATA = \ - account-logged-in.png - -EXTRA_DIST = $(icons_DATA) diff --git a/data/icons/Makefile.am b/data/icons/Makefile.am deleted file mode 100644 index 7394c73..0000000 --- a/data/icons/Makefile.am +++ /dev/null @@ -1,15 +0,0 @@ -SUBDIRS = scalable 16x16 22x22 24x24 32x32 - -gtk_update_icon_cache = gtk-update-icon-cache -f -t $(INDICATORICONSDIR)/hicolor - -install-data-hook: update-icon-cache -uninstall-hook: update-icon-cache -update-icon-cache: - @-if test -z "$(DESTDIR)"; then \ - echo "Updating Gtk icon cache."; \ - $(gtk_update_icon_cache); \ - else \ - echo "*** Icon cache not updated. After (un)install, run this:"; \ - echo "*** $(gtk_update_icon_cache)"; \ - fi - diff --git a/data/icons/scalable/Makefile.am b/data/icons/scalable/Makefile.am deleted file mode 100644 index c163076..0000000 --- a/data/icons/scalable/Makefile.am +++ /dev/null @@ -1 +0,0 @@ -SUBDIRS = actions status diff --git a/data/icons/scalable/actions/Makefile.am b/data/icons/scalable/actions/Makefile.am deleted file mode 100644 index 39b4177..0000000 --- a/data/icons/scalable/actions/Makefile.am +++ /dev/null @@ -1,9 +0,0 @@ - -iconsdir = $(INDICATORICONSDIR)/hicolor/scalable/actions - -icons_DATA = \ - system-restart.svg \ - system-log-out.svg \ - system-shutdown.svg - -EXTRA_DIST = $(icons_DATA) diff --git a/data/icons/scalable/status/Makefile.am b/data/icons/scalable/status/Makefile.am deleted file mode 100644 index cb006e2..0000000 --- a/data/icons/scalable/status/Makefile.am +++ /dev/null @@ -1,7 +0,0 @@ - -iconsdir = $(INDICATORICONSDIR)/hicolor/scalable/status - -icons_DATA = \ - account-logged-in.svg - -EXTRA_DIST = $(icons_DATA) -- cgit v1.2.3 From 59caa78d5ac6410fea8da709189f41fa86e6a2a7 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 20 Jun 2013 18:43:38 -0500 Subject: cmake: cleanup, move DBUSSERVICEDIR's scope from global to the data/ dir --- CMakeLists.txt | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d90d6c9..1299319 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -47,19 +47,11 @@ include_directories (${CMAKE_CURRENT_BINARY_DIR}/src) # Workaround for libexecdir on debian if (EXISTS "/etc/debian_version") - set(CMAKE_INSTALL_LIBEXECDIR ${CMAKE_INSTALL_LIBDIR}) - set(CMAKE_INSTALL_FULL_LIBEXECDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBEXECDIR}") -endif() -message("Installing libexec files to ${CMAKE_INSTALL_FULL_LIBEXECDIR}") + set (CMAKE_INSTALL_LIBEXECDIR ${CMAKE_INSTALL_LIBDIR}) + set (CMAKE_INSTALL_FULL_LIBEXECDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBEXECDIR}") +endif () set (PROJECT_LIBEXECDIR "${CMAKE_INSTALL_FULL_LIBEXECDIR}/${CMAKE_PROJECT_NAME}") - -if(${LOCAL_INSTALL}) - set(DBUSSERVICEDIR "${CMAKE_INSTALL_DATADIR}/dbus-1/services/") -else() - EXEC_PROGRAM(${PKG_CONFIG_EXECUTABLE} ARGS dbus-1 --variable session_bus_services_dir OUTPUT_VARIABLE DBUSSERVICEDIR ) -endif() -message("Installing DBus services to ${DBUSSERVICEDIR}") - +message (STATUS "${PROJECT_LIBEXECDIR} is the libexec install dir") add_subdirectory (src) add_subdirectory (data) -- cgit v1.2.3 From 3d4daff706c39fb6ebdd29b950f3f0ea1402116d Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 20 Jun 2013 18:44:26 -0500 Subject: cmake: fix variables in data/CMakeLists.txt, make status messages more consistent --- cmake/UseGSettings.cmake | 7 ++++--- data/CMakeLists.txt | 52 +++++++++++++++++++++++++++++++----------------- 2 files changed, 38 insertions(+), 21 deletions(-) diff --git a/cmake/UseGSettings.cmake b/cmake/UseGSettings.cmake index 3d8ae1c..c8ea30c 100644 --- a/cmake/UseGSettings.cmake +++ b/cmake/UseGSettings.cmake @@ -15,12 +15,13 @@ endif() macro(add_schema SCHEMA_NAME) set(PKG_CONFIG_EXECUTABLE pkg-config) + set(SCHEMA_SUFFIX "share/glib-2.0/schemas") # Have an option to not install the schema into where GLib is if (GSETTINGS_LOCALINSTALL) - SET (GSETTINGS_DIR "${CMAKE_INSTALL_PREFIX}/share/glib-2.0/schemas/") + SET (GSETTINGS_DIR "${CMAKE_INSTALL_PREFIX}/${SCHEMA_SUFFIX}") else (GSETTINGS_LOCALINSTALL) execute_process (COMMAND ${PKG_CONFIG_EXECUTABLE} glib-2.0 --variable prefix OUTPUT_VARIABLE _glib_prefix OUTPUT_STRIP_TRAILING_WHITESPACE) - SET (GSETTINGS_DIR "${_glib_prefix}/share/glib-2.0/schemas/") + SET (GSETTINGS_DIR "${_glib_prefix}/${SCHEMA_SUFFIX}") endif (GSETTINGS_LOCALINSTALL) # Run the validator and error if it fails @@ -32,7 +33,7 @@ macro(add_schema SCHEMA_NAME) endif (_schemas_invalid) # Actually install and recomple schemas - message (STATUS "GSettings schemas will be installed into ${GSETTINGS_DIR}") + message (STATUS "${GSETTINGS_DIR} is the GSettings install dir") install (FILES ${SCHEMA_NAME} DESTINATION ${GSETTINGS_DIR} OPTIONAL) if (GSETTINGS_COMPILE) diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index de6942d..91f79a5 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -3,55 +3,71 @@ ## set (SCHEMA_NAME "com.canonical.indicator.session.gschema.xml") -set (SCHEMA_PATH "${CMAKE_CURRENT_BINARY_DIR}/${SCHEMA_NAME}") -set (SCHEMA_PATH_IN "${CMAKE_CURRENT_SOURCE_DIR}/${SCHEMA_NAME}.in") +set (SCHEMA_FILE "${CMAKE_CURRENT_BINARY_DIR}/${SCHEMA_NAME}") +set (SCHEMA_FILE_IN "${CMAKE_CURRENT_SOURCE_DIR}/${SCHEMA_NAME}.in") # generate the .xml file using intltool set (ENV{LC_ALL} "C") -execute_process (COMMAND intltool-merge -x -u --no-translations ${SCHEMA_PATH_IN} ${SCHEMA_PATH}) +execute_process (COMMAND intltool-merge -quiet --xml-style --utf8 --no-translations "${SCHEMA_FILE_IN}" "${SCHEMA_FILE}") # let UseGSettings do the rest -add_schema (${SCHEMA_PATH}) +add_schema (${SCHEMA_FILE}) ## ## DBus Service File ## +# where to install +if (${LOCAL_INSTALL}) + set (DBUS_SERVICE_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/dbus-1/services") +else () + EXEC_PROGRAM (${PKG_CONFIG_EXECUTABLE} ARGS dbus-1 --variable session_bus_services_dir OUTPUT_VARIABLE DBUS_SERVICE_DIR) +endif () +message (STATUS "${DBUS_SERVICE_DIR} is the DBus Service File install dir") + set (SERVICE_NAME "${CMAKE_PROJECT_NAME}.service") -set (SERVICE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${SERVICE_NAME}") -set (SERVICE_PATH_IN "${CMAKE_CURRENT_SOURCE_DIR}/${SERVICE_NAME}.in") +set (SERVICE_FILE "${CMAKE_CURRENT_BINARY_DIR}/${SERVICE_NAME}") +set (SERVICE_FILE_IN "${CMAKE_CURRENT_SOURCE_DIR}/${SERVICE_NAME}.in") # build it set (pkglibexecdir "${PROJECT_LIBEXECDIR}") -configure_file ("${SERVICE_PATH_IN}" "${SERVICE_PATH}") +configure_file ("${SERVICE_FILE_IN}" "${SERVICE_FILE}") # install it -install (FILES ${SERVICE_PATH} DESTINATION ${DBUSSERVICEDIR}) +install (FILES "${SERVICE_FILE}" + DESTINATION "${DBUS_SERVICE_DIR}") ## ## Unity Indicator File ## +# where to install +set (UNITY_INDICATOR_DIR "${CMAKE_INSTALL_PREFIX}/share/unity/indicators") +message (STATUS "${UNITY_INDICATOR_DIR} is the Unity Indicator install dir") + set (UNITY_INDICATOR_NAME "com.canonical.indicator.session") -set (UNITY_INDICATOR_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${UNITY_INDICATOR_NAME}") -set (UNITY_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/share/unity") +set (UNITY_INDICATOR_FILE "${CMAKE_CURRENT_SOURCE_DIR}/${UNITY_INDICATOR_NAME}") -install (FILES ${UNITY_INDICATOR_PATH} DESTINATION "${UNITY_INSTALL_PREFIX}/indicators") +install (FILES "${UNITY_INDICATOR_FILE}" + DESTINATION "${UNITY_INDICATOR_DIR}") ## ## Icons ## -if(${LOCAL_INSTALL}) - set (ICON_PREFIX "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/libindicator/icons/") -else() - EXEC_PROGRAM(${PKG_CONFIG_EXECUTABLE} ARGS indicator3-0.4 --variable iconsdir OUTPUT_VARIABLE ICON_PREFIX) -endif() +# where to install +if (${LOCAL_INSTALL}) + set (ICON_PREFIX "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/libindicator/icons") +else () + EXEC_PROGRAM (${PKG_CONFIG_EXECUTABLE} ARGS indicator3-0.4 --variable iconsdir OUTPUT_VARIABLE ICON_PREFIX) +endif () set (ICON_DIR "${ICON_PREFIX}/hicolor") -message ("Installing icons to ${ICON_DIR}") +message (STATUS "${ICON_DIR} is the Icon install dir") + install (DIRECTORY icons - DESTINATION ${ICON_DIR} + DESTINATION "${ICON_DIR}" FILES_MATCHING PATTERN "*.png" PATTERN "*.svg") + -- cgit v1.2.3 From 094ca7d7986027571672cfbcc955310afa6af336 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 20 Jun 2013 19:02:55 -0500 Subject: add a post-install hook to update the icon cache after installation. Taken from geary/icons/CMakeLists.txt. (Thanks, Eric!) --- data/CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index 91f79a5..6700163 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -71,3 +71,6 @@ install (DIRECTORY icons DESTINATION "${ICON_DIR}" FILES_MATCHING PATTERN "*.png" PATTERN "*.svg") +install(CODE "execute_process (COMMAND gtk-update-icon-cache -t -f ${ICON_DIR})" + CODE "message (STATUS \"Updating icon cache\")") + -- cgit v1.2.3 From 4fc1900d906c3c2228279c2e00754a687a38e0d0 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sun, 23 Jun 2013 18:25:10 -0500 Subject: copyediting: fix typo --- README | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README b/README index 29a135f..addf3bb 100644 --- a/README +++ b/README @@ -35,7 +35,7 @@ and (4) a Logged In Mark. 1. You can test for the Active Session Mark by checking the action's state. The state is a dictionary whose "is-active" key yields a boolean. - If the booelan is true, show the Active Session Mark. + If the boolean is true, show the Active Session Mark. 2. The guest user should use a fallback icon such as "avatar-default." -- cgit v1.2.3 From f6ab8644d81f403b0264e126e9631a00dd578418 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sun, 23 Jun 2013 18:26:25 -0500 Subject: add icon support to user menuitems --- src/service.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/service.c b/src/service.c index 4a62bd1..ede3a9f 100644 --- a/src/service.c +++ b/src/service.c @@ -498,6 +498,16 @@ create_switch_section (IndicatorSessionService * self) item = g_menu_item_new (u->real_name, NULL); g_menu_item_set_action_and_target (item, "indicator.switch-to-user", "s", u->user_name); g_menu_item_set_attribute (item, "x-canonical-type", "s", "indicator.user-menu-item"); + + if (u->icon_file != NULL) + { + GFile * file = g_file_new_for_path (u->icon_file); + GIcon * icon = g_file_icon_new (file); + g_menu_item_set_attribute_value (item, G_MENU_ATTRIBUTE_ICON, g_icon_serialize (icon)); + g_clear_object (&icon); + g_clear_object (&file); + } + g_menu_append_item (menu, item); g_object_unref (item); } -- cgit v1.2.3 From d7bb2123f7afffd93524110b4174ad855043f57d Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 10:14:32 -0500 Subject: add replace consolekit xml files with login1; update build files --- src/backend-dbus/CMakeLists.txt | 24 +- .../org.freedesktop.ConsoleKit.Manager.xml | 353 ----------------- .../org.freedesktop.ConsoleKit.Seat.xml | 164 -------- .../org.freedesktop.ConsoleKit.Session.xml | 435 --------------------- .../org.freedesktop.login1.Manager.xml | 199 ++++++++++ src/backend-dbus/org.freedesktop.login1.Seat.xml | 21 + .../org.freedesktop.login1.Session.xml | 49 +++ src/backend-dbus/org.freedesktop.login1.User.xml | 56 +++ src/backend-dbus/upower.xml | 309 --------------- 9 files changed, 337 insertions(+), 1273 deletions(-) delete mode 100644 src/backend-dbus/org.freedesktop.ConsoleKit.Manager.xml delete mode 100644 src/backend-dbus/org.freedesktop.ConsoleKit.Seat.xml delete mode 100644 src/backend-dbus/org.freedesktop.ConsoleKit.Session.xml create mode 100644 src/backend-dbus/org.freedesktop.login1.Manager.xml create mode 100644 src/backend-dbus/org.freedesktop.login1.Seat.xml create mode 100644 src/backend-dbus/org.freedesktop.login1.Session.xml create mode 100644 src/backend-dbus/org.freedesktop.login1.User.xml delete mode 100644 src/backend-dbus/upower.xml diff --git a/src/backend-dbus/CMakeLists.txt b/src/backend-dbus/CMakeLists.txt index dd928cc..58d7b6a 100644 --- a/src/backend-dbus/CMakeLists.txt +++ b/src/backend-dbus/CMakeLists.txt @@ -3,7 +3,7 @@ set(BACKEND_GENERATED_SOURCES add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-display-manager org.freedesktop - ${CMAKE_CURRENT_SOURCE_DIR}/display-manager.xml) + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.DisplayManager.Seat) add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-webcredentials com.canonical.indicators @@ -17,17 +17,21 @@ add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-user org.freedesktop ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.Accounts.User.xml) -add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-consolekit-manager +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-login1-manager org.freedesktop - ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.ConsoleKit.Manager.xml) + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.login1.Manager.xml) -add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-consolekit-seat +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-login1-seat org.freedesktop - ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.ConsoleKit.Seat.xml) + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.login1.Seat.xml) -add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-consolekit-session +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-login1-session org.freedesktop - ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.ConsoleKit.Session.xml) + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.login1.Session.xml) + +add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-login1-user + org.freedesktop + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.login1.User.xml) add_gdbus_codegen (BACKEND_GENERATED_SOURCES gnome-screen-saver org @@ -41,11 +45,7 @@ add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-end-session-dialog org.gnome.SessionManager ${CMAKE_CURRENT_SOURCE_DIR}/org.gnome.SessionManager.EndSessionDialog.xml) -add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-upower - org.freedesktop - ${CMAKE_CURRENT_SOURCE_DIR}/upower.xml) - -set (SOURCES actions.c backend-dbus.c guest.c users.c utils.c) +set (SOURCES actions.c guest.c users.c backend-dbus.c utils.c) # add warnings/coverage info on handwritten files # but not the autogenerated ones... diff --git a/src/backend-dbus/org.freedesktop.ConsoleKit.Manager.xml b/src/backend-dbus/org.freedesktop.ConsoleKit.Manager.xml deleted file mode 100644 index f903b55..0000000 --- a/src/backend-dbus/org.freedesktop.ConsoleKit.Manager.xml +++ /dev/null @@ -1,353 +0,0 @@ - - - - - - - - - This method initiates a request to restart (ie. reboot) the computer system. - - - - - - - - - - - - - - This method initiates a request to stop (ie. shutdown) the computer system. - - - - - - - - - - - - - - The secret cookie that is used to identify the new session - - - - - This method requests that a new Session - be created for the calling process. The properties of this new Session are set automatically - from information collected about the calling process. - - This new session exists until the calling process disconnects from the system bus or - calls CloseSession(). - - It is the responsibility of the calling process to set the environment variable - XDG_SESSION_COOKIE to the value of the returned cookie. This cookie should only - be made available to child processes of the caller so that they may be identified - as members of this session. - - See this simple example: - - DBusError error; - DBusMessage *message; - DBusMessage *reply; - - message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit", - "/org/freedesktop/ConsoleKit/Manager", - "org.freedesktop.ConsoleKit.Manager", - "OpenSession"); - if (message == NULL) { - goto out; - } - - dbus_error_init (&error); - reply = dbus_connection_send_with_reply_and_block (connector->connection, - message, - -1, - &error); - if (reply == NULL) { - goto out; - } - - dbus_error_init (&error); - if (! dbus_message_get_args (reply, - &error, - DBUS_TYPE_STRING, &cookie, - DBUS_TYPE_INVALID)) { - goto out; - } - - - - OpenSessionWithParameters() - - - - - - - An array of sets of property names and values - - - - - The secret cookie that is used to identify the new session - - - - - This method requests that a new Session - be created for the calling process. The properties of this new Session are from the - parameters provided. - - This new session exists until the calling process disconnects from the system bus or - calls CloseSession(). - - It is the responsibility of the calling process to set the environment variable - XDG_SESSION_COOKIE to the value of the returned cookie. This cookie should only - be made available to child processes of the caller so that they may be identified - as members of this session. - - See the Session properties for a list of valid parameters. - - org.freedesktop.ConsoleKit.Session - This method is restricted to privileged users by D-Bus policy. - - - - - - - The secret cookie that is used to identify the session - - - - - Whether the session was successfully closed - - - - - This method is used to close the session identified by the supplied cookie. - - The session can only be closed by the same process that opened the session. - - - - - - - - - an array of Seat IDs - - - - - This gets a list of all the Seats - that are currently present on the system. - Each Seat ID is an D-Bus object path for the object that implements the - Seat interface. - - org.freedesktop.ConsoleKit.Seat - - - - - - - an array of Session IDs - - - - - This gets a list of all the Sessions - that are currently present on the system. - Each Session ID is an D-Bus object path for the object that implements the - Session interface. - - org.freedesktop.ConsoleKit.Session - - - - - - - - The secret cookie that is used to identify the session - - - - - The object identifier for the current session - - - - - Returns the session ID that is associated with the specified cookie. - - - - - - - - - The POSIX process ID - - - - - The object identifier for the current session - - - - - Attempts to determine the session ID for the specified - POSIX process ID (pid). - - - - - - - - - The object identifier for the current session - - - - - Attempts to determine the session ID that the caller belongs to. - - See this example of using dbus-send: - - dbus-send --system --dest=org.freedesktop.ConsoleKit \ - --type=method_call --print-reply --reply-timeout=2000 \ - /org/freedesktop/ConsoleKit/Manager \ - org.freedesktop.ConsoleKit.Manager.GetCurrentSession - - - - - - - - - POSIX User identification - - - - - an array of Session IDs - - - - - This gets a list of all the Sessions - that are currently open for the specified user. - Each Session ID is an D-Bus object path for the object that implements the - Session interface. - - - - - - - - User identification - - - - - an array of Session IDs - - - - - This gets a list of all the Sessions - that are currently open for the specified user. - Each Session ID is an D-Bus object path for the object that implements the - Session interface. - - - - - - - - - The value of the system-idle-hint - - - - - Returns TRUE if the idle-hint - property of every open session is TRUE or if there are no open sessions. - - - - - - - - An ISO 8601 format date-type string - - - - - Returns an ISO 8601 date-time string that corresponds to - the time of the last change of the system-idle-hint. - - - - - - - - - The Seat ID for the added seat - - - - - Emitted when a Seat has been added to the system. - - - - - - - - The Seat ID for the removed seat - - - - - Emitted when a Seat has been removed from the system. - - - - - - - - The value of the system-idle-hint - - - - - Emitted when the value of the system-idle-hint has changed. - - - - - - diff --git a/src/backend-dbus/org.freedesktop.ConsoleKit.Seat.xml b/src/backend-dbus/org.freedesktop.ConsoleKit.Seat.xml deleted file mode 100644 index 58c2ce7..0000000 --- a/src/backend-dbus/org.freedesktop.ConsoleKit.Seat.xml +++ /dev/null @@ -1,164 +0,0 @@ - - - - - - - A seat is a collection of sessions and a set of hardware (usually at -least a keyboard and mouse). Only one session may be active on a -seat at a time. - - - - - - - Seat ID - - - - - Returns the ID for Seat. - - - - - - - - an array of Session IDs - - - - - This gets a list of all the Sessions - that are currently attached to this seat. - Each Session ID is an D-Bus object path for the object that implements the - Session interface. - - - - - - - - an array of devices - - - - - This gets a list of all the devices - that are currently associated with this seat. - Each device is an D-Bus structure that represents - the device type and the device id. - - - - - - - - - Session ID - - - - - Gets the Session ID that is currently active on this Seat. - Returns NULL if there is no active session. - - - - - - - - TRUE if seat supports session activation - - - - Used to determine whether the seat supports session activation. - - - - - - - - - Session ID - - - - - Attempt to activate the specified session. In most - cases, if successful, this will cause the session to - become visible and take control of the hardware that is - associated with this seat. - - Activate() - - - - - - - Session ID - - - - - Emitted when the active session has changed. - - - - - - - Session ID - - - - - Emitted when a session has been added to the seat. - - - - - - - Session ID - - - - - Emitted when a session has been removed from the seat. - - - - - - - Device structure - - - - - Emitted when a device has been associated with the seat. - - - - - - - Device structure - - - - - Emitted when a device has been dissociated from the seat. - - - - - diff --git a/src/backend-dbus/org.freedesktop.ConsoleKit.Session.xml b/src/backend-dbus/org.freedesktop.ConsoleKit.Session.xml deleted file mode 100644 index b6e1cdb..0000000 --- a/src/backend-dbus/org.freedesktop.ConsoleKit.Session.xml +++ /dev/null @@ -1,435 +0,0 @@ - - - - - - - Session objects represent and store information - related to a user session. - - The properties associated with the Session - specifically refer to the properties of the "session leader". - - - - - - - Session ID - - - - Returns the ID for Session. - - - - - - - Seat ID - - - - Returns the ID for the Seat the Session is - attached to. - - org.freedesktop.ConsoleKit.Seat - - - - - - Session type - - - - - Returns the type of the session. - Warning: we haven't yet defined the allowed values for this property. - It is probably best to avoid this until we do. - - - session-type - - - - - - User ID - - - - Returns the user that the session belongs to. - - - user - - - - - - POSIX User ID - - - - Returns the POSIX user ID that the session belongs to. - - unix-user - - - - - - The value of the X11 display - - - - Returns the value of the X11 DISPLAY for this session - if one is present. - - x11-display - - - - - - The value of the X11 display device - - - - Returns the value of the display device (aka TTY) that the - X11 display for the session is connected to. If there is no x11-display set then this value - is undefined. - - x11-display-device - - - - - - The value of the display device - - - - Returns the value of the display device (aka TTY) that the - session is connected to. - - display-device - - - - - - The remote host name - - - - Returns the value of the remote host name for the session. - - - remote-host-name - - - - - - The value of the native system login session ID - - - - Returns the value of the login session ID that the - underlying system uses to enforce session boundaries. If there is no login session ID - set then this value is an empty string. - - - - - - - TRUE if the session is active, otherwise FALSE - - - - Returns whether the session is active on the Seat that - it is attached to. - If the session is not attached to a seat this value is undefined. - - - active - - - - - - TRUE if the session is local, otherwise FALSE - - - - Returns whether the session is local - FIXME: we need to come up with a concrete definition for this value. - It was originally used as a way to identify XDMCP sessions that originate - from a remote system. - - - is-local - - - - - - An ISO 8601 format date-type string - - - - - Returns an ISO 8601 date-time string that corresponds to - the time that the session was opened. - - - - - - - - - - Attempt to activate the this session. In most - cases, if successful, this will cause the session to - become visible and become active on the seat that it - is attached to. - - Seat.ActivateSession() - - - - - - - This will cause a Lock - signal to be emitted for this session. - - - This method is restricted to privileged users by D-Bus policy. - Lock signal - - - - - - - This will cause an Unlock - signal to be emitted for this session. - - This can be used by login managers to unlock a session before it is - re-activated during fast-user-switching. - - - This method is restricted to privileged users by D-Bus policy. - Unlock signal - - - - - - - The value of the idle-hint - - - - - Gets the value of the idle-hint - property. - - - idle-hint - - - - - - An ISO 8601 format date-type string - - - - - Returns an ISO 8601 date-time string that corresponds to - the time of the last change of the idle-hint. - - - - - - - - - boolean value to set the idle-hint to - - - - - This may be used by the session to indicate that - it is idle. - - Use of this method is restricted to the user - that owns the session. - - - - - - - - TRUE if the session is active, otherwise FALSE - - - - - Emitted when the active property has changed. - - - - - - - the new value of idle-hint - - - - - Emitted when the idle-hint property has changed. - - - - - - - Emitted in response to a call to the Lock() method. - It is intended that the screensaver for the session should lock the screen in response to this signal. - - - - - - - Emitted in response to a call to the Unlock() method. - It is intended that the screensaver for the session should unlock the screen in response to this signal. - - - - - - - - The user assigned to the session. - - - - - - - The user assigned to the session. - - - - - - - - The type of the session. - Warning: we haven't yet defined the allowed values for this property. - It is probably best to avoid this until we do. - - - - - - - - The remote host name for the session. - - This will be set in situations where the session is - opened and controlled from a remote system. - - For example, this value will be set when the - session is created from an SSH or XDMCP connection. - - - - - - - - The display device (aka TTY) that the - session is connected to. - - - - - - - - Value of the X11 DISPLAY for this session - if one is present. - - - - - - - - - The display device (aka TTY) that the X11 display for the - session is connected to. If there is no x11-display set then - this value is undefined. - - - - - - - - - Whether the session is active on the Seat that - it is attached to. - If the session is not attached to a seat this value is undefined. - - - - - - - - - Whether the session is local - FIXME: we need to come up with a concrete definition for this value. - It was originally used as a way to identify XDMCP sessions that originate - from a remote system. - - - - - - - - - This is a hint used to indicate that the session may be idle. - - - For sessions with a x11-display set (ie. graphical - sessions), it is up to each session to delegate the - responsibility for updating this value. Typically, the - screensaver will set this. - - However, for non-graphical sessions with a display-device set - the Session object itself will periodically update this value based - on the activity detected on the display-device itself. - - - This should not be considered authoritative. - - - - - - - diff --git a/src/backend-dbus/org.freedesktop.login1.Manager.xml b/src/backend-dbus/org.freedesktop.login1.Manager.xml new file mode 100644 index 0000000..91da5f2 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.login1.Manager.xml @@ -0,0 +1,199 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/backend-dbus/org.freedesktop.login1.Seat.xml b/src/backend-dbus/org.freedesktop.login1.Seat.xml new file mode 100644 index 0000000..b73f724 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.login1.Seat.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/src/backend-dbus/org.freedesktop.login1.Session.xml b/src/backend-dbus/org.freedesktop.login1.Session.xml new file mode 100644 index 0000000..24a6fac --- /dev/null +++ b/src/backend-dbus/org.freedesktop.login1.Session.xml @@ -0,0 +1,49 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/backend-dbus/org.freedesktop.login1.User.xml b/src/backend-dbus/org.freedesktop.login1.User.xml new file mode 100644 index 0000000..8253706 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.login1.User.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/backend-dbus/upower.xml b/src/backend-dbus/upower.xml deleted file mode 100644 index 18d5fbd..0000000 --- a/src/backend-dbus/upower.xml +++ /dev/null @@ -1,309 +0,0 @@ - - - - - - - - The DeviceKit-power service is available via the system message - bus. To access the service, use - the org.freedesktop.UPower interface on - the /org/freedesktop/UPower object on - the D-Bus system bus service with the well-known - name org.freedesktop.UPower. - - - - -$ dbus-send --print-reply \ - --system \ - --dest=org.freedesktop.UPower \ - /org/freedesktop/UPower \ - org.freedesktop.UPower.EnumerateDevices - -method return sender=:1.386 -> dest=:1.451 reply_serial=2 - array [ - object path "/org/freedesktop/UPower/devices/line_power_AC" - object path "/org/freedesktop/UPower/devices/battery_BAT0" - ] - - - - - - - - - - - - An array of object paths for devices. - - - - - - Enumerate all power objects on the system. - - - - - - - - - - Object path of device that was added. - - - - - - Emitted when a device is added. - - - - - - - - - - Object path of device that was removed. - - - - - - Emitted when a device is removed. - - - - - - - - - - Object path of device that was changed. - - - - - - Emitted when a device changed. - - - - - - - - - - - - Emitted when one or more properties on the object changes. - - - - - - - - - - - - This signal is sent when the session is about to be suspended or - hibernated. - Session and system programs have one second to do anything required - before the sleep action is taken (such as sending out Avahi or - Jabber messages). - - - - - - - - - - - - This signal is sent when the session has just returned from - Suspend() or Hibernate(). - Session and system programs can then do anything required (such as - sending out Avahi or Jabber messages). - - - - - - - - - - - - - This method tells UPower that the Suspend() or Hibernate() method - is about to be called. - This allows UPower to emit the Suspending signal whilst - session activities are happening that have to be done before the - suspend process is started. - - - This method would typically be called by the session power - management daemon, before it locks the screen and waits for the - screen to fade to black. - The session power management component would then call Suspend() or - Hibernate() when these syncronous tasks have completed. - - - If this method is not called than nothing bad will happen and - Suspend() or Hibernate() will block for the required second. - - - - - - - - - - - - - Suspends the computer into a low power state. - System state is not preserved if the power is lost. - - - If AboutToRequestSleep() has not been called then UPower will send - the Sleeping() signal and block for one second. - - - If AboutToRequestSleep() has been called less than one second - before this method is called then UPower will block for the - remaining time to complete one second of delay. - - - - - - - - - - - TRUE if allowed, otherwise FALSE - - - - - Check if the caller has (or can get) the PolicyKit privilege to call - Suspend. - - - - - - - - - - - - - Hibernates the computer into a low power state. - System state is preserved if the power is lost. - - - If AboutToRequestSleep() has not been called then UPower will send - the Sleeping() signal and block for one second. - - - If AboutToRequestSleep() has been called less than one second - before this method is called then UPower will block for the - remaining time to complete one second of delay. - - - - - - - - - - - TRUE if allowed, otherwise FALSE - - - - - Check if the caller has (or can get) the PolicyKit privilege to call - Hibernate. - - - - - - - - - - Version of the running daemon, e.g. 002. - - - - - - Whether the system is able to suspend. - - - - - - Whether the system is able to hibernate. - - - - - - Indicates whether the system is running on battery power. - This property is provided for convenience. - - - - - - Indicates whether the system is running on battery power and if the battery is critically low. - This property is provided for convenience. - - - - - - - - Indicates if the laptop lid is closed where the display cannot be seen. - - - - - - - - - - If the system has a lid device. - - - - - - - - -- cgit v1.2.3 From 463ed782d3f2480126cb11d3e18630e275526d9e Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 10:16:43 -0500 Subject: update which proxies the dbus utils helper creates --- src/backend-dbus/backend-dbus.c | 34 ++-- src/backend-dbus/utils.c | 384 ++++++++-------------------------------- src/backend-dbus/utils.h | 16 +- 3 files changed, 96 insertions(+), 338 deletions(-) diff --git a/src/backend-dbus/backend-dbus.c b/src/backend-dbus/backend-dbus.c index ea8f0ec..547c6ab 100644 --- a/src/backend-dbus/backend-dbus.c +++ b/src/backend-dbus/backend-dbus.c @@ -31,38 +31,36 @@ struct dbus_world_data IndicatorSessionGuestDbus * guest; }; -static void -on_proxies_ready (ConsoleKitManager * ck_manager, +static void +on_proxies_ready (Login1Manager * login1_manager, + Login1Seat * login1_seat, + DisplayManagerSeat * display_manager_seat, Accounts * account_manager, - DisplayManagerSeat * dm_seat, - ConsoleKitSeat * ck_seat, - ConsoleKitSession * ck_session, - AccountsUser * active_user G_GNUC_UNUSED, - const GError * error, + GCancellable * cancellable, gpointer gdata) { struct dbus_world_data * data = gdata; - if (error == NULL) + if (!g_cancellable_is_cancelled (cancellable)) { if (data->actions != NULL) indicator_session_actions_dbus_set_proxies (data->actions, - ck_manager, - dm_seat, - ck_seat); + login1_manager, + login1_seat, + display_manager_seat); if (data->users != NULL) indicator_session_users_dbus_set_proxies (data->users, - account_manager, - dm_seat, - ck_seat); + login1_manager, + login1_seat, + display_manager_seat, + account_manager); if (data->guest != NULL) indicator_session_guest_dbus_set_proxies (data->guest, - account_manager, - dm_seat, - ck_seat, - ck_session); + login1_manager, + login1_seat, + display_manager_seat); } g_free (data); diff --git a/src/backend-dbus/utils.c b/src/backend-dbus/utils.c index c8abc2b..25ac7c3 100644 --- a/src/backend-dbus/utils.c +++ b/src/backend-dbus/utils.c @@ -25,346 +25,100 @@ struct session_proxy_data { - ConsoleKitManager * ck_manager; - Accounts * account_manager; + Login1Manager * login1_manager; + Login1Seat * login1_seat; DisplayManagerSeat * dm_seat; - - ConsoleKitSeat * current_seat; - ConsoleKitSession * current_session; - AccountsUser * active_user; + Accounts * account_manager; GCancellable * cancellable; - GError * error; int pending; indicator_session_util_session_proxies_func callback; gpointer user_data; }; -static void -session_proxy_data_free (struct session_proxy_data * data) -{ - g_clear_object (&data->ck_manager); - g_clear_object (&data->account_manager); - g_clear_object (&data->dm_seat); - - g_clear_object (&data->current_seat); - g_clear_object (&data->current_session); - g_clear_object (&data->active_user); - - g_clear_object (&data->cancellable); - g_clear_error (&data->error); - - g_free (data); -} static void -finish_callback (struct session_proxy_data * data) +on_proxy_ready_impl (struct session_proxy_data * data, + gsize member_offset, + GError * err, + gpointer proxy) { - g_assert (data != NULL); - g_debug ("%s %s: pending is %d", G_STRLOC, G_STRFUNC, (data->pending-1)); - - if (!--data->pending) + if (err != NULL) { - data->callback (data->ck_manager, - data->account_manager, - data->dm_seat, - data->current_seat, - data->current_session, - data->active_user, - data->error, - data->user_data); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); - session_proxy_data_free (data); - } -} - -static void -on_user_proxy_ready (GObject * o G_GNUC_UNUSED, - GAsyncResult * res, - gpointer gdata) -{ - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - data->active_user = accounts_user_proxy_new_for_bus_finish (res, &data->error); - - if (data->error != NULL) - { - if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); + g_error_free (err); } else { - g_debug ("%s %s user proxy is %p", G_STRLOC, G_STRFUNC, (void*)data->active_user); - } - - finish_callback (data); -} - -static void -on_user_path_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) -{ - char * path = NULL; - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - accounts_call_find_user_by_id_finish (data->account_manager, &path, res, &data->error); - - if (data->error != NULL) - { - if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - } - else if (path != NULL) - { - g_debug ("%s %s user path is %s", G_STRLOC, G_STRFUNC, path); - ++data->pending; - accounts_user_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - "org.freedesktop.Accounts", - path, - data->cancellable, - on_user_proxy_ready, - data); + *((gpointer*)G_STRUCT_MEMBER_P(data, member_offset)) = proxy; } - finish_callback (data); - g_free (path); -} - -static void -on_uid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) -{ - guint uid = 0; - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - console_kit_session_call_get_unix_user_finish (data->current_session, &uid, res, &data->error); - if (data->error != NULL) - { - if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - } - else if (uid) - { - g_debug ("%s %s uid is %u", G_STRLOC, G_STRFUNC, uid); - ++data->pending; - accounts_call_find_user_by_id (data->account_manager, - uid, - data->cancellable, - on_user_path_ready, - data); - } - - finish_callback (data); -} - -static void -on_seat_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) -{ - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - data->current_seat = console_kit_seat_proxy_new_for_bus_finish (res, &data->error); - - if (data->error && !g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - - finish_callback (data); -} - -static void -on_sid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) -{ - char * sid = NULL; - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - console_kit_session_call_get_seat_id_finish (data->current_session, &sid, res, &data->error); - - if (data->error != NULL) - { - if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - } - else if (sid != NULL) - { - g_debug ("%s %s sid is %s", G_STRLOC, G_STRFUNC, sid); - ++data->pending; - console_kit_seat_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - "org.freedesktop.ConsoleKit", - sid, - data->cancellable, - on_seat_proxy_ready, - data); - } - - finish_callback (data); - g_free (sid); -} - -static void -on_session_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) -{ - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - data->current_session = console_kit_session_proxy_new_finish (res, &data->error); - if (data->error != NULL) - { - if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - } - else + if (!--data->pending) { - ++data->pending; - console_kit_session_call_get_seat_id (data->current_session, - data->cancellable, - on_sid_ready, - data); + data->callback (data->login1_manager, + data->login1_seat, + data->dm_seat, + data->account_manager, + data->cancellable, + data->user_data); - ++data->pending; - console_kit_session_call_get_unix_user (data->current_session, - data->cancellable, - on_uid_ready, - data); + g_clear_object (&data->login1_manager); + g_clear_object (&data->login1_seat); + g_clear_object (&data->dm_seat); + g_clear_object (&data->account_manager); + g_clear_object (&data->cancellable); + g_free (data); } - - finish_callback (data); } - + static void -on_current_session_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +on_display_manager_seat_proxy_ready (GObject * o G_GNUC_UNUSED, + GAsyncResult * res, + gpointer gdata) { - char * ssid = NULL; - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - ssid = NULL; - console_kit_manager_call_get_current_session_finish (data->ck_manager, - &ssid, res, - &data->error); - if (data->error != NULL) - { - if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - } - else if (ssid) - { - g_debug ("%s %s ssid is %s", G_STRLOC, G_STRFUNC, ssid); - data->pending++; - console_kit_session_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - "org.freedesktop.ConsoleKit", - ssid, - data->cancellable, - on_session_proxy_ready, - data); - - } - - finish_callback (data); - g_free (ssid); + gsize offset = G_STRUCT_OFFSET (struct session_proxy_data, dm_seat); + GError * err = NULL; + gpointer proxy = display_manager_seat_proxy_new_for_bus_finish (res, &err); + on_proxy_ready_impl (gdata, offset, err, proxy); } static void -on_display_manager_seat_proxy_ready (GObject * o G_GNUC_UNUSED, - GAsyncResult * res, - gpointer gdata) +on_login1_seat_ready (GObject * o G_GNUC_UNUSED, + GAsyncResult * res, + gpointer gdata) { - DisplayManagerSeat * seat; - struct session_proxy_data * data = gdata; - - seat = display_manager_seat_proxy_new_for_bus_finish (res, &data->error); - - if (data->error != NULL) - { - if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - } - else if (seat != NULL) - { - data->dm_seat = g_object_ref (seat); - } - - finish_callback (data); - g_clear_object (&seat); + gsize offset = G_STRUCT_OFFSET (struct session_proxy_data, login1_seat); + GError * err = NULL; + gpointer proxy = login1_seat_proxy_new_for_bus_finish (res, &err); + on_proxy_ready_impl (gdata, offset, err, proxy); } static void -on_console_kit_manager_proxy_ready (GObject * o G_GNUC_UNUSED, - GAsyncResult * res, - gpointer gdata) +on_login1_manager_ready (GObject * o G_GNUC_UNUSED, + GAsyncResult * res, + gpointer gdata) { - ConsoleKitManager * mgr; - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - if (data->error == NULL) - { - mgr = console_kit_manager_proxy_new_for_bus_finish (res, &data->error); - g_debug ("%s %s mgr is %p, err is %p", G_STRLOC, G_STRFUNC, (void*)mgr, (void*)data->error); - - if (data->error != NULL) - { - if (!g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - } - else - { - data->ck_manager = mgr; - - data->pending++; - console_kit_manager_call_get_current_session (mgr, - data->cancellable, - on_current_session_ready, - data); - - } - } - - finish_callback (data); + gsize offset = G_STRUCT_OFFSET (struct session_proxy_data, login1_manager); + GError * err = NULL; + gpointer proxy = login1_manager_proxy_new_for_bus_finish (res, &err); + on_proxy_ready_impl (gdata, offset, err, proxy); } static void -on_accounts_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gdata) +on_accounts_proxy_ready (GObject * o G_GNUC_UNUSED, + GAsyncResult * res, + gpointer gdata) { - struct session_proxy_data * data = gdata; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - if (data->error == NULL) - { - data->account_manager = accounts_proxy_new_for_bus_finish (res, &data->error); - - if (data->error && !g_error_matches (data->error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, data->error->message); - } - - finish_callback (data); + gsize offset = G_STRUCT_OFFSET (struct session_proxy_data, account_manager); + GError * err = NULL; + gpointer proxy = accounts_proxy_new_for_bus_finish (res, &err); + on_proxy_ready_impl (gdata, offset, err, proxy); } -/** - * Getting all the proxies we want is kind of a pain -- - * especially without blocking (ie, using _sync() funcs) -- - * so it's farmed out to this wrapper utility. - * - * 1. in this func, start getting the ConsoleKit and Accounts proxies - * 2. when the accounts proxy is ready, stash it in data.account_manager - * 3. when the ck manager proxy is ready, stash it in data.ck_manager and - * ask it for the current session's ssid - * 4. when the ssid is ready, start getting a proxy for it - * 5. when the session's proxy is ready, stash it in data.current_session - * and ask it for both the current seat's sid and the active user's uid - * 6. When the current seat's sid is ready, start getting a proxy for it - * 7. When the current seat's proxy is ready, stash it in data.current_seat - * 8. when the active user's uid is ready, ask data.account_manager for the path - * 9. when the user path is ready, start getting an Accounts.User proxy for it - * 10. when the Accounts.User proxy is read, stash it in data.active_user - * - * When everything is done, or if there's an error, invoke the data.callback - */ +/* helper utility to get the dbus proxies used by the backend-dbus classes */ void indicator_session_util_get_session_proxies ( indicator_session_util_session_proxies_func func, @@ -372,12 +126,30 @@ indicator_session_util_get_session_proxies ( gpointer user_data) { struct session_proxy_data * data; + char * seat_path; data = g_new0 (struct session_proxy_data, 1); data->callback = func; data->user_data = user_data; data->cancellable = g_object_ref (cancellable); + data->pending++; + login1_manager_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.login1", + "/org/freedesktop/login1", + data->cancellable, + on_login1_manager_ready, data); + + data->pending++; + seat_path = g_strconcat ("/org/freedesktop/login1/seat/", g_getenv("XDG_SEAT"), NULL); + login1_seat_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.login1", + seat_path, + data->cancellable, + on_login1_seat_ready, + data); data->pending++; accounts_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, @@ -386,15 +158,6 @@ indicator_session_util_get_session_proxies ( data->cancellable, on_accounts_proxy_ready, data); - data->pending++; - console_kit_manager_proxy_new_for_bus ( - G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - "org.freedesktop.ConsoleKit", - "/org/freedesktop/ConsoleKit/Manager", - data->cancellable, - on_console_kit_manager_proxy_ready, data); - data->pending++; display_manager_seat_proxy_new_for_bus ( G_BUS_TYPE_SYSTEM, @@ -404,4 +167,5 @@ indicator_session_util_get_session_proxies ( data->cancellable, on_display_manager_seat_proxy_ready, data); + g_free (seat_path); } diff --git a/src/backend-dbus/utils.h b/src/backend-dbus/utils.h index b4f26c3..802dd5e 100644 --- a/src/backend-dbus/utils.h +++ b/src/backend-dbus/utils.h @@ -25,19 +25,15 @@ #include "dbus-accounts.h" #include "dbus-display-manager.h" -#include "dbus-user.h" -#include "dbus-consolekit-seat.h" -#include "dbus-consolekit-session.h" -#include "dbus-consolekit-manager.h" +#include "dbus-login1-manager.h" +#include "dbus-login1-seat.h" typedef void (*indicator_session_util_session_proxies_func)( - ConsoleKitManager * ck_manager, + Login1Manager * login1_manager, + Login1Seat * login1_seat, + DisplayManagerSeat * display_manager_seat, Accounts * account_manager, - DisplayManagerSeat * dm_seat, - ConsoleKitSeat * current_ck_seat, - ConsoleKitSession * current_ck_session, - AccountsUser * active_user, - const GError * error, + GCancellable * cancellable, gpointer user_data); /** -- cgit v1.2.3 From d3fe504ae1f9936c508bfd95427767833044811a Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 10:20:08 -0500 Subject: in IndicatorSessionGuest, update to login1 --- src/backend-dbus/guest.c | 466 ++++++++++++++++------------------------------- src/backend-dbus/guest.h | 14 +- 2 files changed, 164 insertions(+), 316 deletions(-) diff --git a/src/backend-dbus/guest.c b/src/backend-dbus/guest.c index 317152d..fcb3604 100644 --- a/src/backend-dbus/guest.c +++ b/src/backend-dbus/guest.c @@ -19,28 +19,18 @@ #include -#include "dbus-accounts.h" -#include "dbus-display-manager.h" -#include "dbus-user.h" -#include "dbus-consolekit-seat.h" -#include "dbus-consolekit-manager.h" -#include "dbus-consolekit-session.h" - #include "guest.h" struct _IndicatorSessionGuestDbusPriv { GCancellable * cancellable; - Accounts * accounts; - AccountsUser * guest; - DisplayManagerSeat * display_manager_seat; - - ConsoleKitSeat * seat; - ConsoleKitSession * active_session; - guint active_uid; + Login1Manager * login1_manager; + Login1Seat * login1_seat; + DisplayManagerSeat * dm_seat; gboolean guest_is_active; + gboolean guest_is_logged_in; gboolean guest_is_allowed; }; @@ -55,143 +45,41 @@ G_DEFINE_TYPE (IndicatorSessionGuestDbus, ***/ static void -check_for_active_guest (IndicatorSessionGuestDbus * self) +set_guest_is_allowed_flag (IndicatorSessionGuestDbus * self, gboolean b) { - gboolean guest_is_active; priv_t * p = self->priv; - guest_is_active = (p->active_uid) - && (p->guest != NULL) - && (p->active_uid == accounts_user_get_uid (p->guest)); - - if (p->guest_is_active != guest_is_active) - { - p->guest_is_active = guest_is_active; - - indicator_session_guest_notify_active (INDICATOR_SESSION_GUEST(self)); - } -} - -static void -set_active_uid (IndicatorSessionGuestDbus * self, guint uid) -{ - self->priv->active_uid = uid; - - check_for_active_guest (self); -} - -static void -on_active_uid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) -{ - guint uid; - GError * err; - IndicatorSessionGuestDbus * self; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - uid = 0; - err = NULL; - self = INDICATOR_SESSION_GUEST_DBUS (gself); - console_kit_session_call_get_unix_user_finish (self->priv->active_session, &uid, res, &err); - - if (err != NULL) + if (p->guest_is_allowed != b) { - if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + p->guest_is_allowed = b; - g_error_free (err); - } - else - { - set_active_uid (self, uid); + indicator_session_guest_notify_allowed (INDICATOR_SESSION_GUEST (self)); } } - static void -set_active_session (IndicatorSessionGuestDbus * self, - ConsoleKitSession * session) +set_guest_is_logged_in_flag (IndicatorSessionGuestDbus * self, gboolean b) { priv_t * p = self->priv; - if (p->active_session != NULL) + if (p->guest_is_logged_in != b) { - g_debug ("%s %s active_session refcount is %d before we unref", G_STRLOC, G_STRFUNC, G_OBJECT(self->priv->active_session)->ref_count); + p->guest_is_logged_in = b; - g_clear_object (&p->active_session); - } - - if (session != NULL) - { - p->active_session = g_object_ref (session); - - console_kit_session_call_get_unix_user (session, - p->cancellable, - on_active_uid_ready, - self); + indicator_session_guest_notify_logged_in (INDICATOR_SESSION_GUEST (self)); } } static void -on_active_session_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) -{ - GError * err; - ConsoleKitSession * session; - - err = NULL; - session = console_kit_session_proxy_new_finish (res, &err); - - if (err != NULL) - { - if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); - - g_error_free (err); - } - else - { - set_active_session (gself, session); - } - - g_clear_object (&session); -} - - -static void -on_active_session_changed (ConsoleKitSeat * seat G_GNUC_UNUSED, - const gchar * ssid, - IndicatorSessionGuestDbus * self) -{ - console_kit_session_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - "org.freedesktop.ConsoleKit", - ssid, - self->priv->cancellable, - on_active_session_proxy_ready, - self); -} - -static void -set_seat (IndicatorSessionGuestDbus * self, - ConsoleKitSeat * seat) +set_guest_is_active_flag (IndicatorSessionGuestDbus * self, gboolean b) { priv_t * p = self->priv; - if (p->seat != NULL) + if (p->guest_is_active != b) { -g_debug ("%s %s guest-dbus disconnecting from %p", G_STRLOC, G_STRFUNC, (void*)p->seat); - g_signal_handlers_disconnect_by_data (p->seat, self); -g_debug ("%s %s seat refcount is %d before our unref", G_STRLOC, G_STRFUNC, G_OBJECT(p->seat)->ref_count); + p->guest_is_active = b; - g_clear_object (&p->seat); - } - - if (seat != NULL) - { - p->seat = g_object_ref (seat); -g_debug ("%s %s guest-dbus connecting to %p", G_STRLOC, G_STRFUNC, (void*)p->seat); - - g_signal_connect (seat, "active-session-changed", - G_CALLBACK(on_active_session_changed), self); + indicator_session_guest_notify_active (INDICATOR_SESSION_GUEST(self)); } } @@ -199,63 +87,21 @@ g_debug ("%s %s guest-dbus connecting to %p", G_STRLOC, G_STRFUNC, (void*)p->sea **** ***/ +/* walk the sessions to see if guest is logged in or active */ static void -set_guest (IndicatorSessionGuestDbus * self, - AccountsUser * guest) -{ - priv_t * p = self->priv; - - if (p->guest != NULL) - { - g_debug ("%s %s guest refcount is %d before we unref", G_STRLOC, G_STRFUNC, G_OBJECT(p->guest)->ref_count); - - g_clear_object (&p->guest); - } - - if (guest != NULL) - { - p->guest = g_object_ref (guest); - } - - g_debug ("%s %s guest proxy is now %p", G_STRLOC, G_STRFUNC, (void*)guest); - indicator_session_guest_notify_logged_in (INDICATOR_SESSION_GUEST(self)); - - check_for_active_guest (self); -} - -static void -on_user_deleted (IndicatorSessionGuestDbus * self, - const gchar * path) -{ - AccountsUser * guest = self->priv->guest; - g_debug ("%s %s %s", G_STRLOC, G_STRFUNC, path); - - if (guest != NULL) - if (!g_strcmp0 (path, g_dbus_proxy_get_object_path (G_DBUS_PROXY(guest)))) - set_guest (self, NULL); -} - -static gboolean -is_guest (AccountsUser * user) -{ - /* a guest will look like this: - username:[guest-jjbEVV] realname:[Guest] system:[1] */ - return IS_ACCOUNTS_USER(user) - && accounts_user_get_system_account (user) - && !g_ascii_strcasecmp (accounts_user_get_real_name(user), "Guest"); -} - -static void -on_user_proxy_ready (GObject * o G_GNUC_UNUSED, - GAsyncResult * res, - gpointer self) +on_login1_manager_session_list_ready (GObject * o, + GAsyncResult * res, + gpointer gself) { + GVariant * sessions; GError * err; - AccountsUser * user; + sessions = NULL; err = NULL; - user = accounts_user_proxy_new_for_bus_finish (res, &err); - + login1_manager_call_list_sessions_finish (LOGIN1_MANAGER(o), + &sessions, + res, + &err); if (err != NULL) { if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) @@ -263,139 +109,141 @@ on_user_proxy_ready (GObject * o G_GNUC_UNUSED, g_error_free (err); } - else if (is_guest (user)) + else { - g_debug ("%s %s got guest", G_STRLOC, G_STRFUNC); - set_guest (INDICATOR_SESSION_GUEST_DBUS(self), user); + const gchar * const current_seat_id = g_getenv ("XDG_SEAT"); + const gchar * const current_session_id = g_getenv ("XDG_SESSION_ID"); + gboolean is_logged_in = FALSE; + gboolean is_active = FALSE; + const gchar * session_id = NULL; + guint32 uid = 0; + const gchar * user_name = NULL; + const gchar * seat_id = NULL; + const gchar * path = NULL; + GVariantIter iter; + + g_variant_iter_init (&iter, sessions); + while (g_variant_iter_loop (&iter, "(&su&s&s&o)", &session_id, + &uid, + &user_name, + &seat_id, + &path)) + { + gboolean is_current_session; + gboolean is_guest; + + is_current_session = !g_strcmp0 (current_seat_id, seat_id) + && !g_strcmp0 (current_session_id, session_id); + + is_guest = g_str_has_prefix (user_name, "guest-") + && (uid < 1000); + + if (is_guest) + { + is_logged_in = TRUE; + + is_active = is_current_session; + } + } + + set_guest_is_logged_in_flag (gself, is_logged_in); + set_guest_is_active_flag (gself, is_active); + + g_variant_unref (sessions); } - - g_clear_object (&user); -} - -static void -create_user_proxy_for_path (IndicatorSessionGuestDbus * self, - const char * path) -{ - const char * name = "org.freedesktop.Accounts"; - const GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES; - g_debug ("%s %s creating proxy for %s", G_STRLOC, G_STRFUNC, path); - - accounts_user_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - flags, name, path, - self->priv->cancellable, - on_user_proxy_ready, self); } static void -on_user_list_ready (GObject * o, GAsyncResult * res, gpointer gself) +update_session_list (IndicatorSessionGuestDbus * self) { - GError * err; - gchar ** paths; - - err = NULL; - paths = NULL; - accounts_call_list_cached_users_finish (ACCOUNTS(o), &paths, res, &err); - if (err != NULL) - { - if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + priv_t * p = self->priv; - g_error_free (err); - } - else + if (p->login1_manager != NULL) { - int i; - - for (i=0; paths && paths[i]; ++i) - create_user_proxy_for_path (gself, paths[i]); - - g_strfreev (paths); + login1_manager_call_list_sessions (p->login1_manager, + p->cancellable, + on_login1_manager_session_list_ready, + self); } } static void -set_account_manager (IndicatorSessionGuestDbus * self, - Accounts * a) +set_login1_manager (IndicatorSessionGuestDbus * self, + Login1Manager * login1_manager) { - g_debug ("%s %s setting account manager to %p", G_STRLOC, G_STRFUNC, (void*)a); + priv_t * p = self->priv; - if (self->priv->accounts != NULL) + if (p->login1_manager != NULL) { -g_debug ("%s %s guest-dbus disconnecting from %p", G_STRLOC, G_STRFUNC, (void*)self->priv->accounts); - g_signal_handlers_disconnect_by_data (self->priv->accounts, self); -g_debug ("%s %s account manager refcount is %d before our unref", G_STRLOC, G_STRFUNC, G_OBJECT(self->priv->accounts)->ref_count); - g_clear_object (&self->priv->accounts); + g_signal_handlers_disconnect_by_data (p->login1_manager, self); + + g_clear_object (&p->login1_manager); } - if (a != NULL) + if (login1_manager != NULL) { - self->priv->accounts = g_object_ref (a); - -g_debug ("%s %s guest-dbus connecting to %p", G_STRLOC, G_STRFUNC, (void*)self->priv->accounts); - g_signal_connect_swapped (a, "user-added", - G_CALLBACK(create_user_proxy_for_path), self); - - g_signal_connect_swapped (a, "user-deleted", - G_CALLBACK(on_user_deleted), self); + p->login1_manager = g_object_ref (login1_manager); - accounts_call_list_cached_users (a, - self->priv->cancellable, - on_user_list_ready, - self); + g_signal_connect_swapped (login1_manager, "session-new", + G_CALLBACK(update_session_list), self); + g_signal_connect_swapped (login1_manager, "session-removed", + G_CALLBACK(update_session_list), self); + update_session_list (self); } } static void -set_guest_is_allowed (IndicatorSessionGuestDbus * self, gboolean guest_is_allowed) +update_guest_allowed (IndicatorSessionGuestDbus * self) { priv_t * p = self->priv; - g_debug ("%s %s guest_is_allowed: %d", G_STRLOC, G_STRFUNC, (int)guest_is_allowed); - - if (p->guest_is_allowed != guest_is_allowed) - { - p->guest_is_allowed = guest_is_allowed; - indicator_session_guest_notify_allowed (INDICATOR_SESSION_GUEST (self)); - } -} + gboolean allowed = p->login1_seat + && login1_seat_get_can_multi_session (p->login1_seat); -static void -on_notify_has_guest_account (GObject * seat, GParamSpec * pspec G_GNUC_UNUSED, gpointer gself) -{ - set_guest_is_allowed (INDICATOR_SESSION_GUEST_DBUS (gself), - display_manager_seat_get_has_guest_account (DISPLAY_MANAGER_SEAT(seat))); + set_guest_is_allowed_flag (self, allowed); } static void -set_display_manager_seat (IndicatorSessionGuestDbus * self, DisplayManagerSeat * seat) +set_login1_seat (IndicatorSessionGuestDbus * self, + Login1Seat * login1_seat) { priv_t * p = self->priv; - if (p->display_manager_seat != NULL) + if (p->login1_seat != NULL) { - g_signal_handlers_disconnect_by_data (p->display_manager_seat, self); - g_debug ("%s %s before we unref, dm seat's refcount is %d", G_STRLOC, G_STRFUNC, G_OBJECT(p->display_manager_seat)->ref_count); - g_clear_object (&p->display_manager_seat); + g_signal_handlers_disconnect_by_data (p->login1_seat, self); + g_clear_object (&p->login1_seat); } - if (seat != NULL) + if (login1_seat != NULL) { - p->display_manager_seat = g_object_ref (seat); + p->login1_seat = g_object_ref (login1_seat); - g_signal_connect (seat, "notify::has-guest-account", G_CALLBACK(on_notify_has_guest_account), self); + g_signal_connect_swapped (login1_seat, "notify::active-session", + G_CALLBACK(update_session_list), self); + update_session_list (self); - on_notify_has_guest_account (G_OBJECT(seat), NULL, self); + g_signal_connect_swapped (login1_seat, "notify::can-multi-session", + G_CALLBACK(update_guest_allowed), self); + update_guest_allowed (self); } } +/*** +**** +***/ + static void -on_switch_to_guest_done (GObject * o, GAsyncResult * res, gpointer unused G_GNUC_UNUSED) +on_switch_to_guest_done (GObject * o, + GAsyncResult * res, + gpointer unused G_GNUC_UNUSED) { GError * err; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); err = NULL; - display_manager_seat_call_switch_to_guest_finish (DISPLAY_MANAGER_SEAT(o), res, &err); + display_manager_seat_call_switch_to_guest_finish (DISPLAY_MANAGER_SEAT(o), + res, + &err); if (err != NULL) { if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) @@ -405,30 +253,35 @@ on_switch_to_guest_done (GObject * o, GAsyncResult * res, gpointer unused G_GNUC } } -/*** -**** Virtual Functions -***/ - static void -my_dispose (GObject * o) +my_switch_to_guest (IndicatorSessionGuest * guest) { - IndicatorSessionGuestDbus * self = INDICATOR_SESSION_GUEST_DBUS (o); + IndicatorSessionGuestDbus * self = INDICATOR_SESSION_GUEST_DBUS(guest); - if (self->priv->cancellable != NULL) - { - g_cancellable_cancel (self->priv->cancellable); - g_clear_object (&self->priv->cancellable); - } + g_return_if_fail (self != NULL); + g_return_if_fail (self->priv->dm_seat != NULL); - set_seat (self, NULL); - set_active_session (self, NULL); - set_account_manager (self, NULL); - set_display_manager_seat (self, NULL); - g_clear_object (&self->priv->guest); + display_manager_seat_call_switch_to_guest (self->priv->dm_seat, + "", + self->priv->cancellable, + on_switch_to_guest_done, + self); +} - G_OBJECT_CLASS (indicator_session_guest_dbus_parent_class)->dispose (o); +static void +set_display_manager_seat (IndicatorSessionGuestDbus * self, + DisplayManagerSeat * dm_seat) +{ + g_clear_object (&self->priv->dm_seat); + + if (dm_seat != NULL) + self->priv->dm_seat = g_object_ref (dm_seat); } +/*** +**** IndiatorSessionGuest Virtual Functions +***/ + static gboolean my_is_allowed (IndicatorSessionGuest * self) { @@ -442,7 +295,7 @@ my_is_logged_in (IndicatorSessionGuest * self) { g_return_val_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self), FALSE); - return INDICATOR_SESSION_GUEST_DBUS(self)->priv->guest != NULL; + return INDICATOR_SESSION_GUEST_DBUS(self)->priv->guest_is_logged_in; } static gboolean @@ -453,32 +306,33 @@ my_is_active (IndicatorSessionGuest * self) return INDICATOR_SESSION_GUEST_DBUS(self)->priv->guest_is_active; } +/*** +**** GObject Virtual Functions +***/ + static void -my_switch_to_guest (IndicatorSessionGuest * self) +my_dispose (GObject * o) { - priv_t * p; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - g_return_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self)); - - p = INDICATOR_SESSION_GUEST_DBUS(self)->priv; + IndicatorSessionGuestDbus * self = INDICATOR_SESSION_GUEST_DBUS (o); - if (p->display_manager_seat != NULL) + if (self->priv->cancellable != NULL) { - display_manager_seat_call_switch_to_guest (p->display_manager_seat, - "", - p->cancellable, - on_switch_to_guest_done, - self); + g_cancellable_cancel (self->priv->cancellable); + g_clear_object (&self->priv->cancellable); } + + set_login1_seat (self, NULL); + set_login1_manager (self, NULL); + set_display_manager_seat (self, NULL); + + G_OBJECT_CLASS (indicator_session_guest_dbus_parent_class)->dispose (o); } /*** -**** GObject Boilerplate +**** Instantiation ***/ static void -/* cppcheck-suppress unusedFunction */ indicator_session_guest_dbus_class_init (IndicatorSessionGuestDbusClass * klass) { GObjectClass * object_class; @@ -497,7 +351,6 @@ indicator_session_guest_dbus_class_init (IndicatorSessionGuestDbusClass * klass) } static void -/* cppcheck-suppress unusedFunction */ indicator_session_guest_dbus_init (IndicatorSessionGuestDbus * self) { priv_t * p; @@ -523,16 +376,13 @@ indicator_session_guest_dbus_new (void) void indicator_session_guest_dbus_set_proxies (IndicatorSessionGuestDbus * self, - Accounts * accounts, - DisplayManagerSeat * dm_seat, - ConsoleKitSeat * seat, - ConsoleKitSession * session) + Login1Manager * login1_manager, + Login1Seat * login1_seat, + DisplayManagerSeat * dm_seat) { g_return_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self)); - g_debug ("%s %s accounts %p seat %p session %p", G_STRLOC, G_STRFUNC, (void*)accounts, (void*)seat, (void*)session); - set_account_manager (self, accounts); + set_login1_manager (self, login1_manager); + set_login1_seat (self, login1_seat); set_display_manager_seat (self, dm_seat); - set_seat (self, seat); - set_active_session (self, session); } diff --git a/src/backend-dbus/guest.h b/src/backend-dbus/guest.h index 03b6b28..aca5588 100644 --- a/src/backend-dbus/guest.h +++ b/src/backend-dbus/guest.h @@ -24,9 +24,8 @@ #include #include "../guest.h" /* parent class */ -#include "dbus-accounts.h" -#include "dbus-consolekit-seat.h" -#include "dbus-consolekit-session.h" +#include "dbus-login1-manager.h" +#include "dbus-login1-seat.h" #include "dbus-display-manager.h" @@ -61,11 +60,10 @@ GType indicator_session_guest_dbus_get_type (void); IndicatorSessionGuest * indicator_session_guest_dbus_new (void); -void indicator_session_guest_dbus_set_proxies (IndicatorSessionGuestDbus *, - Accounts *, - DisplayManagerSeat *, - ConsoleKitSeat *, - ConsoleKitSession *); +void indicator_session_guest_dbus_set_proxies (IndicatorSessionGuestDbus * self, + Login1Manager * login1_manager, + Login1Seat * login1_seat, + DisplayManagerSeat * display_manager_seat); G_END_DECLS -- cgit v1.2.3 From df6db45c1bf1ca1e678e8f19974f48c4ead2b06e Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 10:20:23 -0500 Subject: in IndicatorSessionUsers, update to login1 --- src/backend-dbus/users.c | 813 +++++++++++++++++++++-------------------------- src/backend-dbus/users.h | 8 +- 2 files changed, 370 insertions(+), 451 deletions(-) diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 6d9ada6..4466ede 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -17,35 +17,28 @@ * with this program. If not, see . */ -#include "dbus-accounts.h" -#include "dbus-consolekit-seat.h" -#include "dbus-consolekit-session.h" -#include "dbus-consolekit-manager.h" #include "dbus-user.h" #include "users.h" struct _IndicatorSessionUsersDbusPriv { - char * active_session_id; - - Accounts * accounts; - + Login1Manager * login1_manager; + Login1Seat * login1_seat; DisplayManagerSeat * dm_seat; + Accounts * accounts; - ConsoleKitSeat * seat_proxy; - - /* user's dbus object path -> AccountsUser* */ - GHashTable * path_to_user; + /* hash table of int uids to AccountsUser* */ + GHashTable * uid_to_account; - /* uint32 user-id --> user's dbus object path */ - GHashTable * uid_to_user_path; + /* a hashset of int uids of users who are logged in */ + GHashTable * logins; - /* uint32 user-id --> hashset of ssid strings */ - GHashTable * uid_to_sessions; + /* the user-id of the owner of the active session */ + guint active_uid; - /* ssid string --> uint32 user-id */ - GHashTable * session_to_uid; + /* true if this is a live session */ + gboolean is_live; GCancellable * cancellable; }; @@ -60,41 +53,176 @@ G_DEFINE_TYPE (IndicatorSessionUsersDbus, **** ***/ -static void create_user_proxy_for_path (IndicatorSessionUsersDbus * self, - const char * path); +static const gchar * +get_public_key_for_uid (guint uid) +{ + static char buf[16]; + g_snprintf (buf, sizeof(buf), "%u", uid); + return buf; +} + +static void +emit_user_added (IndicatorSessionUsersDbus * self, guint uid) +{ + const gchar * const public_key = get_public_key_for_uid (uid); + indicator_session_users_added (INDICATOR_SESSION_USERS(self), public_key); +} + +static void +emit_user_changed (IndicatorSessionUsersDbus * self, guint uid) +{ + const gchar * const public_key = get_public_key_for_uid (uid); + indicator_session_users_changed (INDICATOR_SESSION_USERS(self), public_key); +} + +static void +emit_user_removed (IndicatorSessionUsersDbus * self, guint uid) +{ + const gchar * const public_key = get_public_key_for_uid (uid); + indicator_session_users_removed (INDICATOR_SESSION_USERS(self), public_key); +} -static void create_session_proxy_for_ssid (IndicatorSessionUsersDbus * self, - const char * ssid); +/*** +**** +***/ static void -emit_user_changed_for_path (IndicatorSessionUsersDbus * self, const char * path) +set_is_live_session_flag (IndicatorSessionUsersDbus * self, gboolean b) { - AccountsUser * user = g_hash_table_lookup (self->priv->path_to_user, path); + priv_t * p = self->priv; + + if (p->is_live != b) + { + p->is_live = b; - if (user && !accounts_user_get_system_account (user)) - indicator_session_users_changed (INDICATOR_SESSION_USERS(self), path); + indicator_session_users_notify_is_live_session (INDICATOR_SESSION_USERS (self)); + } } static void -emit_user_changed_for_uid (IndicatorSessionUsersDbus * self, guint uid) +set_active_uid (IndicatorSessionUsersDbus * self, guint uid) { - const char * path; + priv_t * p = self->priv; + + g_message ("%s %s setting active uid to %u", G_STRLOC, G_STRFUNC, uid); + + if (p->active_uid != uid) + { + const guint old_uid = p->active_uid; - if ((path = g_hash_table_lookup (self->priv->uid_to_user_path, GUINT_TO_POINTER(uid)))) - emit_user_changed_for_path (self, path); + p->active_uid = uid; + + if (old_uid) + emit_user_changed (self, old_uid); + + if (uid) + emit_user_changed (self, uid); + } +} + +static void +set_logins (IndicatorSessionUsersDbus * self, GHashTable * logins) +{ + GHashTable * old_logins = self->priv->logins; + gpointer key; + GHashTableIter iter; + + self->priv->logins = logins; + + /* fire 'user changed' event for users who logged out */ + g_hash_table_iter_init (&iter, old_logins); + while ((g_hash_table_iter_next (&iter, &key, NULL))) + if (!g_hash_table_contains (logins, key)) + emit_user_changed (self, GPOINTER_TO_INT(key)); + + /* fire 'user changed' event for users who logged in */ + g_hash_table_iter_init (&iter, logins); + while ((g_hash_table_iter_next (&iter, &key, NULL))) + if (!g_hash_table_contains (old_logins, key)) + emit_user_changed (self, GPOINTER_TO_INT(key)); + + g_hash_table_destroy (old_logins); } /*** -**** ACCOUNT MANAGER / USER TRACKING +**** ***/ +static GQuark +get_connection_list_quark (void) +{ + static GQuark q = 0; + + if (G_UNLIKELY (q == 0)) + q = g_quark_from_static_string ("connection-ids"); + + return q; +} + +static void +object_unref_and_disconnect (gpointer instance) +{ + GSList * l; + GSList * ids; + const GQuark q = get_connection_list_quark (); + + ids = g_object_steal_qdata (G_OBJECT(instance), q); + for (l=ids; l!=NULL; l=l->next) + { + gulong * handler_id = l->data; + g_signal_handler_disconnect (instance, *handler_id); + g_free (handler_id); + } + + g_slist_free (ids); +} + +static void +object_add_connection (GObject * o, gulong connection_id) +{ + const GQuark q = get_connection_list_quark (); + GSList * ids; + gulong * ptr; + + ptr = g_new (gulong, 1); + *ptr = connection_id; + + ids = g_object_steal_qdata (o, q); + ids = g_slist_prepend (ids, ptr); + g_object_set_qdata (o, q, ids); +} + +/*** +**** +***/ + +static AccountsUser * +get_user_for_uid (IndicatorSessionUsersDbus * self, guint uid) +{ + priv_t * p = self->priv; + + return g_hash_table_lookup (p->uid_to_account, GUINT_TO_POINTER(uid)); +} + +static AccountsUser * +get_user_for_public_key (IndicatorSessionUsersDbus * self, const char * public_key) +{ + return get_user_for_uid (self, g_ascii_strtoull (public_key, NULL, 10)); +} + +/*** +**** User Account Tracking +***/ + +static void create_user_proxy_for_path (IndicatorSessionUsersDbus *, const char *); + /* called when a user proxy gets the 'Changed' signal */ static void on_user_changed (AccountsUser * user, gpointer gself) { /* Accounts.User doesn't update properties in the standard way, * so create a new proxy to pull in the new properties. - * The older proxy is freed when it's removed from our path_to_user hash */ + * The older proxy is freed when it's replaced in our accounts hash */ const char * path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(user)); create_user_proxy_for_path (gself, path); } @@ -103,32 +231,24 @@ static void track_user (IndicatorSessionUsersDbus * self, AccountsUser * user) { - priv_t * p; - const char * path; + priv_t * p = self->priv; + const guint32 uid = accounts_user_get_uid (user); + const gpointer uid_key = GUINT_TO_POINTER (uid); gboolean already_had_user; + gulong id; - p = self->priv; - - path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(user)); - already_had_user = g_hash_table_contains (p->path_to_user, path); + already_had_user = g_hash_table_contains (p->uid_to_account, uid_key); - g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self); - g_hash_table_insert (p->path_to_user, g_strdup(path), user); + id = g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self); + object_add_connection (G_OBJECT(user), id); + g_hash_table_insert (p->uid_to_account, uid_key, user); - if (already_had_user) - { - emit_user_changed_for_path (self, path); - } - else + if (!accounts_user_get_system_account (user)) { - const guint uid = (guint) accounts_user_get_uid (user); - - g_hash_table_insert (p->uid_to_user_path, - GUINT_TO_POINTER(uid), - g_strdup(path)); - - if (!accounts_user_get_system_account (user)) - indicator_session_users_added (INDICATOR_SESSION_USERS(self), path); + if (already_had_user) + emit_user_changed (self, uid); + else + emit_user_added (self, uid); } } @@ -136,14 +256,28 @@ static void untrack_user (IndicatorSessionUsersDbus * self, const gchar * path) { - g_hash_table_remove (self->priv->path_to_user, path); + guint uid; + gpointer key; + gpointer val; + GHashTableIter iter; + priv_t * p = self->priv; - indicator_session_users_removed (INDICATOR_SESSION_USERS(self), path); -} + uid = 0; + g_hash_table_iter_init (&iter, p->uid_to_account); + while (!uid && g_hash_table_iter_next (&iter, &key, &val)) + if (!g_strcmp0 (path, g_dbus_proxy_get_object_path (val))) + uid = GPOINTER_TO_UINT (key); + + if (uid) + { + g_hash_table_remove (p->uid_to_account, GUINT_TO_POINTER(uid)); + emit_user_removed (self, uid); + } +} static void -on_user_proxy_ready (GObject * o G_GNUC_UNUSED, +on_user_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer self) { @@ -169,15 +303,15 @@ static void create_user_proxy_for_path (IndicatorSessionUsersDbus * self, const char * path) { - const char * name = "org.freedesktop.Accounts"; - const GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES; - accounts_user_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - flags, name, path, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.Accounts", + path, self->priv->cancellable, on_user_proxy_ready, self); } +/* create user proxies for everything in Account's user-list */ static void on_user_list_ready (GObject * o, GAsyncResult * res, gpointer gself) { @@ -233,348 +367,143 @@ set_account_manager (IndicatorSessionUsersDbus * self, Accounts * a) } } -/** - * SEAT / SESSION TRACKING - * - * There are two simple goals here: - * - * 1. Keep track of how many GUI sessions each user has - * so that we can set the 'is_logged_in' flag correctly - * - * 2. Also track which is the current session, - * so that we can compare it to those GUI sessions to - * set the 'is_current_session' flag correctly. - * - * Now that you know the goals, these steps may make more sense: - * - * 1. create a ConsoleKitManager proxy - * 2. ask it for the current session - * 3. create a corresponding Session proxy - * 4. ask that Session proxy for its seat - * 5. create a corresponding Seat proxy - * 6. connect to that seat's session-added / session-removed signals - * 7. ask the seat for a list of its current sessions - * 8. create corresponding Session proxies - * 9. of them, look for the GUI sessions by checking their X11 properties - * 10. for each GUI session, get the corresponding uid - * 11. use the information to update our uid <--> GUI sessions tables - */ - -static void -track_session (IndicatorSessionUsersDbus * self, - const char * ssid, - guint uid) -{ - gpointer uid_key; - GHashTable * sessions; - - uid_key = GUINT_TO_POINTER (uid); - sessions = g_hash_table_lookup (self->priv->uid_to_sessions, uid_key); - if (sessions == NULL) - { - sessions = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL); - g_hash_table_insert (self->priv->uid_to_sessions, uid_key, sessions); - } - - g_hash_table_add (sessions, g_strdup (ssid)); - g_hash_table_insert (self->priv->session_to_uid, g_strdup(ssid), uid_key); - - g_debug ("%s %s now tracking ssid:%s uid:%u. uid has %u tracked ssids.", - G_STRLOC, G_STRFUNC, ssid, uid, g_hash_table_size (sessions)); - - emit_user_changed_for_uid (self, uid); -} - -static void -untrack_session (IndicatorSessionUsersDbus * self, - const char * ssid) -{ - gpointer uidptr; - priv_t * p = self->priv; - - if (g_hash_table_lookup_extended (p->session_to_uid, ssid, NULL, &uidptr)) - { - const guint uid = GPOINTER_TO_UINT (uidptr); - GHashTable * sessions = g_hash_table_lookup (p->uid_to_sessions, uidptr); - - g_hash_table_remove (p->session_to_uid, ssid); - g_hash_table_remove (sessions, ssid); - g_debug ("%s %s not tracking ssid:%s uid:%u. uid has %u tracked ssids.", - G_STRLOC, G_STRFUNC, ssid, uid, - sessions ? g_hash_table_size (sessions) : 0); - - emit_user_changed_for_uid (self, uid); - } -} +/*** +**** +***/ +/* Based on the login1 manager's list of current sessions, + update our 'logins', 'is_live', and 'active_uid' fields */ static void -on_session_proxy_uid_ready (GObject * o, - GAsyncResult * res, - gpointer gself) +on_login1_manager_session_list_ready (GObject * o, + GAsyncResult * res, + gpointer gself) { - guint uid; + GVariant * sessions; GError * err; - ConsoleKitSession * session = CONSOLE_KIT_SESSION (o); - uid = 0; + sessions = NULL; err = NULL; - console_kit_session_call_get_unix_user_finish (session, &uid, res, &err); - if (err != NULL) - { - if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); - - g_error_free (err); - } - else if (uid) - { - const char * path = g_dbus_proxy_get_object_path (G_DBUS_PROXY(session)); - track_session (gself, path, uid); - } + login1_manager_call_list_sessions_finish (LOGIN1_MANAGER(o), + &sessions, + res, + &err); - g_object_unref (o); -} - -static void -on_session_x11_display_ready (GObject * o, - GAsyncResult * res, - gpointer gself) -{ - priv_t * p; - GError * err; - gchar * gui; - ConsoleKitSession * session; - - p = INDICATOR_SESSION_USERS_DBUS(gself)->priv; - - err = NULL; - gui = NULL; - session = CONSOLE_KIT_SESSION (o); - console_kit_session_call_get_x11_display_finish (session, &gui, res, &err); if (err != NULL) { if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_warning ("%s: %s", G_STRFUNC, err->message); g_error_free (err); } else { - gboolean is_gui_session; - - is_gui_session = gui && *gui; - - if (!is_gui_session) - g_clear_object (&session); - else - console_kit_session_call_get_unix_user (session, - p->cancellable, - on_session_proxy_uid_ready, - gself); + const gchar * const current_seat_id = g_getenv ("XDG_SEAT"); + const gchar * const current_session_id = g_getenv ("XDG_SESSION_ID"); + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (gself); + const gchar * session_id = NULL; + guint32 uid = 0; + const gchar * user_name = NULL; + const gchar * seat_id = NULL; + const gchar * path = NULL; + gboolean is_live_session = FALSE; + GHashTable * logins = g_hash_table_new (g_direct_hash, g_direct_equal); + GVariantIter iter; + + g_message ("%s %s %s", G_STRLOC, G_STRFUNC, g_variant_print (sessions, TRUE)); + + g_variant_iter_init (&iter, sessions); + while (g_variant_iter_loop (&iter, "(&su&s&s&o)", &session_id, + &uid, + &user_name, + &seat_id, + &path)) + { + /* only track sessions on our seat */ + if (g_strcmp0 (seat_id, current_seat_id)) + continue; - g_free (gui); - } -} + if ((uid==999) && !g_strcmp0 (user_name,"ubuntu")) + is_live_session = TRUE; -static void -on_session_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) -{ - GError * err; - ConsoleKitSession * session; + if (!g_strcmp0 (session_id, current_session_id)) + set_active_uid (self, uid); - err = NULL; - session = console_kit_session_proxy_new_finish (res, &err); - if (err != NULL) - { - if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + /* only count user accounts and the live session */ + if (uid >= 999) + g_hash_table_add (logins, GINT_TO_POINTER(uid)); + } - g_error_free (err); - } - else if (session != NULL) - { - priv_t * p = INDICATOR_SESSION_USERS_DBUS(gself)->priv; + set_is_live_session_flag (self, is_live_session); + set_logins (self, logins); - console_kit_session_call_get_x11_display (session, - p->cancellable, - on_session_x11_display_ready, - gself); + g_variant_unref (sessions); } } static void -create_session_proxy_for_ssid (IndicatorSessionUsersDbus * self, - const char * ssid) -{ - const char * name = "org.freedesktop.ConsoleKit"; - GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES; - - console_kit_session_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - flags, name, ssid, - self->priv->cancellable, - on_session_proxy_ready, self); -} - -static void -on_session_list_ready (GObject * o, GAsyncResult * res, gpointer gself) -{ - GError * err; - gchar ** sessions; - - err = NULL; - sessions = NULL; - console_kit_seat_call_get_sessions_finish (CONSOLE_KIT_SEAT(o), - &sessions, res, &err); - if (err != NULL) - { - if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); - - g_error_free (err); - } - else - { - int i; - - for (i=0; sessions && sessions[i]; i++) - create_session_proxy_for_ssid (gself, sessions[i]); - - g_strfreev (sessions); - } -} - -static inline guint -get_uid_for_session (IndicatorSessionUsersDbus * self, const char * ssid) +update_session_list (IndicatorSessionUsersDbus * self) { - guint uid = 0; - gpointer value; - - if (ssid != NULL) - if ((value = g_hash_table_lookup (self->priv->session_to_uid, ssid))) - uid = GPOINTER_TO_UINT (value); - - return uid; -} - -/* it's a live session if username is 'ubuntu' and uid is 999 */ -static gboolean -is_live_ssid (IndicatorSessionUsersDbus * self, const char * ssid) -{ - priv_t * p; - guint uid; - - p = INDICATOR_SESSION_USERS_DBUS (self)->priv; - uid = get_uid_for_session (self, ssid); + priv_t * p = self->priv; - if (uid == 999) + if (p->login1_manager != NULL) { - const char * path; - AccountsUser * user = NULL; - - if ((path = g_hash_table_lookup (p->uid_to_user_path, GUINT_TO_POINTER (uid)))) - user = g_hash_table_lookup (p->path_to_user, path); - - return (user != NULL) && !g_strcmp0 (accounts_user_get_user_name(user), "ubuntu"); + login1_manager_call_list_sessions (p->login1_manager, + p->cancellable, + on_login1_manager_session_list_ready, + self); } - - return FALSE; } - static void -set_active_session (IndicatorSessionUsersDbus * self, const char * ssid) +set_login1_manager (IndicatorSessionUsersDbus * self, Login1Manager * login1_manager) { priv_t * p = self->priv; - const guint old_uid = get_uid_for_session (self, p->active_session_id); - const guint new_uid = get_uid_for_session (self, ssid); - const gboolean old_live = is_live_ssid (self, p->active_session_id); - const gboolean new_live = is_live_ssid (self, ssid); - - g_debug ("%s %s changing active_session_id from '%s' to '%s'", - G_STRLOC, G_STRFUNC, p->active_session_id, ssid); - g_free (p->active_session_id); - p->active_session_id = g_strdup (ssid); - if (old_uid != new_uid) + if (p->login1_manager != NULL) { - emit_user_changed_for_uid (self, old_uid); - emit_user_changed_for_uid (self, new_uid); - } + g_signal_handlers_disconnect_by_data (p->login1_manager, self); - if (old_live != new_live) - { - indicator_session_users_notify_is_live_session (INDICATOR_SESSION_USERS(self)); + g_clear_object (&p->login1_manager); } -} -static void -on_seat_active_session_ready (GObject * o, GAsyncResult * res, gpointer gself) -{ - GError * err; - gchar * ssid; - ConsoleKitSeat * seat; - - err = NULL; - ssid = NULL; - seat = CONSOLE_KIT_SEAT (o); - console_kit_seat_call_get_active_session_finish (seat, &ssid, res, &err); - if (err != NULL) + if (login1_manager != NULL) { - if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + p->login1_manager = g_object_ref (login1_manager); - g_error_free (err); - } - else if (ssid != NULL) - { - set_active_session (INDICATOR_SESSION_USERS_DBUS(gself), ssid); - g_free (ssid); + g_signal_connect_swapped (login1_manager, "session-new", + G_CALLBACK(update_session_list), self); + g_signal_connect_swapped (login1_manager, "session-removed", + G_CALLBACK(update_session_list), self); + update_session_list (self); } } static void -set_seat (IndicatorSessionUsersDbus * self, ConsoleKitSeat * seat) +set_login1_seat (IndicatorSessionUsersDbus * self, + Login1Seat * login1_seat) { priv_t * p = self->priv; - if (p->seat_proxy != NULL) + if (p->login1_seat != NULL) { - g_signal_handlers_disconnect_by_data (p->seat_proxy, self); - g_clear_object (&p->seat_proxy); + g_signal_handlers_disconnect_by_data (p->login1_seat, self); + + g_clear_object (&p->login1_seat); } - if (seat != NULL) + if (login1_seat != NULL) { - p->seat_proxy = g_object_ref (seat); - - /* ask the seat for a list of all the sessions */ - console_kit_seat_call_get_sessions (seat, - p->cancellable, - on_session_list_ready, - self); + p->login1_seat = g_object_ref (login1_seat); - /* ask the seat for the name of the active session */ - console_kit_seat_call_get_active_session (p->seat_proxy, - p->cancellable, - on_seat_active_session_ready, - self); - - /* listen for session changes in this seat */ - g_signal_connect_swapped (seat, "session-added", - G_CALLBACK(create_session_proxy_for_ssid),self); - g_signal_connect_swapped (seat, "session-removed", - G_CALLBACK(untrack_session), self); - g_signal_connect_swapped (seat, "active-session-changed", - G_CALLBACK(set_active_session), self); + g_signal_connect_swapped (login1_seat, "notify::active-session", + G_CALLBACK(update_session_list), self); + update_session_list (self); } } -/*** -**** -***/ - static void -set_dm_seat (IndicatorSessionUsersDbus * self, DisplayManagerSeat * dm_seat) +set_display_manager_seat (IndicatorSessionUsersDbus * self, + DisplayManagerSeat * dm_seat) { priv_t * p = self->priv; @@ -584,85 +513,49 @@ set_dm_seat (IndicatorSessionUsersDbus * self, DisplayManagerSeat * dm_seat) p->dm_seat = g_object_ref (dm_seat); } -static void -activate_username (IndicatorSessionUsersDbus * self, const char * username) -{ - priv_t * p = self->priv; - const char * session = ""; - - g_return_if_fail (p->dm_seat != NULL); - - display_manager_seat_call_switch_to_user (p->dm_seat, username, session, - p->cancellable, NULL, NULL); -} - /*** -**** +**** IndicatorSessionUsers virtual functions ***/ +/* switch to (or create) a session for the specified user */ static void -my_dispose (GObject * o) +my_activate_user (IndicatorSessionUsers * users, const char * public_key) { - IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (o); + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS(users); priv_t * p = self->priv; + AccountsUser * au; + const char * username; - if (p->cancellable) + au = get_user_for_public_key (self, public_key); + username = au ? accounts_user_get_user_name (au) : NULL; + + if (!username) { - g_cancellable_cancel (p->cancellable); - g_clear_object (&p->cancellable); + g_warning ("%s %s can't find user for '%s'", G_STRLOC, G_STRFUNC, public_key); } - - set_seat (self, NULL); - set_dm_seat (self, NULL); - set_account_manager (self, NULL); - - g_clear_pointer (&p->path_to_user, g_hash_table_destroy); - g_clear_pointer (&p->session_to_uid, g_hash_table_destroy); - g_clear_pointer (&p->uid_to_sessions, g_hash_table_destroy); - g_clear_pointer (&p->uid_to_user_path, g_hash_table_destroy); - - G_OBJECT_CLASS (indicator_session_users_dbus_parent_class)->dispose (o); -} - -static void -my_finalize (GObject * o) -{ - IndicatorSessionUsersDbus * u = INDICATOR_SESSION_USERS_DBUS (o); - - g_free (u->priv->active_session_id); - - G_OBJECT_CLASS (indicator_session_users_dbus_parent_class)->finalize (o); -} - -static void -my_activate_user (IndicatorSessionUsers * users, const char * key) -{ - priv_t * p; - const char * username = 0; - - p = INDICATOR_SESSION_USERS_DBUS (users)->priv; - if (p != 0) + else { - AccountsUser * au = g_hash_table_lookup (p->path_to_user, key); + g_return_if_fail (p->dm_seat != NULL); - if (au != NULL) - username = accounts_user_get_user_name (au); + display_manager_seat_call_switch_to_user (p->dm_seat, + username, + "", + p->cancellable, + NULL, + NULL); } - - if (username != 0) - activate_username (INDICATOR_SESSION_USERS_DBUS(users), username); - else - g_warning ("%s %s can't find user for '%s'", G_STRLOC, G_STRFUNC, key); } +/* returns true if this is a live session */ static gboolean my_is_live_session (IndicatorSessionUsers * users) { - IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS(users); + g_return_val_if_fail (INDICATOR_IS_SESSION_USERS_DBUS(users), FALSE); - return is_live_ssid (self, self->priv->active_session_id); + return INDICATOR_SESSION_USERS_DBUS(users)->priv->is_live; } +/* get a list of public keys for the users that we know about */ static GStrv my_get_keys (IndicatorSessionUsers * users) { @@ -670,64 +563,93 @@ my_get_keys (IndicatorSessionUsers * users) priv_t * p; gchar ** keys; GHashTableIter iter; - gpointer path; + gpointer uid; gpointer user; + GHashTable * h; g_return_val_if_fail (INDICATOR_IS_SESSION_USERS_DBUS(users), NULL); p = INDICATOR_SESSION_USERS_DBUS (users)->priv; i = 0; - keys = g_new (gchar*, g_hash_table_size(p->path_to_user)+1); - g_hash_table_iter_init (&iter, p->path_to_user); - while (g_hash_table_iter_next (&iter, &path, &user)) + h = p->uid_to_account; + keys = g_new (gchar*, g_hash_table_size(h)+1); + g_hash_table_iter_init (&iter, h); + while (g_hash_table_iter_next (&iter, &uid, &user)) if (!accounts_user_get_system_account (user)) - keys[i++] = g_strdup (path); + keys[i++] = g_strdup (get_public_key_for_uid ((guint)uid)); keys[i] = NULL; return keys; } +/* build a new struct populated with info on the specified user */ static IndicatorSessionUser * -my_get_user (IndicatorSessionUsers * users, const gchar * key) +my_get_user (IndicatorSessionUsers * users, const gchar * public_key) { - priv_t * p; + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (users); + priv_t * p = self->priv; + IndicatorSessionUser * ret; AccountsUser * au; - IndicatorSessionUser * ret = NULL; - p = INDICATOR_SESSION_USERS_DBUS (users)->priv; + ret = NULL; + au = get_user_for_public_key (self, public_key); - au = g_hash_table_lookup (p->path_to_user, key); if (au && !accounts_user_get_system_account(au)) { - const guint uid = (guint) accounts_user_get_uid (au); - GHashTable * s; + const guint uid = accounts_user_get_uid (au); ret = g_new0 (IndicatorSessionUser, 1); - - s = g_hash_table_lookup (p->uid_to_sessions, GUINT_TO_POINTER(uid)); - if (s == NULL) - { - ret->is_logged_in = FALSE; - ret->is_current_user = FALSE; - } - else - { - ret->is_logged_in = g_hash_table_size (s) > 0; - ret->is_current_user = g_hash_table_contains (s, p->active_session_id); - } - ret->uid = uid; ret->user_name = g_strdup (accounts_user_get_user_name (au)); ret->real_name = g_strdup (accounts_user_get_real_name (au)); ret->icon_file = g_strdup (accounts_user_get_icon_file (au)); ret->login_frequency = accounts_user_get_login_frequency (au); + ret->is_logged_in = g_hash_table_contains (p->logins, GINT_TO_POINTER(uid)); + ret->is_current_user = uid == p->active_uid; } return ret; } +/*** +**** GObject virtual functions +***/ + +static void +my_dispose (GObject * o) +{ + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (o); + priv_t * p = self->priv; + + if (p->cancellable) + { + g_cancellable_cancel (p->cancellable); + g_clear_object (&p->cancellable); + } + + set_account_manager (self, NULL); + set_display_manager_seat (self, NULL); + set_login1_seat (self, NULL); + set_login1_manager (self, NULL); + + g_hash_table_remove_all (p->uid_to_account); + + G_OBJECT_CLASS (indicator_session_users_dbus_parent_class)->dispose (o); +} + +static void +my_finalize (GObject * o) +{ + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (o); + priv_t * p = self->priv; + + g_hash_table_destroy (p->logins); + g_hash_table_destroy (p->uid_to_account); + + G_OBJECT_CLASS (indicator_session_users_dbus_parent_class)->finalize (o); +} + static void -/* cppcheck-suppress unusedFunction */ indicator_session_users_dbus_class_init (IndicatorSessionUsersDbusClass * klass) { GObjectClass * object_class; @@ -747,7 +669,6 @@ indicator_session_users_dbus_class_init (IndicatorSessionUsersDbusClass * klass) } static void -/* cppcheck-suppress unusedFunction */ indicator_session_users_dbus_init (IndicatorSessionUsersDbus * self) { priv_t * p; @@ -758,18 +679,12 @@ indicator_session_users_dbus_init (IndicatorSessionUsersDbus * self) self->priv = p; p->cancellable = g_cancellable_new (); - p->path_to_user = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, g_object_unref); - - p->uid_to_user_path = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, g_free); - - p->session_to_uid = g_hash_table_new_full (g_str_hash, g_str_equal, - g_free, NULL); + p->uid_to_account = g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, + object_unref_and_disconnect); - p->uid_to_sessions = g_hash_table_new_full (g_direct_hash, g_direct_equal, - NULL, - (GDestroyNotify)g_hash_table_destroy); + p->logins = g_hash_table_new (g_direct_hash, g_direct_equal); } /*** @@ -786,13 +701,15 @@ indicator_session_users_dbus_new (void) void indicator_session_users_dbus_set_proxies (IndicatorSessionUsersDbus * self, - Accounts * accounts, + Login1Manager * login1_manager, + Login1Seat * login1_seat, DisplayManagerSeat * dm_seat, - ConsoleKitSeat * seat) + Accounts * accounts) { g_return_if_fail (INDICATOR_IS_SESSION_USERS_DBUS (self)); + set_login1_manager (self, login1_manager); + set_login1_seat (self, login1_seat); + set_display_manager_seat (self, dm_seat); set_account_manager (self, accounts); - set_seat (self, seat); - set_dm_seat (self, dm_seat); } diff --git a/src/backend-dbus/users.h b/src/backend-dbus/users.h index ff1e0ad..a9aaecf 100644 --- a/src/backend-dbus/users.h +++ b/src/backend-dbus/users.h @@ -25,7 +25,8 @@ #include "../users.h" /* parent class */ #include "dbus-accounts.h" -#include "dbus-consolekit-seat.h" +#include "dbus-login1-manager.h" +#include "dbus-login1-seat.h" #include "dbus-display-manager.h" G_BEGIN_DECLS @@ -60,9 +61,10 @@ GType indicator_session_users_dbus_get_type (void); IndicatorSessionUsers * indicator_session_users_dbus_new (void); void indicator_session_users_dbus_set_proxies (IndicatorSessionUsersDbus *, - Accounts *, + Login1Manager *, + Login1Seat *, DisplayManagerSeat *, - ConsoleKitSeat *); + Accounts *); -- cgit v1.2.3 From ae41c0d677b3ba0be93bafacfb2c48ee36e60f86 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 17:04:08 -0500 Subject: copyediting: the COMMENT in this custom target was being misformatted in the make output --- cmake/Translations.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/Translations.cmake b/cmake/Translations.cmake index 476fb37..f069a15 100644 --- a/cmake/Translations.cmake +++ b/cmake/Translations.cmake @@ -1,7 +1,7 @@ # Translations.cmake, CMake macros written for Marlin, feel free to re-use them macro(add_translations_directory NLS_PACKAGE) - add_custom_target (i18n ALL COMMENT “Building i18n messages.”) + add_custom_target (i18n ALL) find_program (MSGFMT_EXECUTABLE msgfmt) file (GLOB PO_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.po) foreach (PO_INPUT ${PO_FILES}) -- cgit v1.2.3 From eb6abe95552df3aa95f6a263cac3b79462c797ae Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 17:05:27 -0500 Subject: use login1's terminology 'power off', 'reboot' --- src/actions.c | 12 ++++++------ src/actions.h | 8 ++++---- src/service.c | 24 ++++++++++++------------ 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/actions.c b/src/actions.c index 788f418..babc285 100644 --- a/src/actions.c +++ b/src/actions.c @@ -103,8 +103,8 @@ indicator_session_actions_class_init (IndicatorSessionActionsClass * klass) klass->logout = NULL; klass->suspend = NULL; klass->hibernate = NULL; - klass->restart = NULL; - klass->shutdown = NULL; + klass->reboot = NULL; + klass->power_off = NULL; klass->switch_to_screensaver = NULL; klass->switch_to_greeter = NULL; klass->switch_to_guest = NULL; @@ -246,11 +246,11 @@ indicator_session_actions_logout (IndicatorSessionActions * self) } void -indicator_session_actions_shutdown (IndicatorSessionActions * self) +indicator_session_actions_power_off (IndicatorSessionActions * self) { g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); - INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->shutdown (self); + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->power_off (self); } void @@ -270,11 +270,11 @@ indicator_session_actions_about (IndicatorSessionActions * self) } void -indicator_session_actions_restart (IndicatorSessionActions * self) +indicator_session_actions_reboot (IndicatorSessionActions * self) { g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); - INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->restart (self); + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->reboot (self); } void diff --git a/src/actions.h b/src/actions.h index e0d0ec5..bba6045 100644 --- a/src/actions.h +++ b/src/actions.h @@ -71,8 +71,8 @@ struct _IndicatorSessionActionsClass void (*suspend) (IndicatorSessionActions * self); void (*hibernate) (IndicatorSessionActions * self); void (*logout) (IndicatorSessionActions * self); - void (*restart) (IndicatorSessionActions * self); - void (*shutdown) (IndicatorSessionActions * self); + void (*reboot) (IndicatorSessionActions * self); + void (*power_off) (IndicatorSessionActions * self); void (*help) (IndicatorSessionActions * self); void (*about) (IndicatorSessionActions * self); void (*settings) (IndicatorSessionActions * self); @@ -111,8 +111,8 @@ void indicator_session_actions_lock (IndicatorSession void indicator_session_actions_suspend (IndicatorSessionActions * self); void indicator_session_actions_hibernate (IndicatorSessionActions * self); void indicator_session_actions_logout (IndicatorSessionActions * self); -void indicator_session_actions_restart (IndicatorSessionActions * self); -void indicator_session_actions_shutdown (IndicatorSessionActions * self); +void indicator_session_actions_reboot (IndicatorSessionActions * self); +void indicator_session_actions_power_off (IndicatorSessionActions * self); void indicator_session_actions_help (IndicatorSessionActions * self); void indicator_session_actions_about (IndicatorSessionActions * self); diff --git a/src/service.c b/src/service.c index ede3a9f..e41cca6 100644 --- a/src/service.c +++ b/src/service.c @@ -542,13 +542,13 @@ create_session_section (IndicatorSessionService * self) if (!g_settings_get_boolean (s, "suppress-restart-menuitem")) { const char * label = ellipsis ? _("Restart\342\200\246") : _("Restart"); - g_menu_append (menu, label, "indicator.restart"); + g_menu_append (menu, label, "indicator.reboot"); } if (!g_settings_get_boolean (s, "suppress-shutdown-menuitem")) { const char * label = ellipsis ? _("Shutdown\342\200\246") : _("Shutdown"); - g_menu_append (menu, label, "indicator.shutdown"); + g_menu_append (menu, label, "indicator.power-off"); } return G_MENU_MODEL (menu); @@ -661,19 +661,19 @@ on_hibernate_activated (GSimpleAction * a G_GNUC_UNUSED, } static void -on_restart_activated (GSimpleAction * action G_GNUC_UNUSED, - GVariant * param G_GNUC_UNUSED, - gpointer gself) +on_reboot_activated (GSimpleAction * action G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) { - indicator_session_actions_restart (get_backend_actions(gself)); + indicator_session_actions_reboot (get_backend_actions(gself)); } static void -on_shutdown_activated (GSimpleAction * a G_GNUC_UNUSED, - GVariant * param G_GNUC_UNUSED, - gpointer gself) +on_power_off_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) { - indicator_session_actions_shutdown (get_backend_actions(gself)); + indicator_session_actions_power_off (get_backend_actions(gself)); } static void @@ -724,8 +724,8 @@ init_gactions (IndicatorSessionService * self) { "logout", on_logout_activated }, { "suspend", on_suspend_activated }, { "hibernate", on_hibernate_activated }, - { "restart", on_restart_activated }, - { "shutdown", on_shutdown_activated }, + { "reboot", on_reboot_activated }, + { "power-off", on_power_off_activated }, { "switch-to-screensaver", on_screensaver_activated }, { "switch-to-greeter", on_greeter_activated } }; -- cgit v1.2.3 From 94f830aa6324ffa32913bfc8c8dd6c7bce07c9af Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 17:06:36 -0500 Subject: we don't need a login1 session proxy, so don't generate code for one. --- src/backend-dbus/CMakeLists.txt | 4 -- .../org.freedesktop.login1.Session.xml | 49 ---------------------- 2 files changed, 53 deletions(-) delete mode 100644 src/backend-dbus/org.freedesktop.login1.Session.xml diff --git a/src/backend-dbus/CMakeLists.txt b/src/backend-dbus/CMakeLists.txt index 58d7b6a..eb4d971 100644 --- a/src/backend-dbus/CMakeLists.txt +++ b/src/backend-dbus/CMakeLists.txt @@ -25,10 +25,6 @@ add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-login1-seat org.freedesktop ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.login1.Seat.xml) -add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-login1-session - org.freedesktop - ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.login1.Session.xml) - add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-login1-user org.freedesktop ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.login1.User.xml) diff --git a/src/backend-dbus/org.freedesktop.login1.Session.xml b/src/backend-dbus/org.freedesktop.login1.Session.xml deleted file mode 100644 index 24a6fac..0000000 --- a/src/backend-dbus/org.freedesktop.login1.Session.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- cgit v1.2.3 From 1b73a52e6a30b9217cdddc7b6f166a421613eaf6 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 17:07:12 -0500 Subject: migrate from consolekit to login1 --- src/backend-dbus/actions.c | 180 ++++++++++++++++++++++----------------------- src/backend-dbus/actions.h | 12 ++- 2 files changed, 91 insertions(+), 101 deletions(-) diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index bc196f2..a74a524 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -20,7 +20,7 @@ #include #include "dbus-end-session-dialog.h" -#include "dbus-upower.h" +#include "dbus-login1-manager.h" #include "dbus-webcredentials.h" #include "gnome-screen-saver.h" #include "gnome-session-manager.h" @@ -39,17 +39,16 @@ struct _IndicatorSessionActionsDbusPriv GCancellable * cancellable; GSettings * lockdown_settings; - UPower * upower; GnomeScreenSaver * screen_saver; GnomeSessionManager * session_manager; - ConsoleKitManager * ck_manager; - ConsoleKitSeat * ck_seat; + Login1Manager * login1_manager; + Login1Seat * login1_seat; DisplayManagerSeat * dm_seat; Webcredentials * webcredentials; EndSessionDialog * end_session_dialog; - gboolean suspend_allowed; - gboolean hibernate_allowed; + gboolean can_suspend; + gboolean can_hibernate; gboolean seat_allows_activation; }; @@ -75,42 +74,38 @@ log_and_clear_error (GError ** err, const char * loc, const char * func) } } +/*** +**** +***/ + static void -on_can_activate_sessions (GObject * o, GAsyncResult * res, gpointer gself) +on_seat_notify_multi_session (IndicatorSessionActionsDbus * self) { - GError * err; - gboolean can_activate_sessions; + priv_t * p = self->priv; + gboolean b; - err = NULL; - can_activate_sessions = FALSE; - console_kit_seat_call_can_activate_sessions_finish (CONSOLE_KIT_SEAT(o), - &can_activate_sessions, - res, - &err); - if (err == NULL) + b = login1_seat_get_can_multi_session (p->login1_seat); + + if (p->seat_allows_activation != b) { - priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; - p->seat_allows_activation = can_activate_sessions; - } + p->seat_allows_activation = b; - log_and_clear_error (&err, G_STRLOC, G_STRFUNC); + indicator_session_actions_notify_can_switch (INDICATOR_SESSION_ACTIONS(self)); + } } static void -set_ck_seat (IndicatorSessionActionsDbus * self, ConsoleKitSeat * seat) +set_login1_seat (IndicatorSessionActionsDbus * self, Login1Seat * seat) { priv_t * p = self->priv; - g_clear_object (&p->ck_seat); + g_clear_object (&p->login1_seat); if (seat != NULL) { - p->ck_seat = g_object_ref (seat); + p->login1_seat = g_object_ref (seat); - console_kit_seat_call_can_activate_sessions (seat, - p->cancellable, - on_can_activate_sessions, - self); + g_signal_connect_swapped (seat, "notify::can-multi-session", G_CALLBACK(on_seat_notify_multi_session), self); } } @@ -153,75 +148,83 @@ on_screensaver_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpoin } static void -on_suspend_allowed_ready (GObject * o, GAsyncResult * res, gpointer gself) +on_can_suspend_ready (GObject * o, GAsyncResult * res, gpointer gself) { + char * str; GError * err; - gboolean allowed = FALSE; + str = NULL; err = NULL; - upower_call_suspend_allowed_finish (UPOWER(o), &allowed, res, &err); + login1_manager_call_can_suspend_finish (LOGIN1_MANAGER(o), &str, res, &err); if (err == NULL) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; - if (p->suspend_allowed != allowed) + const gboolean b = !g_strcmp0 (str, "yes") || + !g_strcmp0 (str, "challenge"); + + if (p->can_suspend != b) { - p->suspend_allowed = allowed; + p->can_suspend = b; indicator_session_actions_notify_can_suspend (gself); } + + g_free (str); } log_and_clear_error (&err, G_STRLOC, G_STRFUNC); } static void -on_hibernate_allowed_ready (GObject * o, GAsyncResult * res, gpointer gself) +on_can_hibernate_ready (GObject * o, GAsyncResult * res, gpointer gself) { + gchar * str; GError * err; - gboolean allowed = FALSE; + str = NULL; err = NULL; - upower_call_hibernate_allowed_finish (UPOWER(o), &allowed, res, &err); + login1_manager_call_can_hibernate_finish (LOGIN1_MANAGER(o), &str, res, &err); if (err == NULL) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; - if (p->hibernate_allowed != allowed) + const gboolean b = !g_strcmp0 (str, "yes") || + !g_strcmp0 (str, "challenge"); + + if (p->can_hibernate != b) { - p->hibernate_allowed = allowed; + p->can_hibernate = b; indicator_session_actions_notify_can_hibernate (gself); } + + g_free (str); } log_and_clear_error (&err, G_STRLOC, G_STRFUNC); } static void -on_upower_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) +set_login1_manager (IndicatorSessionActionsDbus * self, + Login1Manager * login1_manager) { - GError * err; - UPower * upower; - - err = NULL; - upower = upower_proxy_new_for_bus_finish (res, &err); - if (err == NULL) - { - priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; - - p->upower = upower; + priv_t * p = self->priv; - g_signal_connect_swapped (upower, "notify::can-suspend", - G_CALLBACK(indicator_session_actions_notify_can_suspend), gself); + g_clear_object (&p->login1_manager); - g_signal_connect_swapped (upower, "notify::can-hibernate", - G_CALLBACK(indicator_session_actions_notify_can_hibernate), gself); + if (login1_manager != NULL) + { + p->login1_manager = g_object_ref (login1_manager); - upower_call_suspend_allowed (upower, p->cancellable, on_suspend_allowed_ready, gself); + login1_manager_call_can_suspend (p->login1_manager, + p->cancellable, + on_can_suspend_ready, + self); - upower_call_hibernate_allowed (upower, p->cancellable, on_hibernate_allowed_ready, gself); + login1_manager_call_can_hibernate (p->login1_manager, + p->cancellable, + on_can_hibernate_ready, + self); } - - log_and_clear_error (&err, G_STRLOC, G_STRFUNC); } static void @@ -311,7 +314,7 @@ my_can_suspend (IndicatorSessionActions * self) { const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - return p && p->upower && p->suspend_allowed && upower_get_can_suspend (p->upower); + return p && p->can_suspend; } static gboolean @@ -319,7 +322,7 @@ my_can_hibernate (IndicatorSessionActions * self) { const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - return p && p->upower && p->hibernate_allowed && upower_get_can_hibernate (p->upower); + return p && p->can_hibernate; } static gboolean @@ -345,9 +348,9 @@ my_suspend (IndicatorSessionActions * self) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - g_return_if_fail (p->upower != NULL); + g_return_if_fail (p->login1_manager != NULL); - upower_call_suspend (p->upower, p->cancellable, NULL, NULL); + login1_manager_call_suspend (p->login1_manager, FALSE, p->cancellable, NULL, NULL); } static void @@ -355,9 +358,9 @@ my_hibernate (IndicatorSessionActions * self) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - g_return_if_fail (p->upower != NULL); + g_return_if_fail (p->login1_manager != NULL); - upower_call_hibernate (p->upower, p->cancellable, NULL, NULL); + login1_manager_call_hibernate (p->login1_manager, FALSE, p->cancellable, NULL, NULL); } /*** @@ -392,23 +395,23 @@ logout_now_quietly (IndicatorSessionActions * self) } static void -restart_now (IndicatorSessionActions * self) +reboot_now (IndicatorSessionActions * self) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - g_return_if_fail (p->ck_manager != NULL); + g_return_if_fail (p->login1_manager != NULL); - console_kit_manager_call_restart (p->ck_manager, p->cancellable, NULL, NULL); + login1_manager_call_reboot (p->login1_manager, FALSE, p->cancellable, NULL, NULL); } static void -shutdown_now (IndicatorSessionActions * self) +power_off_now (IndicatorSessionActions * self) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - g_return_if_fail (p->ck_manager != NULL); + g_return_if_fail (p->login1_manager != NULL); - console_kit_manager_call_stop (p->ck_manager, p->cancellable, NULL, NULL); + login1_manager_call_power_off (p->login1_manager, FALSE, p->cancellable, NULL, NULL); } static void @@ -447,8 +450,8 @@ show_end_session_dialog (IndicatorSessionActionsDbus * self, int type) g_assert (o != NULL); g_signal_connect_swapped (o, "confirmed-logout", G_CALLBACK(logout_now_quietly), self); - g_signal_connect_swapped (o, "confirmed-reboot", G_CALLBACK(restart_now), self); - g_signal_connect_swapped (o, "confirmed-shutdown", G_CALLBACK(shutdown_now), self); + g_signal_connect_swapped (o, "confirmed-reboot", G_CALLBACK(reboot_now), self); + g_signal_connect_swapped (o, "confirmed-shutdown", G_CALLBACK(power_off_now), self); g_signal_connect_swapped (o, "canceled", G_CALLBACK(on_end_session_dialog_canceled), self); g_signal_connect_swapped (o, "closed", G_CALLBACK(on_end_session_dialog_closed), self); @@ -469,23 +472,23 @@ my_logout (IndicatorSessionActions * self) static void -my_restart (IndicatorSessionActions * self) +my_reboot (IndicatorSessionActions * self) { if (my_can_prompt (self)) show_end_session_dialog (INDICATOR_SESSION_ACTIONS_DBUS(self), END_SESSION_TYPE_REBOOT); else - restart_now (self); + reboot_now (self); } static void -my_shutdown (IndicatorSessionActions * self) +my_power_off (IndicatorSessionActions * self) { /* NB: TYPE_REBOOT instead of TYPE_SHUTDOWN because the latter adds lock & logout options in Unity... */ if (my_can_prompt (self)) show_end_session_dialog (INDICATOR_SESSION_ACTIONS_DBUS(self), END_SESSION_TYPE_REBOOT); else - shutdown_now (self); + power_off_now (self); } /*** @@ -581,14 +584,13 @@ my_dispose (GObject * o) } g_clear_object (&p->lockdown_settings); - g_clear_object (&p->ck_manager); - g_clear_object (&p->upower); g_clear_object (&p->screen_saver); g_clear_object (&p->session_manager); g_clear_object (&p->webcredentials); g_clear_object (&p->end_session_dialog); set_dm_seat (self, NULL); - set_ck_seat (self, NULL); + set_login1_manager (self, NULL); + set_login1_seat (self, NULL); G_OBJECT_CLASS (indicator_session_actions_dbus_parent_class)->dispose (o); } @@ -618,8 +620,8 @@ indicator_session_actions_dbus_class_init (IndicatorSessionActionsDbusClass * kl actions_class->logout = my_logout; actions_class->suspend = my_suspend; actions_class->hibernate = my_hibernate; - actions_class->restart = my_restart; - actions_class->shutdown = my_shutdown; + actions_class->reboot = my_reboot; + actions_class->power_off = my_power_off; actions_class->settings = my_settings; actions_class->help = my_help; actions_class->about = my_about; @@ -662,14 +664,6 @@ indicator_session_actions_dbus_init (IndicatorSessionActionsDbus * self) on_screensaver_proxy_ready, self); - upower_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - "org.freedesktop.UPower", - "/org/freedesktop/UPower", - p->cancellable, - on_upower_proxy_ready, - self); - gnome_session_manager_proxy_new_for_bus (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, "org.gnome.SessionManager", @@ -709,15 +703,13 @@ indicator_session_actions_dbus_new (void) void indicator_session_actions_dbus_set_proxies (IndicatorSessionActionsDbus * self, - ConsoleKitManager * ck_manager, - DisplayManagerSeat * dm_seat, - ConsoleKitSeat * ck_seat) + Login1Manager * login1_manager, + Login1Seat * login1_seat, + DisplayManagerSeat * dm_seat) { g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS_DBUS(self)); - self->priv->ck_manager = g_object_ref (ck_manager); - + set_login1_manager (self, login1_manager); + set_login1_seat (self, login1_seat); set_dm_seat (self, dm_seat); - - set_ck_seat (self, ck_seat); } diff --git a/src/backend-dbus/actions.h b/src/backend-dbus/actions.h index 997dd73..0c8bed2 100644 --- a/src/backend-dbus/actions.h +++ b/src/backend-dbus/actions.h @@ -24,10 +24,8 @@ #include #include "../actions.h" /* parent class */ -#include "dbus-accounts.h" -#include "dbus-consolekit-manager.h" -#include "dbus-consolekit-seat.h" -#include "dbus-consolekit-session.h" +#include "dbus-login1-manager.h" +#include "dbus-login1-seat.h" #include "dbus-display-manager.h" @@ -63,9 +61,9 @@ GType indicator_session_actions_dbus_get_type (void); IndicatorSessionActions * indicator_session_actions_dbus_new (void); void indicator_session_actions_dbus_set_proxies (IndicatorSessionActionsDbus * self, - ConsoleKitManager * ck_manager, - DisplayManagerSeat * dm_seat, - ConsoleKitSeat * ck_seat); + Login1Manager * login1_manager, + Login1Seat * login1_seat, + DisplayManagerSeat * dm_seat); G_END_DECLS -- cgit v1.2.3 From 889f876ae7263bde2fb54b69930d1d31cbad8423 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 17:08:53 -0500 Subject: in the tests, use login1's terminology 'power off', 'reboot' --- tests/backend-mock-actions.c | 12 ++++++------ tests/test-service.cc | 28 ++++++++++++++-------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/tests/backend-mock-actions.c b/tests/backend-mock-actions.c index 121c7ba..d5a506b 100644 --- a/tests/backend-mock-actions.c +++ b/tests/backend-mock-actions.c @@ -80,15 +80,15 @@ my_hibernate (IndicatorSessionActions * self G_GNUC_UNUSED) } static void -my_restart (IndicatorSessionActions * self G_GNUC_UNUSED) +my_reboot (IndicatorSessionActions * self G_GNUC_UNUSED) { - g_settings_set_string (mock_settings, "last-command", "restart"); + g_settings_set_string (mock_settings, "last-command", "reboot"); } static void -my_shutdown (IndicatorSessionActions * self G_GNUC_UNUSED) +my_power_off (IndicatorSessionActions * self G_GNUC_UNUSED) { - g_settings_set_string (mock_settings, "last-command", "shutdown"); + g_settings_set_string (mock_settings, "last-command", "power-off"); } static void @@ -185,8 +185,8 @@ indicator_session_actions_mock_class_init (IndicatorSessionActionsMockClass * kl actions_class->logout = my_logout; actions_class->suspend = my_suspend; actions_class->hibernate = my_hibernate; - actions_class->restart = my_restart; - actions_class->shutdown = my_shutdown; + actions_class->reboot = my_reboot; + actions_class->power_off = my_power_off; actions_class->settings = my_settings; actions_class->help = my_help; actions_class->about = my_about; diff --git a/tests/test-service.cc b/tests/test-service.cc index 57b4221..2d81441 100644 --- a/tests/test-service.cc +++ b/tests/test-service.cc @@ -374,14 +374,14 @@ TEST_F (ServiceTest, Logout) test_simple_action ("logout"); } -TEST_F (ServiceTest, Shutdown) +TEST_F (ServiceTest, PowerOff) { - test_simple_action ("shutdown"); + test_simple_action ("power-off"); } -TEST_F (ServiceTest, Restart) +TEST_F (ServiceTest, Reboot) { - test_simple_action ("restart"); + test_simple_action ("reboot"); } TEST_F (ServiceTest, SwitchToScreensaver) @@ -477,8 +477,8 @@ TEST_F (ServiceTest, ConfirmationDisabledByBackend) // confirm that the ellipsis are correct ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.switch-to-greeter")); ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.logout")); - ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.restart")); - ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.shutdown")); + ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.reboot")); + ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.power-off")); // now toggle the can-prompt flag confirm_supported = !confirm_supported; @@ -490,8 +490,8 @@ TEST_F (ServiceTest, ConfirmationDisabledByBackend) // confirm that the ellipsis are correct ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.switch-to-greeter")); ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.logout")); - ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.restart")); - ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.shutdown")); + ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.reboot")); + ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.power-off")); // cleanup g_settings_reset (mock_settings, confirm_supported_key); @@ -509,8 +509,8 @@ TEST_F (ServiceTest, ConfirmationDisabledByUser) // confirm that the ellipsis are correct ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.switch-to-greeter")); ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.logout")); - ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.restart")); - ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.shutdown")); + ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.reboot")); + ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.power-off")); // now toggle the can-prompt flag confirm_disabled = !confirm_disabled; @@ -522,8 +522,8 @@ TEST_F (ServiceTest, ConfirmationDisabledByUser) // confirm that the ellipsis are correct ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.switch-to-greeter")); ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.logout")); - ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.restart")); - ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.shutdown")); + ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.reboot")); + ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.power-off")); // cleanup g_settings_reset (indicator_settings, confirm_disabled_key); @@ -542,8 +542,8 @@ TEST_F (ServiceTest, DefaultMenuItems) ASSERT_TRUE (find_menu_item_for_action ("indicator.logout", NULL, NULL)); ASSERT_TRUE (find_menu_item_for_action ("indicator.suspend", NULL, NULL)); ASSERT_TRUE (find_menu_item_for_action ("indicator.hibernate", NULL, NULL)); - ASSERT_TRUE (find_menu_item_for_action ("indicator.restart", NULL, NULL)); - ASSERT_TRUE (find_menu_item_for_action ("indicator.shutdown", NULL, NULL)); + ASSERT_TRUE (find_menu_item_for_action ("indicator.reboot", NULL, NULL)); + ASSERT_TRUE (find_menu_item_for_action ("indicator.power-off", NULL, NULL)); } TEST_F (ServiceTest, OnlineAccountError) -- cgit v1.2.3 From 9cfc9e9da79cabacf1f81e96511d10895992c47d Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 17:13:07 -0500 Subject: get all the tests in test-actions passing again. --- src/backend-dbus/display-manager.xml | 30 --- .../org.freedesktop.DisplayManager.Seat | 30 +++ tests/backend-dbus/CMakeLists.txt | 14 +- tests/backend-dbus/gtest-mock-dbus-fixture.h | 28 +-- tests/backend-dbus/mock-consolekit-manager.cc | 156 ------------ tests/backend-dbus/mock-consolekit-manager.h | 77 ------ tests/backend-dbus/mock-consolekit-seat.cc | 220 ----------------- tests/backend-dbus/mock-consolekit-seat.h | 75 ------ tests/backend-dbus/mock-consolekit-session.cc | 113 --------- tests/backend-dbus/mock-consolekit-session.h | 65 ----- tests/backend-dbus/mock-display-manager-seat.cc | 17 +- tests/backend-dbus/mock-display-manager-seat.h | 6 +- tests/backend-dbus/mock-login1-manager.cc | 275 +++++++++++++++++++++ tests/backend-dbus/mock-login1-manager.h | 68 +++++ tests/backend-dbus/mock-login1-seat.cc | 230 +++++++++++++++++ tests/backend-dbus/mock-login1-seat.h | 77 ++++++ tests/backend-dbus/mock-upower.cc | 103 -------- tests/backend-dbus/mock-upower.h | 72 ------ tests/backend-dbus/test-actions.cc | 137 ++++------ 19 files changed, 756 insertions(+), 1037 deletions(-) delete mode 100644 src/backend-dbus/display-manager.xml create mode 100644 src/backend-dbus/org.freedesktop.DisplayManager.Seat delete mode 100644 tests/backend-dbus/mock-consolekit-manager.cc delete mode 100644 tests/backend-dbus/mock-consolekit-manager.h delete mode 100644 tests/backend-dbus/mock-consolekit-seat.cc delete mode 100644 tests/backend-dbus/mock-consolekit-seat.h delete mode 100644 tests/backend-dbus/mock-consolekit-session.cc delete mode 100644 tests/backend-dbus/mock-consolekit-session.h create mode 100644 tests/backend-dbus/mock-login1-manager.cc create mode 100644 tests/backend-dbus/mock-login1-manager.h create mode 100644 tests/backend-dbus/mock-login1-seat.cc create mode 100644 tests/backend-dbus/mock-login1-seat.h delete mode 100644 tests/backend-dbus/mock-upower.cc delete mode 100644 tests/backend-dbus/mock-upower.h diff --git a/src/backend-dbus/display-manager.xml b/src/backend-dbus/display-manager.xml deleted file mode 100644 index 07b5f29..0000000 --- a/src/backend-dbus/display-manager.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/backend-dbus/org.freedesktop.DisplayManager.Seat b/src/backend-dbus/org.freedesktop.DisplayManager.Seat new file mode 100644 index 0000000..07b5f29 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.DisplayManager.Seat @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/backend-dbus/CMakeLists.txt b/tests/backend-dbus/CMakeLists.txt index 7cd7030..ed9c93a 100644 --- a/tests/backend-dbus/CMakeLists.txt +++ b/tests/backend-dbus/CMakeLists.txt @@ -5,16 +5,16 @@ add_library (gtest STATIC set_target_properties (gtest PROPERTIES INCLUDE_DIRECTORIES ${GTEST_INCLUDE_DIR}) +SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") + # build desktopmock add_library (desktopmock STATIC mock-accounts.cc mock-accounts.h - mock-consolekit-manager.cc - mock-consolekit-manager.h - mock-consolekit-seat.cc - mock-consolekit-seat.h - mock-consolekit-session.cc - mock-consolekit-session.h + mock-login1-manager.cc + mock-login1-manager.h + mock-login1-seat.cc + mock-login1-seat.h mock-display-manager-seat.cc mock-display-manager-seat.h mock-end-session-dialog.cc @@ -25,8 +25,6 @@ add_library (desktopmock STATIC mock-screen-saver.h mock-session-manager.cc mock-session-manager.h - mock-upower.cc - mock-upower.h mock-user.cc mock-user.h mock-webcredentials.cc diff --git a/tests/backend-dbus/gtest-mock-dbus-fixture.h b/tests/backend-dbus/gtest-mock-dbus-fixture.h index 5c4e312..1b1b895 100644 --- a/tests/backend-dbus/gtest-mock-dbus-fixture.h +++ b/tests/backend-dbus/gtest-mock-dbus-fixture.h @@ -20,14 +20,12 @@ #include "gtest-dbus-fixture.h" #include "mock-accounts.h" -#include "mock-consolekit-manager.h" -#include "mock-consolekit-seat.h" -#include "mock-consolekit-session.h" +#include "mock-login1-manager.h" +#include "mock-login1-seat.h" #include "mock-display-manager-seat.h" #include "mock-end-session-dialog.h" #include "mock-screen-saver.h" #include "mock-session-manager.h" -#include "mock-upower.h" #include "mock-user.h" #include "mock-webcredentials.h" @@ -47,10 +45,8 @@ class GTestMockDBusFixture: public GTestDBusFixture MockSessionManager * session_manager; MockDisplayManagerSeat * dm_seat; MockAccounts * accounts; - MockConsoleKitSession * ck_session; - MockConsoleKitSeat * ck_seat; - MockConsoleKitManager * ck_manager; - MockUPower * upower; + MockLogin1Manager * login1_manager; + MockLogin1Seat * login1_seat; MockEndSessionDialog * end_session_dialog; MockWebcredentials * webcredentials; @@ -64,19 +60,18 @@ class GTestMockDBusFixture: public GTestDBusFixture end_session_dialog = new MockEndSessionDialog (loop, conn); session_manager = new MockSessionManager (loop, conn); screen_saver = new MockScreenSaver (loop, conn); - upower = new MockUPower (loop, conn); dm_seat = new MockDisplayManagerSeat (loop, conn); g_setenv ("XDG_SEAT_PATH", dm_seat->path(), TRUE); dm_seat->set_guest_allowed (false); + login1_manager = new MockLogin1Manager (loop, conn); + login1_seat = new MockLogin1Seat (loop, conn, true); + login1_manager->add_seat (login1_seat); accounts = build_accounts_mock (); - ck_manager = new MockConsoleKitManager (loop, conn); - ck_seat = new MockConsoleKitSeat (loop, conn, true); MockUser * user = accounts->find_by_username ("msmith"); - ck_session = ck_seat->add_session_by_user (user); - ck_manager->add_seat (ck_seat); - dm_seat->set_consolekit_seat (ck_seat); + const int session_tag = login1_manager->add_session (login1_seat, user); + dm_seat->set_login1_seat (login1_seat); dm_seat->switch_to_user (user->username()); - ASSERT_EQ (ck_session, ck_manager->current_session()); + ASSERT_EQ (session_tag, login1_seat->active_session()); } protected: @@ -84,9 +79,8 @@ class GTestMockDBusFixture: public GTestDBusFixture virtual void TearDown () { delete accounts; - delete ck_manager; + delete login1_manager; delete dm_seat; - delete upower; delete screen_saver; delete session_manager; delete end_session_dialog; diff --git a/tests/backend-dbus/mock-consolekit-manager.cc b/tests/backend-dbus/mock-consolekit-manager.cc deleted file mode 100644 index 40f9bf9..0000000 --- a/tests/backend-dbus/mock-consolekit-manager.cc +++ /dev/null @@ -1,156 +0,0 @@ -/* - * Copyright 2013 Canonical Ltd. - * - * Authors: - * Charles Kerr - * - * This program 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranties of - * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . - */ - -#include "mock-consolekit-manager.h" -#include "mock-consolekit-seat.h" -#include "mock-consolekit-session.h" - -namespace -{ - const char * CONSOLEKIT_MANAGER_NAME = "org.freedesktop.ConsoleKit"; - - const char * CONSOLEKIT_MANAGER_PATH = "/org/freedesktop/ConsoleKit/Manager"; - - void on_active_session_changed (ConsoleKitSeat * o G_GNUC_UNUSED, - const gchar * new_ssid, - gpointer ssid) - { - *static_cast(ssid) = new_ssid; - } -} - -/*** -**** -***/ - -gboolean -MockConsoleKitManager :: on_get_current_session (ConsoleKitManager * m, - GDBusMethodInvocation * inv, - gpointer gself) -{ - MockConsoleKitManager * self = static_cast(gself); - const std::string& ssid = self->my_current_ssid; - console_kit_manager_complete_get_current_session (m, inv, ssid.c_str()); - return true; -} - -gboolean -MockConsoleKitManager :: on_get_seats (ConsoleKitManager * m, - GDBusMethodInvocation * inv, - gpointer gself) -{ - int i; - char ** sids; - const seats_t& seats = static_cast(gself)->my_seats; - - i = 0; - sids = g_new0 (char*, seats.size()+1); - for (seats_t::const_iterator it(seats.begin()), - end(seats.end()); it!=end; ++it) - sids[i++] = (char*) (*it)->path(); - console_kit_manager_complete_get_seats (m, inv, sids); - g_strfreev (sids); - - return true; -} - -gboolean -MockConsoleKitManager :: handle_restart (ConsoleKitManager * ckm, - GDBusMethodInvocation * inv, - gpointer gself) -{ - static_cast(gself)->my_last_action = Restart; - console_kit_manager_complete_restart (ckm, inv); - return true; -} - -gboolean -MockConsoleKitManager :: handle_stop (ConsoleKitManager * ckm, - GDBusMethodInvocation * inv, - gpointer gself) -{ - static_cast(gself)->my_last_action = Shutdown; - console_kit_manager_complete_stop (ckm, inv); - return true; -} - -/*** -**** -***/ - -MockConsoleKitSession * -MockConsoleKitManager :: current_session () -{ - MockConsoleKitSession * ret = 0; - - for (seats_t::iterator it(my_seats.begin()), - end(my_seats.end()); it!=end; ++it) - if ((ret = (*it)->find (my_current_ssid.c_str()))) - break; - - return ret; -} - -void -MockConsoleKitManager :: add_seat (MockConsoleKitSeat * seat) -{ - g_assert (my_seats.count(seat) == 0); - - my_seats.insert (seat); - - console_kit_manager_emit_seat_added (my_skeleton, seat->sid()); - - g_signal_connect (seat->skeleton(), "active-session-changed", - G_CALLBACK(on_active_session_changed), &my_current_ssid); -} - -/*** -**** -***/ - -MockConsoleKitManager :: MockConsoleKitManager (GMainLoop * loop, - GDBusConnection * conn): - MockObject (loop, conn, CONSOLEKIT_MANAGER_NAME, CONSOLEKIT_MANAGER_PATH), - my_skeleton (console_kit_manager_skeleton_new ()), - my_last_action (None) -{ - g_signal_connect (my_skeleton, "handle-get-current-session", - G_CALLBACK(on_get_current_session), this); - g_signal_connect (my_skeleton, "handle-get-seats", - G_CALLBACK(on_get_seats), this); - g_signal_connect (my_skeleton, "handle-stop", - G_CALLBACK(handle_stop), this); - g_signal_connect (my_skeleton, "handle-restart", - G_CALLBACK(handle_restart), this); - - set_skeleton (G_DBUS_INTERFACE_SKELETON(my_skeleton)); -} - -MockConsoleKitManager :: ~MockConsoleKitManager () -{ - for (seats_t::iterator it(my_seats.begin()); it!=my_seats.end(); ++it) - { - MockConsoleKitSeat * seat = *it; - g_signal_handlers_disconnect_by_data (seat->skeleton(), &my_current_ssid); - delete seat; - } - - g_signal_handlers_disconnect_by_data (my_skeleton, this); - g_clear_object (&my_skeleton); -} diff --git a/tests/backend-dbus/mock-consolekit-manager.h b/tests/backend-dbus/mock-consolekit-manager.h deleted file mode 100644 index c5942b2..0000000 --- a/tests/backend-dbus/mock-consolekit-manager.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2013 Canonical Ltd. - * - * Authors: - * Charles Kerr - * - * This program 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranties of - * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . - */ - -#ifndef MOCK_CONSOLEKIT_MANAGER_H -#define MOCK_CONSOLEKIT_MANAGER_H - -#include -#include -#include "mock-object.h" -#include "backend-dbus/dbus-consolekit-manager.h" - -class MockConsoleKitSession; -class MockConsoleKitSeat; - -class MockConsoleKitManager: public MockObject -{ - public: - - MockConsoleKitManager (GMainLoop * loop, - GDBusConnection * bus_connection); - virtual ~MockConsoleKitManager (); - - void add_seat (MockConsoleKitSeat * seat); - - MockConsoleKitSession * current_session (); - - public: - - enum Action { None, Shutdown, Restart }; - - Action last_action () const { return my_last_action; } - - void clear_last_action () { my_last_action = None; } - - private: - - typedef std::set seats_t; - seats_t my_seats; - - ConsoleKitManager * my_skeleton; - - std::string my_current_ssid; - - Action my_last_action; - - static gboolean on_get_current_session (ConsoleKitManager *, - GDBusMethodInvocation *, - gpointer ); - static gboolean on_get_seats (ConsoleKitManager *, - GDBusMethodInvocation *, - gpointer ); - static gboolean handle_restart (ConsoleKitManager *, - GDBusMethodInvocation *, - gpointer); - static gboolean handle_stop (ConsoleKitManager *, - GDBusMethodInvocation *, - gpointer); - -}; - -#endif // #ifndef MOCK_CONSOLEKIT_MANAGER_H diff --git a/tests/backend-dbus/mock-consolekit-seat.cc b/tests/backend-dbus/mock-consolekit-seat.cc deleted file mode 100644 index ce1fbad..0000000 --- a/tests/backend-dbus/mock-consolekit-seat.cc +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright 2013 Canonical Ltd. - * - * Authors: - * Charles Kerr - * - * This program 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranties of - * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . - */ - -#include "mock-consolekit-seat.h" - -#include "mock-object.h" -#include "mock-consolekit-session.h" -#include "mock-user.h" - -namespace -{ - const char * CONSOLEKIT_BUS_NAME = "org.freedesktop.ConsoleKit"; - - std::string next_unique_sid () - { - static int id = 1; - - char * tmp; - std::string ret; - - tmp = g_strdup_printf ("/org/freedesktop/ConsoleKit/Seat%d", id++); - ret = tmp; - g_free (tmp); - return ret; - } -} - -/*** -**** -***/ - -void -MockConsoleKitSeat :: activate_session (MockConsoleKitSession * session) -{ - g_assert (my_sessions.count(session) == 1); - - const char * ssid = session->ssid (); - if (my_active_ssid != ssid) - { - my_active_ssid = ssid; - console_kit_seat_emit_active_session_changed (my_skeleton, ssid); - } -} - -void -MockConsoleKitSeat :: switch_to_guest () -{ - for (sessions_t::iterator it(my_sessions.begin()), - end(my_sessions.end()); it!=end; ++it) - { - MockConsoleKitSession * session (*it); - - if (session->user()->is_guest()) - { - activate_session (*it); - return; - } - } - - g_warn_if_reached (); -} - -void -MockConsoleKitSeat :: switch_to_user (const char * username) -{ - for (sessions_t::iterator it(my_sessions.begin()), - end(my_sessions.end()); it!=end; ++it) - { - MockConsoleKitSession * session (*it); - - if (!g_strcmp0 (username, session->user()->username())) - { - activate_session (*it); - return; - } - } - - g_warn_if_reached (); -} - -/*** -**** -***/ - -MockConsoleKitSession * -MockConsoleKitSeat :: add_session_by_user (MockUser * mu) -{ - g_assert (mu != 0); - - MockConsoleKitSession * session; - - session = new MockConsoleKitSession (my_loop, my_bus_connection); - session->set_user (mu); - add_session (session); - return session; -} - -void -MockConsoleKitSeat :: add_session (MockConsoleKitSession * session) -{ - g_assert (my_sessions.count(session) == 0); - - my_sessions.insert (session); - session->set_sid (path()); - console_kit_seat_emit_session_added (my_skeleton, session->ssid()); -} - -void -MockConsoleKitSeat :: remove_session (MockConsoleKitSession * session) -{ - g_assert (my_sessions.count(session) == 1); - - my_sessions.erase (session); - session->set_sid (""); - console_kit_seat_emit_session_removed (my_skeleton, session->ssid()); -} - -/*** -**** Handlers -***/ - -gboolean -MockConsoleKitSeat :: on_can_activate_sessions (ConsoleKitSeat * cks, - GDBusMethodInvocation * inv, - gpointer gself) -{ - bool b = static_cast(gself)->my_can_activate_sessions; - console_kit_seat_complete_can_activate_sessions (cks, inv, b); - return true; -} - -gboolean -MockConsoleKitSeat :: on_get_active_session (ConsoleKitSeat * cks, - GDBusMethodInvocation * invoke, - gpointer gself) -{ - std::string ssid = static_cast(gself)->my_active_ssid; - console_kit_seat_complete_get_active_session (cks, invoke, ssid.c_str()); - return true; -} - -gboolean -MockConsoleKitSeat :: on_get_sessions (ConsoleKitSeat * cks, - GDBusMethodInvocation * inv, - gpointer gself) -{ - int i; - const char ** paths; - sessions_t& sessions = static_cast(gself)->my_sessions; - - i = 0; - paths = g_new0 (const char*, sessions.size() + 1); - for (sessions_t::iterator it(sessions.begin()), - end(sessions.end()); it!=end; ++it) - paths[i++] = (*it)->path(); - - g_debug ("returning a list of %d sessions", i); - console_kit_seat_complete_get_sessions (cks, inv, paths); - g_free (paths); - - return true; -} - -MockConsoleKitSession * -MockConsoleKitSeat :: find (const char * ssid) -{ - for (sessions_t::iterator it(my_sessions.begin()), - end(my_sessions.end()); it!=end; ++it) - if (!g_strcmp0 ((*it)->path(), ssid)) - return *it; - - return 0; -} - -/*** -**** Life Cycle -***/ - -MockConsoleKitSeat :: MockConsoleKitSeat (GMainLoop * loop, - GDBusConnection * bus_connection, - bool can_activate_sessions): - MockObject (loop, bus_connection, CONSOLEKIT_BUS_NAME, next_unique_sid()), - my_skeleton (console_kit_seat_skeleton_new ()), - my_can_activate_sessions (can_activate_sessions) -{ - g_signal_connect (my_skeleton, "handle-get-active-session", - G_CALLBACK(on_get_active_session), this); - g_signal_connect (my_skeleton, "handle-get-sessions", - G_CALLBACK(on_get_sessions), this); - g_signal_connect (my_skeleton, "handle-can-activate-sessions", - G_CALLBACK(on_can_activate_sessions), this); - - set_skeleton (G_DBUS_INTERFACE_SKELETON(my_skeleton)); -} - -MockConsoleKitSeat :: ~MockConsoleKitSeat () -{ - for (sessions_t::iterator it(my_sessions.begin()), - end(my_sessions.end()); it!=end; ++it) - delete *it; - - g_signal_handlers_disconnect_by_data (my_skeleton, this); - g_clear_object (&my_skeleton); -} diff --git a/tests/backend-dbus/mock-consolekit-seat.h b/tests/backend-dbus/mock-consolekit-seat.h deleted file mode 100644 index aa52276..0000000 --- a/tests/backend-dbus/mock-consolekit-seat.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright 2013 Canonical Ltd. - * - * Authors: - * Charles Kerr - * - * This program 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranties of - * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . - */ - -#ifndef MOCK_CONSOLEKIT_SEAT_H -#define MOCK_CONSOLEKIT_SEAT_H - -#include -#include -#include "backend-dbus/dbus-consolekit-seat.h" -#include "mock-object.h" - -class MockUser; -class MockConsoleKitSession; - -class MockConsoleKitSeat: public MockObject -{ - public: - - MockConsoleKitSeat (GMainLoop * loop, - GDBusConnection * bus_connection, - bool can_activate_sessions); - virtual ~MockConsoleKitSeat (); - - const char * sid() { return path(); } - MockConsoleKitSession * add_session_by_user (MockUser * user); - void add_session (MockConsoleKitSession * session); - void remove_session (MockConsoleKitSession * session); - void activate_session (MockConsoleKitSession * session); - void switch_to_guest (); - void switch_to_user (const char * username); - bool can_activate_sessions () const { return my_can_activate_sessions; } - MockConsoleKitSession * find (const char * ssid); - - private: - - static gboolean on_get_active_session (ConsoleKitSeat * cks, - GDBusMethodInvocation * inv, - gpointer gself); - static gboolean on_get_sessions (ConsoleKitSeat * cks, - GDBusMethodInvocation * inv, - gpointer gself); - static gboolean on_can_activate_sessions (ConsoleKitSeat * cks, - GDBusMethodInvocation * inv, - gpointer gself); - - - private: - - ConsoleKitSeat * my_skeleton; - - std::string my_active_ssid; - - typedef std::set sessions_t; - sessions_t my_sessions; - bool my_can_activate_sessions; - -}; - -#endif // #ifndef MOCK_CONSOLEKIT_SEAT_H diff --git a/tests/backend-dbus/mock-consolekit-session.cc b/tests/backend-dbus/mock-consolekit-session.cc deleted file mode 100644 index 2f39411..0000000 --- a/tests/backend-dbus/mock-consolekit-session.cc +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2013 Canonical Ltd. - * - * Authors: - * Charles Kerr - * - * This program 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranties of - * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . - */ - -#include "mock-consolekit-session.h" -#include "mock-user.h" - -namespace -{ - const char * const DEFAULT_X11_DISPLAY = ":0:0"; - - const char * const CONSOLEKIT_NAME = "org.freedesktop.ConsoleKit"; - - std::string next_unique_ssid () - { - static int id = 333; // arbitrary - - char * tmp; - std::string ret; - - tmp = g_strdup_printf ("/org/freedesktop/ConsoleKit/Session%d", id++); - ret = tmp; - g_free (tmp); - return ret; - } -} - -void -MockConsoleKitSession :: set_user (MockUser * user) -{ - my_user = user; -} - -/*** -**** -***/ - -gboolean -MockConsoleKitSession :: on_get_seat_id_static (ConsoleKitSession * cks, - GDBusMethodInvocation * inv, - gpointer gself) -{ - const std::string& sid = static_cast(gself)->my_sid; - g_debug ("%s %s returning seat id of %s", G_STRLOC, G_STRFUNC, sid.c_str()); - console_kit_session_complete_get_seat_id (cks, inv, sid.c_str()); - return true; -} - -gboolean -MockConsoleKitSession :: on_get_unix_user_static (ConsoleKitSession * cks, - GDBusMethodInvocation * inv, - gpointer gself) -{ - MockUser * user = static_cast(gself)->my_user; - g_debug ("%s %s returning uid of %u", G_STRLOC, G_STRFUNC, user->uid()); - console_kit_session_complete_get_unix_user (cks, inv, user->uid()); - return true; -} - -gboolean -MockConsoleKitSession :: on_get_x11_display (ConsoleKitSession * cks, - GDBusMethodInvocation * inv, - gpointer gself) -{ - MockConsoleKitSession * self = static_cast(gself); - const char * x11 = self->x11_display(); - g_debug ("%s %s returning x11 display '%s'", G_STRLOC, G_STRFUNC, x11); - console_kit_session_complete_get_x11_display (cks, inv, x11); - return true; -} - -/*** -**** -***/ - -MockConsoleKitSession :: MockConsoleKitSession (GMainLoop * loop, - GDBusConnection * conn): - MockObject (loop, conn, CONSOLEKIT_NAME, next_unique_ssid ()), - my_skeleton (console_kit_session_skeleton_new ()), - my_x11_display (DEFAULT_X11_DISPLAY), - my_user (0) -{ - g_signal_connect (my_skeleton, "handle-get-seat-id", - G_CALLBACK(on_get_seat_id_static), this); - g_signal_connect (my_skeleton, "handle-get-unix-user", - G_CALLBACK(on_get_unix_user_static), this); - g_signal_connect (my_skeleton, "handle-get-x11-display", - G_CALLBACK(on_get_x11_display), this); - - set_skeleton (G_DBUS_INTERFACE_SKELETON(my_skeleton)); -} - -MockConsoleKitSession :: ~MockConsoleKitSession () -{ - const int n = g_signal_handlers_disconnect_by_data (my_skeleton, this); - g_assert (n == 3); - g_clear_object (&my_skeleton); -} diff --git a/tests/backend-dbus/mock-consolekit-session.h b/tests/backend-dbus/mock-consolekit-session.h deleted file mode 100644 index 7759f72..0000000 --- a/tests/backend-dbus/mock-consolekit-session.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright 2013 Canonical Ltd. - * - * Authors: - * Charles Kerr - * - * This program 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranties of - * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . - */ - -#ifndef MOCK_CONSOLEKIT_SESSION_H -#define MOCK_CONSOLEKIT_SESSION_H - -#include -#include "mock-object.h" -#include "backend-dbus/dbus-consolekit-session.h" - -class MockUser; - -class MockConsoleKitSession: public MockObject -{ - public: - - MockConsoleKitSession (GMainLoop * loop, - GDBusConnection * bus_connection); - virtual ~MockConsoleKitSession (); - - MockUser * user () { return my_user; } - void set_user (MockUser * user); - const char * ssid () { return path(); } - void set_sid (const std::string& sid) { my_sid = sid; } - const char * x11_display() { return my_x11_display.c_str(); } - void set_x11_display (const std::string& x) { my_x11_display = x; } - - private: - - static gboolean on_get_seat_id_static (ConsoleKitSession *, - GDBusMethodInvocation *, - gpointer); - static gboolean on_get_unix_user_static (ConsoleKitSession *, - GDBusMethodInvocation *, - gpointer); - static gboolean on_get_x11_display (ConsoleKitSession *, - GDBusMethodInvocation *, - gpointer); - - - private: - - ConsoleKitSession * my_skeleton; - std::string my_sid; - std::string my_x11_display; - MockUser * my_user; -}; - -#endif // #ifndef MOCK_CONSOLEKIT_SESSION_H diff --git a/tests/backend-dbus/mock-display-manager-seat.cc b/tests/backend-dbus/mock-display-manager-seat.cc index 9f30ae1..c8a4857 100644 --- a/tests/backend-dbus/mock-display-manager-seat.cc +++ b/tests/backend-dbus/mock-display-manager-seat.cc @@ -18,7 +18,7 @@ */ #include "mock-display-manager-seat.h" -#include "mock-consolekit-seat.h" +#include "mock-login1-seat.h" namespace { @@ -79,10 +79,10 @@ MockDisplayManagerSeat :: handle_switch_to_guest (DisplayManagerSeat * o, void MockDisplayManagerSeat :: switch_to_guest () { - g_assert (my_ck_seat != 0); + g_assert (my_login1_seat != 0); my_last_action = GUEST; - my_ck_seat->switch_to_guest (); + my_login1_seat->switch_to_guest (); } gboolean @@ -100,16 +100,16 @@ MockDisplayManagerSeat :: handle_switch_to_user (DisplayManagerSeat * o, void MockDisplayManagerSeat :: switch_to_user (const char * username) { - g_assert (my_ck_seat != 0); + g_assert (my_login1_seat != 0); my_last_action = USER; - my_ck_seat->switch_to_user (username); + my_login1_seat->switch_to_user (username); } void -MockDisplayManagerSeat :: set_consolekit_seat (MockConsoleKitSeat * seat) +MockDisplayManagerSeat :: set_login1_seat (MockLogin1Seat * seat) { - my_ck_seat = seat; + my_login1_seat = seat; } /*** @@ -120,7 +120,6 @@ MockDisplayManagerSeat :: MockDisplayManagerSeat (GMainLoop * loop, GDBusConnection * connection): MockObject (loop, connection, DISPLAY_MANAGER_NAME, next_unique_path()), my_skeleton (display_manager_seat_skeleton_new ()), - my_ck_seat (0), my_last_action (NONE) { g_signal_connect (my_skeleton, "handle-switch-to-guest", @@ -135,6 +134,6 @@ MockDisplayManagerSeat :: MockDisplayManagerSeat (GMainLoop * loop, MockDisplayManagerSeat :: ~MockDisplayManagerSeat () { - g_signal_handlers_disconnect_by_data (my_skeleton, this); + //g_signal_handlers_disconnect_by_data (my_skeleton, this); g_clear_object (&my_skeleton); } diff --git a/tests/backend-dbus/mock-display-manager-seat.h b/tests/backend-dbus/mock-display-manager-seat.h index b0ea415..fcdd17a 100644 --- a/tests/backend-dbus/mock-display-manager-seat.h +++ b/tests/backend-dbus/mock-display-manager-seat.h @@ -23,7 +23,7 @@ #include "mock-object.h" // parent class #include "backend-dbus/dbus-display-manager.h" -class MockConsoleKitSeat; +class MockLogin1Seat; class MockDisplayManagerSeat: public MockObject { @@ -35,7 +35,7 @@ class MockDisplayManagerSeat: public MockObject void set_guest_allowed (bool b); - void set_consolekit_seat (MockConsoleKitSeat * ck_seat); + void set_login1_seat (MockLogin1Seat * login1_seat); void switch_to_guest (); @@ -65,7 +65,7 @@ class MockDisplayManagerSeat: public MockObject gpointer gself); DisplayManagerSeat * my_skeleton; - MockConsoleKitSeat * my_ck_seat; + MockLogin1Seat * my_login1_seat; Action my_last_action; }; diff --git a/tests/backend-dbus/mock-login1-manager.cc b/tests/backend-dbus/mock-login1-manager.cc new file mode 100644 index 0000000..2d341df --- /dev/null +++ b/tests/backend-dbus/mock-login1-manager.cc @@ -0,0 +1,275 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include "mock-login1-manager.h" +#include "mock-login1-seat.h" +#include "mock-user.h" + +namespace +{ + const char * const BUS_NAME = "org.freedesktop.login1"; + + const char * const BUS_PATH = "/org/freedesktop/login1"; + +#if 0 + void on_active_session_changed (Login1Seat * o G_GNUC_UNUSED, + const gchar * new_ssid, + gpointer ssid) + { + *static_cast(ssid) = new_ssid; + } +#endif +} + +/*** +**** +***/ + +#if 0 +gboolean +MockLogin1Manager :: on_get_current_session (Login1Manager * m, + GDBusMethodInvocation * inv, + gpointer gself) +{ + MockLogin1Manager * self = static_cast(gself); + const std::string& ssid = self->my_current_ssid; + console_kit_manager_complete_get_current_session (m, inv, ssid.c_str()); + return true; +} + +gboolean +MockLogin1Manager :: on_get_seats (Login1Manager * m, + GDBusMethodInvocation * inv, + gpointer gself) +{ + int i; + char ** sids; + const seats_t& seats = static_cast(gself)->my_seats; + + i = 0; + sids = g_new0 (char*, seats.size()+1); + for (seats_t::const_iterator it(seats.begin()), + end(seats.end()); it!=end; ++it) + sids[i++] = (char*) (*it)->path(); + console_kit_manager_complete_get_seats (m, inv, sids); + g_strfreev (sids); + + return true; +} + +gboolean +MockLogin1Manager :: handle_restart (Login1Manager * ckm, + GDBusMethodInvocation * inv, + gpointer gself) +{ + static_cast(gself)->my_last_action = Restart; + console_kit_manager_complete_restart (ckm, inv); + return true; +} + +gboolean +MockLogin1Manager :: handle_stop (Login1Manager * ckm, + GDBusMethodInvocation * inv, + gpointer gself) +{ + static_cast(gself)->my_last_action = Shutdown; + console_kit_manager_complete_stop (ckm, inv); + return true; +} +#endif + +/*** +**** +***/ + +#if 0 +MockLogin1Session * +MockLogin1Manager :: current_session () +{ + MockLogin1Session * ret = 0; + + for (seats_t::iterator it(my_seats.begin()), + end(my_seats.end()); it!=end; ++it) + if ((ret = (*it)->find (my_current_ssid.c_str()))) + break; + + return ret; +} +#endif + +void +MockLogin1Manager :: emit_session_new (MockLogin1Seat * seat, int tag) const +{ + std::string id; + std::string path; + + seat->get_session_id_and_path_for_tag (tag, id, path); + +g_message ("%s %s emitting session-new [%s][%s]", G_STRLOC, G_STRFUNC, id.c_str(), path.c_str()); + login1_manager_emit_session_new (my_skeleton, id.c_str(), path.c_str()); +} + +int +MockLogin1Manager :: add_session (MockLogin1Seat * seat, MockUser * user) +{ + g_assert (my_seats.count(seat) == 1); + + const int tag = seat->add_session (user); + emit_session_new (seat, tag); + return tag; +} + +void +MockLogin1Manager :: add_seat (MockLogin1Seat * seat) +{ + g_assert (my_seats.count(seat) == 0); + + my_seats.insert (seat); + std::set sessions = seat->sessions (); + for (auto tag : sessions) + emit_session_new (seat, tag); +} + +/*** +**** Skeleton Handlers +***/ + +gboolean +MockLogin1Manager :: handle_can_suspend (Login1Manager * m, + GDBusMethodInvocation * inv, + gpointer gself) +{ + const std::string& s = static_cast(gself)->can_suspend(); + login1_manager_complete_can_suspend (m, inv, s.c_str()); + return true; +} + +gboolean +MockLogin1Manager :: handle_can_hibernate (Login1Manager * m, + GDBusMethodInvocation * inv, + gpointer gself) +{ + const std::string& s = static_cast(gself)->can_hibernate(); + login1_manager_complete_can_hibernate (m, inv, s.c_str()); + return true; +} + +gboolean +MockLogin1Manager :: handle_reboot (Login1Manager * m, + GDBusMethodInvocation * inv, + gboolean interactive, + gpointer gself) +{ + static_cast(gself)->my_last_action = "reboot"; + login1_manager_complete_reboot (m, inv); + return true; +} + +gboolean +MockLogin1Manager :: handle_power_off (Login1Manager * m, + GDBusMethodInvocation * inv, + gboolean interactive, + gpointer gself) +{ + static_cast(gself)->my_last_action = "power-off"; + login1_manager_complete_power_off (m, inv); + return true; +} + +gboolean +MockLogin1Manager :: handle_suspend (Login1Manager * m, + GDBusMethodInvocation * inv, + gboolean interactive, + gpointer gself) +{ + static_cast(gself)->my_last_action = "suspend"; + login1_manager_complete_suspend (m, inv); + return true; +} + +gboolean +MockLogin1Manager :: handle_hibernate (Login1Manager * m, + GDBusMethodInvocation * inv, + gboolean interactive, + gpointer gself) +{ + static_cast(gself)->my_last_action = "hibernate"; + login1_manager_complete_hibernate (m, inv); + return true; +} + +/*** +**** +***/ + +const std::string& +MockLogin1Manager :: can_suspend () const +{ + return my_can_suspend; +} + +const std::string& +MockLogin1Manager :: can_hibernate () const +{ + return my_can_hibernate; +} + +/*** +**** +***/ + +MockLogin1Manager :: MockLogin1Manager (GMainLoop * loop, + GDBusConnection * conn): + MockObject (loop, conn, BUS_NAME, BUS_PATH), + my_skeleton (login1_manager_skeleton_new ()), + my_can_suspend ("yes"), + my_can_hibernate ("yes") +{ + g_signal_connect (my_skeleton, "handle-can-suspend", + G_CALLBACK(handle_can_suspend), this); + g_signal_connect (my_skeleton, "handle-can-hibernate", + G_CALLBACK(handle_can_hibernate), this); + g_signal_connect (my_skeleton, "handle_reboot", + G_CALLBACK(handle_reboot), this); + g_signal_connect (my_skeleton, "handle-power-off", + G_CALLBACK(handle_power_off), this); + g_signal_connect (my_skeleton, "handle-suspend", + G_CALLBACK(handle_suspend), this); + g_signal_connect (my_skeleton, "handle-hibernate", + G_CALLBACK(handle_hibernate), this); +#if 0 + g_signal_connect (my_skeleton, "handle-get-seats", + G_CALLBACK(on_get_seats), this); + g_signal_connect (my_skeleton, "handle-stop", + G_CALLBACK(handle_stop), this); + g_signal_connect (my_skeleton, "handle-restart", + G_CALLBACK(handle_restart), this); +#endif + + set_skeleton (G_DBUS_INTERFACE_SKELETON(my_skeleton)); +} + +MockLogin1Manager :: ~MockLogin1Manager () +{ + for (auto seat : my_seats) + delete seat; + + g_signal_handlers_disconnect_by_data (my_skeleton, this); + g_clear_object (&my_skeleton); +} diff --git a/tests/backend-dbus/mock-login1-manager.h b/tests/backend-dbus/mock-login1-manager.h new file mode 100644 index 0000000..da05660 --- /dev/null +++ b/tests/backend-dbus/mock-login1-manager.h @@ -0,0 +1,68 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef MOCK_LOGIN1_MANAGER_H +#define MOCK_LOGIN1_MANAGER_H + +#include +#include +#include "mock-object.h" +#include "backend-dbus/dbus-login1-manager.h" + +class MockLogin1Seat; +class MockUser; + +class MockLogin1Manager: public MockObject +{ + public: + + MockLogin1Manager (GMainLoop * loop, + GDBusConnection * bus_connection); + virtual ~MockLogin1Manager (); + + int add_session (MockLogin1Seat * seat, MockUser * user); + + void add_seat (MockLogin1Seat * seat); + + const std::string& can_suspend () const; + const std::string& can_hibernate () const; + + const std::string& last_action () const { return my_last_action; } + void clear_last_action () { my_last_action.clear(); } + + private: + void emit_session_new (MockLogin1Seat * seat, int tag) const; + + static gboolean handle_can_suspend (Login1Manager *, GDBusMethodInvocation *, gpointer); + static gboolean handle_can_hibernate (Login1Manager *, GDBusMethodInvocation *, gpointer); + static gboolean handle_reboot (Login1Manager *, GDBusMethodInvocation *, gboolean, gpointer); + static gboolean handle_power_off (Login1Manager *, GDBusMethodInvocation *, gboolean, gpointer); + static gboolean handle_suspend (Login1Manager *, GDBusMethodInvocation *, gboolean, gpointer); + static gboolean handle_hibernate (Login1Manager *, GDBusMethodInvocation *, gboolean, gpointer); + + private: + + Login1Manager * my_skeleton; + std::set my_seats; + std::string my_can_suspend; + std::string my_can_hibernate; + std::string my_last_action; +}; + +#endif // #ifndef MOCK_LOGIN1_MANAGER_H diff --git a/tests/backend-dbus/mock-login1-seat.cc b/tests/backend-dbus/mock-login1-seat.cc new file mode 100644 index 0000000..a95b9e1 --- /dev/null +++ b/tests/backend-dbus/mock-login1-seat.cc @@ -0,0 +1,230 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#include "mock-login1-seat.h" + +#include "mock-object.h" +#include "mock-user.h" + +namespace +{ + const char * BUS_NAME = "org.freedesktop.login1"; + + std::string next_unique_sid () + { + static int id = 1; + + char * tmp; + std::string ret; + + tmp = g_strdup_printf ("/org/freedesktop/login1/seat/seat%d", id++); + ret = tmp; + g_free (tmp); + return ret; + } + + static int next_session_tag = 1; +} + +void +MockLogin1Seat :: get_session_id_and_path_for_tag (int tag, std::string& id, std::string& path) +{ + if (tag) + { + char tmp[80]; + + g_snprintf (tmp, sizeof(tmp), "%d", tag); + id = tmp; + + g_snprintf (tmp, sizeof(tmp), "/org/freedesktop/login1/session/%d", tag); + path = tmp; + } + else + { + id = ""; + path = ""; + } +} + + +/*** +**** +***/ + +void +MockLogin1Seat :: update_sessions_property () +{ + GVariantBuilder b; + + g_variant_builder_init (&b, G_VARIANT_TYPE("a(so)")); + for (const auto& it : my_sessions) + { + std::string id, path; + get_session_id_and_path_for_tag (it.first, id, path); + g_variant_builder_add (&b, "(so)", id.c_str(), path.c_str()); + } + + GVariant * v = g_variant_builder_end (&b); + g_message ("%s %s setting session property to %s", G_STRLOC, G_STRFUNC, g_variant_print (v, true)); + g_object_set (my_skeleton, "sessions", v, NULL); +} + +void +MockLogin1Seat :: update_active_session_property () +{ + std::string id; + std::string path; + get_session_id_and_path_for_tag (my_active_session, id, path); + + GVariant * v = g_variant_new ("(so)", id.c_str(), path.c_str()); + g_message ("%s %s setting active session property to %s", G_STRLOC, G_STRFUNC, g_variant_print (v, true)); + g_object_set (my_skeleton, "active-session", v, NULL); +} + +void +MockLogin1Seat :: update_can_multi_session_property () +{ + g_object_set (my_skeleton, "can-multi-session", my_can_multi_session, NULL); +} + +/*** +**** +***/ + +/* lists this seat's sessions in the format of Login1Manager::ListSessions() */ +GVariant * +MockLogin1Seat :: list_sessions () +{ + GVariantBuilder b; + g_variant_builder_init (&b, G_VARIANT_TYPE("a(susso)")); + for (auto it : my_sessions) + { + std::string id, path; + get_session_id_and_path_for_tag (it.first, id, path); + g_variant_builder_add (&b, "(susso)", + id.c_str(), + uint32_t(it.second->uid()), + it.second->username(), + seat_id(), + path.c_str()); + } + + return g_variant_builder_end (&b); +} + +/*** +**** +***/ + +std::set +MockLogin1Seat :: sessions () const +{ + std::set ret; + + for (auto it : my_sessions) + ret.insert (it.first); + + return ret; +} + +MockLogin1Seat :: session_tag_t +MockLogin1Seat :: add_session (MockUser * user) +{ + const session_tag_t tag = next_session_tag++; + + my_sessions[tag] = user; + update_sessions_property (); + + return tag; +} + +void +MockLogin1Seat :: remove_session (session_tag_t tag) +{ + my_sessions.erase (tag); + update_sessions_property (); +} + +/*** +**** +***/ + +void +MockLogin1Seat :: activate_session (session_tag_t tag) +{ + g_assert (my_sessions.count(tag) == 1); + + if (my_active_session != tag) + { + my_active_session = tag; + update_active_session_property (); + } +} + +void +MockLogin1Seat :: switch_to_guest () +{ + for (const auto& it : my_sessions) + { + if (it.second->is_guest()) + { + activate_session (it.first); + return; + } + } + + g_warn_if_reached (); +} + +void +MockLogin1Seat :: switch_to_user (const char * username) +{ + for (const auto& it : my_sessions) + { + if (!g_strcmp0 (username, it.second->username())) + { + activate_session (it.first); + return; + } + } + + g_warn_if_reached (); +} + +/*** +**** Life Cycle +***/ + +MockLogin1Seat :: MockLogin1Seat (GMainLoop * loop, + GDBusConnection * bus_connection, + bool can_activate_sessions): + MockObject (loop, bus_connection, BUS_NAME, next_unique_sid()), + my_skeleton (login1_seat_skeleton_new ()), + my_can_multi_session (can_activate_sessions), + my_active_session (0) + +{ + set_skeleton (G_DBUS_INTERFACE_SKELETON(my_skeleton)); + update_can_multi_session_property (); +} + +MockLogin1Seat :: ~MockLogin1Seat () +{ + g_clear_object (&my_skeleton); +} diff --git a/tests/backend-dbus/mock-login1-seat.h b/tests/backend-dbus/mock-login1-seat.h new file mode 100644 index 0000000..96ff19c --- /dev/null +++ b/tests/backend-dbus/mock-login1-seat.h @@ -0,0 +1,77 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program 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. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . + */ + +#ifndef MOCK_LOGIN1_SEAT_H +#define MOCK_LOGIN1_SEAT_H + +#include /* strrchr */ +#include +#include +#include +#include "backend-dbus/dbus-login1-seat.h" +#include "mock-object.h" + +class MockUser; +class MockLogin1Session; + +class MockLogin1Seat: public MockObject +{ + public: + + typedef int session_tag_t; + + MockLogin1Seat (GMainLoop * loop, + GDBusConnection * bus_connection, + bool can_activate_sessions); + + virtual ~MockLogin1Seat (); + + const char * seat_id() const { return strrchr(path(),'/')+1; } + + session_tag_t add_session (MockUser * user); + void remove_session (session_tag_t session); + std::set sessions () const; + int active_session () const { return my_active_session; } + + bool can_activate_sessions () const { return my_can_multi_session; } + void activate_session (session_tag_t session); + void switch_to_guest (); + void switch_to_user (const char * username); + + //const char * sid() { return path(); } + //MockLogin1Session * find (const char * ssid); + + GVariant * list_sessions (); + + static void get_session_id_and_path_for_tag (int tag, std::string& id, std::string& path); + + private: + void update_sessions_property (); + void update_active_session_property (); + void update_can_multi_session_property (); + + + private: + Login1Seat * my_skeleton; + std::map my_sessions; + session_tag_t my_active_session; + bool my_can_multi_session; +}; + +#endif // #ifndef MOCK_LOGIN1_SEAT_H diff --git a/tests/backend-dbus/mock-upower.cc b/tests/backend-dbus/mock-upower.cc deleted file mode 100644 index 65757b3..0000000 --- a/tests/backend-dbus/mock-upower.cc +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright 2013 Canonical Ltd. - * - * Authors: - * Charles Kerr - * - * This program 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranties of - * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . - */ - -#include "mock-upower.h" - - -gboolean -MockUPower :: handle_suspend (UPower * upower, - GDBusMethodInvocation * inv, - gpointer gself) -{ - static_cast(gself)->my_last_action = Suspend; - upower_complete_suspend (upower, inv); - return true; -} - -gboolean -MockUPower :: handle_hibernate (UPower * upower, - GDBusMethodInvocation * inv, - gpointer gself) -{ - static_cast(gself)->my_last_action = Hibernate; - upower_complete_hibernate (upower, inv); - return true; -} - -gboolean -MockUPower :: handle_suspend_allowed (UPower * upower, - GDBusMethodInvocation * inv, - gpointer gself) -{ - const bool allowed = static_cast(gself)->my_can_suspend; - upower_complete_suspend_allowed (upower, inv, allowed); - return true; -} - -gboolean -MockUPower :: handle_hibernate_allowed (UPower * upower, - GDBusMethodInvocation * inv, - gpointer gself) -{ - const bool allowed = static_cast(gself)->my_can_hibernate; - upower_complete_hibernate_allowed (upower, inv, allowed); - return true; -} - -/*** -**** -***/ - -namespace -{ - const char * const UPOWER_NAME = "org.freedesktop.UPower"; - const char * const UPOWER_PATH = "/org/freedesktop/UPower"; - -} - -MockUPower :: MockUPower (GMainLoop * loop, - GDBusConnection * bus_connection): - MockObject (loop, bus_connection, UPOWER_NAME, UPOWER_PATH), - my_skeleton (upower_skeleton_new ()), - my_can_suspend (true), - my_can_hibernate (true), - my_suspend_allowed (true), - my_hibernate_allowed (true), - my_last_action (None) -{ - //set_can_hibernate (false); - //set_can_suspend (true); - - g_signal_connect (my_skeleton, "handle-suspend", - G_CALLBACK(handle_suspend), this); - g_signal_connect (my_skeleton, "handle-suspend-allowed", - G_CALLBACK(handle_suspend_allowed), this); - - g_signal_connect (my_skeleton, "handle-hibernate", - G_CALLBACK(handle_hibernate), this); - g_signal_connect (my_skeleton, "handle-hibernate-allowed", - G_CALLBACK(handle_hibernate_allowed), this); - - set_skeleton (G_DBUS_INTERFACE_SKELETON(my_skeleton)); -} - -MockUPower :: ~MockUPower () -{ - g_clear_object (&my_skeleton); -} diff --git a/tests/backend-dbus/mock-upower.h b/tests/backend-dbus/mock-upower.h deleted file mode 100644 index 351d0f7..0000000 --- a/tests/backend-dbus/mock-upower.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2013 Canonical Ltd. - * - * Authors: - * Charles Kerr - * - * This program 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. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranties of - * MERCHANTABILITY, SATISFACTORY QUALITY, 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 this program. If not, see . - */ - -#ifndef MOCK_UPOWER_H -#define MOCK_UPOWER_H - -#include "mock-object.h" // parent class -#include "backend-dbus/dbus-upower.h" // UPower - -class MockUPower: public MockObject -{ - public: - - MockUPower (GMainLoop * loop, - GDBusConnection * bus_connection); - virtual ~MockUPower (); - - void set_can_suspend (bool b) { upower_set_can_suspend (my_skeleton, b); } - void set_can_hibernate (bool b) { upower_set_can_hibernate (my_skeleton, b); } - - bool suspend_allowed () const { return my_suspend_allowed; } - bool hibernate_allowed () const { return my_suspend_allowed; } - bool can_suspend () const { return upower_get_can_suspend (my_skeleton); } - bool can_hibernate () const { return upower_get_can_hibernate (my_skeleton); } - - public: - - enum Action { None, Suspend, Hibernate }; - Action last_action () { return my_last_action; } - - private: - - UPower * my_skeleton; - bool my_can_suspend; - bool my_can_hibernate; - bool my_suspend_allowed; - bool my_hibernate_allowed; - Action my_last_action; - - static gboolean handle_suspend_allowed (UPower *, - GDBusMethodInvocation *, - gpointer); - static gboolean handle_suspend (UPower *, - GDBusMethodInvocation *, - gpointer); - - static gboolean handle_hibernate_allowed (UPower *, - GDBusMethodInvocation *, - gpointer); - static gboolean handle_hibernate (UPower *, - GDBusMethodInvocation *, - gpointer); - -}; - -#endif diff --git a/tests/backend-dbus/test-actions.cc b/tests/backend-dbus/test-actions.cc index f79c913..410a02a 100644 --- a/tests/backend-dbus/test-actions.cc +++ b/tests/backend-dbus/test-actions.cc @@ -90,7 +90,7 @@ TEST_F (Actions, CanSwitch) bool b; gboolean b2; - b = ck_seat->can_activate_sessions() && !g_settings_get_boolean (s, settings_key); + b = login1_seat->can_activate_sessions() && !g_settings_get_boolean (s, settings_key); ASSERT_EQ (b, indicator_session_actions_can_switch (actions)); g_object_get (actions, INDICATOR_SESSION_ACTIONS_PROP_CAN_SWITCH, &b2, NULL); ASSERT_EQ (b, b2); @@ -172,130 +172,88 @@ TEST_F (Actions, CanLogout) TEST_F (Actions, CanSuspend) { - bool b; - bool can; - bool allowed; - gboolean b2; - - can = upower->can_suspend (); - allowed = upower->suspend_allowed (); - b = can && allowed; - - ASSERT_EQ (b, indicator_session_actions_can_suspend (actions)); - g_object_get (actions, INDICATOR_SESSION_ACTIONS_PROP_CAN_SUSPEND, &b2, NULL); - ASSERT_EQ (b, b2); - - for (int i=0; i<2; ++i) - { - can = !can; - b = can && allowed; - - upower->set_can_suspend (can); - wait_for_signal (actions, "notify::" INDICATOR_SESSION_ACTIONS_PROP_CAN_SUSPEND); - ASSERT_EQ (b, indicator_session_actions_can_suspend (actions)); - g_object_get (actions, INDICATOR_SESSION_ACTIONS_PROP_CAN_SUSPEND, &b2, NULL); - ASSERT_EQ (b, b2); - } + const std::string can_suspend = login1_manager->can_suspend (); + gboolean b = indicator_session_actions_can_suspend (actions); + ASSERT_EQ (b, can_suspend=="yes" || can_suspend=="challenge"); } TEST_F (Actions, CanHibernate) { - bool b; - bool can; - bool allowed; - gboolean b2; - - can = upower->can_hibernate (); - allowed = upower->hibernate_allowed (); - b = can && allowed; - - ASSERT_EQ (b, indicator_session_actions_can_hibernate (actions)); - g_object_get (actions, INDICATOR_SESSION_ACTIONS_PROP_CAN_HIBERNATE, &b2, NULL); - ASSERT_EQ (b, b2); - -#if 0 - for (int i=0; i<2; ++i) - { - b = !b; - upower->set_can_hibernate (b); - wait_for_signal (actions, "notify::" INDICATOR_SESSION_ACTIONS_PROP_CAN_HIBERNATE); - ASSERT_EQ (b, indicator_session_actions_can_hibernate (actions)); - g_object_get (actions, INDICATOR_SESSION_ACTIONS_PROP_CAN_HIBERNATE, &b2, NULL); - ASSERT_EQ (b, b2); - } -#endif + const std::string can_hibernate = login1_manager->can_hibernate (); + gboolean b = indicator_session_actions_can_hibernate (actions); + ASSERT_EQ (b, can_hibernate=="yes" || can_hibernate=="challenge"); } -TEST_F (Actions, Restart) +TEST_F (Actions, Reboot) { - ASSERT_EQ (MockConsoleKitManager::None, ck_manager->last_action()); + ASSERT_TRUE (login1_manager->last_action().empty()); // confirm that user is prompted // and that no action is taken when the user cancels the dialog - indicator_session_actions_restart (actions); + indicator_session_actions_reboot (actions); wait_msec (50); ASSERT_TRUE (end_session_dialog->is_open()); end_session_dialog->cancel(); wait_msec (50); - ASSERT_EQ (MockConsoleKitManager::None, ck_manager->last_action()); + ASSERT_TRUE (login1_manager->last_action().empty()); // confirm that user is prompted // and that no action is taken when the user cancels the dialog - indicator_session_actions_restart (actions); + indicator_session_actions_reboot (actions); wait_msec (50); ASSERT_TRUE (end_session_dialog->is_open ()); end_session_dialog->confirm_reboot (); wait_msec (100); - ASSERT_EQ (MockConsoleKitManager::Restart, ck_manager->last_action()); + ASSERT_EQ (login1_manager->last_action(), "reboot"); - // confirm that we try to restart w/o prompting + // confirm that we try to reboot w/o prompting // if the EndSessionDialog isn't available delete end_session_dialog; end_session_dialog = 0; - ck_manager->clear_last_action (); - ASSERT_EQ (MockConsoleKitManager::None, ck_manager->last_action()); + login1_manager->clear_last_action (); + ASSERT_TRUE (login1_manager->last_action().empty()); wait_msec (50); - indicator_session_actions_restart (actions); + indicator_session_actions_reboot (actions); wait_msec (50); - ASSERT_EQ (MockConsoleKitManager::Restart, ck_manager->last_action()); + ASSERT_EQ (login1_manager->last_action(), "reboot"); } -TEST_F (Actions, Shutdown) +TEST_F (Actions, PowerOff) { - ASSERT_EQ (MockConsoleKitManager::None, ck_manager->last_action()); + ASSERT_TRUE (login1_manager->last_action().empty()); // confirm that user is prompted // and that no action is taken when the user cancels the dialog - indicator_session_actions_shutdown (actions); + indicator_session_actions_power_off (actions); wait_msec (50); ASSERT_TRUE (end_session_dialog->is_open()); end_session_dialog->cancel(); wait_msec (50); - ASSERT_EQ (MockConsoleKitManager::None, ck_manager->last_action()); + ASSERT_TRUE (login1_manager->last_action().empty()); // confirm that user is prompted // and that no action is taken when the user cancels the dialog - indicator_session_actions_shutdown (actions); + indicator_session_actions_power_off (actions); wait_msec (50); ASSERT_TRUE (end_session_dialog->is_open ()); end_session_dialog->confirm_shutdown (); wait_msec (100); - ASSERT_EQ (MockConsoleKitManager::Shutdown, ck_manager->last_action()); + ASSERT_EQ (login1_manager->last_action(), "power-off"); // confirm that we try to shutdown w/o prompting // if the EndSessionDialog isn't available delete end_session_dialog; end_session_dialog = 0; - ck_manager->clear_last_action (); + login1_manager->clear_last_action (); wait_msec (50); - indicator_session_actions_shutdown (actions); + indicator_session_actions_power_off (actions); wait_msec (50); - ASSERT_EQ (MockConsoleKitManager::Shutdown, ck_manager->last_action()); + ASSERT_EQ (login1_manager->last_action(), "power-off"); } TEST_F (Actions, Logout) { - ASSERT_EQ (MockConsoleKitManager::None, ck_manager->last_action()); + ASSERT_EQ (MockSessionManager::None, session_manager->last_action ()); // confirm that user is prompted // and that no action is taken when the user cancels the dialog @@ -308,7 +266,7 @@ TEST_F (Actions, Logout) // confirm that user is prompted // and that no action is taken when the user cancels the dialog - indicator_session_actions_shutdown (actions); + indicator_session_actions_logout (actions); wait_msec (50); ASSERT_TRUE (end_session_dialog->is_open ()); end_session_dialog->confirm_logout (); @@ -327,18 +285,18 @@ TEST_F (Actions, Logout) TEST_F (Actions, Suspend) { - ASSERT_EQ (MockUPower::None, upower->last_action()); + ASSERT_TRUE (login1_manager->last_action().empty()); indicator_session_actions_suspend (actions); wait_msec (50); - ASSERT_EQ (MockUPower::Suspend, upower->last_action()); + ASSERT_EQ (login1_manager->last_action(), "suspend"); } TEST_F (Actions, Hibernate) { - ASSERT_EQ (MockUPower::None, upower->last_action()); + ASSERT_TRUE (login1_manager->last_action().empty()); indicator_session_actions_hibernate (actions); wait_msec (50); - ASSERT_EQ (MockUPower::Hibernate, upower->last_action()); + ASSERT_EQ (login1_manager->last_action(), "hibernate"); } TEST_F (Actions, SwitchToScreensaver) @@ -362,18 +320,19 @@ TEST_F (Actions, SwitchToGuest) // allow guests dm_seat->set_guest_allowed (true); MockUser * guest_user; - MockConsoleKitSession * guest_ck_session; + //int guest_session_tag; +// MockConsoleKitSession * guest_ck_session; // set up a guest guest_user = new MockUser (loop, conn, "guest-zzbEVV", "Guest", 10); guest_user->set_system_account (true); accounts->add_user (guest_user); - guest_ck_session = ck_seat->add_session_by_user (guest_user); + int guest_session_tag = login1_manager->add_session (login1_seat, guest_user); // try to switch to guest indicator_session_actions_switch_to_guest (actions); - wait_for_signal (ck_seat->skeleton(), "active-session-changed"); - ASSERT_EQ (guest_ck_session, ck_manager->current_session()); + wait_for_signal (login1_seat->skeleton(), "notify::active-session"); + ASSERT_EQ (guest_session_tag, login1_seat->active_session()); wait_msec (50); } @@ -383,28 +342,28 @@ TEST_F (Actions, SwitchToUsername) const char * const dr2_username = "ptroughton"; MockUser * dr1_user; MockUser * dr2_user; - MockConsoleKitSession * dr1_session; - MockConsoleKitSession * dr2_session; + int dr1_session; + int dr2_session; dr1_user = accounts->find_by_username (dr1_username); - dr1_session = ck_seat->add_session_by_user (dr1_user); + dr1_session = login1_manager->add_session (login1_seat, dr1_user); dr2_user = accounts->find_by_username (dr2_username); - dr2_session = ck_seat->add_session_by_user (dr2_user); + dr2_session = login1_manager->add_session (login1_seat, dr2_user); indicator_session_actions_switch_to_username (actions, dr1_username); - wait_for_signal (ck_seat->skeleton(), "active-session-changed"); - ASSERT_EQ (dr1_session, ck_manager->current_session()); + wait_for_signal (login1_seat->skeleton(), "notify::active-session"); + ASSERT_EQ (dr1_session, login1_seat->active_session()); wait_msec (50); indicator_session_actions_switch_to_username (actions, dr2_username); - wait_for_signal (ck_seat->skeleton(), "active-session-changed"); - ASSERT_EQ (dr2_session, ck_manager->current_session()); + wait_for_signal (login1_seat->skeleton(), "notify::active-session"); + ASSERT_EQ (dr2_session, login1_seat->active_session()); wait_msec (50); indicator_session_actions_switch_to_username (actions, dr1_username); - wait_for_signal (ck_seat->skeleton(), "active-session-changed"); - ASSERT_EQ (dr1_session, ck_manager->current_session()); + wait_for_signal (login1_seat->skeleton(), "notify::active-session"); + ASSERT_EQ (dr1_session, login1_seat->active_session()); wait_msec (50); } -- cgit v1.2.3 From 0ca4b9a4e6b552b9a59bade1d8d44cc950ded994 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 23:08:12 -0500 Subject: in backend-dbus/users.c, fix a user proxy leak --- src/backend-dbus/users.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 4466ede..c135610 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -172,6 +172,7 @@ object_unref_and_disconnect (gpointer instance) gulong * handler_id = l->data; g_signal_handler_disconnect (instance, *handler_id); g_free (handler_id); + g_object_unref (instance); } g_slist_free (ids); -- cgit v1.2.3 From 3882e60f88c19b4522a08145230b7101c1a127d3 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 23:12:03 -0500 Subject: In tests/, enable debuginfo and warnings for C++ file. Fix a couple of minor compile warnings. --- tests/backend-dbus/mock-end-session-dialog.cc | 12 ++++++------ tests/backend-dbus/mock-webcredentials.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/backend-dbus/mock-end-session-dialog.cc b/tests/backend-dbus/mock-end-session-dialog.cc index e289a83..903962b 100644 --- a/tests/backend-dbus/mock-end-session-dialog.cc +++ b/tests/backend-dbus/mock-end-session-dialog.cc @@ -44,10 +44,10 @@ MockEndSessionDialog :: handle_simulate_user_activity (GnomeScreenSaver * s gboolean MockEndSessionDialog :: handle_open (EndSessionDialog * object, GDBusMethodInvocation * invocation, - guint arg_type, - guint arg_timestamp, - guint arg_seconds_to_stay_open, - const gchar * const * inhibitor_paths, + guint arg_type G_GNUC_UNUSED, + guint arg_timestamp G_GNUC_UNUSED, + guint arg_seconds_to_stay_open G_GNUC_UNUSED, + const gchar * const * inhibitor_paths G_GNUC_UNUSED, gpointer gself) { static_cast(gself)->my_isOpen = true; @@ -68,8 +68,8 @@ namespace MockEndSessionDialog :: MockEndSessionDialog (GMainLoop * loop, GDBusConnection * bus_connection): MockObject (loop, bus_connection, MY_NAME, MY_PATH), - my_isOpen (false), - my_skeleton (end_session_dialog_skeleton_new ()) + my_skeleton (end_session_dialog_skeleton_new ()), + my_isOpen (false) { g_signal_connect (my_skeleton, "handle-open", G_CALLBACK(handle_open), this); diff --git a/tests/backend-dbus/mock-webcredentials.h b/tests/backend-dbus/mock-webcredentials.h index 212ca76..fd1b10c 100644 --- a/tests/backend-dbus/mock-webcredentials.h +++ b/tests/backend-dbus/mock-webcredentials.h @@ -32,7 +32,7 @@ class MockWebcredentials: public MockObject virtual ~MockWebcredentials (); bool has_error () const { return webcredentials_get_error_status (my_skeleton); } - bool set_error (bool b) const { webcredentials_set_error_status (my_skeleton, b); } + void set_error (bool b) const { webcredentials_set_error_status (my_skeleton, b); } private: -- cgit v1.2.3 From 084f6cdc08117e26c34a8c6afa00735bd3d75b4a Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 23:13:37 -0500 Subject: remove unused method MockAccounts::find_by_path() --- tests/backend-dbus/mock-accounts.cc | 12 ------------ tests/backend-dbus/mock-accounts.h | 1 - 2 files changed, 13 deletions(-) diff --git a/tests/backend-dbus/mock-accounts.cc b/tests/backend-dbus/mock-accounts.cc index 2a0e7e7..c753c79 100644 --- a/tests/backend-dbus/mock-accounts.cc +++ b/tests/backend-dbus/mock-accounts.cc @@ -69,18 +69,6 @@ MockAccounts :: find_by_uid (guint64 uid) return 0; } -MockUser * -MockAccounts :: find_by_path (const char * path) -{ - const path_to_user_t::iterator it (my_path_to_user.find(path)); - - if (it != my_path_to_user.end()) - return it->second; - - g_warn_if_reached (); - return 0; -} - MockUser * MockAccounts :: find_by_username (const char * username) { diff --git a/tests/backend-dbus/mock-accounts.h b/tests/backend-dbus/mock-accounts.h index 95da102..8032441 100644 --- a/tests/backend-dbus/mock-accounts.h +++ b/tests/backend-dbus/mock-accounts.h @@ -40,7 +40,6 @@ class MockAccounts: public MockObject void remove_user (MockUser * user); size_t size() const { return my_users.size(); } MockUser * find_by_uid (guint64 uid); - MockUser * find_by_path (const char * path); MockUser * find_by_username (const char * username); private: -- cgit v1.2.3 From 0f8caa36ee3efac6ccf0861deb9af9e1c186885d Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 23:14:57 -0500 Subject: fix the first four tests in test-users: HelloWorld, InitialUsers, UserAdded, and UserRemoved. --- tests/backend-dbus/CMakeLists.txt | 2 +- tests/backend-dbus/gtest-mock-dbus-fixture.h | 1 + tests/backend-dbus/mock-login1-manager.cc | 51 +++++++++++++++++++++++--- tests/backend-dbus/mock-login1-manager.h | 4 +++ tests/backend-dbus/mock-login1-seat.cc | 52 ++++++++++++++++++++------- tests/backend-dbus/mock-login1-seat.h | 16 ++++----- tests/backend-dbus/test-users.cc | 54 ++++++++++++++++++++-------- 7 files changed, 141 insertions(+), 39 deletions(-) diff --git a/tests/backend-dbus/CMakeLists.txt b/tests/backend-dbus/CMakeLists.txt index ed9c93a..e28d8e6 100644 --- a/tests/backend-dbus/CMakeLists.txt +++ b/tests/backend-dbus/CMakeLists.txt @@ -5,7 +5,7 @@ add_library (gtest STATIC set_target_properties (gtest PROPERTIES INCLUDE_DIRECTORIES ${GTEST_INCLUDE_DIR}) -SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") +SET (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -g ${CC_WARNING_ARGS}") # build desktopmock add_library (desktopmock STATIC diff --git a/tests/backend-dbus/gtest-mock-dbus-fixture.h b/tests/backend-dbus/gtest-mock-dbus-fixture.h index 1b1b895..bab82bf 100644 --- a/tests/backend-dbus/gtest-mock-dbus-fixture.h +++ b/tests/backend-dbus/gtest-mock-dbus-fixture.h @@ -65,6 +65,7 @@ class GTestMockDBusFixture: public GTestDBusFixture dm_seat->set_guest_allowed (false); login1_manager = new MockLogin1Manager (loop, conn); login1_seat = new MockLogin1Seat (loop, conn, true); + g_setenv ("XDG_SEAT", login1_seat->seat_id(), TRUE); login1_manager->add_seat (login1_seat); accounts = build_accounts_mock (); MockUser * user = accounts->find_by_username ("msmith"); diff --git a/tests/backend-dbus/mock-login1-manager.cc b/tests/backend-dbus/mock-login1-manager.cc index 2d341df..0c1acc9 100644 --- a/tests/backend-dbus/mock-login1-manager.cc +++ b/tests/backend-dbus/mock-login1-manager.cc @@ -146,10 +146,50 @@ MockLogin1Manager :: add_seat (MockLogin1Seat * seat) emit_session_new (seat, tag); } +/*** +**** +***/ + +GVariant * +MockLogin1Manager :: list_sessions () const +{ + GVariantBuilder b; + + g_variant_builder_init (&b, G_VARIANT_TYPE("a(susso)")); + + for (auto seat : my_seats) + { + GVariant * seat_sessions = seat->list_sessions (); + + GVariantIter iter; + g_variant_iter_init (&iter, seat_sessions); + GVariant * child; + while ((child = g_variant_iter_next_value (&iter))) + { + g_variant_builder_add_value (&b, child); + g_variant_unref (child); + } + } + + GVariant * v = g_variant_builder_end (&b); + g_message ("%s %s returning %s", G_STRLOC, G_STRFUNC, g_variant_print (v, true)); + return v; +} + /*** **** Skeleton Handlers ***/ +gboolean +MockLogin1Manager :: handle_list_sessions (Login1Manager * m, + GDBusMethodInvocation * inv, + gpointer gself) +{ + GVariant * sessions = static_cast(gself)->list_sessions(); + login1_manager_complete_list_sessions (m, inv, sessions); + return true; +} + gboolean MockLogin1Manager :: handle_can_suspend (Login1Manager * m, GDBusMethodInvocation * inv, @@ -173,7 +213,7 @@ MockLogin1Manager :: handle_can_hibernate (Login1Manager * m, gboolean MockLogin1Manager :: handle_reboot (Login1Manager * m, GDBusMethodInvocation * inv, - gboolean interactive, + gboolean interactive G_GNUC_UNUSED, gpointer gself) { static_cast(gself)->my_last_action = "reboot"; @@ -184,7 +224,7 @@ MockLogin1Manager :: handle_reboot (Login1Manager * m, gboolean MockLogin1Manager :: handle_power_off (Login1Manager * m, GDBusMethodInvocation * inv, - gboolean interactive, + gboolean interactive G_GNUC_UNUSED, gpointer gself) { static_cast(gself)->my_last_action = "power-off"; @@ -195,7 +235,7 @@ MockLogin1Manager :: handle_power_off (Login1Manager * m, gboolean MockLogin1Manager :: handle_suspend (Login1Manager * m, GDBusMethodInvocation * inv, - gboolean interactive, + gboolean interactive G_GNUC_UNUSED, gpointer gself) { static_cast(gself)->my_last_action = "suspend"; @@ -206,7 +246,7 @@ MockLogin1Manager :: handle_suspend (Login1Manager * m, gboolean MockLogin1Manager :: handle_hibernate (Login1Manager * m, GDBusMethodInvocation * inv, - gboolean interactive, + gboolean interactive G_GNUC_UNUSED, gpointer gself) { static_cast(gself)->my_last_action = "hibernate"; @@ -253,6 +293,9 @@ MockLogin1Manager :: MockLogin1Manager (GMainLoop * loop, G_CALLBACK(handle_suspend), this); g_signal_connect (my_skeleton, "handle-hibernate", G_CALLBACK(handle_hibernate), this); + g_signal_connect (my_skeleton, "handle-list-sessions", + G_CALLBACK(handle_list_sessions), this); + #if 0 g_signal_connect (my_skeleton, "handle-get-seats", G_CALLBACK(on_get_seats), this); diff --git a/tests/backend-dbus/mock-login1-manager.h b/tests/backend-dbus/mock-login1-manager.h index da05660..a093f7f 100644 --- a/tests/backend-dbus/mock-login1-manager.h +++ b/tests/backend-dbus/mock-login1-manager.h @@ -47,8 +47,12 @@ class MockLogin1Manager: public MockObject void clear_last_action () { my_last_action.clear(); } private: + void emit_session_new (MockLogin1Seat * seat, int tag) const; + GVariant * list_sessions () const; + + static gboolean handle_list_sessions (Login1Manager *, GDBusMethodInvocation *, gpointer); static gboolean handle_can_suspend (Login1Manager *, GDBusMethodInvocation *, gpointer); static gboolean handle_can_hibernate (Login1Manager *, GDBusMethodInvocation *, gpointer); static gboolean handle_reboot (Login1Manager *, GDBusMethodInvocation *, gboolean, gpointer); diff --git a/tests/backend-dbus/mock-login1-seat.cc b/tests/backend-dbus/mock-login1-seat.cc index a95b9e1..08a18dc 100644 --- a/tests/backend-dbus/mock-login1-seat.cc +++ b/tests/backend-dbus/mock-login1-seat.cc @@ -49,10 +49,10 @@ MockLogin1Seat :: get_session_id_and_path_for_tag (int tag, std::string& id, std { char tmp[80]; - g_snprintf (tmp, sizeof(tmp), "%d", tag); + g_snprintf (tmp, sizeof(tmp), "c%d", tag); id = tmp; - g_snprintf (tmp, sizeof(tmp), "/org/freedesktop/login1/session/%d", tag); + g_snprintf (tmp, sizeof(tmp), "/org/freedesktop/login1/session/%s", id.c_str()); path = tmp; } else @@ -143,10 +143,10 @@ MockLogin1Seat :: sessions () const return ret; } -MockLogin1Seat :: session_tag_t +int MockLogin1Seat :: add_session (MockUser * user) { - const session_tag_t tag = next_session_tag++; + const int tag = next_session_tag++; my_sessions[tag] = user; update_sessions_property (); @@ -155,9 +155,9 @@ MockLogin1Seat :: add_session (MockUser * user) } void -MockLogin1Seat :: remove_session (session_tag_t tag) +MockLogin1Seat :: remove_session (int session_tag) { - my_sessions.erase (tag); + my_sessions.erase (session_tag); update_sessions_property (); } @@ -165,15 +165,43 @@ MockLogin1Seat :: remove_session (session_tag_t tag) **** ***/ +MockUser * +MockLogin1Seat :: active_user () +{ + auto it = my_sessions.find (active_session()); + return it == my_sessions.end() ? NULL : it->second; +} + +const MockUser * +MockLogin1Seat :: active_user () const +{ + auto it = my_sessions.find (active_session()); + return it == my_sessions.end() ? NULL : it->second; +} + +int +MockLogin1Seat :: find_session_for_user (guint uid) const +{ + for (auto it : my_sessions) + if (it.second->uid() == uid) + return it.first; + + return 0; +} + void -MockLogin1Seat :: activate_session (session_tag_t tag) +MockLogin1Seat :: activate_session (int session_tag) { - g_assert (my_sessions.count(tag) == 1); + g_assert (my_sessions.count(session_tag) == 1); - if (my_active_session != tag) + if (my_active_session != session_tag) { - my_active_session = tag; + std::string id, path; + my_active_session = session_tag; + get_session_id_and_path_for_tag (session_tag, id, path); + g_setenv ("XDG_SESSION_ID", id.c_str(), true); update_active_session_property (); + } } @@ -216,8 +244,8 @@ MockLogin1Seat :: MockLogin1Seat (GMainLoop * loop, bool can_activate_sessions): MockObject (loop, bus_connection, BUS_NAME, next_unique_sid()), my_skeleton (login1_seat_skeleton_new ()), - my_can_multi_session (can_activate_sessions), - my_active_session (0) + my_active_session (0), + my_can_multi_session (can_activate_sessions) { set_skeleton (G_DBUS_INTERFACE_SKELETON(my_skeleton)); diff --git a/tests/backend-dbus/mock-login1-seat.h b/tests/backend-dbus/mock-login1-seat.h index 96ff19c..473d21a 100644 --- a/tests/backend-dbus/mock-login1-seat.h +++ b/tests/backend-dbus/mock-login1-seat.h @@ -34,8 +34,6 @@ class MockLogin1Seat: public MockObject { public: - typedef int session_tag_t; - MockLogin1Seat (GMainLoop * loop, GDBusConnection * bus_connection, bool can_activate_sessions); @@ -44,13 +42,16 @@ class MockLogin1Seat: public MockObject const char * seat_id() const { return strrchr(path(),'/')+1; } - session_tag_t add_session (MockUser * user); - void remove_session (session_tag_t session); + int add_session (MockUser * user); + void remove_session (int session_tag); std::set sessions () const; int active_session () const { return my_active_session; } + MockUser * active_user (); + const MockUser * active_user () const; + int find_session_for_user (guint uid) const; bool can_activate_sessions () const { return my_can_multi_session; } - void activate_session (session_tag_t session); + void activate_session (int session_tag); void switch_to_guest (); void switch_to_user (const char * username); @@ -66,11 +67,10 @@ class MockLogin1Seat: public MockObject void update_active_session_property (); void update_can_multi_session_property (); - private: Login1Seat * my_skeleton; - std::map my_sessions; - session_tag_t my_active_session; + std::map my_sessions; + int my_active_session; bool my_can_multi_session; }; diff --git a/tests/backend-dbus/test-users.cc b/tests/backend-dbus/test-users.cc index bd0547d..fa52df3 100644 --- a/tests/backend-dbus/test-users.cc +++ b/tests/backend-dbus/test-users.cc @@ -153,23 +153,25 @@ TEST_F (Users, HelloWorld) ASSERT_TRUE (true); } - /** * Confirm that 'users' can get the cached users from our Mock Accounts */ TEST_F (Users, InitialUsers) { - const guint logged_in_uid = ck_session->user()->uid(); GStrv keys = indicator_session_users_get_keys (users); + const MockUser * active_user = login1_seat->active_user (); ASSERT_EQ (12, g_strv_length (keys)); for (int i=0; keys && keys[i]; ++i) { - MockUser * mu = accounts->find_by_path (keys[i]); - const bool is_logged_in = mu->uid() == logged_in_uid; - const bool is_current_user = mu->uid() == logged_in_uid; - compare_user (keys[i], mu, is_logged_in, is_current_user); + IndicatorSessionUser * isu = indicator_session_users_get_user (users, keys[i]); + MockUser * mu = accounts->find_by_uid (isu->uid); + const bool is_logged_in = login1_seat->find_session_for_user (isu->uid) != 0; + const bool is_active = active_user && (active_user->uid() == isu->uid); + compare_user (isu, mu, is_logged_in, is_active); + + indicator_session_user_free (isu); } g_strfreev (keys); @@ -187,7 +189,9 @@ TEST_F (Users, UserAdded) ASSERT_EQ (0, event_keys.size()); wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_ADDED, 1); ASSERT_EQ (1, event_keys.size()); - ASSERT_STREQ (mu->path(), event_keys[0].c_str()); + IndicatorSessionUser * isu = indicator_session_users_get_user (users, event_keys[0].c_str()); + ASSERT_EQ (mu->uid(), isu->uid); + indicator_session_user_free (isu); compare_user (event_keys[0], mu, false, false); } @@ -197,24 +201,45 @@ TEST_F (Users, UserAdded) */ TEST_F (Users, UserRemoved) { - MockUser * mu; + MockUser * mu = accounts->find_by_username ("pdavison"); - mu = accounts->find_by_username ("pdavison"); + /* confirm that users knows about pdavison */ + bool found = false; + GStrv keys = indicator_session_users_get_keys (users); + ASSERT_EQ (12, g_strv_length (keys)); + for (int i=0; !found && keys && keys[i]; i++) + { + IndicatorSessionUser * isu = indicator_session_users_get_user (users, keys[i]); + found = isu->uid == mu->uid(); + indicator_session_user_free (isu); + } + g_strfreev (keys); + ASSERT_TRUE (found); + + /* on the bus, remove pdavison. */ accounts->remove_user (mu); + + /* now, users should emit a 'user removed' signal... */ ASSERT_EQ (0, event_keys.size()); wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_REMOVED, 1); ASSERT_EQ (1, event_keys.size()); - ASSERT_STREQ (mu->path(), event_keys[0].c_str()); - GStrv keys = indicator_session_users_get_keys (users); + /* confirm that users doesn't know about pdavison */ + keys = indicator_session_users_get_keys (users); ASSERT_EQ (11, g_strv_length (keys)); + for (int i=0; keys && keys[i]; i++) + { + IndicatorSessionUser * isu = indicator_session_users_get_user (users, keys[i]); + ASSERT_NE (event_keys[0], keys[i]); + ASSERT_NE (mu->uid(), isu->uid); + indicator_session_user_free (isu); + } g_strfreev (keys); - ASSERT_TRUE (indicator_session_users_get_user (users, mu->path()) == NULL); - delete mu; } +#if 0 /** * Confirm that 'users' notices when a user's real name changes */ @@ -368,10 +393,11 @@ TEST_F (Users, LiveSession) MockConsoleKitSession * session = ck_seat->add_session_by_user (live_user); wait_msec (100); ck_seat->activate_session (session); - wait_for_signal (users, "notify::"INDICATOR_SESSION_USERS_PROP_IS_LIVE_SESSION); + wait_for_signal (users, "notify::" INDICATOR_SESSION_USERS_PROP_IS_LIVE_SESSION); // confirm the backend thinks it's a live session ASSERT_TRUE (indicator_session_users_is_live_session (users)); g_object_get (users, INDICATOR_SESSION_USERS_PROP_IS_LIVE_SESSION, &b, NULL); ASSERT_TRUE (b); } +#endif -- cgit v1.2.3 From c572f9940e9c0081e281d13e8f8038dcb1b92c3c Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 25 Jun 2013 01:07:36 -0500 Subject: in tests-users, fix 3 more tests: RealnameChanged, LogInLogOut, ActivateSession --- tests/backend-dbus/mock-accounts.cc | 5 +- tests/backend-dbus/mock-login1-manager.cc | 25 ++++++-- tests/backend-dbus/mock-login1-manager.h | 2 + tests/backend-dbus/mock-login1-seat.cc | 22 ++----- tests/backend-dbus/mock-login1-seat.h | 5 +- tests/backend-dbus/test-users.cc | 95 +++++++++++++------------------ 6 files changed, 69 insertions(+), 85 deletions(-) diff --git a/tests/backend-dbus/mock-accounts.cc b/tests/backend-dbus/mock-accounts.cc index c753c79..16e37d2 100644 --- a/tests/backend-dbus/mock-accounts.cc +++ b/tests/backend-dbus/mock-accounts.cc @@ -107,9 +107,8 @@ MockAccounts :: on_list_cached_users_static (Accounts * a, i = 0; paths = g_new0 (const char*, users.size() + 1); - for (users_t::iterator it(users.begin()), - end(users.end()); it!=end; ++it) - paths[i++] = (*it)->path(); + for (auto it : users) + paths[i++] = it->path(); accounts_complete_list_cached_users (a, invocation, paths); g_free (paths); diff --git a/tests/backend-dbus/mock-login1-manager.cc b/tests/backend-dbus/mock-login1-manager.cc index 0c1acc9..3bd652b 100644 --- a/tests/backend-dbus/mock-login1-manager.cc +++ b/tests/backend-dbus/mock-login1-manager.cc @@ -121,7 +121,6 @@ MockLogin1Manager :: emit_session_new (MockLogin1Seat * seat, int tag) const seat->get_session_id_and_path_for_tag (tag, id, path); -g_message ("%s %s emitting session-new [%s][%s]", G_STRLOC, G_STRFUNC, id.c_str(), path.c_str()); login1_manager_emit_session_new (my_skeleton, id.c_str(), path.c_str()); } @@ -130,9 +129,27 @@ MockLogin1Manager :: add_session (MockLogin1Seat * seat, MockUser * user) { g_assert (my_seats.count(seat) == 1); - const int tag = seat->add_session (user); - emit_session_new (seat, tag); - return tag; + const int session_tag = seat->add_session (user); + emit_session_new (seat, session_tag); + return session_tag; +} + +void +MockLogin1Manager :: emit_session_removed (MockLogin1Seat * seat, int tag) const +{ + std::string id; + std::string path; + + seat->get_session_id_and_path_for_tag (tag, id, path); + + login1_manager_emit_session_removed (my_skeleton, id.c_str(), path.c_str()); +} + +void +MockLogin1Manager :: remove_session (MockLogin1Seat * seat, int session_tag) +{ + seat->remove_session (session_tag); + emit_session_removed (seat, session_tag); } void diff --git a/tests/backend-dbus/mock-login1-manager.h b/tests/backend-dbus/mock-login1-manager.h index a093f7f..f630329 100644 --- a/tests/backend-dbus/mock-login1-manager.h +++ b/tests/backend-dbus/mock-login1-manager.h @@ -37,6 +37,7 @@ class MockLogin1Manager: public MockObject virtual ~MockLogin1Manager (); int add_session (MockLogin1Seat * seat, MockUser * user); + void remove_session (MockLogin1Seat * seat, int session_tag); void add_seat (MockLogin1Seat * seat); @@ -49,6 +50,7 @@ class MockLogin1Manager: public MockObject private: void emit_session_new (MockLogin1Seat * seat, int tag) const; + void emit_session_removed (MockLogin1Seat * seat, int tag) const; GVariant * list_sessions () const; diff --git a/tests/backend-dbus/mock-login1-seat.cc b/tests/backend-dbus/mock-login1-seat.cc index 08a18dc..46dc5f9 100644 --- a/tests/backend-dbus/mock-login1-seat.cc +++ b/tests/backend-dbus/mock-login1-seat.cc @@ -165,28 +165,14 @@ MockLogin1Seat :: remove_session (int session_tag) **** ***/ -MockUser * -MockLogin1Seat :: active_user () -{ - auto it = my_sessions.find (active_session()); - return it == my_sessions.end() ? NULL : it->second; -} - -const MockUser * -MockLogin1Seat :: active_user () const -{ - auto it = my_sessions.find (active_session()); - return it == my_sessions.end() ? NULL : it->second; -} - -int -MockLogin1Seat :: find_session_for_user (guint uid) const +std::string +MockLogin1Seat :: user_state (unsigned int uid) const { for (auto it : my_sessions) if (it.second->uid() == uid) - return it.first; + return it.first == my_active_session ? "active" : "online"; - return 0; + return "offline"; // no matching session } void diff --git a/tests/backend-dbus/mock-login1-seat.h b/tests/backend-dbus/mock-login1-seat.h index 473d21a..254ebe9 100644 --- a/tests/backend-dbus/mock-login1-seat.h +++ b/tests/backend-dbus/mock-login1-seat.h @@ -46,9 +46,8 @@ class MockLogin1Seat: public MockObject void remove_session (int session_tag); std::set sessions () const; int active_session () const { return my_active_session; } - MockUser * active_user (); - const MockUser * active_user () const; - int find_session_for_user (guint uid) const; + + std::string user_state (unsigned int uid) const; bool can_activate_sessions () const { return my_can_multi_session; } void activate_session (int session_tag); diff --git a/tests/backend-dbus/test-users.cc b/tests/backend-dbus/test-users.cc index fa52df3..d477a4f 100644 --- a/tests/backend-dbus/test-users.cc +++ b/tests/backend-dbus/test-users.cc @@ -62,31 +62,23 @@ class Users: public GTestMockDBusFixture protected: - void compare_user (const IndicatorSessionUser * isu, - MockUser * mu, - bool is_logged_in, - bool is_current_user) + void compare_user (const MockUser * mu, const IndicatorSessionUser * isu, const std::string& user_state) { - ASSERT_TRUE (isu != 0); - ASSERT_TRUE (mu != 0); - + ASSERT_EQ (user_state, login1_seat->user_state (mu->uid())); ASSERT_EQ (mu->uid(), isu->uid); ASSERT_EQ (mu->login_frequency(), isu->login_frequency); ASSERT_STREQ (mu->username(), isu->user_name); ASSERT_STREQ (mu->realname(), isu->real_name); - ASSERT_EQ (is_logged_in, isu->is_logged_in); - ASSERT_EQ (is_current_user, isu->is_current_user); - // FIXME: test icon file? + ASSERT_EQ (mu->uid(), isu->uid); + ASSERT_EQ (user_state!="offline", isu->is_logged_in); + ASSERT_EQ (user_state=="active", isu->is_current_user); } - void compare_user (const std::string & key, - MockUser * mu, - bool is_logged_in, - bool is_current_user) + void compare_user (const MockUser * mu, const std::string& key, const std::string& user_state) { IndicatorSessionUser * isu; isu = indicator_session_users_get_user (users, key.c_str()); - compare_user (isu, mu, is_logged_in, is_current_user); + compare_user (mu, isu, user_state); indicator_session_user_free (isu); } @@ -159,7 +151,6 @@ TEST_F (Users, HelloWorld) TEST_F (Users, InitialUsers) { GStrv keys = indicator_session_users_get_keys (users); - const MockUser * active_user = login1_seat->active_user (); ASSERT_EQ (12, g_strv_length (keys)); @@ -167,10 +158,7 @@ TEST_F (Users, InitialUsers) { IndicatorSessionUser * isu = indicator_session_users_get_user (users, keys[i]); MockUser * mu = accounts->find_by_uid (isu->uid); - const bool is_logged_in = login1_seat->find_session_for_user (isu->uid) != 0; - const bool is_active = active_user && (active_user->uid() == isu->uid); - compare_user (isu, mu, is_logged_in, is_active); - + compare_user (mu, isu, login1_seat->user_state (isu->uid)); indicator_session_user_free (isu); } @@ -189,11 +177,7 @@ TEST_F (Users, UserAdded) ASSERT_EQ (0, event_keys.size()); wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_ADDED, 1); ASSERT_EQ (1, event_keys.size()); - IndicatorSessionUser * isu = indicator_session_users_get_user (users, event_keys[0].c_str()); - ASSERT_EQ (mu->uid(), isu->uid); - indicator_session_user_free (isu); - - compare_user (event_keys[0], mu, false, false); + compare_user (mu, event_keys[0], "offline"); } /** @@ -239,7 +223,6 @@ TEST_F (Users, UserRemoved) delete mu; } -#if 0 /** * Confirm that 'users' notices when a user's real name changes */ @@ -254,8 +237,7 @@ TEST_F (Users, RealnameChanged) ASSERT_STREQ (mu->realname(), realname); wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 1); ASSERT_EQ (1, event_keys.size()); - ASSERT_STREQ (mu->path(), event_keys[0].c_str()); - compare_user (mu->path(), mu, false, false); + compare_user (mu, event_keys[0], "offline"); } /** @@ -266,21 +248,18 @@ TEST_F (Users, LogInLogOut) // The fist doctor logs in. // Confirm that 'users' notices. MockUser * mu = accounts->find_by_username ("whartnell"); - compare_user (mu->path(), mu, false, false); - MockConsoleKitSession * session = ck_seat->add_session_by_user (mu); + ASSERT_EQ (login1_seat->user_state (mu->uid()), "offline"); + const int session_tag = login1_manager->add_session (login1_seat, mu); wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 1); - ASSERT_STREQ (mu->path(), event_keys[0].c_str()); - compare_user (mu->path(), mu, true, false); + ASSERT_EQ (1, event_keys.size()); + compare_user (mu, event_keys[0], "online"); - // The fist doctor logs out. + // The first doctor logs out. // Confirm that 'users' notices. - ck_seat->remove_session (session); + login1_manager->remove_session (login1_seat, session_tag); wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 1); ASSERT_EQ (1, event_keys.size()); - ASSERT_STREQ (mu->path(), event_keys[0].c_str()); - compare_user (event_keys[0], mu, false, false); - - delete session; + compare_user (mu, event_keys[0], "offline"); } /** @@ -288,34 +267,36 @@ TEST_F (Users, LogInLogOut) */ TEST_F (Users, ActivateSession) { - // The fist doctor logs in. - // Confirm that 'users' notices. - MockUser * mu = accounts->find_by_username ("whartnell"); - compare_user (mu->path(), mu, false, false); - MockConsoleKitSession * session = ck_seat->add_session_by_user (mu); + // confirm preconditions: msmith is active, msmith is offline + MockUser * const whartnell = accounts->find_by_username ("whartnell"); + ASSERT_EQ (login1_seat->user_state (whartnell->uid()), "offline"); + MockUser * const msmith = accounts->find_by_username ("msmith"); + ASSERT_EQ (login1_seat->user_state (msmith->uid()), "active"); + + // whartnell logs in... confirm that 'users' notices + login1_manager->add_session (login1_seat, whartnell); wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 1); - ASSERT_STREQ (mu->path(), event_keys[0].c_str()); - compare_user (mu->path(), mu, true, false); + ASSERT_EQ (1, event_keys.size()); + compare_user (whartnell, event_keys[0], "online"); - // activate the first doctor's session. - // confirm that 'users' sees he's active and that ck_session isn't. - // this should come in the form of two 'user-changed' events - ck_seat->activate_session (session); + // activate whartnell's session... confirm that 'users' sees: + // 1. msmith changes from 'active' to 'online' + // 2. whartnell changes from 'online' to 'active' + login1_seat->switch_to_user (whartnell->username()); wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 2); ASSERT_EQ (2, event_keys.size()); - compare_user (event_keys[0], ck_session->user(), true, false); - compare_user (event_keys[1], mu, true, true); + compare_user (msmith, event_keys[0], "online"); + compare_user (whartnell, event_keys[1], "active"); - // switch back to the previous - // confirm that 'users' sees it's active and the first doctor's session isn't - // this should come in the form of two 'user-changed' events - ck_seat->activate_session (ck_session); + // reverse the test + login1_seat->switch_to_user (msmith->username()); wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 2); ASSERT_EQ (2, event_keys.size()); - compare_user (event_keys[0], mu, true, false); - compare_user (event_keys[1], ck_session->user(), true, true); + compare_user (whartnell, event_keys[0], "online"); + compare_user (msmith, event_keys[1], "active"); } +#if 0 /** * Confirm that we can change the active session via users' API. * This is nearly the same as ActivateSession but uses users' API -- cgit v1.2.3 From b3938a1f14b687d62ad1d6e4e27bac47f58722de Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 25 Jun 2013 11:16:34 -0500 Subject: in IndicatorSessionUsers, use the uid as the user's key. Users.ActivateUser is now green. --- src/backend-dbus/users.c | 73 +++++++++---------------- src/service.c | 40 +++++++------- src/users.c | 38 ++++++------- src/users.h | 30 +++++------ tests/CMakeLists.txt | 4 +- tests/backend-dbus/test-users.cc | 114 +++++++++++++++++++-------------------- tests/backend-mock-users.c | 52 +++++++----------- tests/backend-mock-users.h | 3 +- tests/test-service.cc | 43 +++++++-------- 9 files changed, 178 insertions(+), 219 deletions(-) diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index c135610..48de06c 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -53,33 +53,22 @@ G_DEFINE_TYPE (IndicatorSessionUsersDbus, **** ***/ -static const gchar * -get_public_key_for_uid (guint uid) -{ - static char buf[16]; - g_snprintf (buf, sizeof(buf), "%u", uid); - return buf; -} - static void emit_user_added (IndicatorSessionUsersDbus * self, guint uid) { - const gchar * const public_key = get_public_key_for_uid (uid); - indicator_session_users_added (INDICATOR_SESSION_USERS(self), public_key); + indicator_session_users_added (INDICATOR_SESSION_USERS(self), uid); } static void emit_user_changed (IndicatorSessionUsersDbus * self, guint uid) { - const gchar * const public_key = get_public_key_for_uid (uid); - indicator_session_users_changed (INDICATOR_SESSION_USERS(self), public_key); + indicator_session_users_changed (INDICATOR_SESSION_USERS(self), uid); } static void emit_user_removed (IndicatorSessionUsersDbus * self, guint uid) { - const gchar * const public_key = get_public_key_for_uid (uid); - indicator_session_users_removed (INDICATOR_SESSION_USERS(self), public_key); + indicator_session_users_removed (INDICATOR_SESSION_USERS(self), uid); } /*** @@ -124,22 +113,22 @@ static void set_logins (IndicatorSessionUsersDbus * self, GHashTable * logins) { GHashTable * old_logins = self->priv->logins; - gpointer key; + gpointer uid; GHashTableIter iter; self->priv->logins = logins; /* fire 'user changed' event for users who logged out */ g_hash_table_iter_init (&iter, old_logins); - while ((g_hash_table_iter_next (&iter, &key, NULL))) - if (!g_hash_table_contains (logins, key)) - emit_user_changed (self, GPOINTER_TO_INT(key)); + while ((g_hash_table_iter_next (&iter, &uid, NULL))) + if (!g_hash_table_contains (logins, uid)) + emit_user_changed (self, GPOINTER_TO_UINT(uid)); /* fire 'user changed' event for users who logged in */ g_hash_table_iter_init (&iter, logins); - while ((g_hash_table_iter_next (&iter, &key, NULL))) - if (!g_hash_table_contains (old_logins, key)) - emit_user_changed (self, GPOINTER_TO_INT(key)); + while ((g_hash_table_iter_next (&iter, &uid, NULL))) + if (!g_hash_table_contains (old_logins, uid)) + emit_user_changed (self, GPOINTER_TO_UINT(uid)); g_hash_table_destroy (old_logins); } @@ -205,12 +194,6 @@ get_user_for_uid (IndicatorSessionUsersDbus * self, guint uid) return g_hash_table_lookup (p->uid_to_account, GUINT_TO_POINTER(uid)); } -static AccountsUser * -get_user_for_public_key (IndicatorSessionUsersDbus * self, const char * public_key) -{ - return get_user_for_uid (self, g_ascii_strtoull (public_key, NULL, 10)); -} - /*** **** User Account Tracking ***/ @@ -520,19 +503,19 @@ set_display_manager_seat (IndicatorSessionUsersDbus * self, /* switch to (or create) a session for the specified user */ static void -my_activate_user (IndicatorSessionUsers * users, const char * public_key) +my_activate_user (IndicatorSessionUsers * users, guint uid) { IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS(users); priv_t * p = self->priv; AccountsUser * au; const char * username; - au = get_user_for_public_key (self, public_key); + au = get_user_for_uid (self, uid); username = au ? accounts_user_get_user_name (au) : NULL; if (!username) { - g_warning ("%s %s can't find user for '%s'", G_STRLOC, G_STRFUNC, public_key); + g_warning ("%s %s can't find user '%u'", G_STRLOC, G_STRFUNC, uid); } else { @@ -556,36 +539,31 @@ my_is_live_session (IndicatorSessionUsers * users) return INDICATOR_SESSION_USERS_DBUS(users)->priv->is_live; } -/* get a list of public keys for the users that we know about */ -static GStrv -my_get_keys (IndicatorSessionUsers * users) +/* get a list of our user ids */ +static GList * +my_get_uids (IndicatorSessionUsers * users) { - int i; priv_t * p; - gchar ** keys; + GList * uids; GHashTableIter iter; gpointer uid; gpointer user; - GHashTable * h; g_return_val_if_fail (INDICATOR_IS_SESSION_USERS_DBUS(users), NULL); p = INDICATOR_SESSION_USERS_DBUS (users)->priv; - i = 0; - h = p->uid_to_account; - keys = g_new (gchar*, g_hash_table_size(h)+1); - g_hash_table_iter_init (&iter, h); + uids = NULL; + g_hash_table_iter_init (&iter, p->uid_to_account); while (g_hash_table_iter_next (&iter, &uid, &user)) if (!accounts_user_get_system_account (user)) - keys[i++] = g_strdup (get_public_key_for_uid ((guint)uid)); - keys[i] = NULL; + uids = g_list_prepend (uids, uid); - return keys; + return uids; } /* build a new struct populated with info on the specified user */ static IndicatorSessionUser * -my_get_user (IndicatorSessionUsers * users, const gchar * public_key) +my_get_user (IndicatorSessionUsers * users, guint uid) { IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (users); priv_t * p = self->priv; @@ -593,11 +571,10 @@ my_get_user (IndicatorSessionUsers * users, const gchar * public_key) AccountsUser * au; ret = NULL; - au = get_user_for_public_key (self, public_key); - + au = get_user_for_uid (self, uid); if (au && !accounts_user_get_system_account(au)) { - const guint uid = accounts_user_get_uid (au); + g_assert (uid == accounts_user_get_uid (au)); ret = g_new0 (IndicatorSessionUser, 1); ret->uid = uid; @@ -662,7 +639,7 @@ indicator_session_users_dbus_class_init (IndicatorSessionUsersDbusClass * klass) users_class = INDICATOR_SESSION_USERS_CLASS (klass); users_class->is_live_session = my_is_live_session; - users_class->get_keys = my_get_keys; + users_class->get_uids = my_get_uids; users_class->get_user = my_get_user; users_class->activate_user = my_activate_user; diff --git a/src/service.c b/src/service.c index e41cca6..1fcbd07 100644 --- a/src/service.c +++ b/src/service.c @@ -206,13 +206,13 @@ update_header_action (IndicatorSessionService * self) static GMenuModel * create_switch_section (IndicatorSessionService * self); static void -add_user (IndicatorSessionService * self, const gchar * key) +add_user (IndicatorSessionService * self, guint uid) { IndicatorSessionUser * u; /* update our user table */ - u = indicator_session_users_get_user (self->priv->backend_users, key); - g_hash_table_insert (self->priv->users, g_strdup(key), u); + u = indicator_session_users_get_user (self->priv->backend_users, uid); + g_hash_table_insert (self->priv->users, GUINT_TO_POINTER(uid), u); /* enqueue rebuilds for the affected sections */ rebuild_switch_section_soon (self); @@ -222,30 +222,30 @@ add_user (IndicatorSessionService * self, const gchar * key) static void on_user_added (IndicatorSessionUsers * backend_users G_GNUC_UNUSED, - const char * key, + guint uid, gpointer gself) { - add_user (INDICATOR_SESSION_SERVICE(gself), key); + add_user (INDICATOR_SESSION_SERVICE(gself), uid); } static void on_user_changed (IndicatorSessionUsers * backend_users G_GNUC_UNUSED, - const char * key, + guint uid, gpointer gself) { - add_user (INDICATOR_SESSION_SERVICE(gself), key); + add_user (INDICATOR_SESSION_SERVICE(gself), uid); } static void on_user_removed (IndicatorSessionUsers * backend_users G_GNUC_UNUSED, - const char * key, + guint uid, gpointer gself) { IndicatorSessionService * self = INDICATOR_SESSION_SERVICE (gself); g_return_if_fail (self != NULL); /* update our user table */ - g_hash_table_remove (self->priv->users, key); + g_hash_table_remove (self->priv->users, GUINT_TO_POINTER(uid)); /* enqueue rebuilds for the affected sections */ rebuild_switch_section_soon (self); @@ -334,13 +334,13 @@ create_user_switcher_state (IndicatorSessionService * self) GVariantBuilder * b; GVariant * val; GHashTableIter ht_iter; - gpointer ht_key, ht_value; + gpointer ht_value; const char * current_user; current_user = ""; a = g_variant_builder_new (G_VARIANT_TYPE("as")); g_hash_table_iter_init (&ht_iter, self->priv->users); - while (g_hash_table_iter_next (&ht_iter, &ht_key, &ht_value)) + while (g_hash_table_iter_next (&ht_iter, NULL, &ht_value)) { const IndicatorSessionUser * u = ht_value; @@ -950,8 +950,8 @@ static void /* cppcheck-suppress unusedFunction */ indicator_session_service_init (IndicatorSessionService * self) { - int i; - GStrv keys; + GList * l; + GList * uids; priv_t * p; gpointer gp; @@ -970,14 +970,14 @@ indicator_session_service_init (IndicatorSessionService * self) &p->backend_guest); /* init our key-to-User table */ - p->users = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, + p->users = g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, (GDestroyNotify)indicator_session_user_free); - keys = indicator_session_users_get_keys (p->backend_users); - for (i=0; keys && keys[i]; ++i) - add_user (self, keys[i]); - g_strfreev (keys); + uids = indicator_session_users_get_uids (p->backend_users); + for (l=uids; l!=NULL; l=l->next) + add_user (self, GPOINTER_TO_UINT(l->data)); + g_list_free (uids); init_gactions (self); diff --git a/src/users.c b/src/users.c index 4b9c0ad..5e4d910 100644 --- a/src/users.c +++ b/src/users.c @@ -75,24 +75,24 @@ indicator_session_users_class_init (IndicatorSessionUsersClass * klass) G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IndicatorSessionUsersClass, user_added), NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); signals[USER_REMOVED] = g_signal_new (INDICATOR_SESSION_USERS_SIGNAL_USER_REMOVED, G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IndicatorSessionUsersClass, user_removed), NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); signals[USER_CHANGED] = g_signal_new (INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (IndicatorSessionUsersClass, user_changed), NULL, NULL, - g_cclosure_marshal_VOID__STRING, - G_TYPE_NONE, 1, G_TYPE_STRING); + g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, 1, G_TYPE_UINT); properties[PROP_IS_LIVE_SESSION] = @@ -115,30 +115,30 @@ indicator_session_users_init (IndicatorSessionUsers * self G_GNUC_UNUSED) **** Virtual Functions ***/ -GStrv -indicator_session_users_get_keys (IndicatorSessionUsers * self) +GList * +indicator_session_users_get_uids (IndicatorSessionUsers * self) { g_return_val_if_fail (INDICATOR_IS_SESSION_USERS (self), NULL); - return INDICATOR_SESSION_USERS_GET_CLASS (self)->get_keys (self); + return INDICATOR_SESSION_USERS_GET_CLASS (self)->get_uids (self); } IndicatorSessionUser * indicator_session_users_get_user (IndicatorSessionUsers * self, - const char * key) + guint uid) { g_return_val_if_fail (INDICATOR_IS_SESSION_USERS (self), NULL); - return INDICATOR_SESSION_USERS_GET_CLASS (self)->get_user (self, key); + return INDICATOR_SESSION_USERS_GET_CLASS (self)->get_user (self, uid); } void indicator_session_users_activate_user (IndicatorSessionUsers * self, - const char * key) + guint uid) { g_return_if_fail (INDICATOR_IS_SESSION_USERS (self)); - INDICATOR_SESSION_USERS_GET_CLASS (self)->activate_user (self, key); + INDICATOR_SESSION_USERS_GET_CLASS (self)->activate_user (self, uid); } gboolean @@ -165,27 +165,27 @@ indicator_session_user_free (IndicatorSessionUser * user) ***/ void -indicator_session_users_added (IndicatorSessionUsers * self, const char * key) +indicator_session_users_added (IndicatorSessionUsers * self, guint uid) { g_return_if_fail (INDICATOR_IS_SESSION_USERS (self)); - g_signal_emit (self, signals[USER_ADDED], 0, key); + g_signal_emit (self, signals[USER_ADDED], 0, uid); } void -indicator_session_users_removed (IndicatorSessionUsers * self, const char * key) +indicator_session_users_removed (IndicatorSessionUsers * self, guint uid) { g_return_if_fail (INDICATOR_IS_SESSION_USERS (self)); - g_signal_emit (self, signals[USER_REMOVED], 0, key); + g_signal_emit (self, signals[USER_REMOVED], 0, uid); } void -indicator_session_users_changed (IndicatorSessionUsers * self, const char * key) +indicator_session_users_changed (IndicatorSessionUsers * self, guint uid) { g_return_if_fail (INDICATOR_IS_SESSION_USERS (self)); - g_signal_emit (self, signals[USER_CHANGED], 0, key); + g_signal_emit (self, signals[USER_CHANGED], 0, uid); } void diff --git a/src/users.h b/src/users.h index f2d7404..9871766 100644 --- a/src/users.h +++ b/src/users.h @@ -72,13 +72,13 @@ struct _IndicatorSessionUsersClass /* signals */ void (* user_added) (IndicatorSessionUsers * self, - const gchar * key); + guint uid); void (* user_removed) (IndicatorSessionUsers * self, - const gchar * key); + guint uid); void (* user_changed) (IndicatorSessionUsers * self, - const gchar * key); + guint uid); /* pure virtual functions */ @@ -86,13 +86,13 @@ struct _IndicatorSessionUsersClass gboolean (* is_live_session) (IndicatorSessionUsers * self); - GStrv (* get_keys) (IndicatorSessionUsers * self); + GList* (* get_uids) (IndicatorSessionUsers * self); IndicatorSessionUser * (* get_user) (IndicatorSessionUsers * self, - const gchar * key); + guint uid); void ( * activate_user) (IndicatorSessionUsers * self, - const gchar * key); + guint uid); }; /*** @@ -103,15 +103,15 @@ GType indicator_session_users_get_type (void); /* emits the "user-added" signal */ void indicator_session_users_added (IndicatorSessionUsers * self, - const gchar * key); + guint uid); /* emits the "user-removed" signal */ void indicator_session_users_removed (IndicatorSessionUsers * self, - const gchar * key); + guint uid); /* emits the "user-changed" signal */ void indicator_session_users_changed (IndicatorSessionUsers * self, - const gchar * key); + guint uid); /* notify listeners of a change to the 'is-live-session' property */ void indicator_session_users_notify_is_live_session (IndicatorSessionUsers * self); @@ -125,12 +125,12 @@ void indicator_session_users_notify_is_live_session (IndicatorSessionUsers * sel gboolean indicator_session_users_is_live_session (IndicatorSessionUsers * users); /** - * Get a list of user keys. + * Get a list of the users to show in the indicator * - * Return value: (transfer full): a NULL-terminated array of user keys. - * Free with g_strfreev() when done. + * Return value: (transfer container): a GList of guint user ids. + * Free with g_slist_free() when done. */ -GStrv indicator_session_users_get_keys (IndicatorSessionUsers * users); +GList * indicator_session_users_get_uids (IndicatorSessionUsers * users); /** * Get information about a particular user. @@ -141,14 +141,14 @@ GStrv indicator_session_users_get_keys (IndicatorSessionUsers * users); */ IndicatorSessionUser * indicator_session_users_get_user (IndicatorSessionUsers * users, - const gchar * key); + guint uid); /* frees a IndicatorSessionUser struct */ void indicator_session_user_free (IndicatorSessionUser * user); /* activate to a different session */ void indicator_session_users_activate_user (IndicatorSessionUsers * self, - const char * key); + guint uid); G_END_DECLS diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 45ab69f..f67008e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -39,13 +39,13 @@ add_library (backendmock STATIC backend-mock-guest.h backend-mock-users.c backend-mock-users.h) -set_target_properties (backendmock PROPERTIES COMPILE_FLAGS " ${CC_WARNING_ARGS}") +set_target_properties (backendmock PROPERTIES COMPILE_FLAGS " ${CC_WARNING_ARGS} -std=c++0x -g") # test-service add_executable (test-service test-service.cc gschemas.compiled) -set_target_properties (test-service PROPERTIES COMPILE_FLAGS " ${CC_WARNING_ARGS}") +set_target_properties (test-service PROPERTIES COMPILE_FLAGS " ${CC_WARNING_ARGS} -std=c++0x -g") add_test (test-service test-service) add_dependencies (test-service libindicatorsessionservice backendmock) target_link_libraries (test-service libindicatorsessionservice backendmock gtest ${SERVICE_LIBRARIES} ${GTEST_LIBS}) diff --git a/tests/backend-dbus/test-users.cc b/tests/backend-dbus/test-users.cc index d477a4f..279796e 100644 --- a/tests/backend-dbus/test-users.cc +++ b/tests/backend-dbus/test-users.cc @@ -74,10 +74,18 @@ class Users: public GTestMockDBusFixture ASSERT_EQ (user_state=="active", isu->is_current_user); } - void compare_user (const MockUser * mu, const std::string& key, const std::string& user_state) + void compare_user (const MockUser * mu, guint uid, const std::string& user_state) { IndicatorSessionUser * isu; - isu = indicator_session_users_get_user (users, key.c_str()); + isu = indicator_session_users_get_user (users, uid); + compare_user (mu, isu, user_state); + indicator_session_user_free (isu); + } + + void compare_user (guint uid, const std::string& user_state) + { + IndicatorSessionUser * isu = indicator_session_users_get_user (users, uid); + MockUser * mu = accounts->find_by_uid (uid); compare_user (mu, isu, user_state); indicator_session_user_free (isu); } @@ -99,12 +107,12 @@ class Users: public GTestMockDBusFixture static void wait_for_signals__event (IndicatorSessionUser * u G_GNUC_UNUSED, - const char * key, - gpointer gself) + guint uid, + gpointer gself) { Users * self = static_cast(gself); - self->event_keys.push_back (key); + self->event_keys.push_back (uid); if (self->event_keys.size() == self->expected_event_count) g_main_loop_quit (self->loop); @@ -112,7 +120,7 @@ class Users: public GTestMockDBusFixture protected: - std::vector event_keys; + std::vector event_keys; size_t expected_event_count; void wait_for_signals (gpointer o, const gchar * name, size_t n) @@ -150,19 +158,18 @@ TEST_F (Users, HelloWorld) */ TEST_F (Users, InitialUsers) { - GStrv keys = indicator_session_users_get_keys (users); + GList * l; + GList * uids = indicator_session_users_get_uids (users); - ASSERT_EQ (12, g_strv_length (keys)); + ASSERT_EQ (12, g_list_length (uids)); - for (int i=0; keys && keys[i]; ++i) + for (l=uids; l!=NULL; l=l->next) { - IndicatorSessionUser * isu = indicator_session_users_get_user (users, keys[i]); - MockUser * mu = accounts->find_by_uid (isu->uid); - compare_user (mu, isu, login1_seat->user_state (isu->uid)); - indicator_session_user_free (isu); + const guint uid = GPOINTER_TO_UINT (l->data); + compare_user (uid, login1_seat->user_state (uid)); } - g_strfreev (keys); + g_list_free (uids); } /** @@ -188,17 +195,10 @@ TEST_F (Users, UserRemoved) MockUser * mu = accounts->find_by_username ("pdavison"); /* confirm that users knows about pdavison */ - bool found = false; - GStrv keys = indicator_session_users_get_keys (users); - ASSERT_EQ (12, g_strv_length (keys)); - for (int i=0; !found && keys && keys[i]; i++) - { - IndicatorSessionUser * isu = indicator_session_users_get_user (users, keys[i]); - found = isu->uid == mu->uid(); - indicator_session_user_free (isu); - } - g_strfreev (keys); - ASSERT_TRUE (found); + IndicatorSessionUser * isu = indicator_session_users_get_user (users, mu->uid()); + ASSERT_TRUE (isu != NULL); + compare_user (mu, isu, "offline"); + g_clear_pointer (&isu, indicator_session_user_free); /* on the bus, remove pdavison. */ accounts->remove_user (mu); @@ -208,17 +208,14 @@ TEST_F (Users, UserRemoved) wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_REMOVED, 1); ASSERT_EQ (1, event_keys.size()); - /* confirm that users doesn't know about pdavison */ - keys = indicator_session_users_get_keys (users); - ASSERT_EQ (11, g_strv_length (keys)); - for (int i=0; keys && keys[i]; i++) - { - IndicatorSessionUser * isu = indicator_session_users_get_user (users, keys[i]); - ASSERT_NE (event_keys[0], keys[i]); - ASSERT_NE (mu->uid(), isu->uid); - indicator_session_user_free (isu); - } - g_strfreev (keys); + /* confirm that users won't give us pdavison's info */ + isu = indicator_session_users_get_user (users, mu->uid()); + ASSERT_TRUE (isu == NULL); + + /* confirm that users won't give us pdavison's uid */ + GList * uids = indicator_session_users_get_uids (users); + ASSERT_TRUE (g_list_find (uids, GUINT_TO_POINTER(mu->uid())) == NULL); + g_list_free (uids); delete mu; } @@ -296,43 +293,42 @@ TEST_F (Users, ActivateSession) compare_user (msmith, event_keys[1], "active"); } -#if 0 /** * Confirm that we can change the active session via users' API. * This is nearly the same as ActivateSession but uses users' API */ TEST_F (Users, ActivateUser) { - // The fist doctor logs in. - // Confirm that 'users' notices. - MockUser * mu = accounts->find_by_username ("whartnell"); - compare_user (mu->path(), mu, false, false); - MockConsoleKitSession * session = ck_seat->add_session_by_user (mu); + // confirm preconditions: msmith is active, msmith is offline + MockUser * const whartnell = accounts->find_by_username ("whartnell"); + ASSERT_EQ (login1_seat->user_state (whartnell->uid()), "offline"); + MockUser * const msmith = accounts->find_by_username ("msmith"); + ASSERT_EQ (login1_seat->user_state (msmith->uid()), "active"); + + // whartnell logs in... confirm that 'users' notices + login1_manager->add_session (login1_seat, whartnell); wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 1); - ASSERT_STREQ (mu->path(), event_keys[0].c_str()); - compare_user (mu->path(), mu, true, false); + ASSERT_EQ (1, event_keys.size()); + compare_user (whartnell, event_keys[0], "online"); - // activate the first doctor's session. - // confirm that 'users' sees he's active and that ck_session isn't. - // this should come in the form of two 'user-changed' events - indicator_session_users_activate_user (users, mu->path()); - ck_seat->activate_session (session); + // activate whartnell's session... confirm that 'users' sees: + // 1. msmith changes from 'active' to 'online' + // 2. whartnell changes from 'online' to 'active' + indicator_session_users_activate_user (users, whartnell->uid()); wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 2); ASSERT_EQ (2, event_keys.size()); - compare_user (event_keys[0], ck_session->user(), true, false); - compare_user (event_keys[1], mu, true, true); - - // switch back to the previous - // confirm that 'users' sees it's active and the first doctor's session isn't - // this should come in the form of two 'user-changed' events - indicator_session_users_activate_user (users, ck_session->user()->path()); - ck_seat->activate_session (ck_session); + compare_user (msmith, event_keys[0], "online"); + compare_user (whartnell, event_keys[1], "active"); + + // reverse the test + indicator_session_users_activate_user (users, msmith->uid()); wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_CHANGED, 2); ASSERT_EQ (2, event_keys.size()); - compare_user (event_keys[0], mu, true, false); - compare_user (event_keys[1], ck_session->user(), true, true); + compare_user (whartnell, event_keys[0], "online"); + compare_user (msmith, event_keys[1], "active"); } +#if 0 /** * Confirm that adding a Guest doesn't show up in the users list */ diff --git a/tests/backend-mock-users.c b/tests/backend-mock-users.c index d9ab5a8..bae40b6 100644 --- a/tests/backend-mock-users.c +++ b/tests/backend-mock-users.c @@ -58,35 +58,21 @@ my_is_live_session (IndicatorSessionUsers * users G_GNUC_UNUSED) } static void -my_activate_user (IndicatorSessionUsers * users, const char * key) +my_activate_user (IndicatorSessionUsers * users, guint uid) { - g_message ("%s %s users %p key %s FIXME", G_STRLOC, G_STRFUNC, (void*)users, key); + g_message ("%s %s users %p uid %u FIXME", G_STRLOC, G_STRFUNC, (void*)users, uid); } -static GStrv -my_get_keys (IndicatorSessionUsers * users) +static GList * +my_get_uids (IndicatorSessionUsers * users) { - int i; - priv_t * p; - gchar ** keys; - GHashTableIter iter; - gpointer key; - g_return_val_if_fail (INDICATOR_IS_SESSION_USERS_MOCK(users), NULL); - p = INDICATOR_SESSION_USERS_MOCK (users)->priv; - - i = 0; - keys = g_new (gchar*, g_hash_table_size(p->users)+1); - g_hash_table_iter_init (&iter, p->users); - while (g_hash_table_iter_next (&iter, &key, NULL)) - keys[i++] = g_strdup (key); - keys[i] = NULL; - return keys; + return g_hash_table_get_keys (INDICATOR_SESSION_USERS_MOCK(users)->priv->users); } static IndicatorSessionUser * -my_get_user (IndicatorSessionUsers * self, const gchar * key) +my_get_user (IndicatorSessionUsers * self, guint uid) { priv_t * p; const IndicatorSessionUser * src; @@ -95,7 +81,7 @@ my_get_user (IndicatorSessionUsers * self, const gchar * key) g_return_val_if_fail (INDICATOR_IS_SESSION_USERS_MOCK(self), NULL); p = INDICATOR_SESSION_USERS_MOCK (self)->priv; - if ((src = g_hash_table_lookup (p->users, key))) + if ((src = g_hash_table_lookup (p->users, GUINT_TO_POINTER(uid)))) { ret = g_new0 (IndicatorSessionUser, 1); ret->is_current_user = src->is_current_user; @@ -123,7 +109,7 @@ indicator_session_users_mock_class_init (IndicatorSessionUsersMockClass * klass) users_class = INDICATOR_SESSION_USERS_CLASS (klass); users_class->is_live_session = my_is_live_session; - users_class->get_keys = my_get_keys; + users_class->get_uids = my_get_uids; users_class->get_user = my_get_user; users_class->activate_user = my_activate_user; @@ -141,9 +127,9 @@ indicator_session_users_mock_init (IndicatorSessionUsersMock * self) IndicatorSessionUsersMockPriv); self->priv = p; - p->users = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, + p->users = g_hash_table_new_full (g_direct_hash, + g_direct_equal, + NULL, (GDestroyNotify)indicator_session_user_free); g_signal_connect_swapped (mock_settings, "changed::is-live-session", @@ -165,25 +151,25 @@ indicator_session_users_mock_new (void) void indicator_session_users_mock_add_user (IndicatorSessionUsersMock * self, - const char * key, IndicatorSessionUser * user) { g_return_if_fail (INDICATOR_IS_SESSION_USERS_MOCK (self)); - g_return_if_fail (key && *key); g_return_if_fail (user != NULL); + g_return_if_fail (user->uid > 0); + g_return_if_fail (!g_hash_table_contains (self->priv->users, GUINT_TO_POINTER(user->uid))); - g_hash_table_insert (self->priv->users, g_strdup(key), user); - indicator_session_users_added (INDICATOR_SESSION_USERS (self), key); + g_hash_table_insert (self->priv->users, GUINT_TO_POINTER(user->uid), user); + indicator_session_users_added (INDICATOR_SESSION_USERS (self), user->uid); } void indicator_session_users_mock_remove_user (IndicatorSessionUsersMock * self, - const char * key) + guint uid) { g_return_if_fail (INDICATOR_IS_SESSION_USERS_MOCK (self)); - g_return_if_fail (key && *key); + g_return_if_fail (uid > 0); - g_hash_table_remove (self->priv->users, key); - indicator_session_users_removed (INDICATOR_SESSION_USERS (self), key); + g_hash_table_remove (self->priv->users, GUINT_TO_POINTER(uid)); + indicator_session_users_removed (INDICATOR_SESSION_USERS (self), uid); } diff --git a/tests/backend-mock-users.h b/tests/backend-mock-users.h index c7e11d3..7470ec9 100644 --- a/tests/backend-mock-users.h +++ b/tests/backend-mock-users.h @@ -57,11 +57,10 @@ GType indicator_session_users_mock_get_type (void); IndicatorSessionUsers * indicator_session_users_mock_new (void); void indicator_session_users_mock_add_user (IndicatorSessionUsersMock * self, - const char * key, IndicatorSessionUser * user); void indicator_session_users_mock_remove_user (IndicatorSessionUsersMock * self, - const char * key); + guint uid); diff --git a/tests/test-service.cc b/tests/test-service.cc index 2d81441..996332d 100644 --- a/tests/test-service.cc +++ b/tests/test-service.cc @@ -619,23 +619,24 @@ TEST_F (ServiceTest, User) const char * const error_key = "has-online-account-error"; const char * const show_name_key = "show-real-name-on-panel"; - const struct { + struct { + guint uid; guint64 login_frequency; const gchar * user_name; const gchar * real_name; } account_info[] = { - { 134, "whartnell", "First Doctor" }, - { 119, "ptroughton", "Second Doctor" }, - { 128, "jpertwee", "Third Doctor" }, - { 172, "tbaker", "Fourth Doctor" }, - { 69, "pdavison", "Fifth Doctor" }, - { 31, "cbaker", "Sixth Doctor" }, - { 42, "smccoy", "Seventh Doctor" }, - { 1, "pmcgann", "Eigth Doctor" }, - { 13, "ceccleston", "Ninth Doctor" }, - { 47, "dtennant", "Tenth Doctor" }, - { 34, "msmith", "Eleventh Doctor" }, - { 1, "rhurndall", "First Doctor" } + { 101, 134, "whartnell", "First Doctor" }, + { 102, 119, "ptroughton", "Second Doctor" }, + { 103, 128, "jpertwee", "Third Doctor" }, + { 104, 172, "tbaker", "Fourth Doctor" }, + { 105, 69, "pdavison", "Fifth Doctor" }, + { 106, 31, "cbaker", "Sixth Doctor" }, + { 107, 42, "smccoy", "Seventh Doctor" }, + { 108, 1, "pmcgann", "Eigth Doctor" }, + { 109, 13, "ceccleston", "Ninth Doctor" }, + { 110, 47, "dtennant", "Tenth Doctor" }, + { 111, 34, "msmith", "Eleventh Doctor" }, + { 201, 1, "rhurndall", "First Doctor" } }; // Find the switcher menu model. @@ -656,11 +657,11 @@ TEST_F (ServiceTest, User) IndicatorSessionUser * u = g_new0 (IndicatorSessionUser, 1); u->is_current_user = false; u->is_logged_in = false; - u->uid = 101 + i; + u->uid = account_info[i].uid; u->login_frequency = account_info[i].login_frequency; u->user_name = g_strdup (account_info[i].user_name); u->real_name = g_strdup (account_info[i].real_name); - indicator_session_users_mock_add_user (INDICATOR_SESSION_USERS_MOCK(mock_users), u->user_name, u); + indicator_session_users_mock_add_user (INDICATOR_SESSION_USERS_MOCK(mock_users), u); users[i] = u; } @@ -679,8 +680,8 @@ TEST_F (ServiceTest, User) g_clear_object (&switch_menu); // now remove a couple of 'em - indicator_session_users_mock_remove_user (INDICATOR_SESSION_USERS_MOCK(mock_users), account_info[3].user_name); - indicator_session_users_mock_remove_user (INDICATOR_SESSION_USERS_MOCK(mock_users), account_info[4].user_name); + indicator_session_users_mock_remove_user (INDICATOR_SESSION_USERS_MOCK(mock_users), account_info[3].uid); + indicator_session_users_mock_remove_user (INDICATOR_SESSION_USERS_MOCK(mock_users), account_info[4].uid); wait_for_menu_resync (); @@ -697,7 +698,7 @@ TEST_F (ServiceTest, User) // now let's have the third one be the current user users[2]->is_current_user = true; users[2]->is_logged_in = true; - indicator_session_users_changed (mock_users, users[2]->user_name); + indicator_session_users_changed (mock_users, users[2]->uid); wait_for_menu_resync (); @@ -749,14 +750,14 @@ TEST_F (ServiceTest, User) u->login_frequency = account_info[i].login_frequency; u->user_name = g_strdup (account_info[i].user_name); u->real_name = g_strdup (account_info[i].real_name); - indicator_session_users_mock_add_user (INDICATOR_SESSION_USERS_MOCK(mock_users), u->user_name, u); + indicator_session_users_mock_add_user (INDICATOR_SESSION_USERS_MOCK(mock_users), u); users[i] = u; } users[2]->is_current_user = false; - indicator_session_users_changed (mock_users, users[2]->user_name); + indicator_session_users_changed (mock_users, users[2]->uid); users[10]->is_current_user = true; users[10]->is_logged_in = true; - indicator_session_users_changed (mock_users, users[10]->user_name); + indicator_session_users_changed (mock_users, users[10]->uid); wait_for_menu_resync (); ASSERT_TRUE (find_menu_item_for_action ("indicator.switch-to-greeter", &switch_menu, &pos)); ASSERT_EQ (0, pos); -- cgit v1.2.3 From d16aaaed46f3381ea7ac4cb4c2cb491d4c5d2e03 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 25 Jun 2013 11:39:46 -0500 Subject: all the tests in test-users pass --- src/backend-dbus/users.c | 14 ++++++-------- tests/backend-dbus/test-users.cc | 20 +++++++++----------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 48de06c..1ecadf3 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -93,8 +93,6 @@ set_active_uid (IndicatorSessionUsersDbus * self, guint uid) { priv_t * p = self->priv; - g_message ("%s %s setting active uid to %u", G_STRLOC, G_STRFUNC, uid); - if (p->active_uid != uid) { const guint old_uid = p->active_uid; @@ -393,8 +391,6 @@ on_login1_manager_session_list_ready (GObject * o, GHashTable * logins = g_hash_table_new (g_direct_hash, g_direct_equal); GVariantIter iter; - g_message ("%s %s %s", G_STRLOC, G_STRFUNC, g_variant_print (sessions, TRUE)); - g_variant_iter_init (&iter, sessions); while (g_variant_iter_loop (&iter, "(&su&s&s&o)", &session_id, &uid, @@ -406,11 +402,13 @@ on_login1_manager_session_list_ready (GObject * o, if (g_strcmp0 (seat_id, current_seat_id)) continue; - if ((uid==999) && !g_strcmp0 (user_name,"ubuntu")) - is_live_session = TRUE; - if (!g_strcmp0 (session_id, current_session_id)) - set_active_uid (self, uid); + { + set_active_uid (self, uid); + + if ((uid==999) && !g_strcmp0 (user_name,"ubuntu")) + is_live_session = TRUE; + } /* only count user accounts and the live session */ if (uid >= 999) diff --git a/tests/backend-dbus/test-users.cc b/tests/backend-dbus/test-users.cc index 279796e..b022984 100644 --- a/tests/backend-dbus/test-users.cc +++ b/tests/backend-dbus/test-users.cc @@ -328,26 +328,25 @@ TEST_F (Users, ActivateUser) compare_user (msmith, event_keys[1], "active"); } -#if 0 /** * Confirm that adding a Guest doesn't show up in the users list */ TEST_F (Users, UnwantedGuest) { - GStrv keys; + GList * uids; - keys = indicator_session_users_get_keys (users); - const size_t n = g_strv_length (keys); - g_strfreev (keys); + uids = indicator_session_users_get_uids (users); + const size_t n = g_list_length (uids); + g_list_free (uids); MockUser * mu = new MockUser (loop, conn, "guest-jjbEVV", "Guest", 1); mu->set_system_account (true); accounts->add_user (mu); wait_msec (50); - keys = indicator_session_users_get_keys (users); - ASSERT_EQ (n, g_strv_length (keys)); - g_strfreev (keys); + uids = indicator_session_users_get_uids (users); + ASSERT_EQ (n, g_list_length (uids)); + g_list_free (uids); } @@ -367,9 +366,9 @@ TEST_F (Users, LiveSession) MockUser * live_user = new MockUser (loop, conn, "ubuntu", "Ubuntu", 1, 999); live_user->set_system_account (true); accounts->add_user (live_user); - MockConsoleKitSession * session = ck_seat->add_session_by_user (live_user); + const int session_tag = login1_manager->add_session (login1_seat, live_user); wait_msec (100); - ck_seat->activate_session (session); + login1_seat->activate_session (session_tag); wait_for_signal (users, "notify::" INDICATOR_SESSION_USERS_PROP_IS_LIVE_SESSION); // confirm the backend thinks it's a live session @@ -377,4 +376,3 @@ TEST_F (Users, LiveSession) g_object_get (users, INDICATOR_SESSION_USERS_PROP_IS_LIVE_SESSION, &b, NULL); ASSERT_TRUE (b); } -#endif -- cgit v1.2.3 From 7a995d0b4466b12be7b7f297d1f964aae37eae63 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 25 Jun 2013 12:31:53 -0500 Subject: don't pass -std=c++0x to the compiler when building .c files --- tests/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index f67008e..33009a3 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -39,7 +39,7 @@ add_library (backendmock STATIC backend-mock-guest.h backend-mock-users.c backend-mock-users.h) -set_target_properties (backendmock PROPERTIES COMPILE_FLAGS " ${CC_WARNING_ARGS} -std=c++0x -g") +set_target_properties (backendmock PROPERTIES COMPILE_FLAGS " ${CC_WARNING_ARGS} -g") # test-service add_executable (test-service -- cgit v1.2.3 From 9ed837fbafae3021d597508ba9272a54d3623534 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 25 Jun 2013 12:32:16 -0500 Subject: test-guest's HelloWorld and Allowed tests now pass --- src/backend-dbus/guest.c | 42 ++++++++++++++++++++++++---------------- tests/backend-dbus/test-guest.cc | 9 ++++----- 2 files changed, 29 insertions(+), 22 deletions(-) diff --git a/src/backend-dbus/guest.c b/src/backend-dbus/guest.c index fcb3604..08ac648 100644 --- a/src/backend-dbus/guest.c +++ b/src/backend-dbus/guest.c @@ -192,17 +192,6 @@ set_login1_manager (IndicatorSessionGuestDbus * self, } } -static void -update_guest_allowed (IndicatorSessionGuestDbus * self) -{ - priv_t * p = self->priv; - - gboolean allowed = p->login1_seat - && login1_seat_get_can_multi_session (p->login1_seat); - - set_guest_is_allowed_flag (self, allowed); -} - static void set_login1_seat (IndicatorSessionGuestDbus * self, Login1Seat * login1_seat) @@ -222,10 +211,6 @@ set_login1_seat (IndicatorSessionGuestDbus * self, g_signal_connect_swapped (login1_seat, "notify::active-session", G_CALLBACK(update_session_list), self); update_session_list (self); - - g_signal_connect_swapped (login1_seat, "notify::can-multi-session", - G_CALLBACK(update_guest_allowed), self); - update_guest_allowed (self); } } @@ -268,14 +253,37 @@ my_switch_to_guest (IndicatorSessionGuest * guest) self); } +static void +on_notify_has_guest_account (DisplayManagerSeat * dm_seat, + GParamSpec * pspec G_GNUC_UNUSED, + IndicatorSessionGuestDbus * self) +{ + gboolean guest_exists = display_manager_seat_get_has_guest_account (dm_seat); + set_guest_is_allowed_flag (self, guest_exists); +} + static void set_display_manager_seat (IndicatorSessionGuestDbus * self, DisplayManagerSeat * dm_seat) { - g_clear_object (&self->priv->dm_seat); + priv_t * p = self->priv; + + if (p->dm_seat != NULL) + { + g_signal_handlers_disconnect_by_data (p->dm_seat, self); + + g_clear_object (&p->dm_seat); + } if (dm_seat != NULL) - self->priv->dm_seat = g_object_ref (dm_seat); + { + p->dm_seat = g_object_ref (dm_seat); + + g_signal_connect (dm_seat, "notify::has-guest-account", + G_CALLBACK(on_notify_has_guest_account), self); + on_notify_has_guest_account (dm_seat, NULL, self); + } + } /*** diff --git a/tests/backend-dbus/test-guest.cc b/tests/backend-dbus/test-guest.cc index db55dd1..c5f948a 100644 --- a/tests/backend-dbus/test-guest.cc +++ b/tests/backend-dbus/test-guest.cc @@ -66,14 +66,11 @@ class Guest: public GTestMockDBusFixture protected: void add_mock_guest (MockUser *& guest_user, - MockConsoleKitSession *& guest_session) + int & guest_session_tag) { guest_user = new MockUser (loop, conn, "guest-jjbEVV", "Guest", 10); guest_user->set_system_account (true); - accounts->add_user (guest_user); - guest_session = new MockConsoleKitSession (loop, conn); - guest_session->set_user (guest_user); - ck_seat->add_session (guest_session); + guest_session_tag = login1_manager->add_session (login1_seat, guest_user); } }; @@ -104,6 +101,7 @@ TEST_F (Guest, Allowed) ASSERT_FALSE (indicator_session_guest_is_active (guest)); } +#if 0 /** * Have a guest user log in & out. * Confirm that "guest" reflects the changes. @@ -190,3 +188,4 @@ TEST_F (Guest, Activate) ASSERT_EQ (guest_session, ck_manager->current_session()); wait_msec (50); } +#endif -- cgit v1.2.3 From 95e99abc20dc4e0c5de390e11f467d44dd05cba0 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 25 Jun 2013 12:59:32 -0500 Subject: TestGuest::Login now passes --- tests/backend-dbus/test-guest.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/backend-dbus/test-guest.cc b/tests/backend-dbus/test-guest.cc index c5f948a..ea04f3c 100644 --- a/tests/backend-dbus/test-guest.cc +++ b/tests/backend-dbus/test-guest.cc @@ -68,7 +68,8 @@ class Guest: public GTestMockDBusFixture void add_mock_guest (MockUser *& guest_user, int & guest_session_tag) { - guest_user = new MockUser (loop, conn, "guest-jjbEVV", "Guest", 10); + guest_user = new MockUser (loop, conn, "guest-jjbEVV", "Guest", 10, 100); + accounts->add_user (guest_user); guest_user->set_system_account (true); guest_session_tag = login1_manager->add_session (login1_seat, guest_user); } @@ -101,7 +102,6 @@ TEST_F (Guest, Allowed) ASSERT_FALSE (indicator_session_guest_is_active (guest)); } -#if 0 /** * Have a guest user log in & out. * Confirm that "guest" reflects the changes. @@ -115,8 +115,8 @@ TEST_F (Guest, Login) // Log a Guest in // And confirm that guest's is_login changes to true MockUser * guest_user; - MockConsoleKitSession * guest_session; - add_mock_guest (guest_user, guest_session); + int session_tag; + add_mock_guest (guest_user, session_tag); wait_for_signal (guest, "notify::guest-is-logged-in"); ASSERT_TRUE (indicator_session_guest_is_allowed (guest)); ASSERT_TRUE (indicator_session_guest_is_logged_in (guest)); @@ -126,10 +126,9 @@ TEST_F (Guest, Login) // Log the Guest User out // and confirm that guest's is_login changes to false - ck_seat->remove_session (guest_session); + login1_manager->remove_session (login1_seat, session_tag); accounts->remove_user (guest_user); delete guest_user; - delete guest_session; wait_for_signal (guest, "notify::guest-is-logged-in"); ASSERT_TRUE (indicator_session_guest_is_allowed (guest)); ASSERT_FALSE (indicator_session_guest_is_logged_in (guest)); @@ -138,6 +137,7 @@ TEST_F (Guest, Login) ASSERT_FALSE (indicator_session_guest_is_active (guest)); } +#if 0 /** * Activate a Guest session, then activate a different session. * Confirm that "guest" reflects the changes. -- cgit v1.2.3 From 3cabab005963648247d8af74645c8e245efe13e8 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 25 Jun 2013 13:36:02 -0500 Subject: everything in test-guest now passes --- src/backend-dbus/guest.c | 1 - tests/backend-dbus/test-guest.cc | 22 ++++++++++++---------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/backend-dbus/guest.c b/src/backend-dbus/guest.c index 08ac648..963bdc8 100644 --- a/src/backend-dbus/guest.c +++ b/src/backend-dbus/guest.c @@ -283,7 +283,6 @@ set_display_manager_seat (IndicatorSessionGuestDbus * self, G_CALLBACK(on_notify_has_guest_account), self); on_notify_has_guest_account (dm_seat, NULL, self); } - } /*** diff --git a/tests/backend-dbus/test-guest.cc b/tests/backend-dbus/test-guest.cc index ea04f3c..f71d445 100644 --- a/tests/backend-dbus/test-guest.cc +++ b/tests/backend-dbus/test-guest.cc @@ -137,7 +137,6 @@ TEST_F (Guest, Login) ASSERT_FALSE (indicator_session_guest_is_active (guest)); } -#if 0 /** * Activate a Guest session, then activate a different session. * Confirm that "guest" reflects the changes. @@ -145,15 +144,16 @@ TEST_F (Guest, Login) TEST_F (Guest, Active) { gboolean b; + const int user_session_tag = login1_seat->active_session(); dm_seat->set_guest_allowed (true); MockUser * guest_user; - MockConsoleKitSession * guest_session; - add_mock_guest (guest_user, guest_session); + int guest_session_tag; + add_mock_guest (guest_user, guest_session_tag); // Activate the guest session // and confirm that guest's is_active changes to true - ck_seat->activate_session (guest_session); + login1_seat->activate_session (guest_session_tag); wait_for_signal (guest, "notify::guest-is-active-session"); ASSERT_TRUE (indicator_session_guest_is_allowed (guest)); ASSERT_TRUE (indicator_session_guest_is_logged_in (guest)); @@ -163,7 +163,7 @@ TEST_F (Guest, Active) // Activate a non-guest session // and confirm that guest's is_active changes to false - ck_seat->activate_session (ck_session); + login1_seat->activate_session (user_session_tag); wait_for_signal (guest, "notify::guest-is-active-session"); ASSERT_TRUE (indicator_session_guest_is_allowed (guest)); ASSERT_TRUE (indicator_session_guest_is_logged_in (guest)); @@ -179,13 +179,15 @@ TEST_F (Guest, Active) TEST_F (Guest, Activate) { dm_seat->set_guest_allowed (true); + wait_for_signal (guest, "notify::guest-is-allowed"); + MockUser * guest_user; - MockConsoleKitSession * guest_session; - add_mock_guest (guest_user, guest_session); + int guest_session_tag; + add_mock_guest (guest_user, guest_session_tag); indicator_session_guest_switch_to_guest (guest); - wait_for_signal (ck_seat->skeleton(), "active-session-changed"); - ASSERT_EQ (guest_session, ck_manager->current_session()); + + wait_for_signal (login1_seat->skeleton(), "notify::active-session"); + ASSERT_EQ (guest_session_tag, login1_seat->active_session()); wait_msec (50); } -#endif -- cgit v1.2.3 From 660d7bcbbddf3ea10146b47d3bf5c64899b8b2e0 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 25 Jun 2013 13:53:25 -0500 Subject: copyediting: remove g_messages() added while fixing the tests, remove dead code --- tests/backend-dbus/mock-end-session-dialog.cc | 28 -------- tests/backend-dbus/mock-login1-manager.cc | 96 +-------------------------- tests/backend-dbus/mock-login1-seat.cc | 6 +- tests/backend-dbus/mock-user.cc | 8 --- tests/backend-dbus/mock-webcredentials.cc | 15 ----- 5 files changed, 4 insertions(+), 149 deletions(-) diff --git a/tests/backend-dbus/mock-end-session-dialog.cc b/tests/backend-dbus/mock-end-session-dialog.cc index 903962b..2772423 100644 --- a/tests/backend-dbus/mock-end-session-dialog.cc +++ b/tests/backend-dbus/mock-end-session-dialog.cc @@ -19,28 +19,6 @@ #include "mock-end-session-dialog.h" -#if 0 -gboolean -MockEndSessionDialog :: handle_lock (GnomeScreenSaver * ss, - GDBusMethodInvocation * inv, - gpointer gself) -{ - static_cast(gself)->my_last_action = Lock; - gnome_screen_saver_complete_lock (ss, inv); - return true; -} - -gboolean -MockEndSessionDialog :: handle_simulate_user_activity (GnomeScreenSaver * ss, - GDBusMethodInvocation * inv, - gpointer gself) -{ - static_cast(gself)->my_last_action = UserActivity; - gnome_screen_saver_complete_simulate_user_activity (ss, inv); - return true; -} -#endif - gboolean MockEndSessionDialog :: handle_open (EndSessionDialog * object, GDBusMethodInvocation * invocation, @@ -73,12 +51,6 @@ MockEndSessionDialog :: MockEndSessionDialog (GMainLoop * loop, { g_signal_connect (my_skeleton, "handle-open", G_CALLBACK(handle_open), this); -#if 0 - g_signal_connect (my_skeleton, "handle-lock", - G_CALLBACK(handle_lock), this); - g_signal_connect (my_skeleton, "handle-simulate-user-activity", - G_CALLBACK(handle_simulate_user_activity), this); -#endif set_skeleton (G_DBUS_INTERFACE_SKELETON(my_skeleton)); } diff --git a/tests/backend-dbus/mock-login1-manager.cc b/tests/backend-dbus/mock-login1-manager.cc index 3bd652b..4461125 100644 --- a/tests/backend-dbus/mock-login1-manager.cc +++ b/tests/backend-dbus/mock-login1-manager.cc @@ -26,99 +26,17 @@ namespace const char * const BUS_NAME = "org.freedesktop.login1"; const char * const BUS_PATH = "/org/freedesktop/login1"; - -#if 0 - void on_active_session_changed (Login1Seat * o G_GNUC_UNUSED, - const gchar * new_ssid, - gpointer ssid) - { - *static_cast(ssid) = new_ssid; - } -#endif -} - -/*** -**** -***/ - -#if 0 -gboolean -MockLogin1Manager :: on_get_current_session (Login1Manager * m, - GDBusMethodInvocation * inv, - gpointer gself) -{ - MockLogin1Manager * self = static_cast(gself); - const std::string& ssid = self->my_current_ssid; - console_kit_manager_complete_get_current_session (m, inv, ssid.c_str()); - return true; -} - -gboolean -MockLogin1Manager :: on_get_seats (Login1Manager * m, - GDBusMethodInvocation * inv, - gpointer gself) -{ - int i; - char ** sids; - const seats_t& seats = static_cast(gself)->my_seats; - - i = 0; - sids = g_new0 (char*, seats.size()+1); - for (seats_t::const_iterator it(seats.begin()), - end(seats.end()); it!=end; ++it) - sids[i++] = (char*) (*it)->path(); - console_kit_manager_complete_get_seats (m, inv, sids); - g_strfreev (sids); - - return true; -} - -gboolean -MockLogin1Manager :: handle_restart (Login1Manager * ckm, - GDBusMethodInvocation * inv, - gpointer gself) -{ - static_cast(gself)->my_last_action = Restart; - console_kit_manager_complete_restart (ckm, inv); - return true; } -gboolean -MockLogin1Manager :: handle_stop (Login1Manager * ckm, - GDBusMethodInvocation * inv, - gpointer gself) -{ - static_cast(gself)->my_last_action = Shutdown; - console_kit_manager_complete_stop (ckm, inv); - return true; -} -#endif - /*** **** ***/ -#if 0 -MockLogin1Session * -MockLogin1Manager :: current_session () -{ - MockLogin1Session * ret = 0; - - for (seats_t::iterator it(my_seats.begin()), - end(my_seats.end()); it!=end; ++it) - if ((ret = (*it)->find (my_current_ssid.c_str()))) - break; - - return ret; -} -#endif - void MockLogin1Manager :: emit_session_new (MockLogin1Seat * seat, int tag) const { std::string id; std::string path; - seat->get_session_id_and_path_for_tag (tag, id, path); login1_manager_emit_session_new (my_skeleton, id.c_str(), path.c_str()); @@ -139,7 +57,6 @@ MockLogin1Manager :: emit_session_removed (MockLogin1Seat * seat, int tag) const { std::string id; std::string path; - seat->get_session_id_and_path_for_tag (tag, id, path); login1_manager_emit_session_removed (my_skeleton, id.c_str(), path.c_str()); @@ -188,9 +105,7 @@ MockLogin1Manager :: list_sessions () const } } - GVariant * v = g_variant_builder_end (&b); - g_message ("%s %s returning %s", G_STRLOC, G_STRFUNC, g_variant_print (v, true)); - return v; + return g_variant_builder_end (&b); } /*** @@ -313,15 +228,6 @@ MockLogin1Manager :: MockLogin1Manager (GMainLoop * loop, g_signal_connect (my_skeleton, "handle-list-sessions", G_CALLBACK(handle_list_sessions), this); -#if 0 - g_signal_connect (my_skeleton, "handle-get-seats", - G_CALLBACK(on_get_seats), this); - g_signal_connect (my_skeleton, "handle-stop", - G_CALLBACK(handle_stop), this); - g_signal_connect (my_skeleton, "handle-restart", - G_CALLBACK(handle_restart), this); -#endif - set_skeleton (G_DBUS_INTERFACE_SKELETON(my_skeleton)); } diff --git a/tests/backend-dbus/mock-login1-seat.cc b/tests/backend-dbus/mock-login1-seat.cc index 46dc5f9..49d7fb6 100644 --- a/tests/backend-dbus/mock-login1-seat.cc +++ b/tests/backend-dbus/mock-login1-seat.cc @@ -43,7 +43,9 @@ namespace } void -MockLogin1Seat :: get_session_id_and_path_for_tag (int tag, std::string& id, std::string& path) +MockLogin1Seat :: get_session_id_and_path_for_tag (int tag, + std::string & id, + std::string & path) { if (tag) { @@ -81,7 +83,6 @@ MockLogin1Seat :: update_sessions_property () } GVariant * v = g_variant_builder_end (&b); - g_message ("%s %s setting session property to %s", G_STRLOC, G_STRFUNC, g_variant_print (v, true)); g_object_set (my_skeleton, "sessions", v, NULL); } @@ -93,7 +94,6 @@ MockLogin1Seat :: update_active_session_property () get_session_id_and_path_for_tag (my_active_session, id, path); GVariant * v = g_variant_new ("(so)", id.c_str(), path.c_str()); - g_message ("%s %s setting active session property to %s", G_STRLOC, G_STRFUNC, g_variant_print (v, true)); g_object_set (my_skeleton, "active-session", v, NULL); } diff --git a/tests/backend-dbus/mock-user.cc b/tests/backend-dbus/mock-user.cc index abf2e21..f74b5a4 100644 --- a/tests/backend-dbus/mock-user.cc +++ b/tests/backend-dbus/mock-user.cc @@ -54,14 +54,6 @@ MockUser :: login_frequency () const return accounts_user_get_login_frequency (my_skeleton); } -#if 0 -bool -MockUser :: system_account() const -{ - return accounts_user_get_system_account (my_skeleton); -} -#endif - void MockUser :: set_system_account (gboolean b) { diff --git a/tests/backend-dbus/mock-webcredentials.cc b/tests/backend-dbus/mock-webcredentials.cc index 44fa8ac..22e10b7 100644 --- a/tests/backend-dbus/mock-webcredentials.cc +++ b/tests/backend-dbus/mock-webcredentials.cc @@ -30,21 +30,6 @@ MockWebcredentials :: MockWebcredentials (GMainLoop * loop, MockObject (loop, bus_connection, MY_NAME, MY_PATH), my_skeleton (webcredentials_skeleton_new ()) { - //set_can_hibernate (false); - //set_can_suspend (true); - -#if 0 - g_signal_connect (my_skeleton, "handle-suspend", - G_CALLBACK(handle_suspend), this); - g_signal_connect (my_skeleton, "handle-suspend-allowed", - G_CALLBACK(handle_suspend_allowed), this); - - g_signal_connect (my_skeleton, "handle-hibernate", - G_CALLBACK(handle_hibernate), this); - g_signal_connect (my_skeleton, "handle-hibernate-allowed", - G_CALLBACK(handle_hibernate_allowed), this); -#endif - set_skeleton (G_DBUS_INTERFACE_SKELETON(my_skeleton)); } -- cgit v1.2.3 From c23454157d46837d5cc6acd9cdd551c371819699 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 25 Jun 2013 14:12:19 -0500 Subject: sync text with trunk: make the shutdown menuitem read 'Shut Down' instead of 'Shutdown' --- src/service.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/service.c b/src/service.c index 1fcbd07..7f90c9c 100644 --- a/src/service.c +++ b/src/service.c @@ -547,7 +547,7 @@ create_session_section (IndicatorSessionService * self) if (!g_settings_get_boolean (s, "suppress-shutdown-menuitem")) { - const char * label = ellipsis ? _("Shutdown\342\200\246") : _("Shutdown"); + const char * label = ellipsis ? _("Shut Down\342\200\246") : _("Shut Down"); g_menu_append (menu, label, "indicator.power-off"); } -- cgit v1.2.3 From 2d089b9e30b1d292ed8d1a7e84d0a0019aa10784 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 26 Jun 2013 11:11:41 -0500 Subject: bump TODO --- TODO | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 178bb97..93ca1a0 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,7 @@ code x x-canonical-type for user/guest menuitems x remove the --replace command-line argument - - fix deprecated/dead APIs use in backend + x fix deprecated/dead APIs use in backend cmake x add cmake rule to install .indicator file @@ -9,4 +9,8 @@ cmake x add cmake rule to install indicator-session-service x gsettings schema validation x icon installation - - test schema installation + x test schema installation + +bugs + - Suspend button should be hidden when shell is available + - J Random User is showing up when we switch sessions -- cgit v1.2.3 From 951592e1349e863b721ca32273577e6f1b517d13 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 26 Jun 2013 11:40:14 -0500 Subject: fix regression that displayed the 'restart' button even when prompting was enabled and the user was running Unity --- TODO | 2 +- src/service.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/TODO b/TODO index 93ca1a0..eab0f56 100644 --- a/TODO +++ b/TODO @@ -12,5 +12,5 @@ cmake x test schema installation bugs - - Suspend button should be hidden when shell is available + x Suspend button should be hidden when shell is available - J Random User is showing up when we switch sessions diff --git a/src/service.c b/src/service.c index 7f90c9c..d8fc961 100644 --- a/src/service.c +++ b/src/service.c @@ -539,7 +539,9 @@ create_session_section (IndicatorSessionService * self) if (indicator_session_actions_can_hibernate (p->backend_actions)) g_menu_append (menu, _("Hibernate"), "indicator.hibernate"); - if (!g_settings_get_boolean (s, "suppress-restart-menuitem")) + /* NB: check 'ellipsis' here to skip this item if prompting is enabled + because this shows the same prompt as 'Shut Down' in Unity */ + if (!ellipsis && !g_settings_get_boolean (s, "suppress-restart-menuitem")) { const char * label = ellipsis ? _("Restart\342\200\246") : _("Restart"); g_menu_append (menu, label, "indicator.reboot"); -- cgit v1.2.3 From e986476c83c3e647dab067087865f895cd32a899 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 27 Jun 2013 13:07:52 -0500 Subject: only show the restart or hibernate menuitems if login1 says these features are available --- src/backend-dbus/actions.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index a74a524..3f0e6ec 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -160,8 +160,7 @@ on_can_suspend_ready (GObject * o, GAsyncResult * res, gpointer gself) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; - const gboolean b = !g_strcmp0 (str, "yes") || - !g_strcmp0 (str, "challenge"); + const gboolean b = !g_strcmp0 (str, "yes"); if (p->can_suspend != b) { @@ -188,8 +187,7 @@ on_can_hibernate_ready (GObject * o, GAsyncResult * res, gpointer gself) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv; - const gboolean b = !g_strcmp0 (str, "yes") || - !g_strcmp0 (str, "challenge"); + const gboolean b = !g_strcmp0 (str, "yes"); if (p->can_hibernate != b) { -- cgit v1.2.3 From 4c5a5e7146a878a17239e44ce2debffb5b525bf1 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 27 Jun 2013 13:53:44 -0500 Subject: in users.c, fix bugs that leaked system accounts into the list of users to show in the indicator --- TODO | 5 +- src/backend-dbus/users.c | 137 +++++++++++++++++++++++++++++------------------ 2 files changed, 90 insertions(+), 52 deletions(-) diff --git a/TODO b/TODO index eab0f56..c58b986 100644 --- a/TODO +++ b/TODO @@ -13,4 +13,7 @@ cmake bugs x Suspend button should be hidden when shell is available - - J Random User is showing up when we switch sessions + x showing multiple users as having the active session... + x Hibernate button is appearing when it shouldn't + x J Random User is showing up when we switch sessions, difficult to reproduce + _ when logged in as Guest, i-session can't recognize other users' icons? diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 1ecadf3..1db5ac1 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -53,22 +53,82 @@ G_DEFINE_TYPE (IndicatorSessionUsersDbus, **** ***/ +/* returns true if the fields indicate this is the 'live cd' user */ +static gboolean +is_live_user (guint uid, const char * username) +{ + return uid==999 && !g_strcmp0 (username, "ubuntu"); +} + +/* returns true if this is a user who should be listed in the session indicator */ +static gboolean +is_public_user (IndicatorSessionUsersDbus * self G_GNUC_UNUSED, + AccountsUser * au) +{ + gboolean is_public; + + /* the 'live session' user is the only system account we'll show */ + if (is_live_user (accounts_user_get_uid(au), accounts_user_get_user_name(au))) + is_public = TRUE; + else + is_public = !accounts_user_get_system_account (au); + + return is_public; +} + +/* get our private org.freedesktop.Accounts.User proxy for the given uid */ +static AccountsUser * +get_user_for_uid (IndicatorSessionUsersDbus * self, guint uid) +{ + priv_t * p = self->priv; + + return g_hash_table_lookup (p->uid_to_account, GUINT_TO_POINTER(uid)); +} + +/* returns true if this is a uid that should be listed in the session indicator */ +static gboolean +is_public_uid (IndicatorSessionUsersDbus * self, guint uid) +{ + AccountsUser * au; + gboolean is_public; + + if ((au = get_user_for_uid (self, uid))) + { + is_public = is_public_user (self, au); + } + else + { + /* making a guess to serve until the user's proxy object is ready. + assuming that 999 is a 'live session' user, <999 is system account */ + is_public = uid >= 999; + } + + return is_public; +} + +/*** +**** +***/ + static void emit_user_added (IndicatorSessionUsersDbus * self, guint uid) { - indicator_session_users_added (INDICATOR_SESSION_USERS(self), uid); + if (is_public_uid (self, uid)) + indicator_session_users_added (INDICATOR_SESSION_USERS(self), uid); } static void emit_user_changed (IndicatorSessionUsersDbus * self, guint uid) { - indicator_session_users_changed (INDICATOR_SESSION_USERS(self), uid); + if (is_public_uid (self, uid)) + indicator_session_users_changed (INDICATOR_SESSION_USERS(self), uid); } static void emit_user_removed (IndicatorSessionUsersDbus * self, guint uid) { - indicator_session_users_removed (INDICATOR_SESSION_USERS(self), uid); + if (is_public_uid (self, uid)) + indicator_session_users_removed (INDICATOR_SESSION_USERS(self), uid); } /*** @@ -99,11 +159,8 @@ set_active_uid (IndicatorSessionUsersDbus * self, guint uid) p->active_uid = uid; - if (old_uid) - emit_user_changed (self, old_uid); - - if (uid) - emit_user_changed (self, uid); + emit_user_changed (self, old_uid); + emit_user_changed (self, uid); } } @@ -180,18 +237,6 @@ object_add_connection (GObject * o, gulong connection_id) g_object_set_qdata (o, q, ids); } -/*** -**** -***/ - -static AccountsUser * -get_user_for_uid (IndicatorSessionUsersDbus * self, guint uid) -{ - priv_t * p = self->priv; - - return g_hash_table_lookup (p->uid_to_account, GUINT_TO_POINTER(uid)); -} - /*** **** User Account Tracking ***/ @@ -213,25 +258,24 @@ static void track_user (IndicatorSessionUsersDbus * self, AccountsUser * user) { - priv_t * p = self->priv; const guint32 uid = accounts_user_get_uid (user); const gpointer uid_key = GUINT_TO_POINTER (uid); - gboolean already_had_user; + priv_t * p = self->priv; gulong id; + gboolean already_had_user; + + g_return_if_fail (is_public_user (self, user)); already_had_user = g_hash_table_contains (p->uid_to_account, uid_key); - id = g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self); + id = g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self); object_add_connection (G_OBJECT(user), id); g_hash_table_insert (p->uid_to_account, uid_key, user); - if (!accounts_user_get_system_account (user)) - { - if (already_had_user) - emit_user_changed (self, uid); - else - emit_user_added (self, uid); - } + if (already_had_user) + emit_user_changed (self, uid); + else + emit_user_added (self, uid); } static void @@ -258,6 +302,8 @@ untrack_user (IndicatorSessionUsersDbus * self, } } +/* We got a new org.freedesktop.Accounts.User proxy. + If it's one we want to remember, pass it to track_user() */ static void on_user_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, @@ -275,10 +321,14 @@ on_user_proxy_ready (GObject * o G_GNUC_UNUSED, g_error_free (err); } - else + else if (is_public_user (self, user)) { track_user (self, user); } + else + { + g_object_unref (self); + } } static void @@ -293,7 +343,7 @@ create_user_proxy_for_path (IndicatorSessionUsersDbus * self, on_user_proxy_ready, self); } -/* create user proxies for everything in Account's user-list */ +/* create proxy objects for everything in Account's user-list */ static void on_user_list_ready (GObject * o, GAsyncResult * res, gpointer gself) { @@ -406,12 +456,11 @@ on_login1_manager_session_list_ready (GObject * o, { set_active_uid (self, uid); - if ((uid==999) && !g_strcmp0 (user_name,"ubuntu")) + if (is_live_user (uid, user_name)) is_live_session = TRUE; } - /* only count user accounts and the live session */ - if (uid >= 999) + if (is_public_uid (self, uid)) g_hash_table_add (logins, GINT_TO_POINTER(uid)); } @@ -541,22 +590,8 @@ my_is_live_session (IndicatorSessionUsers * users) static GList * my_get_uids (IndicatorSessionUsers * users) { - priv_t * p; - GList * uids; - GHashTableIter iter; - gpointer uid; - gpointer user; - - g_return_val_if_fail (INDICATOR_IS_SESSION_USERS_DBUS(users), NULL); - p = INDICATOR_SESSION_USERS_DBUS (users)->priv; - - uids = NULL; - g_hash_table_iter_init (&iter, p->uid_to_account); - while (g_hash_table_iter_next (&iter, &uid, &user)) - if (!accounts_user_get_system_account (user)) - uids = g_list_prepend (uids, uid); - - return uids; + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (users); + return g_hash_table_get_keys (self->priv->uid_to_account); } /* build a new struct populated with info on the specified user */ -- cgit v1.2.3 From cc57405ebf537239ab2953b41b27908b6dadfbeb Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 27 Jun 2013 21:43:13 -0500 Subject: in actions.c's my_can_prompt(), don't leak the string returned by g_dbus_proxy_get_name_owner --- src/backend-dbus/actions.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index 3f0e6ec..67fe9f1 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -326,11 +326,18 @@ my_can_hibernate (IndicatorSessionActions * self) static gboolean my_can_prompt (IndicatorSessionActions * self) { + gboolean can_prompt = FALSE; const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - return (p != NULL) - && (p->end_session_dialog != NULL) - && (g_dbus_proxy_get_name_owner (G_DBUS_PROXY(p->end_session_dialog)) != NULL); + if (p && p->end_session_dialog) + { + GDBusProxy * proxy = G_DBUS_PROXY (p->end_session_dialog); + char * name = g_dbus_proxy_get_name_owner (proxy); + can_prompt = name != NULL; + g_free (name); + } + + return can_prompt; } static gboolean -- cgit v1.2.3 From b6467f327dcfc2c4fb60b57f293747259d0b7228 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 27 Jun 2013 21:44:03 -0500 Subject: in create_guest_switcher_state() and create_user_switcher_state(), don't leak GVariantBuilders --- src/service.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/service.c b/src/service.c index d8fc961..931c626 100644 --- a/src/service.c +++ b/src/service.c @@ -311,15 +311,15 @@ static GVariant * create_guest_switcher_state (IndicatorSessionService * self) { GVariant * val; - GVariantBuilder * b; + GVariantBuilder b; IndicatorSessionGuest * const g = self->priv->backend_guest; - b = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}")); + g_variant_builder_init (&b, G_VARIANT_TYPE ("a{sv}")); val = g_variant_new_boolean (indicator_session_guest_is_active (g)); - g_variant_builder_add (b, "{sv}", "is-active", val); + g_variant_builder_add (&b, "{sv}", "is-active", val); val = g_variant_new_boolean (indicator_session_guest_is_logged_in (g)); - g_variant_builder_add (b, "{sv}", "is-logged-in", val); - return g_variant_builder_end (b); + g_variant_builder_add (&b, "{sv}", "is-logged-in", val); + return g_variant_builder_end (&b); } /** @@ -330,15 +330,15 @@ create_guest_switcher_state (IndicatorSessionService * self) static GVariant * create_user_switcher_state (IndicatorSessionService * self) { - GVariantBuilder * a; - GVariantBuilder * b; + GVariantBuilder a; + GVariantBuilder b; GVariant * val; GHashTableIter ht_iter; gpointer ht_value; const char * current_user; current_user = ""; - a = g_variant_builder_new (G_VARIANT_TYPE("as")); + g_variant_builder_init (&a, G_VARIANT_TYPE("as")); g_hash_table_iter_init (&ht_iter, self->priv->users); while (g_hash_table_iter_next (&ht_iter, NULL, &ht_value)) { @@ -348,15 +348,15 @@ create_user_switcher_state (IndicatorSessionService * self) current_user = u->user_name; if (u->is_logged_in) - g_variant_builder_add (a, "s", u->user_name); + g_variant_builder_add (&a, "s", u->user_name); } - b = g_variant_builder_new (G_VARIANT_TYPE("a{sv}")); + g_variant_builder_init (&b, G_VARIANT_TYPE("a{sv}")); val = g_variant_new_string (current_user); - g_variant_builder_add (b, "{sv}", "active-user", val); - val = g_variant_builder_end (a); - g_variant_builder_add (b, "{sv}", "logged-in-users", val); - return g_variant_builder_end (b); + g_variant_builder_add (&b, "{sv}", "active-user", val); + val = g_variant_builder_end (&a); + g_variant_builder_add (&b, "{sv}", "logged-in-users", val); + return g_variant_builder_end (&b); } static void -- cgit v1.2.3 From 3bd279a7de3b32bc33ab2f80d4eae0ecfe83dd38 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 28 Jun 2013 09:47:32 -0500 Subject: =?UTF-8?q?use=20the=20unicode=20'=E2=80=A6'=20directly=20intead?= =?UTF-8?q?=20of=20\342\200\246?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/service.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/service.c b/src/service.c index 931c626..a9f2f65 100644 --- a/src/service.c +++ b/src/service.c @@ -295,9 +295,9 @@ create_settings_section (IndicatorSessionService * self) priv_t * p = self->priv; menu = g_menu_new (); - g_menu_append (menu, _("System Settings\342\200\246"), "indicator.settings"); + g_menu_append (menu, _("System Settings…"), "indicator.settings"); if (indicator_session_actions_has_online_account_error (p->backend_actions)) - g_menu_append (menu, _("Online Accounts\342\200\246"), "indicator.online-accounts"); + g_menu_append (menu, _("Online Accounts…"), "indicator.online-accounts"); return G_MENU_MODEL (menu); } @@ -443,19 +443,19 @@ create_switch_section (IndicatorSessionService * self) else if (indicator_session_guest_is_active (p->backend_guest)) { const char * action = "indicator.switch-to-greeter"; - item = g_menu_item_new (ellipsis ? _("Switch Account\342\200\246") + item = g_menu_item_new (ellipsis ? _("Switch Account…") : _("Switch Account"), action); } else if (g_hash_table_size (p->users) == 1) { const char * action = "indicator.switch-to-greeter"; - item = g_menu_item_new (ellipsis ? _("Lock\342\200\246") + item = g_menu_item_new (ellipsis ? _("Lock…") : _("Lock"), action); } else { const char * action = "indicator.switch-to-greeter"; - item = g_menu_item_new (ellipsis ? _("Lock/Switch Account\342\200\246") + item = g_menu_item_new (ellipsis ? _("Lock/Switch Account…") : _("Lock/Switch Account"), action); } str = g_settings_get_string (p->keybinding_settings, "screensaver"); @@ -529,7 +529,7 @@ create_session_section (IndicatorSessionService * self) if (indicator_session_actions_can_logout (p->backend_actions) && !g_settings_get_boolean (s, "suppress-logout-menuitem")) { - const char * label = ellipsis ? _("Log Out\342\200\246") : _("Log Out"); + const char * label = ellipsis ? _("Log Out…") : _("Log Out"); g_menu_append (menu, label, "indicator.logout"); } @@ -543,13 +543,13 @@ create_session_section (IndicatorSessionService * self) because this shows the same prompt as 'Shut Down' in Unity */ if (!ellipsis && !g_settings_get_boolean (s, "suppress-restart-menuitem")) { - const char * label = ellipsis ? _("Restart\342\200\246") : _("Restart"); + const char * label = ellipsis ? _("Restart…") : _("Restart"); g_menu_append (menu, label, "indicator.reboot"); } if (!g_settings_get_boolean (s, "suppress-shutdown-menuitem")) { - const char * label = ellipsis ? _("Shut Down\342\200\246") : _("Shut Down"); + const char * label = ellipsis ? _("Shut Down…") : _("Shut Down"); g_menu_append (menu, label, "indicator.power-off"); } -- cgit v1.2.3 From 69bf3537b0fe5aa00d015c7339ce20e9c2b80d1f Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 28 Jun 2013 09:48:54 -0500 Subject: finish up backend-dbus/users.c: fix an unref bug when creating user proxies. fix an async race condition where we emitted change events for users before their proxy objects had finished being asynchronously constructed. --- TODO | 19 -------- src/backend-dbus/users.c | 118 ++++++++++++++++++++++------------------------- 2 files changed, 54 insertions(+), 83 deletions(-) delete mode 100644 TODO diff --git a/TODO b/TODO deleted file mode 100644 index c58b986..0000000 --- a/TODO +++ /dev/null @@ -1,19 +0,0 @@ -code - x x-canonical-type for user/guest menuitems - x remove the --replace command-line argument - x fix deprecated/dead APIs use in backend - -cmake - x add cmake rule to install .indicator file - x add cmake rule to install dbus service file - x add cmake rule to install indicator-session-service - x gsettings schema validation - x icon installation - x test schema installation - -bugs - x Suspend button should be hidden when shell is available - x showing multiple users as having the active session... - x Hibernate button is appearing when it shouldn't - x J Random User is showing up when we switch sessions, difficult to reproduce - _ when logged in as Guest, i-session can't recognize other users' icons? diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 1db5ac1..b5a6d32 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -41,6 +41,8 @@ struct _IndicatorSessionUsersDbusPriv gboolean is_live; GCancellable * cancellable; + + guint update_list_tag; }; typedef IndicatorSessionUsersDbusPriv priv_t; @@ -53,29 +55,6 @@ G_DEFINE_TYPE (IndicatorSessionUsersDbus, **** ***/ -/* returns true if the fields indicate this is the 'live cd' user */ -static gboolean -is_live_user (guint uid, const char * username) -{ - return uid==999 && !g_strcmp0 (username, "ubuntu"); -} - -/* returns true if this is a user who should be listed in the session indicator */ -static gboolean -is_public_user (IndicatorSessionUsersDbus * self G_GNUC_UNUSED, - AccountsUser * au) -{ - gboolean is_public; - - /* the 'live session' user is the only system account we'll show */ - if (is_live_user (accounts_user_get_uid(au), accounts_user_get_user_name(au))) - is_public = TRUE; - else - is_public = !accounts_user_get_system_account (au); - - return is_public; -} - /* get our private org.freedesktop.Accounts.User proxy for the given uid */ static AccountsUser * get_user_for_uid (IndicatorSessionUsersDbus * self, guint uid) @@ -85,50 +64,30 @@ get_user_for_uid (IndicatorSessionUsersDbus * self, guint uid) return g_hash_table_lookup (p->uid_to_account, GUINT_TO_POINTER(uid)); } -/* returns true if this is a uid that should be listed in the session indicator */ static gboolean -is_public_uid (IndicatorSessionUsersDbus * self, guint uid) +is_tracked_uid (IndicatorSessionUsersDbus * self, guint uid) { - AccountsUser * au; - gboolean is_public; - - if ((au = get_user_for_uid (self, uid))) - { - is_public = is_public_user (self, au); - } - else - { - /* making a guess to serve until the user's proxy object is ready. - assuming that 999 is a 'live session' user, <999 is system account */ - is_public = uid >= 999; - } - - return is_public; + return get_user_for_uid (self, uid) != NULL; } -/*** -**** -***/ - static void -emit_user_added (IndicatorSessionUsersDbus * self, guint uid) +emit_user_added (IndicatorSessionUsersDbus * self, guint32 uid) { - if (is_public_uid (self, uid)) + if (is_tracked_uid (self, uid)) indicator_session_users_added (INDICATOR_SESSION_USERS(self), uid); } static void -emit_user_changed (IndicatorSessionUsersDbus * self, guint uid) +emit_user_changed (IndicatorSessionUsersDbus * self, guint32 uid) { - if (is_public_uid (self, uid)) + if (is_tracked_uid (self, uid)) indicator_session_users_changed (INDICATOR_SESSION_USERS(self), uid); } static void -emit_user_removed (IndicatorSessionUsersDbus * self, guint uid) +emit_user_removed (IndicatorSessionUsersDbus * self, guint32 uid) { - if (is_public_uid (self, uid)) - indicator_session_users_removed (INDICATOR_SESSION_USERS(self), uid); + indicator_session_users_removed (INDICATOR_SESSION_USERS(self), uid); } /*** @@ -259,18 +218,13 @@ track_user (IndicatorSessionUsersDbus * self, AccountsUser * user) { const guint32 uid = accounts_user_get_uid (user); - const gpointer uid_key = GUINT_TO_POINTER (uid); priv_t * p = self->priv; gulong id; - gboolean already_had_user; - - g_return_if_fail (is_public_user (self, user)); - - already_had_user = g_hash_table_contains (p->uid_to_account, uid_key); + const gboolean already_had_user = is_tracked_uid (self, uid); id = g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self); object_add_connection (G_OBJECT(user), id); - g_hash_table_insert (p->uid_to_account, uid_key, user); + g_hash_table_insert (p->uid_to_account, GUINT_TO_POINTER (uid), user); if (already_had_user) emit_user_changed (self, uid); @@ -321,13 +275,13 @@ on_user_proxy_ready (GObject * o G_GNUC_UNUSED, g_error_free (err); } - else if (is_public_user (self, user)) + else if (!accounts_user_get_system_account (user)) { track_user (self, user); } else { - g_object_unref (self); + g_object_unref (user); } } @@ -456,12 +410,11 @@ on_login1_manager_session_list_ready (GObject * o, { set_active_uid (self, uid); - if (is_live_user (uid, user_name)) + if ((uid==999) && !g_strcmp0 (user_name, "ubuntu")) is_live_session = TRUE; } - if (is_public_uid (self, uid)) - g_hash_table_add (logins, GINT_TO_POINTER(uid)); + g_hash_table_add (logins, GINT_TO_POINTER(uid)); } set_is_live_session_flag (self, is_live_session); @@ -485,8 +438,35 @@ update_session_list (IndicatorSessionUsersDbus * self) } } +static gboolean +on_update_session_list_timer (gpointer gself) +{ + IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (gself); + + update_session_list (self); + + self->priv->update_list_tag = 0; + return G_SOURCE_REMOVE; +} + +/* A dead session can still show up in list-sessions for a few seconds. + So just to be safe, queue up a rebuild for a few seconds from now */ static void -set_login1_manager (IndicatorSessionUsersDbus * self, Login1Manager * login1_manager) +update_session_list_twice (IndicatorSessionUsersDbus * self) +{ + priv_t * p = self->priv; + + update_session_list (self); + + if (p->update_list_tag == 0) + p->update_list_tag = g_timeout_add_seconds (5, + on_update_session_list_timer, + self); +} + +static void +set_login1_manager (IndicatorSessionUsersDbus * self, + Login1Manager * login1_manager) { priv_t * p = self->priv; @@ -504,7 +484,11 @@ set_login1_manager (IndicatorSessionUsersDbus * self, Login1Manager * login1_man g_signal_connect_swapped (login1_manager, "session-new", G_CALLBACK(update_session_list), self); g_signal_connect_swapped (login1_manager, "session-removed", + G_CALLBACK(update_session_list_twice), self); + g_signal_connect_swapped (login1_manager, "user-new", G_CALLBACK(update_session_list), self); + g_signal_connect_swapped (login1_manager, "user-removed", + G_CALLBACK(update_session_list_twice), self); update_session_list (self); } } @@ -632,6 +616,12 @@ my_dispose (GObject * o) IndicatorSessionUsersDbus * self = INDICATOR_SESSION_USERS_DBUS (o); priv_t * p = self->priv; + if (p->update_list_tag != 0) + { + g_source_remove (p->update_list_tag); + p->update_list_tag = 0; + } + if (p->cancellable) { g_cancellable_cancel (p->cancellable); -- cgit v1.2.3 From 4850b1b6ba8a1438d8c0903592108fcefc35235e Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 28 Jun 2013 10:31:51 -0500 Subject: update comments & documentation to reflect that we've replaced consolekit and login1 --- INSTALL | 7 +++---- src/backend-dbus/actions.h | 2 +- src/backend-dbus/guest.h | 2 +- src/backend-dbus/users.h | 2 +- tests/backend-dbus/test-actions.cc | 5 +---- tests/backend-mock-actions.h | 3 +-- tests/backend-mock-guest.h | 3 +-- tests/backend-mock-users.h | 3 +-- 8 files changed, 10 insertions(+), 17 deletions(-) diff --git a/INSTALL b/INSTALL index 2920993..772eae0 100644 --- a/INSTALL +++ b/INSTALL @@ -29,11 +29,10 @@ Runtime DBus dependencies - com.canonical.indicators.webcredentials - org.freedesktop.Accounts - org.freedesktop.Accounts.User - - org.freedesktop.ConsoleKit.Manager - - org.freedesktop.ConsoleKit.Seat - - org.freedesktop.ConsoleKit.Session - org.freedesktop.DisplayManager.Seat - - org.freedesktop.UPower + - org.freedesktop.login1.Manager + - org.freedesktop.login1.Seat + - org.freedesktop.login1.User - org.gnome.ScreenSaver - org.gnome.SessionManager - org.gnome.SessionManager.EndSessionDialog diff --git a/src/backend-dbus/actions.h b/src/backend-dbus/actions.h index 0c8bed2..d3d722d 100644 --- a/src/backend-dbus/actions.h +++ b/src/backend-dbus/actions.h @@ -42,7 +42,7 @@ typedef struct _IndicatorSessionActionsDbusClass IndicatorSessionActionsDbusCl /** * An implementation of IndicatorSessionActions that gets its user information - * from org.freedesktop.ConsoleKit and org.freedesktop.Accounts over DBus. + * from org.freedesktop.login1 org.freedesktop.DisplayManager over DBus. */ struct _IndicatorSessionActionsDbus { diff --git a/src/backend-dbus/guest.h b/src/backend-dbus/guest.h index aca5588..73bb3ca 100644 --- a/src/backend-dbus/guest.h +++ b/src/backend-dbus/guest.h @@ -42,7 +42,7 @@ typedef struct _IndicatorSessionGuestDbusClass IndicatorSessionGuestDbusClass; /** * An implementation of IndicatorSessionGuest that gets its user information - * from org.freedesktop.ConsoleKit and org.freedesktop.Accounts over DBus. + * from org.freedesktop.login1 and org.freedesktop.Accounts over DBus. */ struct _IndicatorSessionGuestDbus { diff --git a/src/backend-dbus/users.h b/src/backend-dbus/users.h index a9aaecf..d6c17df 100644 --- a/src/backend-dbus/users.h +++ b/src/backend-dbus/users.h @@ -42,7 +42,7 @@ typedef struct _IndicatorSessionUsersDbusClass IndicatorSessionUsersDbusClass; /** * An implementation of IndicatorSessionUsers that gets its user information - * from org.freedesktop.ConsoleKit and org.freedesktop.Accounts over DBus. + * from org.freedesktop.login1 and org.freedesktop.Accounts over DBus. */ struct _IndicatorSessionUsersDbus { diff --git a/tests/backend-dbus/test-actions.cc b/tests/backend-dbus/test-actions.cc index 410a02a..20e2521 100644 --- a/tests/backend-dbus/test-actions.cc +++ b/tests/backend-dbus/test-actions.cc @@ -319,12 +319,9 @@ TEST_F (Actions, SwitchToGuest) { // allow guests dm_seat->set_guest_allowed (true); - MockUser * guest_user; - //int guest_session_tag; -// MockConsoleKitSession * guest_ck_session; // set up a guest - guest_user = new MockUser (loop, conn, "guest-zzbEVV", "Guest", 10); + MockUser * guest_user = new MockUser (loop, conn, "guest-zzbEVV", "Guest", 10); guest_user->set_system_account (true); accounts->add_user (guest_user); int guest_session_tag = login1_manager->add_session (login1_seat, guest_user); diff --git a/tests/backend-mock-actions.h b/tests/backend-mock-actions.h index bd9ed47..96c51be 100644 --- a/tests/backend-mock-actions.h +++ b/tests/backend-mock-actions.h @@ -37,8 +37,7 @@ typedef struct _IndicatorSessionActionsMockPriv IndicatorSessionActionsMockPr typedef struct _IndicatorSessionActionsMockClass IndicatorSessionActionsMockClass; /** - * An implementation of IndicatorSessionActions that gets its user information - * from org.freedesktop.ConsoleKit and org.freedesktop.Accounts over DBus. + * An implementation of IndicatorSessionActions that lies about everything. */ struct _IndicatorSessionActionsMock { diff --git a/tests/backend-mock-guest.h b/tests/backend-mock-guest.h index db6ce86..4a15c70 100644 --- a/tests/backend-mock-guest.h +++ b/tests/backend-mock-guest.h @@ -37,8 +37,7 @@ typedef struct _IndicatorSessionGuestMockPriv IndicatorSessionGuestMockPriv; typedef struct _IndicatorSessionGuestMockClass IndicatorSessionGuestMockClass; /** - * An implementation of IndicatorSessionGuest that gets its user information - * from org.freedesktop.ConsoleKit and org.freedesktop.Accounts over DBus. + * An implementation of IndicatorSessionGuest that lies about everything. */ struct _IndicatorSessionGuestMock { diff --git a/tests/backend-mock-users.h b/tests/backend-mock-users.h index 7470ec9..513e799 100644 --- a/tests/backend-mock-users.h +++ b/tests/backend-mock-users.h @@ -37,8 +37,7 @@ typedef struct _IndicatorSessionUsersMockPriv IndicatorSessionUsersMockPriv; typedef struct _IndicatorSessionUsersMockClass IndicatorSessionUsersMockClass; /** - * An implementation of IndicatorSessionUsers that gets its user information - * from org.freedesktop.ConsoleKit and org.freedesktop.Accounts over DBus. + * An implementation of IndicatorSessionUsers that lies about everything. */ struct _IndicatorSessionUsersMock { -- cgit v1.2.3 From b95037a00e92e8e997d72b77f4cd7145d3a7d9e7 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 28 Jun 2013 14:52:08 -0500 Subject: add cmake to the debian control list; alphabetize the entries --- debian/control | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/debian/control b/debian/control index ff581db..373c3ff 100644 --- a/debian/control +++ b/debian/control @@ -2,15 +2,14 @@ Source: indicator-session Section: gnome Priority: optional Maintainer: Ubuntu Developers -Build-Depends: debhelper (>= 9), +Build-Depends: cmake, + debhelper (>= 9), dh-autoreconf, dh-translations, + gnome-doc-utils, intltool, libgtest-dev, - libdbustest1-dev, - dbus-test-runner, - libglib2.0-dev (>= 2.35.4), - gnome-doc-utils + libglib2.0-dev (>= 2.35.4) Standards-Version: 3.9.3 Homepage: https://launchpad.net/indicator-session # If you aren't a member of ~indicator-applet-developers but need to upload -- cgit v1.2.3 From d176666fbd302857b7af69774f516a53fbe086fa Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 28 Jun 2013 14:58:11 -0500 Subject: cleanup: put an '.xml' file suffix at the end of the DisplayManager.Seat xml file --- src/backend-dbus/CMakeLists.txt | 2 +- .../org.freedesktop.DisplayManager.Seat | 30 ---------------------- .../org.freedesktop.DisplayManager.Seat.xml | 30 ++++++++++++++++++++++ 3 files changed, 31 insertions(+), 31 deletions(-) delete mode 100644 src/backend-dbus/org.freedesktop.DisplayManager.Seat create mode 100644 src/backend-dbus/org.freedesktop.DisplayManager.Seat.xml diff --git a/src/backend-dbus/CMakeLists.txt b/src/backend-dbus/CMakeLists.txt index eb4d971..1c0df8e 100644 --- a/src/backend-dbus/CMakeLists.txt +++ b/src/backend-dbus/CMakeLists.txt @@ -3,7 +3,7 @@ set(BACKEND_GENERATED_SOURCES add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-display-manager org.freedesktop - ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.DisplayManager.Seat) + ${CMAKE_CURRENT_SOURCE_DIR}/org.freedesktop.DisplayManager.Seat.xml) add_gdbus_codegen (BACKEND_GENERATED_SOURCES dbus-webcredentials com.canonical.indicators diff --git a/src/backend-dbus/org.freedesktop.DisplayManager.Seat b/src/backend-dbus/org.freedesktop.DisplayManager.Seat deleted file mode 100644 index 07b5f29..0000000 --- a/src/backend-dbus/org.freedesktop.DisplayManager.Seat +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/backend-dbus/org.freedesktop.DisplayManager.Seat.xml b/src/backend-dbus/org.freedesktop.DisplayManager.Seat.xml new file mode 100644 index 0000000..07b5f29 --- /dev/null +++ b/src/backend-dbus/org.freedesktop.DisplayManager.Seat.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3 From f79e660887abb06169bc6e9b5972ca8dae457357 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 28 Jun 2013 17:00:36 -0500 Subject: no no need to pass libexecdir manually into dh_uato_configure --- debian/rules | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/debian/rules b/debian/rules index f679369..e64aff1 100644 --- a/debian/rules +++ b/debian/rules @@ -3,19 +3,13 @@ export DPKG_GENSYMBOLS_CHECK_LEVEL=4 %: - dh $@ --with translations,autoreconf - -override_dh_autoreconf: - NOCONFIGURE=1 dh_autoreconf ./autogen.sh + dh $@ --with translations override_dh_install: find debian/indicator-session/usr/lib -name *.la -delete find debian/indicator-session/usr/lib -name *.a -delete dh_install --fail-missing -override_dh_auto_configure: - dh_auto_configure -- --libexecdir="\$${prefix}/lib/indicator-session" - # Hack as it seems it's not possible to easy run that under dbus-test-runner override_dh_auto_test: env -u LD_PRELOAD dh_auto_test -- cgit v1.2.3 From 0180339dd65daa9878b93e06ad8da3742999dd3d Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 28 Jun 2013 17:06:26 -0500 Subject: remove localinstall mode --- CMakeLists.txt | 1 - build.sh | 2 +- cmake/UseGSettings.cmake | 31 +++++-------------------------- data/CMakeLists.txt | 12 ++---------- 4 files changed, 8 insertions(+), 38 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1299319..875de0f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,6 @@ set (GETTEXT_PACKAGE ${CMAKE_PROJECT_NAME}) option (enable_tests "Build the package's automatic tests." ON) option (full_warnings "Full compiler warnings." ON) option (enable_lcov "Generate lcov code coverage reports." ON) -option (LOCAL_INSTALL "Support local installation." OFF) find_package(PkgConfig REQUIRED) include (GNUInstallDirs) diff --git a/build.sh b/build.sh index c98285e..b69687c 100755 --- a/build.sh +++ b/build.sh @@ -13,6 +13,6 @@ fi echo "Using $BUILD_COMMAND to build" ( cd build - cmake .. $EXTRA_ARGS -DCMAKE_INSTALL_PREFIX=../../install -DLOCAL_INSTALL=ON -DCMAKE_BUILD_TYPE=Debug + cmake .. $EXTRA_ARGS -DCMAKE_INSTALL_PREFIX=../../install -DCMAKE_BUILD_TYPE=Debug $BUILD_COMMAND ) diff --git a/cmake/UseGSettings.cmake b/cmake/UseGSettings.cmake index c8ea30c..4050b53 100644 --- a/cmake/UseGSettings.cmake +++ b/cmake/UseGSettings.cmake @@ -1,32 +1,13 @@ # GSettings.cmake, CMake macros written for Marlin, feel free to re-use them. -option (GSETTINGS_LOCALINSTALL "Install GSettings Schemas locally instead of to the GLib prefix" ${LOCAL_INSTALL}) - -option (GSETTINGS_COMPILE "Compile GSettings Schemas after installation" ${GSETTINGS_LOCALINSTALL}) - -if(GSETTINGS_LOCALINSTALL) - message(STATUS "GSettings schemas will be installed locally.") -endif() - -if(GSETTINGS_COMPILE) - message(STATUS "GSettings shemas will be compiled.") -endif() - macro(add_schema SCHEMA_NAME) set(PKG_CONFIG_EXECUTABLE pkg-config) - set(SCHEMA_SUFFIX "share/glib-2.0/schemas") - # Have an option to not install the schema into where GLib is - if (GSETTINGS_LOCALINSTALL) - SET (GSETTINGS_DIR "${CMAKE_INSTALL_PREFIX}/${SCHEMA_SUFFIX}") - else (GSETTINGS_LOCALINSTALL) - execute_process (COMMAND ${PKG_CONFIG_EXECUTABLE} glib-2.0 --variable prefix OUTPUT_VARIABLE _glib_prefix OUTPUT_STRIP_TRAILING_WHITESPACE) - SET (GSETTINGS_DIR "${_glib_prefix}/${SCHEMA_SUFFIX}") - endif (GSETTINGS_LOCALINSTALL) + set(GSETTINGS_DIR "${CMAKE_INSTALL_PREFIX}/share/glib-2.0/schemas") # Run the validator and error if it fails - execute_process (COMMAND ${PKG_CONFIG_EXECUTABLE} gio-2.0 --variable glib_compile_schemas OUTPUT_VARIABLE _glib_comple_schemas OUTPUT_STRIP_TRAILING_WHITESPACE) - execute_process (COMMAND ${_glib_comple_schemas} --dry-run --schema-file=${SCHEMA_NAME} ERROR_VARIABLE _schemas_invalid OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process (COMMAND ${PKG_CONFIG_EXECUTABLE} gio-2.0 --variable glib_compile_schemas OUTPUT_VARIABLE _glib_compile_schemas OUTPUT_STRIP_TRAILING_WHITESPACE) + execute_process (COMMAND ${_glib_compile_schemas} --dry-run --schema-file=${SCHEMA_NAME} ERROR_VARIABLE _schemas_invalid OUTPUT_STRIP_TRAILING_WHITESPACE) if (_schemas_invalid) message (SEND_ERROR "Schema validation error: ${_schemas_invalid}") @@ -36,9 +17,7 @@ macro(add_schema SCHEMA_NAME) message (STATUS "${GSETTINGS_DIR} is the GSettings install dir") install (FILES ${SCHEMA_NAME} DESTINATION ${GSETTINGS_DIR} OPTIONAL) - if (GSETTINGS_COMPILE) - install (CODE "message (STATUS \"Compiling GSettings schemas\")") - install (CODE "execute_process (COMMAND ${_glib_comple_schemas} ${GSETTINGS_DIR})") - endif () + install (CODE "message (STATUS \"Compiling GSettings schemas\")") + install (CODE "execute_process (COMMAND ${_glib_compile_schemas} ${GSETTINGS_DIR})") endmacro() diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index 6700163..6eb257c 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -19,11 +19,7 @@ add_schema (${SCHEMA_FILE}) ## # where to install -if (${LOCAL_INSTALL}) - set (DBUS_SERVICE_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/dbus-1/services") -else () - EXEC_PROGRAM (${PKG_CONFIG_EXECUTABLE} ARGS dbus-1 --variable session_bus_services_dir OUTPUT_VARIABLE DBUS_SERVICE_DIR) -endif () +set (DBUS_SERVICE_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/dbus-1/services") message (STATUS "${DBUS_SERVICE_DIR} is the DBus Service File install dir") set (SERVICE_NAME "${CMAKE_PROJECT_NAME}.service") @@ -59,11 +55,7 @@ install (FILES "${UNITY_INDICATOR_FILE}" ## # where to install -if (${LOCAL_INSTALL}) - set (ICON_PREFIX "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/libindicator/icons") -else () - EXEC_PROGRAM (${PKG_CONFIG_EXECUTABLE} ARGS indicator3-0.4 --variable iconsdir OUTPUT_VARIABLE ICON_PREFIX) -endif () +set (ICON_PREFIX "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/libindicator/icons") set (ICON_DIR "${ICON_PREFIX}/hicolor") message (STATUS "${ICON_DIR} is the Icon install dir") -- cgit v1.2.3 From 9a3e46e73ee201771c8bc9ae9f95adecbb71fe69 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 28 Jun 2013 18:38:51 -0500 Subject: in service.c's add_user(), test for NULL before adding the user struct to our collection --- src/service.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/service.c b/src/service.c index a9f2f65..36ef282 100644 --- a/src/service.c +++ b/src/service.c @@ -210,14 +210,16 @@ add_user (IndicatorSessionService * self, guint uid) { IndicatorSessionUser * u; - /* update our user table */ - u = indicator_session_users_get_user (self->priv->backend_users, uid); - g_hash_table_insert (self->priv->users, GUINT_TO_POINTER(uid), u); + if ((u = indicator_session_users_get_user (self->priv->backend_users, uid))) + { + /* update our user table */ + g_hash_table_insert (self->priv->users, GUINT_TO_POINTER(uid), u); - /* enqueue rebuilds for the affected sections */ - rebuild_switch_section_soon (self); - if (u->is_current_user) - rebuild_header_soon (self); + /* queue rebuilds for the affected sections */ + rebuild_switch_section_soon (self); + if (u->is_current_user) + rebuild_header_soon (self); + } } static void -- cgit v1.2.3 From f85ba52944c1924271ce4734a31dacb4a8e51e71 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 28 Jun 2013 20:15:52 -0500 Subject: add dbus to the dependency list, we need a dbus-daemon for GTestDBus to spawn --- debian/control | 1 + 1 file changed, 1 insertion(+) diff --git a/debian/control b/debian/control index 373c3ff..e9d80bd 100644 --- a/debian/control +++ b/debian/control @@ -3,6 +3,7 @@ Section: gnome Priority: optional Maintainer: Ubuntu Developers Build-Depends: cmake, + dbus, debhelper (>= 9), dh-autoreconf, dh-translations, -- cgit v1.2.3 From 3222a77d7159826d89743685d35710597f269e00 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 28 Jun 2013 21:15:15 -0500 Subject: fix test breakage introduced with the recent commit that hides the reboot menuitem when running in unity shell --- tests/backend-mock-guest.c | 34 +++++++++++++++++++--------------- tests/backend-mock-users.c | 42 +++++++++++++++++++++++++----------------- tests/test-service.cc | 25 ++++++++++++++++++++----- 3 files changed, 64 insertions(+), 37 deletions(-) diff --git a/tests/backend-mock-guest.c b/tests/backend-mock-guest.c index b04c805..8bc188f 100644 --- a/tests/backend-mock-guest.c +++ b/tests/backend-mock-guest.c @@ -34,21 +34,9 @@ G_DEFINE_TYPE (IndicatorSessionGuestMock, indicator_session_guest_mock, INDICATOR_TYPE_SESSION_GUEST) -/*** -**** Virtual Functions -***/ - -static void -my_dispose (GObject * o) -{ - G_OBJECT_CLASS (indicator_session_guest_mock_parent_class)->dispose (o); -} - -static void -my_finalize (GObject * o) -{ - G_OBJECT_CLASS (indicator_session_guest_mock_parent_class)->finalize (o); -} +/** +*** IndicatorSessionGuest virtual functions +**/ static gboolean my_is_allowed (IndicatorSessionGuest * self) @@ -76,6 +64,22 @@ my_switch_to_guest (IndicatorSessionGuest * self G_GNUC_UNUSED) g_message ("%s %s FIXME", G_STRLOC, G_STRFUNC); } +/*** +**** GObject virtual Functions +***/ + +static void +my_dispose (GObject * o) +{ + G_OBJECT_CLASS (indicator_session_guest_mock_parent_class)->dispose (o); +} + +static void +my_finalize (GObject * o) +{ + G_OBJECT_CLASS (indicator_session_guest_mock_parent_class)->finalize (o); +} + /*** **** GObject Boilerplate ***/ diff --git a/tests/backend-mock-users.c b/tests/backend-mock-users.c index bae40b6..f2291cd 100644 --- a/tests/backend-mock-users.c +++ b/tests/backend-mock-users.c @@ -32,25 +32,9 @@ G_DEFINE_TYPE (IndicatorSessionUsersMock, INDICATOR_TYPE_SESSION_USERS) /*** -**** +**** IndicatorSessionUsers virtual functions ***/ -static void -my_dispose (GObject * o) -{ - G_OBJECT_CLASS (indicator_session_users_mock_parent_class)->dispose (o); -} - -static void -my_finalize (GObject * o) -{ - priv_t * p = INDICATOR_SESSION_USERS_MOCK (o)->priv; - - g_hash_table_destroy (p->users); - - G_OBJECT_CLASS (indicator_session_users_mock_parent_class)->finalize (o); -} - static gboolean my_is_live_session (IndicatorSessionUsers * users G_GNUC_UNUSED) { @@ -96,6 +80,30 @@ my_get_user (IndicatorSessionUsers * self, guint uid) return ret; } +/*** +**** GObject virtual functions +***/ + +static void +my_dispose (GObject * o) +{ + G_OBJECT_CLASS (indicator_session_users_mock_parent_class)->dispose (o); +} + +static void +my_finalize (GObject * o) +{ + priv_t * p = INDICATOR_SESSION_USERS_MOCK (o)->priv; + + g_hash_table_destroy (p->users); + + G_OBJECT_CLASS (indicator_session_users_mock_parent_class)->finalize (o); +} + +/*** +**** GObject boilerplate +***/ + static void /* cppcheck-suppress unusedFunction */ indicator_session_users_mock_class_init (IndicatorSessionUsersMockClass * klass) diff --git a/tests/test-service.cc b/tests/test-service.cc index 996332d..86f49e6 100644 --- a/tests/test-service.cc +++ b/tests/test-service.cc @@ -285,6 +285,18 @@ class ServiceTest: public GTestDBusFixture return success; } + bool action_menuitem_exists (const char * action_name) + { + bool found; + GMenuModel * model = 0; + int pos = -1; + + if ((found = find_menu_item_for_action (action_name, &model, &pos))) + g_object_unref (G_OBJECT(model)); + + return found; + } + bool action_menuitem_label_is_ellipsized (const char * action_name) { int pos = -1; @@ -477,7 +489,8 @@ TEST_F (ServiceTest, ConfirmationDisabledByBackend) // confirm that the ellipsis are correct ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.switch-to-greeter")); ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.logout")); - ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.reboot")); + if (action_menuitem_exists ("indicator.reboot")) + ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.reboot")); ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.power-off")); // now toggle the can-prompt flag @@ -490,7 +503,8 @@ TEST_F (ServiceTest, ConfirmationDisabledByBackend) // confirm that the ellipsis are correct ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.switch-to-greeter")); ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.logout")); - ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.reboot")); + if (action_menuitem_exists ("indicator.reboot")) + ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.reboot")); ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.power-off")); // cleanup @@ -509,7 +523,8 @@ TEST_F (ServiceTest, ConfirmationDisabledByUser) // confirm that the ellipsis are correct ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.switch-to-greeter")); ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.logout")); - ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.reboot")); + if (action_menuitem_exists ("indicator.reboot")) + ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.reboot")); ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.power-off")); // now toggle the can-prompt flag @@ -522,7 +537,8 @@ TEST_F (ServiceTest, ConfirmationDisabledByUser) // confirm that the ellipsis are correct ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.switch-to-greeter")); ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.logout")); - ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.reboot")); + if (action_menuitem_exists ("indicator.reboot")) + ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.reboot")); ASSERT_EQ (confirm, action_menuitem_label_is_ellipsized ("indicator.power-off")); // cleanup @@ -542,7 +558,6 @@ TEST_F (ServiceTest, DefaultMenuItems) ASSERT_TRUE (find_menu_item_for_action ("indicator.logout", NULL, NULL)); ASSERT_TRUE (find_menu_item_for_action ("indicator.suspend", NULL, NULL)); ASSERT_TRUE (find_menu_item_for_action ("indicator.hibernate", NULL, NULL)); - ASSERT_TRUE (find_menu_item_for_action ("indicator.reboot", NULL, NULL)); ASSERT_TRUE (find_menu_item_for_action ("indicator.power-off", NULL, NULL)); } -- cgit v1.2.3 From 0c8526d6686623f1d77231dd43a61775e3b6aadf Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 28 Jun 2013 23:00:27 -0500 Subject: in test-users, fix timing issue in the fixture's SetUp --- tests/backend-dbus/test-users.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/backend-dbus/test-users.cc b/tests/backend-dbus/test-users.cc index b022984..dccacbb 100644 --- a/tests/backend-dbus/test-users.cc +++ b/tests/backend-dbus/test-users.cc @@ -48,7 +48,10 @@ class Users: public GTestMockDBusFixture users = 0; backend_get (cancellable, NULL, &users, NULL); g_assert (users != 0); - wait_msec (100); + + // wait for the users added by GTestMockDBusFixture::SetUp() to show up + wait_for_signals (users, INDICATOR_SESSION_USERS_SIGNAL_USER_ADDED, 12); + init_event_keys (0); } virtual void TearDown () -- cgit v1.2.3 From 34b4d992f042293af1db641e66bef5620576d1ba Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 28 Jun 2013 23:17:22 -0500 Subject: in test-users, possible fix to async dbus action timing issue in SetUp --- tests/backend-dbus/test-actions.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/backend-dbus/test-actions.cc b/tests/backend-dbus/test-actions.cc index 20e2521..a7e7a5f 100644 --- a/tests/backend-dbus/test-actions.cc +++ b/tests/backend-dbus/test-actions.cc @@ -46,7 +46,7 @@ class Actions: public GTestMockDBusFixture actions = 0; backend_get (cancellable, &actions, NULL, NULL); g_assert (actions != 0); - wait_msec (100); + wait_msec (300); } virtual void TearDown () -- cgit v1.2.3 From b70902d0ab7f999dd1d7e9f2fe656ea8e609d7ee Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Sat, 29 Jun 2013 00:31:09 -0500 Subject: in debian/control, remove unneeded Build-Depends dh-autoreconf (this package uses cmake now) and gnome-doc-utils (we don't generate gtkdoc for i-session) --- debian/control | 2 -- 1 file changed, 2 deletions(-) diff --git a/debian/control b/debian/control index e9d80bd..039ccb5 100644 --- a/debian/control +++ b/debian/control @@ -5,9 +5,7 @@ Maintainer: Ubuntu Developers Build-Depends: cmake, dbus, debhelper (>= 9), - dh-autoreconf, dh-translations, - gnome-doc-utils, intltool, libgtest-dev, libglib2.0-dev (>= 2.35.4) -- cgit v1.2.3 From 64b4f1394068fe1c6029e9bad3135e92303f2cd4 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Sun, 30 Jun 2013 22:21:34 -0400 Subject: session-menu-mgr.c: don't leak user menu items --- src/session-menu-mgr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/session-menu-mgr.c b/src/session-menu-mgr.c index 22f70e5..c406009 100644 --- a/src/session-menu-mgr.c +++ b/src/session-menu-mgr.c @@ -990,6 +990,7 @@ update_user_menuitems (SessionMenuMgr * mgr) for (l=mgr->user_menuitems; l!=NULL; l=l->next) { dbusmenu_menuitem_child_delete (mgr->top_mi, l->data); + g_object_unref (l->data); } g_slist_free (mgr->user_menuitems); mgr->user_menuitems = NULL; -- cgit v1.2.3 From 39750137bbbbe1f3ba1aa7ae8dc5d39e0f354313 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 09:53:32 -0500 Subject: when user switching isn't available, don't ellipsize the 'Lock' menuitem --- src/service.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/service.c b/src/service.c index 36ef282..45bbdad 100644 --- a/src/service.c +++ b/src/service.c @@ -451,8 +451,7 @@ create_switch_section (IndicatorSessionService * self) else if (g_hash_table_size (p->users) == 1) { const char * action = "indicator.switch-to-greeter"; - item = g_menu_item_new (ellipsis ? _("Lock…") - : _("Lock"), action); + item = g_menu_item_new (_("Lock"), action); } else { -- cgit v1.2.3 From 974a5ecba82e944b74ecf14699e032579d519250 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 12:29:33 -0500 Subject: bump the glib prerequisite in CMakeLists.txt and debian/control to the first stable version number containing the features we need (2.36). It had been a beta (2.35.x) for historical reasons. --- CMakeLists.txt | 4 ++-- debian/control | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 875de0f..593d916 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,8 +21,8 @@ add_definitions( -DGETTEXT_PACKAGE="${GETTEXT_PACKAGE}" ) add_definitions (-DGNOMELOCALEDIR=\"@CMAKE_INSTALL_PREFIX@/share/locale\") pkg_check_modules (SERVICE REQUIRED - glib-2.0>=2.35.4 - gio-unix-2.0>=2.25.11) + glib-2.0>=2.36 + gio-unix-2.0>=2.36) include_directories (${SERVICE_INCLUDE_DIRS}) set (CC_WARNING_ARGS " -Wall -pedantic -Wextra -Wno-missing-field-initializers") diff --git a/debian/control b/debian/control index 039ccb5..a0dfdb1 100644 --- a/debian/control +++ b/debian/control @@ -8,7 +8,7 @@ Build-Depends: cmake, dh-translations, intltool, libgtest-dev, - libglib2.0-dev (>= 2.35.4) + libglib2.0-dev (>= 2.36) Standards-Version: 3.9.3 Homepage: https://launchpad.net/indicator-session # If you aren't a member of ~indicator-applet-developers but need to upload -- cgit v1.2.3 From b252745c8111c9be1d7e95a88daab1e2568b1afc Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 12:33:08 -0500 Subject: in backend-dbus/actions.c's set_login1_seat(), disconnect from the previous seat's signals before unreff'ing it --- src/backend-dbus/actions.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index 67fe9f1..8c1b70b 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -99,13 +99,18 @@ set_login1_seat (IndicatorSessionActionsDbus * self, Login1Seat * seat) { priv_t * p = self->priv; - g_clear_object (&p->login1_seat); + if (p->login1_seat != NULL) + { + g_signal_handlers_disconnect_by_data (p->login1_seat, self); + g_clear_object (&p->login1_seat); + } if (seat != NULL) { p->login1_seat = g_object_ref (seat); - g_signal_connect_swapped (seat, "notify::can-multi-session", G_CALLBACK(on_seat_notify_multi_session), self); + g_signal_connect_swapped (seat, "notify::can-multi-session", + G_CALLBACK(on_seat_notify_multi_session), self); } } -- cgit v1.2.3 From 37694a94d8c188b909740f2eed7a984273dc2320 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 12:35:17 -0500 Subject: in backend-dbus/actions.c's set_dm_seat(), since we don't listen to displaymanager's signals anymore, remove unnecessary g_signal_handlers_disconnect() call. --- src/backend-dbus/actions.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index 8c1b70b..1756a0f 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -123,17 +123,10 @@ set_dm_seat (IndicatorSessionActionsDbus * self, DisplayManagerSeat * seat) { priv_t * p = self->priv; - if (p->dm_seat != NULL) - { - g_signal_handlers_disconnect_by_data (p->dm_seat, self); - g_clear_object (&p->dm_seat); - } + g_clear_object (&p->dm_seat); if (seat != NULL) - { - p->dm_seat = g_object_ref (seat); - /*g_signal_connect (seat, "notify::has-actions-account", G_CALLBACK(on_notify_has_actions_account), self);*/ - } + p->dm_seat = g_object_ref (seat); } static void -- cgit v1.2.3 From 90c7f19eeaf0c89e40ddd59f00edbb0d7b1c0789 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 12:41:41 -0500 Subject: in backend-dbus/actions.c, create a separate cancellable for login1_manager s.t. new calls to set_login1_manager() will cancel any previous async calls pending on the old login1 manager object. --- src/backend-dbus/actions.c | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index 1756a0f..c40d0c6 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -37,6 +37,7 @@ enum struct _IndicatorSessionActionsDbusPriv { GCancellable * cancellable; + GCancellable * login1_manager_cancellable; GSettings * lockdown_settings; GnomeScreenSaver * screen_saver; @@ -205,19 +206,26 @@ set_login1_manager (IndicatorSessionActionsDbus * self, { priv_t * p = self->priv; - g_clear_object (&p->login1_manager); + if (p->login1_manager != NULL) + { + g_cancellable_cancel (p->login1_manager_cancellable); + g_clear_object (&p->login1_manager_cancellable); + g_clear_object (&p->login1_manager); + } if (login1_manager != NULL) { + p->login1_manager_cancellable = g_cancellable_new (); + p->login1_manager = g_object_ref (login1_manager); login1_manager_call_can_suspend (p->login1_manager, - p->cancellable, + p->login1_manager_cancellable, on_can_suspend_ready, self); login1_manager_call_can_hibernate (p->login1_manager, - p->cancellable, + p->login1_manager_cancellable, on_can_hibernate_ready, self); } @@ -353,7 +361,11 @@ my_suspend (IndicatorSessionActions * self) g_return_if_fail (p->login1_manager != NULL); - login1_manager_call_suspend (p->login1_manager, FALSE, p->cancellable, NULL, NULL); + login1_manager_call_suspend (p->login1_manager, + FALSE, + p->login1_manager_cancellable, + NULL, + NULL); } static void @@ -363,7 +375,11 @@ my_hibernate (IndicatorSessionActions * self) g_return_if_fail (p->login1_manager != NULL); - login1_manager_call_hibernate (p->login1_manager, FALSE, p->cancellable, NULL, NULL); + login1_manager_call_hibernate (p->login1_manager, + FALSE, + p->login1_manager_cancellable, + NULL, + NULL); } /*** @@ -404,7 +420,11 @@ reboot_now (IndicatorSessionActions * self) g_return_if_fail (p->login1_manager != NULL); - login1_manager_call_reboot (p->login1_manager, FALSE, p->cancellable, NULL, NULL); + login1_manager_call_reboot (p->login1_manager, + FALSE, + p->login1_manager_cancellable, + NULL, + NULL); } static void @@ -414,7 +434,11 @@ power_off_now (IndicatorSessionActions * self) g_return_if_fail (p->login1_manager != NULL); - login1_manager_call_power_off (p->login1_manager, FALSE, p->cancellable, NULL, NULL); + login1_manager_call_power_off (p->login1_manager, + FALSE, + p->login1_manager_cancellable, + NULL, + NULL); } static void -- cgit v1.2.3 From 0b5f283691222c23599ab460bb5dad7a78378aa8 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 12:46:00 -0500 Subject: in backend-dbus/actions.c, create a separate cancellable for dm_seat s.t. new calls to set_dm_seat() will cancel any previous async calls pending on the old DisplayManager seat object. --- src/backend-dbus/actions.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index c40d0c6..c095896 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -37,14 +37,15 @@ enum struct _IndicatorSessionActionsDbusPriv { GCancellable * cancellable; - GCancellable * login1_manager_cancellable; GSettings * lockdown_settings; GnomeScreenSaver * screen_saver; GnomeSessionManager * session_manager; Login1Manager * login1_manager; + GCancellable * login1_manager_cancellable; Login1Seat * login1_seat; DisplayManagerSeat * dm_seat; + GCancellable * dm_seat_cancellable; Webcredentials * webcredentials; EndSessionDialog * end_session_dialog; @@ -124,10 +125,18 @@ set_dm_seat (IndicatorSessionActionsDbus * self, DisplayManagerSeat * seat) { priv_t * p = self->priv; - g_clear_object (&p->dm_seat); + if (p->dm_seat != NULL) + { + g_cancellable_cancel (p->dm_seat_cancellable); + g_clear_object (&p->dm_seat); + g_clear_object (&p->dm_seat); + } if (seat != NULL) - p->dm_seat = g_object_ref (seat); + { + p->dm_seat = g_object_ref (seat); + p->dm_seat_cancellable = g_cancellable_new (); + } } static void @@ -570,7 +579,8 @@ my_switch_to_greeter (IndicatorSessionActions * self) g_return_if_fail (p->dm_seat != NULL); - display_manager_seat_call_switch_to_greeter (p->dm_seat, p->cancellable, + display_manager_seat_call_switch_to_greeter (p->dm_seat, + p->dm_seat_cancellable, NULL, NULL); } @@ -582,7 +592,7 @@ my_switch_to_guest (IndicatorSessionActions * self) g_return_if_fail (p->dm_seat != NULL); display_manager_seat_call_switch_to_guest (p->dm_seat, "", - p->cancellable, + p->dm_seat_cancellable, NULL, NULL); } @@ -594,7 +604,7 @@ my_switch_to_username (IndicatorSessionActions * self, const char * username) g_return_if_fail (p->dm_seat != NULL); display_manager_seat_call_switch_to_user (p->dm_seat, username, "", - p->cancellable, + p->dm_seat_cancellable, NULL, NULL); } -- cgit v1.2.3 From 73a9ac42d15b01c6807eb5bdaee0c24431e7e539 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 12:54:52 -0500 Subject: in src/backend-dbus/guest.c's on_login1_manager_session_list_ready(), remove unused variable 'path' --- src/backend-dbus/guest.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/backend-dbus/guest.c b/src/backend-dbus/guest.c index 963bdc8..3269097 100644 --- a/src/backend-dbus/guest.c +++ b/src/backend-dbus/guest.c @@ -119,15 +119,14 @@ on_login1_manager_session_list_ready (GObject * o, guint32 uid = 0; const gchar * user_name = NULL; const gchar * seat_id = NULL; - const gchar * path = NULL; GVariantIter iter; g_variant_iter_init (&iter, sessions); - while (g_variant_iter_loop (&iter, "(&su&s&s&o)", &session_id, + while (g_variant_iter_loop (&iter, "(&su&s&so)", &session_id, &uid, &user_name, &seat_id, - &path)) + NULL)) { gboolean is_current_session; gboolean is_guest; -- cgit v1.2.3 From 604640ebeca2fe1b2eb4aa475dbb4221dd8aeb72 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 13:06:17 -0500 Subject: in src/backend-dbus/users.c's set_logins(), fix ref/unref semantics of the hashtable argument --- src/backend-dbus/users.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index b5a6d32..caf6403 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -130,7 +130,7 @@ set_logins (IndicatorSessionUsersDbus * self, GHashTable * logins) gpointer uid; GHashTableIter iter; - self->priv->logins = logins; + self->priv->logins = g_hash_table_ref (logins); /* fire 'user changed' event for users who logged out */ g_hash_table_iter_init (&iter, old_logins); @@ -420,6 +420,7 @@ on_login1_manager_session_list_ready (GObject * o, set_is_live_session_flag (self, is_live_session); set_logins (self, logins); + g_hash_table_unref (logins); g_variant_unref (sessions); } } -- cgit v1.2.3 From d5421fec0a7e51ddb1979a97de271a3f1733321e Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 13:07:33 -0500 Subject: in src/backend-dbus/users.c, use G_DEFINE_QUARK() instead of rolling our own quark func --- src/backend-dbus/users.c | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index caf6403..b9a79e5 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -151,23 +151,14 @@ set_logins (IndicatorSessionUsersDbus * self, GHashTable * logins) **** ***/ -static GQuark -get_connection_list_quark (void) -{ - static GQuark q = 0; - - if (G_UNLIKELY (q == 0)) - q = g_quark_from_static_string ("connection-ids"); - - return q; -} +G_DEFINE_QUARK (connection-ids, connection_list) static void object_unref_and_disconnect (gpointer instance) { - GSList * l; + const GQuark q = connection_list_quark (); GSList * ids; - const GQuark q = get_connection_list_quark (); + GSList * l; ids = g_object_steal_qdata (G_OBJECT(instance), q); for (l=ids; l!=NULL; l=l->next) @@ -184,7 +175,7 @@ object_unref_and_disconnect (gpointer instance) static void object_add_connection (GObject * o, gulong connection_id) { - const GQuark q = get_connection_list_quark (); + const GQuark q = connection_list_quark (); GSList * ids; gulong * ptr; -- cgit v1.2.3 From eb7e99b24b15a311f188754bf3d0d4f72551deab Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 13:12:08 -0500 Subject: in src/backend-dbus/users.c's track_user(), simplify the ref/unref semantics of the user argument --- src/backend-dbus/users.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index b9a79e5..738eda4 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -215,7 +215,9 @@ track_user (IndicatorSessionUsersDbus * self, id = g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self); object_add_connection (G_OBJECT(user), id); - g_hash_table_insert (p->uid_to_account, GUINT_TO_POINTER (uid), user); + g_hash_table_insert (p->uid_to_account, + GUINT_TO_POINTER (uid), + g_object_ref (user)); if (already_had_user) emit_user_changed (self, uid); @@ -266,12 +268,11 @@ on_user_proxy_ready (GObject * o G_GNUC_UNUSED, g_error_free (err); } - else if (!accounts_user_get_system_account (user)) - { - track_user (self, user); - } else { + if (!accounts_user_get_system_account (user)) + track_user (self, user); + g_object_unref (user); } } -- cgit v1.2.3 From bb2129f5fada412c88e5d3f739038d560a5444a9 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 13:13:07 -0500 Subject: in src/backend-dbus/users.c's object_unref_and_disconnect(), fix an unbalanced ref/unref --- src/backend-dbus/users.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 738eda4..6f02a53 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -166,9 +166,10 @@ object_unref_and_disconnect (gpointer instance) gulong * handler_id = l->data; g_signal_handler_disconnect (instance, *handler_id); g_free (handler_id); - g_object_unref (instance); } + g_object_unref (instance); + g_slist_free (ids); } -- cgit v1.2.3 From c96e42d1d00d68b6c858d7d314c13b4d05ca0d8b Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 13:28:05 -0500 Subject: in src/backend-dbus/users.c, use a helper struct for disconnecting the signals to the user proxies in our uid-to-user hashtable --- src/backend-dbus/users.c | 94 +++++++++++++++++++++++------------------------- 1 file changed, 45 insertions(+), 49 deletions(-) diff --git a/src/backend-dbus/users.c b/src/backend-dbus/users.c index 6f02a53..f770695 100644 --- a/src/backend-dbus/users.c +++ b/src/backend-dbus/users.c @@ -28,7 +28,7 @@ struct _IndicatorSessionUsersDbusPriv DisplayManagerSeat * dm_seat; Accounts * accounts; - /* hash table of int uids to AccountsUser* */ + /* hash table of int uids to UserRecord* */ GHashTable * uid_to_account; /* a hashset of int uids of users who are logged in */ @@ -55,13 +55,46 @@ G_DEFINE_TYPE (IndicatorSessionUsersDbus, **** ***/ +struct UserRecord +{ + AccountsUser * user; + + gulong signal_id; +}; + +struct UserRecord * +user_record_new (AccountsUser * user, gulong signal_id) +{ + struct UserRecord * rec; + rec = g_new (struct UserRecord, 1); + rec->user = g_object_ref (user); + rec->signal_id = signal_id; + return rec; +} + +static void +user_record_free (struct UserRecord * rec) +{ + g_signal_handler_disconnect (rec->user, rec->signal_id); + g_object_unref (G_OBJECT (rec->user)); + g_free (rec); +} + +/*** +**** +***/ + /* get our private org.freedesktop.Accounts.User proxy for the given uid */ static AccountsUser * get_user_for_uid (IndicatorSessionUsersDbus * self, guint uid) { - priv_t * p = self->priv; + struct UserRecord * rec; + + if ((rec = g_hash_table_lookup (self->priv->uid_to_account, + GUINT_TO_POINTER(uid)))) + return rec->user; - return g_hash_table_lookup (p->uid_to_account, GUINT_TO_POINTER(uid)); + return NULL; } static gboolean @@ -147,47 +180,6 @@ set_logins (IndicatorSessionUsersDbus * self, GHashTable * logins) g_hash_table_destroy (old_logins); } -/*** -**** -***/ - -G_DEFINE_QUARK (connection-ids, connection_list) - -static void -object_unref_and_disconnect (gpointer instance) -{ - const GQuark q = connection_list_quark (); - GSList * ids; - GSList * l; - - ids = g_object_steal_qdata (G_OBJECT(instance), q); - for (l=ids; l!=NULL; l=l->next) - { - gulong * handler_id = l->data; - g_signal_handler_disconnect (instance, *handler_id); - g_free (handler_id); - } - - g_object_unref (instance); - - g_slist_free (ids); -} - -static void -object_add_connection (GObject * o, gulong connection_id) -{ - const GQuark q = connection_list_quark (); - GSList * ids; - gulong * ptr; - - ptr = g_new (gulong, 1); - *ptr = connection_id; - - ids = g_object_steal_qdata (o, q); - ids = g_slist_prepend (ids, ptr); - g_object_set_qdata (o, q, ids); -} - /*** **** User Account Tracking ***/ @@ -215,10 +207,9 @@ track_user (IndicatorSessionUsersDbus * self, const gboolean already_had_user = is_tracked_uid (self, uid); id = g_signal_connect (user, "changed", G_CALLBACK(on_user_changed), self); - object_add_connection (G_OBJECT(user), id); g_hash_table_insert (p->uid_to_account, GUINT_TO_POINTER (uid), - g_object_ref (user)); + user_record_new (user, id)); if (already_had_user) emit_user_changed (self, uid); @@ -236,11 +227,16 @@ untrack_user (IndicatorSessionUsersDbus * self, GHashTableIter iter; priv_t * p = self->priv; + /* find the uid matching this object path */ uid = 0; g_hash_table_iter_init (&iter, p->uid_to_account); while (!uid && g_hash_table_iter_next (&iter, &key, &val)) - if (!g_strcmp0 (path, g_dbus_proxy_get_object_path (val))) - uid = GPOINTER_TO_UINT (key); + { + struct UserRecord * rec = val; + GDBusProxy * proxy = G_DBUS_PROXY (rec->user); + if (!g_strcmp0 (path, g_dbus_proxy_get_object_path (proxy))) + uid = GPOINTER_TO_UINT (key); + } if (uid) { @@ -677,7 +673,7 @@ indicator_session_users_dbus_init (IndicatorSessionUsersDbus * self) p->uid_to_account = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, - object_unref_and_disconnect); + (GDestroyNotify)user_record_free); p->logins = g_hash_table_new (g_direct_hash, g_direct_equal); } -- cgit v1.2.3 From 695aba24f30be53f291c52ef42f2dce76fb656cf Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 18:38:37 -0500 Subject: in data/CMakeLists.txt, install icons/' subdirectories, not the icons/ directory itself. --- data/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index 6eb257c..e37f647 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -60,6 +60,11 @@ set (ICON_DIR "${ICON_PREFIX}/hicolor") message (STATUS "${ICON_DIR} is the Icon install dir") install (DIRECTORY icons + icons/16x16 + icons/22x22 + icons/24x24 + icons/32x32 + icons/scalable DESTINATION "${ICON_DIR}" FILES_MATCHING PATTERN "*.png" PATTERN "*.svg") -- cgit v1.2.3 From 6ee61b9bb4d92e5c9a41d2259e879486ec0d730a Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 18:39:09 -0500 Subject: in data/CMakeLists.txt, install icons into the standard hicolor directory, rather than a custom libindicator hicolor directory, as discussed with ted and lars in #systems --- data/CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index e37f647..335582c 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -55,8 +55,7 @@ install (FILES "${UNITY_INDICATOR_FILE}" ## # where to install -set (ICON_PREFIX "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/libindicator/icons") -set (ICON_DIR "${ICON_PREFIX}/hicolor") +set (ICON_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/icons/hicolor") message (STATUS "${ICON_DIR} is the Icon install dir") install (DIRECTORY icons -- cgit v1.2.3 From 477dc6fa22bcd37b23deb45b57bec6518ba52ad9 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 19:02:47 -0500 Subject: in the cmake files, prefer the _FULL versions of the GNU variables --- CMakeLists.txt | 4 ++-- cmake/UseGSettings.cmake | 2 +- data/CMakeLists.txt | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 593d916..25c2be1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,8 +46,8 @@ include_directories (${CMAKE_CURRENT_BINARY_DIR}/src) # Workaround for libexecdir on debian if (EXISTS "/etc/debian_version") - set (CMAKE_INSTALL_LIBEXECDIR ${CMAKE_INSTALL_LIBDIR}) - set (CMAKE_INSTALL_FULL_LIBEXECDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBEXECDIR}") + set (CMAKE_INSTALL_LIBEXECDIR "${CMAKE_INSTALL_LIBDIR}") + set (CMAKE_INSTALL_FULL_LIBEXECDIR "${CMAKE_INSTALL_FULL_LIBDIR}") endif () set (PROJECT_LIBEXECDIR "${CMAKE_INSTALL_FULL_LIBEXECDIR}/${CMAKE_PROJECT_NAME}") message (STATUS "${PROJECT_LIBEXECDIR} is the libexec install dir") diff --git a/cmake/UseGSettings.cmake b/cmake/UseGSettings.cmake index 4050b53..3b61523 100644 --- a/cmake/UseGSettings.cmake +++ b/cmake/UseGSettings.cmake @@ -3,7 +3,7 @@ macro(add_schema SCHEMA_NAME) set(PKG_CONFIG_EXECUTABLE pkg-config) - set(GSETTINGS_DIR "${CMAKE_INSTALL_PREFIX}/share/glib-2.0/schemas") + set(GSETTINGS_DIR "${CMAKE_INSTALL_FULL_DATAROOTDIR}/glib-2.0/schemas") # Run the validator and error if it fails execute_process (COMMAND ${PKG_CONFIG_EXECUTABLE} gio-2.0 --variable glib_compile_schemas OUTPUT_VARIABLE _glib_compile_schemas OUTPUT_STRIP_TRAILING_WHITESPACE) diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index 335582c..3ddf422 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -19,7 +19,7 @@ add_schema (${SCHEMA_FILE}) ## # where to install -set (DBUS_SERVICE_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/dbus-1/services") +set (DBUS_SERVICE_DIR "${CMAKE_INSTALL_FULL_DATADIR}/dbus-1/services") message (STATUS "${DBUS_SERVICE_DIR} is the DBus Service File install dir") set (SERVICE_NAME "${CMAKE_PROJECT_NAME}.service") @@ -40,7 +40,7 @@ install (FILES "${SERVICE_FILE}" ## # where to install -set (UNITY_INDICATOR_DIR "${CMAKE_INSTALL_PREFIX}/share/unity/indicators") +set (UNITY_INDICATOR_DIR "${CMAKE_INSTALL_FULL_DATAROOTDIR}/unity/indicators") message (STATUS "${UNITY_INDICATOR_DIR} is the Unity Indicator install dir") set (UNITY_INDICATOR_NAME "com.canonical.indicator.session") -- cgit v1.2.3 From ca86fd5c9dae0ef231394f5b1cf98645c7312f9a Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 19:26:11 -0500 Subject: in cmake/Translations.cmake, use the GNUInstallDirs variables --- cmake/Translations.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/Translations.cmake b/cmake/Translations.cmake index f069a15..178bded 100644 --- a/cmake/Translations.cmake +++ b/cmake/Translations.cmake @@ -10,7 +10,7 @@ macro(add_translations_directory NLS_PACKAGE) add_custom_command (TARGET i18n COMMAND ${MSGFMT_EXECUTABLE} -o ${MO_OUTPUT} ${PO_INPUT}) install (FILES ${MO_OUTPUT} DESTINATION - share/locale/${PO_INPUT_BASE}/LC_MESSAGES + ${CMAKE_INSTALL_LOCALEDIR}/LC_MESSAGES RENAME ${NLS_PACKAGE}.mo) endforeach (PO_INPUT ${PO_FILES}) endmacro(add_translations_directory) -- cgit v1.2.3 From 47bd4aebb17b165792c5883e73c99f57d601778b Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 19:27:04 -0500 Subject: in our cmake files, rename PROJECT_LIBEXECDIR as CMAKE_INSTALL_LIBEXECDIR and CMAKE_INSTALL_FULL_LIBEXECDIR for consistency with the other GNUInstallDirs --- CMakeLists.txt | 5 +++-- data/CMakeLists.txt | 2 +- src/CMakeLists.txt | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 25c2be1..a043d9d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,8 +49,9 @@ if (EXISTS "/etc/debian_version") set (CMAKE_INSTALL_LIBEXECDIR "${CMAKE_INSTALL_LIBDIR}") set (CMAKE_INSTALL_FULL_LIBEXECDIR "${CMAKE_INSTALL_FULL_LIBDIR}") endif () -set (PROJECT_LIBEXECDIR "${CMAKE_INSTALL_FULL_LIBEXECDIR}/${CMAKE_PROJECT_NAME}") -message (STATUS "${PROJECT_LIBEXECDIR} is the libexec install dir") + +set (CMAKE_INSTALL_PKGLIBEXECDIR "${CMAKE_INSTALL_LIBEXECDIR}/${CMAKE_PROJECT_NAME}") +set (CMAKE_INSTALL_FULL_PKGLIBEXECDIR "${CMAKE_INSTALL_FULL_LIBEXECDIR}/${CMAKE_PROJECT_NAME}") add_subdirectory (src) add_subdirectory (data) diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index 3ddf422..3aa8ce4 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -27,7 +27,7 @@ set (SERVICE_FILE "${CMAKE_CURRENT_BINARY_DIR}/${SERVICE_NAME}") set (SERVICE_FILE_IN "${CMAKE_CURRENT_SOURCE_DIR}/${SERVICE_NAME}.in") # build it -set (pkglibexecdir "${PROJECT_LIBEXECDIR}") +set (pkglibexecdir "${CMAKE_INSTALL_FULL_PKGLIBEXECDIR}") configure_file ("${SERVICE_FILE_IN}" "${SERVICE_FILE}") # install it diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7b65629..b327820 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -17,4 +17,4 @@ link_directories(${SERVICE_LIBRARY_DIRS}) set (SERVICE_EXEC "indicator-session-service") add_executable (${SERVICE_EXEC} main.c) target_link_libraries (${SERVICE_EXEC} libindicatorsessionservice backenddbus ${SERVICE_LIBRARIES} ${GCOV_LIBS}) -install (TARGETS ${SERVICE_EXEC} RUNTIME DESTINATION ${PROJECT_LIBEXECDIR}) +install (TARGETS ${SERVICE_EXEC} RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_PKGLIBEXECDIR}) -- cgit v1.2.3 From 13139b04cb8cfbe99f5d3fd6433020567af92971 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 19:42:20 -0500 Subject: in cmake, remove the 'full_warnings' option because we always run with full warnings. --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a043d9d..c8dc83e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,6 @@ set (PACKAGE ${CMAKE_PROJECT_NAME}) set (GETTEXT_PACKAGE ${CMAKE_PROJECT_NAME}) option (enable_tests "Build the package's automatic tests." ON) -option (full_warnings "Full compiler warnings." ON) option (enable_lcov "Generate lcov code coverage reports." ON) find_package(PkgConfig REQUIRED) -- cgit v1.2.3 From cba24317a60a2670c0c917aaa637488b834da379 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 20:55:54 -0500 Subject: in main.c's on_name_lost(), silence minor 'unused parameter' compiler warning --- src/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.c b/src/main.c index 8df5e60..45c5394 100644 --- a/src/main.c +++ b/src/main.c @@ -30,7 +30,7 @@ ***/ static void -on_name_lost (gpointer instance, gpointer loop) +on_name_lost (gpointer instance G_GNUC_UNUSED, gpointer loop) { g_warning ("exiting: service couldn't acquire, or lost ownership of, busname"); -- cgit v1.2.3 From e875abf22fc02939185b6aa881865cff58fc1543 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 21:00:17 -0500 Subject: in cmake files, limit scopes by moving single-target properties out of the global variables to single-target ones and moving single-use includes into the directories where they're used --- CMakeLists.txt | 30 ++++++++++++++---------------- data/CMakeLists.txt | 2 ++ src/CMakeLists.txt | 11 +++++++++-- src/backend-dbus/CMakeLists.txt | 2 ++ 4 files changed, 27 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c8dc83e..f8a366b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,15 +10,23 @@ set (GETTEXT_PACKAGE ${CMAKE_PROJECT_NAME}) option (enable_tests "Build the package's automatic tests." ON) option (enable_lcov "Generate lcov code coverage reports." ON) -find_package(PkgConfig REQUIRED) +## +## GNU standard installation directories +## include (GNUInstallDirs) -include (FindPkgConfig) -include (GdbusCodegen) -include (UseGSettings) +if (EXISTS "/etc/debian_version") # Workaround for libexecdir on debian + set (CMAKE_INSTALL_LIBEXECDIR "${CMAKE_INSTALL_LIBDIR}") + set (CMAKE_INSTALL_FULL_LIBEXECDIR "${CMAKE_INSTALL_FULL_LIBDIR}") +endif () +set (CMAKE_INSTALL_PKGLIBEXECDIR "${CMAKE_INSTALL_LIBEXECDIR}/${CMAKE_PROJECT_NAME}") +set (CMAKE_INSTALL_FULL_PKGLIBEXECDIR "${CMAKE_INSTALL_FULL_LIBEXECDIR}/${CMAKE_PROJECT_NAME}") -add_definitions( -DGETTEXT_PACKAGE="${GETTEXT_PACKAGE}" ) -add_definitions (-DGNOMELOCALEDIR=\"@CMAKE_INSTALL_PREFIX@/share/locale\") +## +## Check for prerequisites +## +find_package (PkgConfig REQUIRED) +include (FindPkgConfig) pkg_check_modules (SERVICE REQUIRED glib-2.0>=2.36 gio-unix-2.0>=2.36) @@ -26,8 +34,6 @@ include_directories (${SERVICE_INCLUDE_DIRS}) set (CC_WARNING_ARGS " -Wall -pedantic -Wextra -Wno-missing-field-initializers") - - set (ARCHIVE_NAME ${CMAKE_PROJECT_NAME}-${PROJECT_VERSION}) add_custom_target (dist COMMAND bzr export --root=${ARCHIVE_NAME} ${CMAKE_BINARY_DIR}/${ARCHIVE_NAME}.tar.gz @@ -43,14 +49,6 @@ add_custom_target (cppcheck COMMAND cppcheck --enable=all -q --error-exitcode=2 include_directories (${CMAKE_CURRENT_SOURCE_DIR}/src) include_directories (${CMAKE_CURRENT_BINARY_DIR}/src) -# Workaround for libexecdir on debian -if (EXISTS "/etc/debian_version") - set (CMAKE_INSTALL_LIBEXECDIR "${CMAKE_INSTALL_LIBDIR}") - set (CMAKE_INSTALL_FULL_LIBEXECDIR "${CMAKE_INSTALL_FULL_LIBDIR}") -endif () - -set (CMAKE_INSTALL_PKGLIBEXECDIR "${CMAKE_INSTALL_LIBEXECDIR}/${CMAKE_PROJECT_NAME}") -set (CMAKE_INSTALL_FULL_PKGLIBEXECDIR "${CMAKE_INSTALL_FULL_LIBEXECDIR}/${CMAKE_PROJECT_NAME}") add_subdirectory (src) add_subdirectory (data) diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index 3aa8ce4..ac4e76c 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -1,3 +1,5 @@ +include (UseGSettings) + ## ## GSettings schema ## diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b327820..a00b6f1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,12 +9,19 @@ add_library (libindicatorsessionservice STATIC service.h users.c users.h) -set_target_properties (libindicatorsessionservice PROPERTIES COMPILE_FLAGS " -g ${CC_WARNING_ARGS} ${GCOV_FLAGS}") - include_directories(${SERVICE_INCLUDE_DIRS}) link_directories(${SERVICE_LIBRARY_DIRS}) set (SERVICE_EXEC "indicator-session-service") +set_property (SOURCE main.c + APPEND PROPERTY COMPILE_DEFINITIONS + GETTEXT_PACKAGE="${GETTEXT_PACKAGE}" + GNOMELOCALEDIR="@CMAKE_INSTALL_FULL_LOCALEDIR@") add_executable (${SERVICE_EXEC} main.c) target_link_libraries (${SERVICE_EXEC} libindicatorsessionservice backenddbus ${SERVICE_LIBRARIES} ${GCOV_LIBS}) install (TARGETS ${SERVICE_EXEC} RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_PKGLIBEXECDIR}) + +# common properties +set_property (TARGET libindicatorsessionservice ${SERVICE_EXEC} + APPEND_STRING PROPERTY COMPILE_FLAGS + " -g ${CC_WARNING_ARGS} ${GCOV_FLAGS}") diff --git a/src/backend-dbus/CMakeLists.txt b/src/backend-dbus/CMakeLists.txt index 1c0df8e..fa41534 100644 --- a/src/backend-dbus/CMakeLists.txt +++ b/src/backend-dbus/CMakeLists.txt @@ -1,3 +1,5 @@ +include (GdbusCodegen) + set(BACKEND_GENERATED_SOURCES ) -- cgit v1.2.3 From d95cce515fb4c1e04ef3e9d7363102996cc00d09 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 2 Jul 2013 09:35:15 -0500 Subject: in the .indicator file, add a Position entry --- data/com.canonical.indicator.session | 1 + 1 file changed, 1 insertion(+) diff --git a/data/com.canonical.indicator.session b/data/com.canonical.indicator.session index fce3554..81ade06 100644 --- a/data/com.canonical.indicator.session +++ b/data/com.canonical.indicator.session @@ -1,6 +1,7 @@ [Indicator Service] Name=indicator-session ObjectPath=/com/canonical/indicator/session +Position=10 [desktop] ObjectPath=/com/canonical/indicator/session/desktop -- cgit v1.2.3 From 9df7720fabd9ee7cb98dfd7ea6736224daf26364 Mon Sep 17 00:00:00 2001 From: Lars Uebernickel Date: Tue, 2 Jul 2013 15:07:49 -0400 Subject: Set the desired position in the panel --- src/indicator-session.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/indicator-session.c b/src/indicator-session.c index 431292e..ada8c6e 100644 --- a/src/indicator-session.c +++ b/src/indicator-session.c @@ -93,8 +93,7 @@ static void indicator_session_init (IndicatorSession *self); static void indicator_session_dispose (GObject *object); static void indicator_session_finalize (GObject *object); static GList* indicator_session_get_entries (IndicatorObject* obj); -static guint indicator_session_get_location (IndicatorObject * io, - IndicatorObjectEntry * entry); +static gint indicator_session_get_position (IndicatorObject * io); G_DEFINE_TYPE (IndicatorSession, indicator_session, INDICATOR_OBJECT_TYPE); @@ -108,7 +107,7 @@ indicator_session_class_init (IndicatorSessionClass *klass) IndicatorObjectClass * io_class = INDICATOR_OBJECT_CLASS(klass); io_class->get_entries = indicator_session_get_entries; - io_class->get_location = indicator_session_get_location; + io_class->get_position = indicator_session_get_position; return; } @@ -201,11 +200,10 @@ indicator_session_get_entries (IndicatorObject* obj) return g_list_append (NULL, &self->entry); } -static guint -indicator_session_get_location (IndicatorObject * io, - IndicatorObjectEntry * entry) +static gint +indicator_session_get_position (IndicatorObject * io) { - return 0; + return 10; } /* callback for the service manager state of being */ -- cgit v1.2.3 From b8846bc27ad107ff3a06f0378da73b239e8ed2b0 Mon Sep 17 00:00:00 2001 From: Automatic PS uploader Date: Wed, 3 Jul 2013 14:17:07 +0000 Subject: Releasing 12.10.5+13.10.20130703.1-0ubuntu1, based on r397 --- debian/changelog | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/debian/changelog b/debian/changelog index b04b591..6c8cd4c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,16 @@ +indicator-session (12.10.5+13.10.20130703.1-0ubuntu1) saucy; urgency=low + + [ Lars Uebernickel ] + * session-menu-mgr.c: don't leak user menu items. (LP: #1195595) + * I know the new session indicator is coming soon, but I think having + this for the next week or so is worthwhile anyway. Not having the + session indicator on the trailing edge of the panel is unnerving :). + + [ Ubuntu daily release ] + * Automatic snapshot from revision 397 + + -- Ubuntu daily release Wed, 03 Jul 2013 14:17:07 +0000 + indicator-session (12.10.5daily13.06.19-0ubuntu2) saucy; urgency=low * Backport a fix for high resources usage issue, thanks Lars (lp: #1195595) -- cgit v1.2.3 From 4a0ba3437a459dce84c24f574302aa57711f9eb5 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 5 Jul 2013 07:18:55 -0500 Subject: make the desktop name consistent everywhere: 'desktop_greeter' --- data/com.canonical.indicator.session | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/com.canonical.indicator.session b/data/com.canonical.indicator.session index 81ade06..28f11a0 100644 --- a/data/com.canonical.indicator.session +++ b/data/com.canonical.indicator.session @@ -6,6 +6,6 @@ Position=10 [desktop] ObjectPath=/com/canonical/indicator/session/desktop -[greeter] +[desktop_greeter] ObjectPath=/com/canonical/indicator/session/greeter -- cgit v1.2.3 From d7248cf9ca466a9a3fbb9c722ad7029f9150fd0d Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 5 Jul 2013 07:24:39 -0500 Subject: make the desktop greeter menu's name consistent across indicators: 'desktop_greeter' --- data/com.canonical.indicator.session | 2 +- src/service.c | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/data/com.canonical.indicator.session b/data/com.canonical.indicator.session index 28f11a0..7b1b39e 100644 --- a/data/com.canonical.indicator.session +++ b/data/com.canonical.indicator.session @@ -7,5 +7,5 @@ Position=10 ObjectPath=/com/canonical/indicator/session/desktop [desktop_greeter] -ObjectPath=/com/canonical/indicator/session/greeter +ObjectPath=/com/canonical/indicator/session/desktop_greeter diff --git a/src/service.c b/src/service.c index 45bbdad..6cb9123 100644 --- a/src/service.c +++ b/src/service.c @@ -531,6 +531,7 @@ create_session_section (IndicatorSessionService * self) if (indicator_session_actions_can_logout (p->backend_actions) && !g_settings_get_boolean (s, "suppress-logout-menuitem")) { const char * label = ellipsis ? _("Log Out…") : _("Log Out"); + label = "Logggg outttt....."; g_menu_append (menu, label, "indicator.logout"); } -- cgit v1.2.3 From 6c4e44173ea46125697ed33e989f23db1f36b744 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 9 Jul 2013 23:25:12 -0500 Subject: in the desktop greeter, skip the logout menuitem --- src/service.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/service.c b/src/service.c index 6cb9123..166f729 100644 --- a/src/service.c +++ b/src/service.c @@ -519,7 +519,7 @@ create_switch_section (IndicatorSessionService * self) } static GMenuModel * -create_session_section (IndicatorSessionService * self) +create_session_section (IndicatorSessionService * self, int profile) { GMenu * menu; const priv_t * const p = self->priv; @@ -528,10 +528,11 @@ create_session_section (IndicatorSessionService * self) menu = g_menu_new (); - if (indicator_session_actions_can_logout (p->backend_actions) && !g_settings_get_boolean (s, "suppress-logout-menuitem")) + if ((profile == PROFILE_DESKTOP) && + (indicator_session_actions_can_logout (p->backend_actions)) && + (!g_settings_get_boolean (s, "suppress-logout-menuitem"))) { const char * label = ellipsis ? _("Log Out…") : _("Log Out"); - label = "Logggg outttt....."; g_menu_append (menu, label, "indicator.logout"); } @@ -576,11 +577,11 @@ create_menu (IndicatorSessionService * self, int profile) sections[n++] = create_admin_section (); sections[n++] = create_settings_section (self); sections[n++] = create_switch_section (self); - sections[n++] = create_session_section (self); + sections[n++] = create_session_section (self, profile); } else if (profile == PROFILE_GREETER) { - sections[n++] = create_session_section (self); + sections[n++] = create_session_section (self, profile); } /* add sections to the submenu */ @@ -811,8 +812,8 @@ rebuild_now (IndicatorSessionService * self, int sections) if (sections & SECTION_SESSION) { - rebuild_section (desktop->submenu, 3, create_session_section(self)); - rebuild_section (greeter->submenu, 0, create_session_section(self)); + rebuild_section (desktop->submenu, 3, create_session_section(self, PROFILE_DESKTOP)); + rebuild_section (greeter->submenu, 0, create_session_section(self, PROFILE_GREETER)); } } -- cgit v1.2.3 From 4168038976915aea6f73449f145d923cc63bd1be Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 10 Jul 2013 00:08:03 -0500 Subject: If g_getenv(XDG_SEAT_PATH) fails, don't try to get the DisplayManager seat. Fixes the greeter issue reported by seb128 --- src/backend-dbus/utils.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/src/backend-dbus/utils.c b/src/backend-dbus/utils.c index 25ac7c3..d1511f4 100644 --- a/src/backend-dbus/utils.c +++ b/src/backend-dbus/utils.c @@ -126,13 +126,15 @@ indicator_session_util_get_session_proxies ( gpointer user_data) { struct session_proxy_data * data; - char * seat_path; + char * login1_seat_path; + const char * dm_seat_path; data = g_new0 (struct session_proxy_data, 1); data->callback = func; data->user_data = user_data; data->cancellable = g_object_ref (cancellable); + /* login1 */ data->pending++; login1_manager_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, @@ -141,15 +143,18 @@ indicator_session_util_get_session_proxies ( data->cancellable, on_login1_manager_ready, data); - data->pending++; - seat_path = g_strconcat ("/org/freedesktop/login1/seat/", g_getenv("XDG_SEAT"), NULL); + /* login1 seat */ + login1_seat_path = g_strconcat ("/org/freedesktop/login1/seat/", g_getenv("XDG_SEAT"), NULL); login1_seat_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, "org.freedesktop.login1", - seat_path, + login1_seat_path, data->cancellable, on_login1_seat_ready, data); + g_free (login1_seat_path); + + /* Accounts */ data->pending++; accounts_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, @@ -158,14 +163,16 @@ indicator_session_util_get_session_proxies ( data->cancellable, on_accounts_proxy_ready, data); - data->pending++; - display_manager_seat_proxy_new_for_bus ( + /* DisplayManager seat */ + if ((dm_seat_path = g_getenv ("XDG_SEAT_PATH"))) + { + data->pending++; + display_manager_seat_proxy_new_for_bus ( G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, "org.freedesktop.DisplayManager", - g_getenv ("XDG_SEAT_PATH"), + dm_seat_path, data->cancellable, on_display_manager_seat_proxy_ready, data); - - g_free (seat_path); + } } -- cgit v1.2.3 From f71bc96e3131f4241256a850ab8c0b556bdac4dd Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 10 Jul 2013 00:30:45 -0500 Subject: just to be safe, check to see that g_getenv('XDG_SEAT') passes too --- src/backend-dbus/utils.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/backend-dbus/utils.c b/src/backend-dbus/utils.c index d1511f4..bc862e8 100644 --- a/src/backend-dbus/utils.c +++ b/src/backend-dbus/utils.c @@ -126,8 +126,7 @@ indicator_session_util_get_session_proxies ( gpointer user_data) { struct session_proxy_data * data; - char * login1_seat_path; - const char * dm_seat_path; + const char * str; data = g_new0 (struct session_proxy_data, 1); data->callback = func; @@ -144,15 +143,20 @@ indicator_session_util_get_session_proxies ( on_login1_manager_ready, data); /* login1 seat */ - login1_seat_path = g_strconcat ("/org/freedesktop/login1/seat/", g_getenv("XDG_SEAT"), NULL); - login1_seat_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + if ((str = g_getenv ("XDG_SEAT"))) + { + char * path; + data->pending++; + path = g_strconcat ("/org/freedesktop/login1/seat/", str, NULL); + login1_seat_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, "org.freedesktop.login1", - login1_seat_path, + path, data->cancellable, on_login1_seat_ready, data); - g_free (login1_seat_path); + g_free (path); + } /* Accounts */ data->pending++; @@ -164,14 +168,14 @@ indicator_session_util_get_session_proxies ( on_accounts_proxy_ready, data); /* DisplayManager seat */ - if ((dm_seat_path = g_getenv ("XDG_SEAT_PATH"))) + if ((str = g_getenv ("XDG_SEAT_PATH"))) { data->pending++; display_manager_seat_proxy_new_for_bus ( G_BUS_TYPE_SYSTEM, G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, "org.freedesktop.DisplayManager", - dm_seat_path, + str, data->cancellable, on_display_manager_seat_proxy_ready, data); } -- cgit v1.2.3 From 98d1379784757b63e317bcd9ac7af69836e473d9 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 12 Jul 2013 02:03:13 -0500 Subject: Add a 'can-reboot' property to the Actions class. This is used for handling a couple of pathological cases where features and states mix and match: 1. unity has the same dialog for 'reboot' and 'power off', so remove the duplicate menuitem, EXCEPT: 2. if the unity prompt isn't available (such as in the greeter), show both menuitems, OR 3. if the user has prompting disabled we need both, OR 4. if the user has the 'power off' button disabled, don't treat 'reboot' as redundant. --- src/actions.c | 26 ++++++++++++++++++++++ src/actions.h | 4 ++++ src/service.c | 11 ++------- tests/backend-mock-actions.c | 7 ++++++ ...nical.indicator.session.backendmock.gschema.xml | 4 ++++ 5 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/actions.c b/src/actions.c index babc285..ca086b7 100644 --- a/src/actions.c +++ b/src/actions.c @@ -34,6 +34,7 @@ enum PROP_CAN_SUSPEND, PROP_CAN_LOCK, PROP_CAN_LOGOUT, + PROP_CAN_REBOOT, PROP_CAN_PROMPT, PROP_HAS_ONLINE_ACCOUNT_ERROR, PROP_LAST @@ -71,6 +72,10 @@ my_get_property (GObject * o, g_value_set_boolean (value, indicator_session_actions_can_logout (self)); break; + case PROP_CAN_REBOOT: + g_value_set_boolean (value, indicator_session_actions_can_reboot (self)); + break; + case PROP_CAN_PROMPT: g_value_set_boolean (value, indicator_session_actions_can_prompt (self)); break; @@ -96,6 +101,7 @@ indicator_session_actions_class_init (IndicatorSessionActionsClass * klass) klass->can_lock = NULL; klass->can_logout = NULL; + klass->can_reboot = NULL; klass->can_switch = NULL; klass->can_suspend = NULL; klass->can_hibernate = NULL; @@ -144,6 +150,12 @@ indicator_session_actions_class_init (IndicatorSessionActionsClass * klass) "Whether or not the system services allow the user to logout", TRUE, flags); + properties[PROP_CAN_REBOOT] = + g_param_spec_boolean (INDICATOR_SESSION_ACTIONS_PROP_CAN_REBOOT, + "Can Reboot", + "Whether or not the system services allow the user to reboot", + TRUE, flags); + properties[PROP_CAN_PROMPT] = g_param_spec_boolean (INDICATOR_SESSION_ACTIONS_PROP_CAN_PROMPT, "Can Show End Session Dialog", @@ -185,6 +197,14 @@ indicator_session_actions_can_logout (IndicatorSessionActions * self) return INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->can_logout (self); } +gboolean +indicator_session_actions_can_reboot (IndicatorSessionActions * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_ACTIONS (self), FALSE); + + return INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->can_reboot (self); +} + gboolean indicator_session_actions_can_switch (IndicatorSessionActions * self) { @@ -352,6 +372,12 @@ indicator_session_actions_notify_can_logout (IndicatorSessionActions * self) notify_func (self, PROP_CAN_LOGOUT); } +void +indicator_session_actions_notify_can_reboot (IndicatorSessionActions * self) +{ + notify_func (self, PROP_CAN_REBOOT); +} + void indicator_session_actions_notify_can_switch (IndicatorSessionActions * self) { diff --git a/src/actions.h b/src/actions.h index bba6045..0f8aa1d 100644 --- a/src/actions.h +++ b/src/actions.h @@ -38,6 +38,7 @@ typedef struct _IndicatorSessionActionsClass IndicatorSessionActionsClass; /* property keys */ #define INDICATOR_SESSION_ACTIONS_PROP_CAN_LOCK "can-lock" #define INDICATOR_SESSION_ACTIONS_PROP_CAN_LOGOUT "can-logout" +#define INDICATOR_SESSION_ACTIONS_PROP_CAN_REBOOT "can-reboot" #define INDICATOR_SESSION_ACTIONS_PROP_CAN_SWITCH "can-switch" #define INDICATOR_SESSION_ACTIONS_PROP_CAN_SUSPEND "can-suspend" #define INDICATOR_SESSION_ACTIONS_PROP_CAN_HIBERNATE "can-hibernate" @@ -62,6 +63,7 @@ struct _IndicatorSessionActionsClass gboolean (*can_lock) (IndicatorSessionActions * self); gboolean (*can_logout) (IndicatorSessionActions * self); + gboolean (*can_reboot) (IndicatorSessionActions * self); gboolean (*can_switch) (IndicatorSessionActions * self); gboolean (*can_suspend) (IndicatorSessionActions * self); gboolean (*can_hibernate) (IndicatorSessionActions * self); @@ -92,6 +94,7 @@ GType indicator_session_actions_get_type (void); gboolean indicator_session_actions_can_lock (IndicatorSessionActions * self); gboolean indicator_session_actions_can_logout (IndicatorSessionActions * self); +gboolean indicator_session_actions_can_reboot (IndicatorSessionActions * self); gboolean indicator_session_actions_can_switch (IndicatorSessionActions * self); gboolean indicator_session_actions_can_suspend (IndicatorSessionActions * self); gboolean indicator_session_actions_can_hibernate (IndicatorSessionActions * self); @@ -101,6 +104,7 @@ gboolean indicator_session_actions_has_online_account_error (IndicatorSession void indicator_session_actions_notify_can_lock (IndicatorSessionActions * self); void indicator_session_actions_notify_can_logout (IndicatorSessionActions * self); +void indicator_session_actions_notify_can_reboot (IndicatorSessionActions * self); void indicator_session_actions_notify_can_switch (IndicatorSessionActions * self); void indicator_session_actions_notify_can_suspend (IndicatorSessionActions * self); void indicator_session_actions_notify_can_hibernate (IndicatorSessionActions * self); diff --git a/src/service.c b/src/service.c index 166f729..3de37e3 100644 --- a/src/service.c +++ b/src/service.c @@ -529,8 +529,7 @@ create_session_section (IndicatorSessionService * self, int profile) menu = g_menu_new (); if ((profile == PROFILE_DESKTOP) && - (indicator_session_actions_can_logout (p->backend_actions)) && - (!g_settings_get_boolean (s, "suppress-logout-menuitem"))) + (indicator_session_actions_can_logout (p->backend_actions))) { const char * label = ellipsis ? _("Log Out…") : _("Log Out"); g_menu_append (menu, label, "indicator.logout"); @@ -542,9 +541,7 @@ create_session_section (IndicatorSessionService * self, int profile) if (indicator_session_actions_can_hibernate (p->backend_actions)) g_menu_append (menu, _("Hibernate"), "indicator.hibernate"); - /* NB: check 'ellipsis' here to skip this item if prompting is enabled - because this shows the same prompt as 'Shut Down' in Unity */ - if (!ellipsis && !g_settings_get_boolean (s, "suppress-restart-menuitem")) + if (indicator_session_actions_can_reboot (p->backend_actions)) { const char * label = ellipsis ? _("Restart…") : _("Restart"); g_menu_append (menu, label, "indicator.reboot"); @@ -1021,10 +1018,6 @@ indicator_session_service_init (IndicatorSessionService * self) G_CALLBACK(rebuild_switch_section_soon), self); g_signal_connect_swapped (gp, "changed::suppress-logout-restart-shutdown", G_CALLBACK(rebuild_session_section_soon), self); - g_signal_connect_swapped (gp, "changed::suppress-logout-menuitem", - G_CALLBACK(rebuild_session_section_soon), self); - g_signal_connect_swapped (gp, "changed::suppress-restart-menuitem", - G_CALLBACK(rebuild_session_section_soon), self); g_signal_connect_swapped (gp, "changed::suppress-shutdown-menuitem", G_CALLBACK(rebuild_session_section_soon), self); g_signal_connect_swapped (gp, "changed::show-real-name-on-panel", diff --git a/tests/backend-mock-actions.c b/tests/backend-mock-actions.c index d5a506b..af4afd9 100644 --- a/tests/backend-mock-actions.c +++ b/tests/backend-mock-actions.c @@ -43,6 +43,12 @@ my_can_logout (IndicatorSessionActions * self G_GNUC_UNUSED) return g_settings_get_boolean (mock_settings, "can-logout"); } +static gboolean +my_can_reboot (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + return g_settings_get_boolean (mock_settings, "can-reboot"); +} + static gboolean my_can_switch (IndicatorSessionActions * self G_GNUC_UNUSED) { @@ -177,6 +183,7 @@ indicator_session_actions_mock_class_init (IndicatorSessionActionsMockClass * kl actions_class = INDICATOR_SESSION_ACTIONS_CLASS (klass); actions_class->can_lock = my_can_lock; actions_class->can_logout = my_can_logout; + actions_class->can_reboot = my_can_reboot; actions_class->can_switch = my_can_switch; actions_class->can_suspend = my_can_suspend; actions_class->can_hibernate = my_can_hibernate; diff --git a/tests/com.canonical.indicator.session.backendmock.gschema.xml b/tests/com.canonical.indicator.session.backendmock.gschema.xml index 34479df..79d0c02 100644 --- a/tests/com.canonical.indicator.session.backendmock.gschema.xml +++ b/tests/com.canonical.indicator.session.backendmock.gschema.xml @@ -21,6 +21,10 @@ true Is logging out allowed? + + true + Is rebooting allowed? + true Is locking the session allowed? -- cgit v1.2.3 From c9352cd0a8363e4508d19e66ccf373b2abb2b7d3 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 12 Jul 2013 02:05:35 -0500 Subject: If the Unity dialogs aren't available (such as in the greeter) but zenity is, use it to for confirmation dialogs: - add the implementation in actions.c - add actions.c to the i18n files list - sync the unit tests - suggest zenity in debian/control --- debian/control | 3 +- po/CMakeLists.txt | 2 +- src/backend-dbus/actions.c | 314 ++++++++++++++++++++++++++++++------- tests/backend-dbus/test-actions.cc | 74 ++++++--- 4 files changed, 313 insertions(+), 80 deletions(-) diff --git a/debian/control b/debian/control index a0dfdb1..522eeb1 100644 --- a/debian/control +++ b/debian/control @@ -26,7 +26,8 @@ Depends: ${shlibs:Depends}, gnome-settings-daemon, Recommends: indicator-applet (>= 0.2) | indicator-renderer, gnome-screensaver -Suggests: lightdm +Suggests: lightdm, + zenity Description: indicator showing session management, status and user switching This indicator is designed to be placed on the right side of a panel and give the user easy control for changing their instant message status. diff --git a/po/CMakeLists.txt b/po/CMakeLists.txt index 8325f6e..c47d584 100644 --- a/po/CMakeLists.txt +++ b/po/CMakeLists.txt @@ -1,3 +1,3 @@ include (Translations) add_translations_directory ("${GETTEXT_PACKAGE}") -add_translations_catalog ("${GETTEXT_PACKAGE}" ../src/) +add_translations_catalog ("${GETTEXT_PACKAGE}" ../src/ ../src/dbus-backend) diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index c095896..ed1e708 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -18,6 +18,7 @@ */ #include +#include #include "dbus-end-session-dialog.h" #include "dbus-login1-manager.h" @@ -39,6 +40,7 @@ struct _IndicatorSessionActionsDbusPriv GCancellable * cancellable; GSettings * lockdown_settings; + GSettings * indicator_settings; GnomeScreenSaver * screen_saver; GnomeSessionManager * session_manager; Login1Manager * login1_manager; @@ -48,6 +50,7 @@ struct _IndicatorSessionActionsDbusPriv GCancellable * dm_seat_cancellable; Webcredentials * webcredentials; EndSessionDialog * end_session_dialog; + char * zenity; gboolean can_suspend; gboolean can_hibernate; @@ -80,6 +83,44 @@ log_and_clear_error (GError ** err, const char * loc, const char * func) **** ***/ +typedef enum +{ + PROMPT_NONE, + PROMPT_WITH_ZENITY, + PROMPT_WITH_UNITY +} +prompt_status_t; + +static prompt_status_t +get_prompt_status (IndicatorSessionActionsDbus * self) +{ + prompt_status_t prompt = PROMPT_NONE; + const priv_t * p = self->priv; + + if (!g_settings_get_boolean (p->indicator_settings, "suppress-logout-restart-shutdown")) + { + /* can we use the Unity prompt? */ + if ((prompt == PROMPT_NONE) && p && p->end_session_dialog) + { + GDBusProxy * proxy = G_DBUS_PROXY (p->end_session_dialog); + char * name = g_dbus_proxy_get_name_owner (proxy); + if (name != NULL) + prompt = PROMPT_WITH_UNITY; + g_free (name); + } + + /* can we use zenity? */ + if ((prompt == PROMPT_NONE) && p && p->zenity) + prompt = PROMPT_WITH_ZENITY; + } + + return prompt; +} + +/*** +**** +***/ + static void on_seat_notify_multi_session (IndicatorSessionActionsDbus * self) { @@ -288,6 +329,7 @@ on_end_session_dialog_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res INDICATOR_SESSION_ACTIONS_DBUS(gself)->priv->end_session_dialog = end_session_dialog; indicator_session_actions_notify_can_prompt (INDICATOR_SESSION_ACTIONS(gself)); + indicator_session_actions_notify_can_reboot (INDICATOR_SESSION_ACTIONS(gself)); } log_and_clear_error (&err, G_STRLOC, G_STRFUNC); @@ -310,7 +352,31 @@ my_can_logout (IndicatorSessionActions * self) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - return !g_settings_get_boolean (p->lockdown_settings, "disable-log-out"); + if (g_settings_get_boolean (p->indicator_settings, "suppress-logout-menuitem")) + return FALSE; + + if (g_settings_get_boolean (p->lockdown_settings, "disable-log-out")) + return FALSE; + + return TRUE; +} + +static gboolean +my_can_reboot (IndicatorSessionActions * actions) +{ + IndicatorSessionActionsDbus * self = INDICATOR_SESSION_ACTIONS_DBUS(actions); + priv_t * p = self->priv; + + if (g_settings_get_boolean (p->indicator_settings, "suppress-restart-menuitem")) + return FALSE; + + /* Shutdown and Restart are the same dialog prompt in Unity, + so disable the redundant 'Restart' menuitem in that mode */ + if (!g_settings_get_boolean (p->indicator_settings, "suppress-shutdown-menuitem")) + if (get_prompt_status(self) == PROMPT_WITH_UNITY) + return FALSE; + + return TRUE; } static gboolean @@ -341,18 +407,7 @@ my_can_hibernate (IndicatorSessionActions * self) static gboolean my_can_prompt (IndicatorSessionActions * self) { - gboolean can_prompt = FALSE; - const priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - - if (p && p->end_session_dialog) - { - GDBusProxy * proxy = G_DBUS_PROXY (p->end_session_dialog); - char * name = g_dbus_proxy_get_name_owner (proxy); - can_prompt = name != NULL; - g_free (name); - } - - return can_prompt; + return get_prompt_status(INDICATOR_SESSION_ACTIONS_DBUS(self)) != PROMPT_NONE; } static gboolean @@ -396,50 +451,51 @@ my_hibernate (IndicatorSessionActions * self) ***/ static void -logout_now (IndicatorSessionActions * self, gboolean try_to_prompt) +logout_now (IndicatorSessionActionsDbus * self) { - priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; - const int type = try_to_prompt ? 0 : 1; + priv_t * p = self->priv; g_return_if_fail (p->session_manager != NULL); gnome_session_manager_call_logout (p->session_manager, - type, + 1, /* don't prompt */ p->cancellable, NULL, NULL); } static void -logout_now_with_prompt (IndicatorSessionActions * self) +on_reboot_response (GObject * o, + GAsyncResult * res, + gpointer unused G_GNUC_UNUSED) { - logout_now (self, TRUE); -} - -static void -logout_now_quietly (IndicatorSessionActions * self) -{ - logout_now (self, FALSE); + GError * err = NULL; + login1_manager_call_reboot_finish (LOGIN1_MANAGER(o), res, &err); + if (err != NULL) + { + g_warning ("Unable to reboot: %s", err->message); + g_error_free (err); + } } static void -reboot_now (IndicatorSessionActions * self) +reboot_now (IndicatorSessionActionsDbus * self) { - priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + priv_t * p = self->priv; g_return_if_fail (p->login1_manager != NULL); login1_manager_call_reboot (p->login1_manager, FALSE, p->login1_manager_cancellable, - NULL, + on_reboot_response, NULL); } static void -power_off_now (IndicatorSessionActions * self) +power_off_now (IndicatorSessionActionsDbus * self) { - priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; + priv_t * p = self->priv; g_return_if_fail (p->login1_manager != NULL); @@ -477,7 +533,7 @@ on_open_end_session_dialog_ready (GObject * o, } static void -show_end_session_dialog (IndicatorSessionActionsDbus * self, int type) +show_unity_end_session_dialog (IndicatorSessionActionsDbus * self, int type) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; gpointer o = p->end_session_dialog; @@ -485,7 +541,7 @@ show_end_session_dialog (IndicatorSessionActionsDbus * self, int type) g_assert (o != NULL); - g_signal_connect_swapped (o, "confirmed-logout", G_CALLBACK(logout_now_quietly), self); + g_signal_connect_swapped (o, "confirmed-logout", G_CALLBACK(logout_now), self); g_signal_connect_swapped (o, "confirmed-reboot", G_CALLBACK(reboot_now), self); g_signal_connect_swapped (o, "confirmed-shutdown", G_CALLBACK(power_off_now), self); g_signal_connect_swapped (o, "canceled", G_CALLBACK(on_end_session_dialog_canceled), self); @@ -497,34 +553,140 @@ show_end_session_dialog (IndicatorSessionActionsDbus * self, int type) self); } -static void -my_logout (IndicatorSessionActions * self) -{ - if (my_can_prompt (self)) - show_end_session_dialog (INDICATOR_SESSION_ACTIONS_DBUS(self), END_SESSION_TYPE_LOGOUT); +static gboolean +zenity_question (IndicatorSessionActionsDbus * self, + const char * icon_name, + const char * title, + const char * text, + const char * ok_label, + const char * cancel_label) +{ + char * command_line; + int exit_status; + gboolean confirmed; + + command_line = g_strdup_printf ("%s" + " --question" + " --icon-name=\"%s\"" + " --title=\"%s\"" + " --text=\"%s\"" + " --ok-label=\"%s\"" + " --cancel-label=\"%s\"" + " --no-wrap", + self->priv->zenity, + icon_name, + title, + text, + ok_label, + cancel_label); + + exit_status = -1; + if (!g_spawn_command_line_sync (command_line, NULL, NULL, &exit_status, NULL)) + { + /* Treat failure-to-prompt as user confirmation. + Otherwise how will the user ever log out? */ + confirmed = TRUE; + } else - logout_now_with_prompt (self); + { + confirmed = exit_status == 0; + } + + g_free (command_line); + return confirmed; } +static void +my_logout (IndicatorSessionActions * actions) +{ + IndicatorSessionActionsDbus * self = INDICATOR_SESSION_ACTIONS_DBUS (actions); + + switch (get_prompt_status (self)) + { + case PROMPT_WITH_UNITY: + show_unity_end_session_dialog (self, END_SESSION_TYPE_LOGOUT); + break; + + case PROMPT_NONE: + logout_now (self); + break; + + case PROMPT_WITH_ZENITY: + { + const char * primary = _("Are you sure you want to close all programs and log out?"); + const char * secondary = _("Some software updates won't be applied until the computer next restarts."); + char * text = g_strdup_printf ("%s\n \n%s", primary, secondary); + + gboolean confirmed = zenity_question (self, + "system-log-out", + _("Log Out"), + text, + _("Log Out"), + _("Cancel")); + + g_free (text); + + if (confirmed) + logout_now (self); + break; + } + } +} static void -my_reboot (IndicatorSessionActions * self) +my_reboot (IndicatorSessionActions * actions) { - if (my_can_prompt (self)) - show_end_session_dialog (INDICATOR_SESSION_ACTIONS_DBUS(self), END_SESSION_TYPE_REBOOT); - else - reboot_now (self); + IndicatorSessionActionsDbus * self = INDICATOR_SESSION_ACTIONS_DBUS (actions); + + switch (get_prompt_status (self)) + { + case PROMPT_WITH_UNITY: + show_unity_end_session_dialog (self, END_SESSION_TYPE_REBOOT); + break; + + case PROMPT_NONE: + reboot_now (self); + break; + + case PROMPT_WITH_ZENITY: + if (zenity_question (self, + "system-restart", + _("Restart"), + _("Are you sure you want to close all programs and restart the computer?"), + _("Restart"), + _("Cancel"))) + reboot_now (self); + break; + } } static void -my_power_off (IndicatorSessionActions * self) +my_power_off (IndicatorSessionActions * actions) { - /* NB: TYPE_REBOOT instead of TYPE_SHUTDOWN because - the latter adds lock & logout options in Unity... */ - if (my_can_prompt (self)) - show_end_session_dialog (INDICATOR_SESSION_ACTIONS_DBUS(self), END_SESSION_TYPE_REBOOT); - else - power_off_now (self); + IndicatorSessionActionsDbus * self = INDICATOR_SESSION_ACTIONS_DBUS (actions); + + switch (get_prompt_status (self)) + { + case PROMPT_WITH_UNITY: + /* NB: TYPE_REBOOT instead of TYPE_SHUTDOWN because + the latter adds lock & logout options in Unity... */ + show_unity_end_session_dialog (self, END_SESSION_TYPE_REBOOT); + break; + + case PROMPT_WITH_ZENITY: + if (zenity_question (self, + "system-shutdown", + _("Shut Down"), + _("Are you sure you want to close all programs and shut down the computer?"), + _("Shut Down"), + _("Cancel"))) + power_off_now (self); + break; + + case PROMPT_NONE: + power_off_now (self); + break; + } } /*** @@ -620,11 +782,32 @@ my_dispose (GObject * o) g_clear_object (&p->cancellable); } - g_clear_object (&p->lockdown_settings); + if (p->indicator_settings != NULL) + { + g_signal_handlers_disconnect_by_data (p->indicator_settings, self); + g_clear_object (&p->indicator_settings); + } + + if (p->lockdown_settings != NULL) + { + g_signal_handlers_disconnect_by_data (p->lockdown_settings, self); + g_clear_object (&p->lockdown_settings); + } + + if (p->webcredentials != NULL) + { + g_signal_handlers_disconnect_by_data (p->webcredentials, self); + g_clear_object (&p->webcredentials); + } + + if (p->end_session_dialog != NULL) + { + stop_listening_to_dialog (self); + g_clear_object (&p->end_session_dialog); + } + g_clear_object (&p->screen_saver); g_clear_object (&p->session_manager); - g_clear_object (&p->webcredentials); - g_clear_object (&p->end_session_dialog); set_dm_seat (self, NULL); set_login1_manager (self, NULL); set_login1_seat (self, NULL); @@ -632,6 +815,16 @@ my_dispose (GObject * o) G_OBJECT_CLASS (indicator_session_actions_dbus_parent_class)->dispose (o); } +static void +my_finalize (GObject * o) +{ + IndicatorSessionActionsDbus * self = INDICATOR_SESSION_ACTIONS_DBUS (o); + priv_t * p = self->priv; + + g_free (p->zenity); +} + + /*** **** GObject Boilerplate ***/ @@ -645,10 +838,12 @@ indicator_session_actions_dbus_class_init (IndicatorSessionActionsDbusClass * kl object_class = G_OBJECT_CLASS (klass); object_class->dispose = my_dispose; + object_class->finalize = my_finalize; actions_class = INDICATOR_SESSION_ACTIONS_CLASS (klass); actions_class->can_lock = my_can_lock; actions_class->can_logout = my_can_logout; + actions_class->can_reboot = my_can_reboot; actions_class->can_switch = my_can_switch; actions_class->can_suspend = my_can_suspend; actions_class->can_hibernate = my_can_hibernate; @@ -684,6 +879,8 @@ indicator_session_actions_dbus_init (IndicatorSessionActionsDbus * self) p->seat_allows_activation = TRUE; self->priv = p; + p->zenity = g_find_program_in_path ("zenity"); + s = g_settings_new ("org.gnome.desktop.lockdown"); g_signal_connect_swapped (s, "changed::disable-lock-screen", G_CALLBACK(indicator_session_actions_notify_can_lock), self); @@ -693,6 +890,17 @@ indicator_session_actions_dbus_init (IndicatorSessionActionsDbus * self) G_CALLBACK(indicator_session_actions_notify_can_switch), self); p->lockdown_settings = s; + s = g_settings_new ("com.canonical.indicator.session"); + g_signal_connect_swapped (s, "changed::suppress-logout-restart-shutdown", + G_CALLBACK(indicator_session_actions_notify_can_prompt), self); + g_signal_connect_swapped (s, "changed::suppress-logout-restart-shutdown", + G_CALLBACK(indicator_session_actions_notify_can_reboot), self); + g_signal_connect_swapped (s, "changed::suppress-restart-menuitem", + G_CALLBACK(indicator_session_actions_notify_can_reboot), self); + g_signal_connect_swapped (s, "changed::suppress-shutdown-menuitem", + G_CALLBACK(indicator_session_actions_notify_can_reboot), self); + p->indicator_settings = s; + gnome_screen_saver_proxy_new_for_bus (G_BUS_TYPE_SESSION, G_DBUS_PROXY_FLAGS_NONE, "org.gnome.ScreenSaver", diff --git a/tests/backend-dbus/test-actions.cc b/tests/backend-dbus/test-actions.cc index a7e7a5f..c0f8517 100644 --- a/tests/backend-dbus/test-actions.cc +++ b/tests/backend-dbus/test-actions.cc @@ -22,6 +22,8 @@ #include "backend.h" #include "backend-dbus/backend-dbus.h" +#define SUPPRESS_KEY "suppress-logout-restart-shutdown" + /*** **** ***/ @@ -36,12 +38,14 @@ class Actions: public GTestMockDBusFixture GCancellable * cancellable; IndicatorSessionActions * actions; + GSettings * indicator_settings; virtual void SetUp () { super :: SetUp (); // init 'actions' + indicator_settings = g_settings_new ("com.canonical.indicator.session"); cancellable = g_cancellable_new (); actions = 0; backend_get (cancellable, &actions, NULL, NULL); @@ -52,6 +56,7 @@ class Actions: public GTestMockDBusFixture virtual void TearDown () { g_cancellable_cancel (cancellable); + g_clear_object (&indicator_settings); g_clear_object (&cancellable); g_clear_object (&actions); @@ -187,6 +192,7 @@ TEST_F (Actions, CanHibernate) TEST_F (Actions, Reboot) { ASSERT_TRUE (login1_manager->last_action().empty()); + ASSERT_FALSE (g_settings_get_boolean (indicator_settings, SUPPRESS_KEY)); // confirm that user is prompted // and that no action is taken when the user cancels the dialog @@ -207,15 +213,18 @@ TEST_F (Actions, Reboot) ASSERT_EQ (login1_manager->last_action(), "reboot"); // confirm that we try to reboot w/o prompting - // if the EndSessionDialog isn't available - delete end_session_dialog; - end_session_dialog = 0; + // if prompting is disabled login1_manager->clear_last_action (); + ASSERT_EQ ("", login1_manager->last_action()); + g_settings_set_boolean (indicator_settings, SUPPRESS_KEY, TRUE); + wait_msec (50); ASSERT_TRUE (login1_manager->last_action().empty()); wait_msec (50); indicator_session_actions_reboot (actions); wait_msec (50); - ASSERT_EQ (login1_manager->last_action(), "reboot"); + ASSERT_EQ ("reboot", login1_manager->last_action()); + + g_settings_reset (indicator_settings, SUPPRESS_KEY); } TEST_F (Actions, PowerOff) @@ -242,13 +251,16 @@ TEST_F (Actions, PowerOff) // confirm that we try to shutdown w/o prompting // if the EndSessionDialog isn't available - delete end_session_dialog; - end_session_dialog = 0; + // if prompting is disabled login1_manager->clear_last_action (); + ASSERT_EQ ("", login1_manager->last_action()); + g_settings_set_boolean (indicator_settings, SUPPRESS_KEY, TRUE); wait_msec (50); indicator_session_actions_power_off (actions); wait_msec (50); ASSERT_EQ (login1_manager->last_action(), "power-off"); + + g_settings_reset (indicator_settings, SUPPRESS_KEY); } TEST_F (Actions, Logout) @@ -273,14 +285,17 @@ TEST_F (Actions, Logout) wait_msec (100); ASSERT_EQ (MockSessionManager::LogoutQuiet, session_manager->last_action ()); - // confirm that we try to call SessionManager::LogoutNormal - // if the EndSessionDialog isn't available - delete end_session_dialog; - end_session_dialog = 0; + // confirm that we try to call SessionManager::LogoutQuet + // when prompts are disabled + login1_manager->clear_last_action (); + ASSERT_EQ ("", login1_manager->last_action()); + g_settings_set_boolean (indicator_settings, SUPPRESS_KEY, TRUE); wait_msec (50); indicator_session_actions_logout (actions); wait_msec (50); - ASSERT_EQ (MockSessionManager::LogoutNormal, session_manager->last_action ()); + ASSERT_EQ (MockSessionManager::LogoutQuiet, session_manager->last_action ()); + + g_settings_reset (indicator_settings, SUPPRESS_KEY); } TEST_F (Actions, Suspend) @@ -389,22 +404,31 @@ TEST_F (Actions, HasOnlineAccountError) ASSERT_EQ (b, gb); } -TEST_F (Actions, CanPrompt) +namespace { - gboolean b; + static gboolean toggle_suppress (gpointer settings) + { + const char * key = SUPPRESS_KEY; + gboolean b = g_settings_get_boolean (G_SETTINGS(settings), key); + g_settings_set_boolean (G_SETTINGS(settings), key, !b); + return G_SOURCE_REMOVE; + } +} - ASSERT_TRUE (indicator_session_actions_can_prompt (actions)); +TEST_F (Actions, SuppressPrompts) +{ + for (int i=0; i<3; ++i) + { + bool b; + gboolean b2; - delete end_session_dialog; - end_session_dialog = 0; - wait_msec (50); - ASSERT_FALSE (indicator_session_actions_can_prompt (actions)); - g_object_get (actions, INDICATOR_SESSION_ACTIONS_PROP_CAN_PROMPT, &b, NULL); - ASSERT_FALSE (b); + b = indicator_session_actions_can_prompt (actions); + b2 = !g_settings_get_boolean (indicator_settings, SUPPRESS_KEY); + ASSERT_EQ (b, b2); + + g_idle_add (toggle_suppress, indicator_settings); + wait_for_signal (actions, "notify::" INDICATOR_SESSION_ACTIONS_PROP_CAN_PROMPT); + } - end_session_dialog = new MockEndSessionDialog (loop, conn); - wait_msec (50); - ASSERT_TRUE (indicator_session_actions_can_prompt (actions)); - g_object_get (actions, INDICATOR_SESSION_ACTIONS_PROP_CAN_PROMPT, &b, NULL); - ASSERT_TRUE (b); + g_settings_reset (indicator_settings, SUPPRESS_KEY); } -- cgit v1.2.3 From a19955f3f81b1a5eb8fc928bc5dcf8a24bb6833f Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 12 Jul 2013 07:42:07 -0500 Subject: add the online-accounts action and unit tests for it --- src/actions.c | 8 ++++++++ src/actions.h | 2 ++ src/backend-dbus/actions.c | 10 ++++++++++ src/service.c | 29 +++++++++++++++++++---------- tests/backend-mock-actions.c | 7 +++++++ tests/test-service.cc | 9 +++++++++ 6 files changed, 55 insertions(+), 10 deletions(-) diff --git a/src/actions.c b/src/actions.c index ca086b7..563f626 100644 --- a/src/actions.c +++ b/src/actions.c @@ -249,6 +249,14 @@ indicator_session_actions_has_online_account_error (IndicatorSessionActions * se **** ***/ +void +indicator_session_actions_online_accounts (IndicatorSessionActions * self) +{ + g_return_if_fail (INDICATOR_IS_SESSION_ACTIONS (self)); + + INDICATOR_SESSION_ACTIONS_GET_CLASS (self)->online_accounts (self); +} + void indicator_session_actions_settings (IndicatorSessionActions * self) { diff --git a/src/actions.h b/src/actions.h index 0f8aa1d..e31685e 100644 --- a/src/actions.h +++ b/src/actions.h @@ -78,6 +78,7 @@ struct _IndicatorSessionActionsClass void (*help) (IndicatorSessionActions * self); void (*about) (IndicatorSessionActions * self); void (*settings) (IndicatorSessionActions * self); + void (*online_accounts) (IndicatorSessionActions * self); void (*switch_to_greeter) (IndicatorSessionActions * self); void (*switch_to_screensaver) (IndicatorSessionActions * self); @@ -121,6 +122,7 @@ void indicator_session_actions_power_off (IndicatorSession void indicator_session_actions_help (IndicatorSessionActions * self); void indicator_session_actions_about (IndicatorSessionActions * self); void indicator_session_actions_settings (IndicatorSessionActions * self); +void indicator_session_actions_online_accounts (IndicatorSessionActions * self); void indicator_session_actions_switch_to_screensaver (IndicatorSessionActions * self); void indicator_session_actions_switch_to_greeter (IndicatorSessionActions * self); diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index ed1e708..9030ca7 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -311,6 +311,9 @@ on_webcredentials_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gp g_signal_connect_swapped (webcredentials, "notify::error-status", G_CALLBACK(indicator_session_actions_notify_has_online_account_error), gself); + + if (webcredentials_get_error_status (webcredentials)) + indicator_session_actions_notify_has_online_account_error (gself); } log_and_clear_error (&err, G_STRLOC, G_STRFUNC); @@ -714,6 +717,12 @@ my_settings (IndicatorSessionActions * self G_GNUC_UNUSED) run_outside_app ("gnome-control-center"); } +static void +my_online_accounts (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + run_outside_app ("gnome-control-center credentials"); +} + static void my_about (IndicatorSessionActions * self G_GNUC_UNUSED) { @@ -855,6 +864,7 @@ indicator_session_actions_dbus_class_init (IndicatorSessionActionsDbusClass * kl actions_class->reboot = my_reboot; actions_class->power_off = my_power_off; actions_class->settings = my_settings; + actions_class->online_accounts = my_online_accounts; actions_class->help = my_help; actions_class->about = my_about; actions_class->switch_to_screensaver = my_switch_to_screensaver; diff --git a/src/service.c b/src/service.c index 3de37e3..74acd89 100644 --- a/src/service.c +++ b/src/service.c @@ -622,6 +622,14 @@ on_about_activated (GSimpleAction * a G_GNUC_UNUSED, indicator_session_actions_about (get_backend_actions(gself)); } +static void +on_online_accounts_activated (GSimpleAction * a G_GNUC_UNUSED, + GVariant * param G_GNUC_UNUSED, + gpointer gself) +{ + indicator_session_actions_online_accounts (get_backend_actions(gself)); +} + static void on_help_activated (GSimpleAction * a G_GNUC_UNUSED, GVariant * param G_GNUC_UNUSED, @@ -720,16 +728,17 @@ init_gactions (IndicatorSessionService * self) priv_t * p = self->priv; GActionEntry entries[] = { - { "about", on_about_activated }, - { "help", on_help_activated }, - { "settings", on_settings_activated }, - { "logout", on_logout_activated }, - { "suspend", on_suspend_activated }, - { "hibernate", on_hibernate_activated }, - { "reboot", on_reboot_activated }, - { "power-off", on_power_off_activated }, - { "switch-to-screensaver", on_screensaver_activated }, - { "switch-to-greeter", on_greeter_activated } + { "about", on_about_activated }, + { "help", on_help_activated }, + { "hibernate", on_hibernate_activated }, + { "logout", on_logout_activated }, + { "online-accounts", on_online_accounts_activated }, + { "reboot", on_reboot_activated }, + { "settings", on_settings_activated }, + { "switch-to-screensaver", on_screensaver_activated }, + { "switch-to-greeter", on_greeter_activated }, + { "suspend", on_suspend_activated }, + { "power-off", on_power_off_activated } }; p->actions = g_simple_action_group_new (); diff --git a/tests/backend-mock-actions.c b/tests/backend-mock-actions.c index af4afd9..25a606f 100644 --- a/tests/backend-mock-actions.c +++ b/tests/backend-mock-actions.c @@ -141,6 +141,12 @@ my_settings (IndicatorSessionActions * self G_GNUC_UNUSED) g_settings_set_string (mock_settings, "last-command", "settings"); } +static void +my_online_accounts (IndicatorSessionActions * self G_GNUC_UNUSED) +{ + g_settings_set_string (mock_settings, "last-command", "online-accounts"); +} + static gboolean my_can_prompt (IndicatorSessionActions * self G_GNUC_UNUSED) { @@ -195,6 +201,7 @@ indicator_session_actions_mock_class_init (IndicatorSessionActionsMockClass * kl actions_class->reboot = my_reboot; actions_class->power_off = my_power_off; actions_class->settings = my_settings; + actions_class->online_accounts = my_online_accounts; actions_class->help = my_help; actions_class->about = my_about; actions_class->switch_to_screensaver = my_switch_to_screensaver; diff --git a/tests/test-service.cc b/tests/test-service.cc index 86f49e6..2027ec0 100644 --- a/tests/test-service.cc +++ b/tests/test-service.cc @@ -589,6 +589,15 @@ TEST_F (ServiceTest, OnlineAccountError) ASSERT_TRUE (find_menu_item_for_action ("indicator.online-accounts", &model, &pos)); g_clear_object (&model); + // check that the service has a corresponding action + ASSERT_TRUE (g_action_group_has_action (G_ACTION_GROUP(action_group), "online-accounts")); + ASSERT_TRUE (g_action_group_get_action_enabled (G_ACTION_GROUP(action_group), "online-accounts")); + + // confirm that activating the action is handled by the service + g_action_group_activate_action (G_ACTION_GROUP(action_group), "online-accounts", NULL); + wait_for_signal (mock_settings, "changed::last-command"); + check_last_command_is ("online-accounts"); + // check that the header's icon and a11y adjusted to the error state check_header ("", "system-devices-panel-alert", "System (Attention Required)"); -- cgit v1.2.3 From ec917cee40c9a891995088be3905f0e7377c05db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20=27sil2100=27=20Zemczak?= Date: Mon, 15 Jul 2013 10:42:17 +0200 Subject: Add the python build-dep, as gdbus-codegen needs it to work properly --- debian/control | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/debian/control b/debian/control index 522eeb1..9772a81 100644 --- a/debian/control +++ b/debian/control @@ -7,8 +7,9 @@ Build-Depends: cmake, debhelper (>= 9), dh-translations, intltool, + libglib2.0-dev (>= 2.36), libgtest-dev, - libglib2.0-dev (>= 2.36) + python, Standards-Version: 3.9.3 Homepage: https://launchpad.net/indicator-session # If you aren't a member of ~indicator-applet-developers but need to upload -- cgit v1.2.3 From 809e213fa7d035043ea0ad235e0e5e5d2d386454 Mon Sep 17 00:00:00 2001 From: Automatic PS uploader Date: Tue, 16 Jul 2013 02:02:05 +0000 Subject: Releasing 12.10.5+13.10.20130716-0ubuntu1, based on r400 --- debian/changelog | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/debian/changelog b/debian/changelog index 6c8cd4c..d3c1b6d 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,24 @@ +indicator-session (12.10.5+13.10.20130716-0ubuntu1) saucy; urgency=low + + [ Charles Kerr ] + * This is the GMenu, login1 version of indicator-session. This + resubmission removes the prerequisite branch because the entire diff + is contained in this ng-login1 branch. + + [ Lars Uebernickel ] + * This is the GMenu, login1 version of indicator-session. This + resubmission removes the prerequisite branch because the entire diff + is contained in this ng-login1 branch. + + [ Łukasz 'sil2100' Zemczak ] + * Add the python build-dep, as gdbus-codegen needs it to work + properly. + + [ Ubuntu daily release ] + * Automatic snapshot from revision 400 + + -- Ubuntu daily release Tue, 16 Jul 2013 02:02:05 +0000 + indicator-session (12.10.5+13.10.20130703.1-0ubuntu1) saucy; urgency=low [ Lars Uebernickel ] -- cgit v1.2.3 From 0196545074366e2f35bc11dcb69f081b39cde1a6 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 16 Jul 2013 14:29:35 -0500 Subject: fix failing tests on ppc & add more verbose warnings in the menu sync tests --- tests/test-service.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test-service.cc b/tests/test-service.cc index 2027ec0..e69b574 100644 --- a/tests/test-service.cc +++ b/tests/test-service.cc @@ -88,7 +88,7 @@ class ServiceTest: public GTestDBusFixture GSList * menu_references; - bool any_item_changed; + gboolean any_item_changed; static void on_items_changed (GMenuModel * model G_GNUC_UNUSED, gint position G_GNUC_UNUSED, @@ -149,7 +149,7 @@ class ServiceTest: public GTestDBusFixture super :: SetUp (); menu_references = NULL; - any_item_changed = NULL; + any_item_changed = FALSE; timer = g_timer_new (); mock_settings = g_settings_new ("com.canonical.indicator.session.backendmock"); @@ -231,6 +231,7 @@ class ServiceTest: public GTestDBusFixture any_item_changed = false; while (!times_up() && !any_item_changed) wait_msec (50); + g_warn_if_fail (any_item_changed); sync_menu (); } -- cgit v1.2.3 From 94ef5c4f24502ee34511929fd67a40b37fd89c28 Mon Sep 17 00:00:00 2001 From: Automatic PS uploader Date: Wed, 17 Jul 2013 02:01:46 +0000 Subject: Releasing 12.10.5+13.10.20130717-0ubuntu1, based on r402 --- debian/changelog | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/debian/changelog b/debian/changelog index d3c1b6d..d273b09 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,13 @@ +indicator-session (12.10.5+13.10.20130717-0ubuntu1) saucy; urgency=low + + [ Charles Kerr ] + * Fix a test failure on PPC architectures. + + [ Ubuntu daily release ] + * Automatic snapshot from revision 402 + + -- Ubuntu daily release Wed, 17 Jul 2013 02:01:46 +0000 + indicator-session (12.10.5+13.10.20130716-0ubuntu1) saucy; urgency=low [ Charles Kerr ] -- cgit v1.2.3 From 5cc9ae3dd2d78b205400779b969f528f3b602f15 Mon Sep 17 00:00:00 2001 From: Ritesh Khadgaray Date: Tue, 6 Aug 2013 14:32:18 +0530 Subject: lp# 1205273 - Session is not locked when switching to guest session --- src/service.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/service.c b/src/service.c index 74acd89..45de7d4 100644 --- a/src/service.c +++ b/src/service.c @@ -707,6 +707,7 @@ on_greeter_activated (GSimpleAction * a G_GNUC_UNUSED, GVariant * param G_GNUC_UNUSED, gpointer gself) { + indicator_session_actions_switch_to_screensaver (get_backend_actions(gself)); indicator_session_actions_switch_to_greeter (get_backend_actions(gself)); } -- cgit v1.2.3 From d8d4a6fa9f650e86d35d7141406195d4fee54a6c Mon Sep 17 00:00:00 2001 From: Ritesh Khadgaray Date: Tue, 6 Aug 2013 14:33:21 +0530 Subject: lp# 1205273 - Session is not locked when switching to guest session For a single user system, the Lock should lock the screen rather than throwing the user back at DM. At the DM, user would have to key in their password twice, once at DM, second at screensaver. The appropriate fix would be for DM to unlock the screensaver, if session is active --- src/service.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/service.c b/src/service.c index 45de7d4..ae4eb75 100644 --- a/src/service.c +++ b/src/service.c @@ -450,7 +450,7 @@ create_switch_section (IndicatorSessionService * self) } else if (g_hash_table_size (p->users) == 1) { - const char * action = "indicator.switch-to-greeter"; + const char * action = "indicator.switch-to-screensaver"; item = g_menu_item_new (_("Lock"), action); } else -- cgit v1.2.3 From 843fa1f19c2d6c1072ab3479c0969eb0b6b73076 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 8 Aug 2013 16:00:42 -0500 Subject: as discussed with dednick and ted, have a header action state type of a{sv} rather than the obsoleted (sssb) --- src/service.c | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/src/service.c b/src/service.c index 74acd89..41dba10 100644 --- a/src/service.c +++ b/src/service.c @@ -143,29 +143,28 @@ rebuild_settings_section_soon (IndicatorSessionService * self) **** ***/ -static void -update_header_action (IndicatorSessionService * self) +static GVariant * +action_state_for_header (IndicatorSessionService * self) { - gchar * a11y; + const priv_t * const p = self->priv; gboolean need_attn; + GIcon * icon; gboolean show_name; - GVariant * variant; const gchar * real_name; const gchar * label; - const gchar * iconstr; - const priv_t * const p = self->priv; - - g_return_if_fail (p->header_action != NULL); + gchar * a11y; + GVariantBuilder b; + GVariant * state; if (indicator_session_actions_has_online_account_error (p->backend_actions)) { need_attn = TRUE; - iconstr = ICON_ALERT; + icon = g_themed_icon_new (ICON_ALERT); } else { need_attn = FALSE; - iconstr = ICON_DEFAULT; + icon = g_themed_icon_new (ICON_DEFAULT); } show_name = g_settings_get_boolean (p->indicator_settings, @@ -194,9 +193,27 @@ update_header_action (IndicatorSessionService * self) a11y = g_strdup (_("System")); } - variant = g_variant_new ("(sssb)", label, iconstr, a11y, TRUE); - g_simple_action_set_state (p->header_action, variant); + /* build the state */ + g_variant_builder_init (&b, G_VARIANT_TYPE("a{sv}")); + g_variant_builder_add (&b, "{sv}", "accessible-desc", g_variant_new_string (a11y)); + g_variant_builder_add (&b, "{sv}", "icon", g_icon_serialize (icon)); + if (label && *label) + g_variant_builder_add (&b, "{sv}", "label", g_variant_new_string (label)); + g_variant_builder_add (&b, "{sv}", "visible", g_variant_new_boolean (TRUE)); + state = g_variant_builder_end (&b); +g_message ("---\n%s\n---\n", g_variant_print(state, TRUE)); + + /* cleanup */ g_free (a11y); + g_object_unref (G_OBJECT (icon)); + + return state; +} + +static void +update_header_action (IndicatorSessionService * self) +{ + g_simple_action_set_state (self->priv->header_action, action_state_for_header (self)); } /*** @@ -763,8 +780,7 @@ init_gactions (IndicatorSessionService * self) p->user_switcher_action = a; /* add the header action */ - v = g_variant_new ("(sssb)", "label", ICON_DEFAULT, "a11y", TRUE); - a = g_simple_action_new_stateful ("_header", NULL, v); + a = g_simple_action_new_stateful ("_header", NULL, action_state_for_header (self)); g_simple_action_group_insert (p->actions, G_ACTION(a)); p->header_action = a; -- cgit v1.2.3 From a699afab31403d69bbd6f20c45a6f601b1ea3dc5 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 8 Aug 2013 16:02:22 -0500 Subject: remove debugging stub --- src/service.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/service.c b/src/service.c index 41dba10..a097876 100644 --- a/src/service.c +++ b/src/service.c @@ -201,7 +201,6 @@ action_state_for_header (IndicatorSessionService * self) g_variant_builder_add (&b, "{sv}", "label", g_variant_new_string (label)); g_variant_builder_add (&b, "{sv}", "visible", g_variant_new_boolean (TRUE)); state = g_variant_builder_end (&b); -g_message ("---\n%s\n---\n", g_variant_print(state, TRUE)); /* cleanup */ g_free (a11y); -- cgit v1.2.3 From 752149b96a3b78937fee7d95ef119df8bb6b7c52 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 12 Aug 2013 12:01:00 -0500 Subject: in CMakeLists.txt, include the GCov rules before adding the src subdirectory. This unbreaks coverage report generation. --- CMakeLists.txt | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f8a366b..69ac18e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,18 +49,20 @@ add_custom_target (cppcheck COMMAND cppcheck --enable=all -q --error-exitcode=2 include_directories (${CMAKE_CURRENT_SOURCE_DIR}/src) include_directories (${CMAKE_CURRENT_BINARY_DIR}/src) - -add_subdirectory (src) -add_subdirectory (data) -add_subdirectory (po) - +# testing & coverage if (${enable_tests}) set (GTEST_SOURCE_DIR /usr/src/gtest/src) set (GTEST_INCLUDE_DIR ${GTEST_SOURCE_DIR}/..) set (GTEST_LIBS -lpthread) enable_testing () if (${enable_lcov}) - include(cmake/GCov.cmake) + include(GCov) endif () - add_subdirectory(tests) +endif () + +add_subdirectory (src) +add_subdirectory (data) +add_subdirectory (po) +if (${enable_tests}) + add_subdirectory (tests) endif () -- cgit v1.2.3 From d31e14e5afc14259f81efd54852f990ffe053889 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 12 Aug 2013 12:45:35 -0500 Subject: sync tests to look for a header action state of type a{sv} instead of (sssb) --- tests/test-service.cc | 44 ++++++++++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 14 deletions(-) diff --git a/tests/test-service.cc b/tests/test-service.cc index e69b574..b199175 100644 --- a/tests/test-service.cc +++ b/tests/test-service.cc @@ -318,28 +318,44 @@ class ServiceTest: public GTestDBusFixture void check_header (const char * expected_label, const char * expected_icon, const char * expected_a11y) { - GVariant * variant; - const gchar * label = NULL; - const gchar * icon = NULL; - const gchar * a11y = NULL; - gboolean visible; - - variant = g_action_group_get_action_state (G_ACTION_GROUP(action_group), "_header"); - g_variant_get (variant, "(&s&s&sb)", &label, &icon, &a11y, &visible); + GVariant * state = g_action_group_get_action_state (G_ACTION_GROUP(action_group), "_header"); + ASSERT_TRUE (state != NULL); + ASSERT_TRUE (g_variant_is_of_type (state, G_VARIANT_TYPE ("a{sv}"))); if (expected_label != NULL) - ASSERT_STREQ (expected_label, label); - - if (expected_icon != NULL) - ASSERT_STREQ (expected_icon, icon); + { + GVariant * v = g_variant_lookup_value (state, "label", G_VARIANT_TYPE_STRING); + if (!v) // if no label in the state, expected_label must be an empty string + ASSERT_FALSE (*expected_label); + else + ASSERT_STREQ (expected_label, g_variant_get_string (v, NULL)); + } if (expected_a11y != NULL) - ASSERT_STREQ (expected_a11y, a11y); + { + GVariant * v = g_variant_lookup_value (state, "accessible-desc", G_VARIANT_TYPE_STRING); + ASSERT_TRUE (v != NULL); + ASSERT_STREQ (expected_a11y, g_variant_get_string (v, NULL)); + g_variant_unref (v); + } + + if (expected_icon != NULL) + { + GVariant * v = g_variant_lookup_value (state, "icon", NULL); + GIcon * expected = g_themed_icon_new (expected_icon); + GIcon * actual = g_icon_deserialize (v); + ASSERT_TRUE (g_icon_equal (expected, actual)); + g_object_unref (actual); + g_object_unref (expected); + g_variant_unref (v); + } // the session menu is always visible... + gboolean visible = false; + g_variant_lookup (state, "visible", "b", &visible); ASSERT_TRUE (visible); - g_variant_unref (variant); + g_variant_unref (state); } void check_label (const char * expected_label, GMenuModel * model, int pos) -- cgit v1.2.3 From 981f8071b2ba632f6867b7a2973c64fc85f873e6 Mon Sep 17 00:00:00 2001 From: Automatic PS uploader Date: Mon, 12 Aug 2013 18:39:36 +0000 Subject: Releasing 12.10.5+13.10.20130812-0ubuntu1, based on r404 --- debian/changelog | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/debian/changelog b/debian/changelog index d273b09..72588f3 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,14 @@ +indicator-session (12.10.5+13.10.20130812-0ubuntu1) saucy; urgency=low + + [ Charles Kerr ] + * Ensure that GCov CFLAGS & LIBS are set before cmake traverses into + the src/ directory. + + [ Ubuntu daily release ] + * Automatic snapshot from revision 404 + + -- Ubuntu daily release Mon, 12 Aug 2013 18:39:36 +0000 + indicator-session (12.10.5+13.10.20130717-0ubuntu1) saucy; urgency=low [ Charles Kerr ] -- cgit v1.2.3 From 4759a380da77dd1f8746f298a5ae051319a70ddd Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 20 Aug 2013 08:42:24 -0500 Subject: when switching to the guest session, explicitly lock the current users's session --- src/backend-dbus/actions.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index 9030ca7..17547f0 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -734,7 +734,7 @@ my_about (IndicatorSessionActions * self G_GNUC_UNUSED) ***/ static void -my_switch_to_screensaver (IndicatorSessionActions * self) +lock_current_session (IndicatorSessionActions * self) { priv_t * p = INDICATOR_SESSION_ACTIONS_DBUS(self)->priv; @@ -743,6 +743,12 @@ my_switch_to_screensaver (IndicatorSessionActions * self) gnome_screen_saver_call_lock (p->screen_saver, p->cancellable, NULL, NULL); } +static void +my_switch_to_screensaver (IndicatorSessionActions * self) +{ + lock_current_session (self); +} + static void my_switch_to_greeter (IndicatorSessionActions * self) { @@ -750,6 +756,7 @@ my_switch_to_greeter (IndicatorSessionActions * self) g_return_if_fail (p->dm_seat != NULL); + /* show the greeter */ display_manager_seat_call_switch_to_greeter (p->dm_seat, p->dm_seat_cancellable, NULL, NULL); @@ -762,6 +769,8 @@ my_switch_to_guest (IndicatorSessionActions * self) g_return_if_fail (p->dm_seat != NULL); + lock_current_session (self); + display_manager_seat_call_switch_to_guest (p->dm_seat, "", p->dm_seat_cancellable, NULL, NULL); -- cgit v1.2.3 From e48d65866fa228929ddc545eac456635bf763501 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 20 Aug 2013 08:43:47 -0500 Subject: fix minor GCancellable memory leak noticed while fixing 1205273 --- src/backend-dbus/actions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index 17547f0..2550fdb 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -169,7 +169,7 @@ set_dm_seat (IndicatorSessionActionsDbus * self, DisplayManagerSeat * seat) if (p->dm_seat != NULL) { g_cancellable_cancel (p->dm_seat_cancellable); - g_clear_object (&p->dm_seat); + g_clear_object (&p->dm_seat_cancellable); g_clear_object (&p->dm_seat); } -- cgit v1.2.3 From 14964539aec0c91e39e3abdb70c08ad8d65824bb Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 20 Aug 2013 08:52:54 -0500 Subject: copyediting: remove unnecessary comment that snuck into r406 --- src/backend-dbus/actions.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backend-dbus/actions.c b/src/backend-dbus/actions.c index 2550fdb..fcf850d 100644 --- a/src/backend-dbus/actions.c +++ b/src/backend-dbus/actions.c @@ -756,7 +756,6 @@ my_switch_to_greeter (IndicatorSessionActions * self) g_return_if_fail (p->dm_seat != NULL); - /* show the greeter */ display_manager_seat_call_switch_to_greeter (p->dm_seat, p->dm_seat_cancellable, NULL, NULL); -- cgit v1.2.3 From b5019663e8a7093c42a9184329734aa8a409cc32 Mon Sep 17 00:00:00 2001 From: Automatic PS uploader Date: Wed, 21 Aug 2013 06:07:34 +0000 Subject: Releasing 12.10.5+13.10.20130821-0ubuntu1, based on r406 --- debian/changelog | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/debian/changelog b/debian/changelog index 72588f3..1dddf7f 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,22 @@ +indicator-session (12.10.5+13.10.20130821-0ubuntu1) saucy; urgency=low + + [ Charles Kerr ] + * Lock the current session before switching to the guest session. This + is done by modifying IndicatorSessionActionsDbus::switch_to_guest() + to call org.gnome.ScreenSaver's Lock function before switching to + the guest session. (LP: #1205273) + + [ Ritesh Khadgaray ] + * Lock the current session before switching to the guest session. This + is done by modifying IndicatorSessionActionsDbus::switch_to_guest() + to call org.gnome.ScreenSaver's Lock function before switching to + the guest session. (LP: #1205273) + + [ Ubuntu daily release ] + * Automatic snapshot from revision 406 + + -- Ubuntu daily release Wed, 21 Aug 2013 06:07:34 +0000 + indicator-session (12.10.5+13.10.20130812-0ubuntu1) saucy; urgency=low [ Charles Kerr ] -- cgit v1.2.3 From 3b35ef115b35d21b627f5802f364906243418247 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 22 Aug 2013 10:04:10 -0500 Subject: don't use deprecated API calls to GSimpleActionGroup --- src/service.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/service.c b/src/service.c index 74acd89..7303fcf 100644 --- a/src/service.c +++ b/src/service.c @@ -752,20 +752,20 @@ init_gactions (IndicatorSessionService * self) v = create_guest_switcher_state (self); a = g_simple_action_new_stateful ("switch-to-guest", NULL, v); g_signal_connect (a, "activate", G_CALLBACK(on_guest_activated), self); - g_simple_action_group_insert (p->actions, G_ACTION(a)); + g_action_map_add_action (G_ACTION_MAP (p->actions), G_ACTION(a)); p->guest_switcher_action = a; /* add switch-to-user action... parameter is the uesrname */ v = create_user_switcher_state (self); a = g_simple_action_new_stateful ("switch-to-user", G_VARIANT_TYPE_STRING, v); g_signal_connect (a, "activate", G_CALLBACK(on_user_activated), self); - g_simple_action_group_insert (p->actions, G_ACTION(a)); + g_action_map_add_action (G_ACTION_MAP (p->actions), G_ACTION(a)); p->user_switcher_action = a; /* add the header action */ v = g_variant_new ("(sssb)", "label", ICON_DEFAULT, "a11y", TRUE); a = g_simple_action_new_stateful ("_header", NULL, v); - g_simple_action_group_insert (p->actions, G_ACTION(a)); + g_action_map_add_action (G_ACTION_MAP (p->actions), G_ACTION(a)); p->header_action = a; rebuild_now (self, SECTION_HEADER); -- cgit v1.2.3 From 55ef0d63e38c954e1f9e81ad7a7bd3c3b2595e6b Mon Sep 17 00:00:00 2001 From: Automatic PS uploader Date: Thu, 22 Aug 2013 20:30:20 +0000 Subject: Releasing 12.10.5+13.10.20130822-0ubuntu1, based on r408 --- debian/changelog | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/debian/changelog b/debian/changelog index 1dddf7f..04d440c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,13 @@ +indicator-session (12.10.5+13.10.20130822-0ubuntu1) saucy; urgency=low + + [ Charles Kerr ] + * remove deprecated GSimpleActionGroup API use. + + [ Ubuntu daily release ] + * Automatic snapshot from revision 408 + + -- Ubuntu daily release Thu, 22 Aug 2013 20:30:19 +0000 + indicator-session (12.10.5+13.10.20130821-0ubuntu1) saucy; urgency=low [ Charles Kerr ] -- cgit v1.2.3 From a8f9de4bd749b33c97b345eee2efaa5214b26266 Mon Sep 17 00:00:00 2001 From: Automatic PS uploader Date: Fri, 23 Aug 2013 22:07:25 +0000 Subject: Releasing 12.10.5+13.10.20130823-0ubuntu1, based on r410 --- debian/changelog | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/debian/changelog b/debian/changelog index 04d440c..d4f1a25 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,14 @@ +indicator-session (12.10.5+13.10.20130823-0ubuntu1) saucy; urgency=low + + [ Charles Kerr ] + * use an a{sv}, rather than the obsoleted (sssb), for the root + action's state. + + [ Ubuntu daily release ] + * Automatic snapshot from revision 410 + + -- Ubuntu daily release Fri, 23 Aug 2013 22:07:25 +0000 + indicator-session (12.10.5+13.10.20130822-0ubuntu1) saucy; urgency=low [ Charles Kerr ] -- cgit v1.2.3