~brandontschaefer/unity/lp.1099815-fix

« back to all changes in this revision

Viewing changes to UnityCore/GnomeSessionManager.cpp

  • Committer: Tarmac
  • Author(s): Martin Pitt
  • Date: 2013-03-21 11:43:07 UTC
  • mfrom: (3226.3.7 unity)
  • Revision ID: tarmac-20130321114307-y55vy9k252p640yq
Add logind alternatives to ConsoleKit and UPower suspend/hibernate calls (LP: #1155021)

ConsoleKit is being deprecated, so add support for logind for logout, shutdown, and reboot.

Future UPower versions will drop suspend/release calls, as they moved into logind:
  http://lists.freedesktop.org/archives/devkit-devel/2013-January/001339.html

With ConsoleKit, sessions get $XDG_SESSION_COOKIE set, while with logind they get $XDG_SESSION_ID. So use that to determine which one to talk to until we drop support for ConsoleKit/upower. Fixes: https://bugs.launchpad.net/bugs/1155021.

Approved by PS Jenkins bot, Marco Trevisan (Treviño).

Show diffs side-by-side

added added

removed removed

Lines of Context:
87
87
  shell_object_ = shell_server_.GetObject(shell::DBUS_INTERFACE);
88
88
  shell_object_->SetMethodsCallsHandler(sigc::mem_fun(this, &Impl::OnShellMethodCall));
89
89
 
90
 
  CallUPowerMethod("HibernateAllowed", [this] (GVariant* variant) {
91
 
    can_hibernate_ = glib::Variant(variant).GetBool();
92
 
    LOG_INFO(logger) << "Can hibernate: " << can_hibernate_;
 
90
  CallLogindMethod("CanHibernate", nullptr, [this] (GVariant* variant, glib::Error const& err) {
 
91
    if (err)
 
92
    {
 
93
      // fall back to upower
 
94
      CallUPowerMethod("HibernateAllowed", [this] (GVariant* variant) {
 
95
        can_hibernate_ = glib::Variant(variant).GetBool();
 
96
        LOG_INFO(logger) << "Can hibernate (upower): " << can_hibernate_;
 
97
      });
 
98
    }
 
99
    else
 
100
    {
 
101
      can_hibernate_ = glib::Variant(variant).GetString() == "yes";
 
102
      LOG_INFO(logger) << "Can hibernate (logind): " << can_hibernate_;
 
103
    }
93
104
  });
94
105
 
95
 
  CallUPowerMethod("SuspendAllowed", [this] (GVariant* variant) {
96
 
    can_suspend_ = glib::Variant(variant).GetBool();
97
 
    LOG_INFO(logger) << "Can suspend: " << can_suspend_;
 
106
  CallLogindMethod("CanSuspend", nullptr, [this] (GVariant* variant, glib::Error const& err) {
 
107
    if (err)
 
108
    {
 
109
      // fall back to upower
 
110
      CallUPowerMethod("SuspendAllowed", [this] (GVariant* variant) {
 
111
        can_suspend_ = glib::Variant(variant).GetBool();
 
112
        LOG_INFO(logger) << "Can suspend (upower): " << can_suspend_;
 
113
      });
 
114
    }
 
115
    else
 
116
    {
 
117
      can_suspend_ = glib::Variant(variant).GetString() == "yes";
 
118
      LOG_INFO(logger) << "Can suspend (logind): " << can_suspend_;
 
119
    }
98
120
  });
99
121
 
100
122
  CallGnomeSessionMethod("CanShutdown", nullptr, [this] (GVariant* variant, glib::Error const& e) {
298
320
  });
299
321
}
300
322
 
 
323
void GnomeManager::Impl::CallLogindMethod(std::string const& method, GVariant* parameters, glib::DBusProxy::CallFinishedCallback const& cb)
 
324
{
 
325
  auto proxy = std::make_shared<glib::DBusProxy>(test_mode_ ? testing::DBUS_NAME : "org.freedesktop.login1",
 
326
                                                 "/org/freedesktop/login1",
 
327
                                                 "org.freedesktop.login1.Manager",
 
328
                                                 test_mode_ ? G_BUS_TYPE_SESSION : G_BUS_TYPE_SYSTEM);
 
329
 
 
330
  // By passing the proxy to the lambda we ensure that it will be smartly handled
 
331
  proxy->CallBegin(method, parameters, [proxy, cb, method] (GVariant* ret, glib::Error const& e) {
 
332
    if (e)
 
333
    {
 
334
      LOG_ERROR(logger) << "logind " << method << " call failed: " << e.Message();
 
335
    }
 
336
 
 
337
    if (cb)
 
338
    {
 
339
      cb(ret, e);
 
340
    }
 
341
  });
 
342
}
 
343
 
301
344
void GnomeManager::Impl::CallConsoleKitMethod(std::string const& method, GVariant* parameters)
302
345
{
303
346
  auto proxy = std::make_shared<glib::DBusProxy>(test_mode_ ? testing::DBUS_NAME : "org.freedesktop.ConsoleKit",
379
422
        LOG_WARNING(logger) << "Got error during call: " << err.Message();
380
423
 
381
424
        impl_->pending_action_ = shell::Action::NONE;
382
 
        const char* cookie = g_getenv("XDG_SESSION_COOKIE");
383
 
 
384
 
        if (cookie && cookie[0] != '\0')
385
 
          impl_->CallConsoleKitMethod("CloseSession", g_variant_new("(s)", cookie));
 
425
        // fallback to logind
 
426
        const char* session_id = g_getenv("XDG_SESSION_ID");
 
427
 
 
428
        auto call_consolekit_lambda = [this] {
 
429
          // fallback to ConsoleKit
 
430
          const char* cookie = g_getenv("XDG_SESSION_COOKIE");
 
431
 
 
432
          if (cookie && cookie[0] != '\0')
 
433
            impl_->CallConsoleKitMethod("CloseSession", g_variant_new("(s)", cookie));
 
434
        };
 
435
 
 
436
        if (session_id && session_id[0] != '\0')
 
437
        {
 
438
          impl_->CallLogindMethod("TerminateSession", g_variant_new("(s)", session_id), [call_consolekit_lambda] (GVariant*, glib::Error const& err) {
 
439
            if (err)
 
440
              call_consolekit_lambda();
 
441
          });
 
442
        }
 
443
        else
 
444
        {
 
445
          call_consolekit_lambda();
 
446
        }
386
447
      }
387
448
  });
388
449
}
399
460
                            << ". Using fallback method";
400
461
 
401
462
        impl_->pending_action_ = shell::Action::NONE;
402
 
        impl_->CallConsoleKitMethod("Restart");
 
463
        // logind fallback
 
464
        impl_->CallLogindMethod("Reboot", g_variant_new("(b)", FALSE), [this] (GVariant* variant, glib::Error const& err) {
 
465
         // ConsoleKit fallback
 
466
         if (err)
 
467
           impl_->CallConsoleKitMethod("Restart");
 
468
         });
403
469
      }
404
470
  });
