diff --git a/Slim/Control/Request.pm b/Slim/Control/Request.pm index 8fdccbe..0b1e62b 100644 --- a/Slim/Control/Request.pm +++ b/Slim/Control/Request.pm @@ -638,6 +638,7 @@ addDispatch(['image_titles', '_index', '_quantity'], [0, 1, 1, \&Slim::Control::Queries::imageTitlesQuery]); # NOTIFICATIONS + addDispatch(['clientactivity'], [0, 0, 0, undef]); addDispatch(['client', 'disconnect'], [1, 0, 0, undef]); addDispatch(['client', 'new'], [1, 0, 0, undef]); addDispatch(['client', 'reconnect'], [1, 0, 0, undef]); diff --git a/Slim/Player/Client.pm b/Slim/Player/Client.pm index 99fc618..558731b 100644 --- a/Slim/Player/Client.pm +++ b/Slim/Player/Client.pm @@ -107,7 +107,7 @@ revision _needsUpgrade isUpgrading macaddress paddr udpsock tcpsock irRefTime irRefTimeStored ircodes irmaps lastirtime lastircode lastircodebytes lastirbutton - startirhold irtimediff irrepeattime irenable _epochirtime lastActivityTime + startirhold irtimediff irrepeattime irenable _epochirtime _lastActivityTime knobPos knobTime knobSync sequenceNumber controllerSequenceId controllerSequenceNumber @@ -200,7 +200,7 @@ irrepeattime => 0, irenable => 1, _epochirtime => Time::HiRes::time(), - lastActivityTime => 0, # last time this client performed some action (IR, CLI, web) + _lastActivityTime => 0, # last time this client performed some action (IR, CLI, web) knobPos => undef, knobTime => undef, knobSync => 0, @@ -1198,6 +1198,19 @@ return $client->_epochirtime; } +sub lastActivityTime { + my $client = shift; + + if ( @_ ) { + $client->_lastActivityTime($_[0]); + + # tell our listeners that some client was active + Slim::Control::Request::notifyFromArray($client, ['clientactivity']); + } + + return $client->_lastActivityTime; +} + sub currentplayingsong { my $client = shift->master(); diff --git a/Slim/Plugin/PreventStandby/OSX.pm b/Slim/Plugin/PreventStandby/OSX.pm index 4cfeeae..dffe2c5 100644 --- a/Slim/Plugin/PreventStandby/OSX.pm +++ b/Slim/Plugin/PreventStandby/OSX.pm @@ -8,10 +8,13 @@ use strict; use Proc::Background; -use Slim::Utils::Log; use Slim::Plugin::PreventStandby::Plugin; +use Slim::Utils::Log; +use Slim::Utils::Prefs; +use Slim::Utils::Timers; my $log = logger('plugin.preventstandby'); +my $prefs = preferences('plugin.preventstandby'); my $command; my $process; @@ -22,32 +25,58 @@ $command = Slim::Utils::Misc::findbin('pmset'); if ($command) { - $command .= ' noidle'; + $command .= ' noidle > /dev/null'; } else { $log->warn("Didn't find pmset tool - standby can't be prevented!"); + return; } return $class; } sub isBusy { - my ($class, $currenttime) = @_; - return !Slim::Plugin::PreventStandby::Plugin->_hasResumed($currenttime) && Slim::Plugin::PreventStandby::Plugin->_playersBusy(); + return Slim::Plugin::PreventStandby::Plugin->_playersBusy(); } -# shut down caffeinate when the plugin is being shut down +# shut down pmset when the plugin is being shut down sub cleanup { $process->die if $process; }; sub setBusy { + my ($class, $currenttime) = @_; + + # Bug 8141: when coming out of standby, we don't want to keep the system alive for the full defined idle time + # OSX 10.8+ often resumes for some clean up work etc. In those cases only keep LMS awake for a few minutes + # before we can determine that we are really busy. Then either go back to sleep or to business as usual. + if ( Slim::Plugin::PreventStandby::Plugin->_hasResumed($currenttime) ) { + my $idletime = $prefs->get('idletime'); + + Slim::Utils::Timers::killTimers( undef, \&_setShortIdleTime ); + if ($idletime && $idletime > 2) { + Slim::Utils::Timers::setTimer( + undef, + time + 60, + \&_setShortIdleTime + ); + } + } + if (!$process || !$process->alive) { - $log->debug("Injecting some caffein to keep system alive: '$command'"); + main::DEBUGLOG && $log->debug("Injecting some caffeine to keep system alive: '$command'"); $process = Proc::Background->new($command); } } +sub _setShortIdleTime { + my $idletime = $prefs->get('idletime'); + + main::DEBUGLOG && $log->debug("System came out of standby - keep alive for only a few minutes"); + + Slim::Plugin::PreventStandby::Plugin->hasBeenIdle($idletime - 2) if $idletime && $idletime > 2; +} + sub setIdle { shift->cleanup; } diff --git a/Slim/Plugin/PreventStandby/Plugin.pm b/Slim/Plugin/PreventStandby/Plugin.pm index 1c75d88..9d93c53 100644 --- a/Slim/Plugin/PreventStandby/Plugin.pm +++ b/Slim/Plugin/PreventStandby/Plugin.pm @@ -100,12 +100,13 @@ Slim::Plugin::PreventStandby::Settings->new; } - if (my $idletime = $prefs->get('idletime')) { - $log->debug("System standby now allowed after $idletime minutes of player idle time.") - } - else { - $log->debug("System standby now prohibited.") - } + Slim::Control::Request::subscribe(sub { + # only check for activity if we're getting close to idle state + return unless $hasbeenidle; + + main::DEBUGLOG && $log->is_debug && $log->debug("Client activity was signaled"); + checkClientActivity(); + }, [[ 'clientactivity' ]]); checkClientActivity(); } @@ -141,12 +142,12 @@ if ( (!$idletime) || $hasbeenidle < $idletime) { main::INFOLOG && $log->is_info && $log->info("Preventing System Standby..."); - $handler->setBusy(); + $handler->setBusy($currenttime); } else { main::INFOLOG && $log->is_info && $log->info("Players have been idle for $hasbeenidle minutes. Allowing System Standby..."); - $handler->setIdle(); + $handler->setIdle($currenttime); } $lastchecktime = $currenttime; @@ -206,10 +207,12 @@ # Reset our counter on prefs change.. $hasbeenidle = 0; - if ($value) { - $log->debug("System standby now allowed after $value minutes of player idle time.") - } else { - $log->debug("System standby now prohibited.") + if (main::DEBUGLOG) { + if ($value) { + $log->debug("System standby now allowed after $value minutes of player idle time.") + } else { + $log->debug("System standby now prohibited.") + } } } @@ -223,11 +226,17 @@ # Reset our counter on prefs change.. $hasbeenidle = 0; - if ($value) { + if ($value && main::DEBUGLOG) { $log->debug("System standby now prohibited when players are powered on.") } } +sub hasBeenIdle { + my ($class, $newValue) = @_; + $hasbeenidle = $newValue if $newValue; + return $hasbeenidle; +} + sub shutdownPlugin { Slim::Utils::Timers::killTimers( undef, \&checkClientActivity ); $handler->cleanup();