405
471
}
416
482
                            << ". Using fallback method";
417
483
 
418
484
        impl_->pending_action_ = shell::Action::NONE;
419
 
        impl_->CallConsoleKitMethod("Stop");
 
485
        // logind fallback
 
486
        impl_->CallLogindMethod("PowerOff", g_variant_new("(b)", FALSE), [this] (GVariant* variant, glib::Error const& err) {
 
487
         // ConsoleKit fallback
 
488
         if (err)
 
489
           impl_->CallConsoleKitMethod("Stop");
 
490
         });
420
491
      }
421
492
  });
422
493
}
424
495
void GnomeManager::Suspend()
425
496
{
426
497
  impl_->EnsureCancelPendingAction();
427
 
  impl_->CallUPowerMethod("Suspend");
 
498
  impl_->CallLogindMethod("Suspend", g_variant_new("(b)", FALSE), [this] (GVariant* variant, glib::Error const& err) {
 
499
    // fallback to UPower
 
500
    if (err) 
 
501
      impl_->CallUPowerMethod("Suspend");
 
502
  });
428
503
}
429
504
 
430
505
void GnomeManager::Hibernate()
431
506
{
432
507
  impl_->EnsureCancelPendingAction();
433
 
  impl_->CallUPowerMethod("Hibernate");
 
508
  impl_->CallLogindMethod("Hibernate", g_variant_new("(b)", FALSE), [this] (GVariant* variant, glib::Error const& err) {
 
509
    // fallback to UPower
 
510
    if (err)
 
511
      impl_->CallUPowerMethod("Hibernate");
 
512
  });
434
513
}
435
514
 
436
515
bool GnomeManager::CanShutdown() const