aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xlanguage/English/strings.po14
-rw-r--r--xbmc/Application.cpp20
-rw-r--r--xbmc/GUIInfoManager.cpp6
-rw-r--r--xbmc/URL.cpp8
-rw-r--r--xbmc/addons/include/xbmc_pvr_dll.h9
-rw-r--r--xbmc/addons/include/xbmc_pvr_types.h5
-rw-r--r--xbmc/interfaces/Builtins.cpp34
-rw-r--r--xbmc/interfaces/Builtins.h1
-rw-r--r--xbmc/network/Network.cpp40
-rw-r--r--xbmc/network/Network.h5
-rw-r--r--xbmc/peripherals/devices/PeripheralCecAdapter.cpp4
-rw-r--r--xbmc/pvr/PVRManager.cpp20
-rw-r--r--xbmc/pvr/PVRManager.h12
-rw-r--r--xbmc/pvr/addons/PVRClient.cpp13
-rw-r--r--xbmc/pvr/addons/PVRClient.h6
-rw-r--r--xbmc/pvr/addons/PVRClients.cpp31
-rw-r--r--xbmc/pvr/addons/PVRClients.h8
-rw-r--r--xbmc/windows/GUIWindowLoginScreen.cpp4
18 files changed, 217 insertions, 23 deletions
diff --git a/language/English/strings.po b/language/English/strings.po
index 4ebfbd9411..9f6842c4f2 100755
--- a/language/English/strings.po
+++ b/language/English/strings.po
@@ -9295,7 +9295,19 @@ msgctxt "#19684"
msgid "Adult"
msgstr ""
-#empty strings from id 19685 to 19999
+#. Title for shutdown confirmation dialog
+#: xbmc/ApplicationMessenger.cpp
+msgctxt "#19685"
+msgid "Confirm shutdown"
+msgstr ""
+
+#. Text for shutdown confirmation dialog
+#: xbmc/ApplicationMessenger.cpp
+msgctxt "#19686"
+msgid "The PVR backend is busy. Shutdown anyway?"
+msgstr ""
+
+#empty strings from id 19687 to 19999
#: system/settings/settings.xml
msgctxt "#20000"
diff --git a/xbmc/Application.cpp b/xbmc/Application.cpp
index 22144b7da6..f73193a625 100644
--- a/xbmc/Application.cpp
+++ b/xbmc/Application.cpp
@@ -734,7 +734,9 @@ bool CApplication::Create()
std::string executable = CUtil::ResolveExecutablePath();
CLog::Log(LOGNOTICE, "The executable running is: %s", executable.c_str());
- CLog::Log(LOGNOTICE, "Local hostname: %s", m_network->GetHostName().c_str());
+ std::string hostname("[unknown]");
+ m_network->GetHostName(hostname);
+ CLog::Log(LOGNOTICE, "Local hostname: %s", hostname.c_str());
std::string lowerAppName = CCompileInfo::GetAppName();
StringUtils::ToLower(lowerAppName);
CLog::Log(LOGNOTICE, "Log File is located: %s%s.log", g_advancedSettings.m_logFolder.c_str(), lowerAppName.c_str());
@@ -2589,8 +2591,12 @@ bool CApplication::OnAction(const CAction &action)
// built in functions : execute the built-in
if (action.GetID() == ACTION_BUILT_IN_FUNCTION)
{
- CBuiltins::Execute(action.GetName());
- m_navigationTimer.StartZero();
+ if (!CBuiltins::IsSystemPowerdownCommand(action.GetName()) ||
+ g_PVRManager.CanSystemPowerdown())
+ {
+ CBuiltins::Execute(action.GetName());
+ m_navigationTimer.StartZero();
+ }
return true;
}
@@ -4723,7 +4729,7 @@ void CApplication::CheckShutdown()
|| m_musicInfoScanner->IsScanning()
|| m_videoInfoScanner->IsScanning()
|| g_windowManager.IsWindowActive(WINDOW_DIALOG_PROGRESS) // progress dialog is onscreen
- || (CSettings::Get().GetBool("pvrmanager.enabled") && !g_PVRManager.IsIdle()))
+ || !g_PVRManager.CanSystemPowerdown(false))
{
m_shutdownTimer.StartZero();
return;
@@ -4999,7 +5005,11 @@ bool CApplication::ExecuteXBMCAction(std::string actionStr)
// user has asked for something to be executed
if (CBuiltins::HasCommand(actionStr))
- CBuiltins::Execute(actionStr);
+ {
+ if (!CBuiltins::IsSystemPowerdownCommand(actionStr) ||
+ g_PVRManager.CanSystemPowerdown())
+ CBuiltins::Execute(actionStr);
+ }
else
{
// try translating the action from our ButtonTranslator
diff --git a/xbmc/GUIInfoManager.cpp b/xbmc/GUIInfoManager.cpp
index 2b7e0b8012..39c7b34722 100644
--- a/xbmc/GUIInfoManager.cpp
+++ b/xbmc/GUIInfoManager.cpp
@@ -1921,7 +1921,11 @@ std::string CGUIInfoManager::GetLabel(int info, int contextWindow, std::string *
{
std::string friendlyName = CSettings::Get().GetString("services.devicename");
if (StringUtils::EqualsNoCase(friendlyName, CCompileInfo::GetAppName()))
- strLabel = StringUtils::Format("%s (%s)", friendlyName.c_str(), g_application.getNetwork().GetHostName().c_str());
+ {
+ std::string hostname("[unknown]");
+ g_application.getNetwork().GetHostName(hostname);
+ strLabel = StringUtils::Format("%s (%s)", friendlyName.c_str(), hostname.c_str());
+ }
else
strLabel = friendlyName;
}
diff --git a/xbmc/URL.cpp b/xbmc/URL.cpp
index ed4549dd4c..6b13a57ed4 100644
--- a/xbmc/URL.cpp
+++ b/xbmc/URL.cpp
@@ -19,6 +19,7 @@
*/
#include "URL.h"
+#include "Application.h"
#include "utils/RegExp.h"
#include "utils/log.h"
#include "utils/URIUtils.h"
@@ -29,6 +30,7 @@
#include "filesystem/StackDirectory.h"
#include "addons/Addon.h"
#include "utils/StringUtils.h"
+#include "network/Network.h"
#ifndef TARGET_POSIX
#include <sys\types.h>
#include <sys\stat.h>
@@ -679,14 +681,12 @@ std::string CURL::GetRedacted(const std::string& path)
bool CURL::IsLocal() const
{
- return (IsLocalHost() || m_strProtocol.empty());
+ return (m_strProtocol.empty() || IsLocalHost());
}
bool CURL::IsLocalHost() const
{
- // localhost is case-insensitive
- return (StringUtils::EqualsNoCase(m_strHostName, "localhost") ||
- m_strHostName == "127.0.0.1");
+ return g_application.getNetwork().IsLocalHost(m_strHostName);
}
bool CURL::IsFileOnly(const std::string &url)
diff --git a/xbmc/addons/include/xbmc_pvr_dll.h b/xbmc/addons/include/xbmc_pvr_dll.h
index 50012b0497..6ef21f3b8e 100644
--- a/xbmc/addons/include/xbmc_pvr_dll.h
+++ b/xbmc/addons/include/xbmc_pvr_dll.h
@@ -595,6 +595,13 @@ extern "C"
time_t GetBufferTimeEnd();
/*!
+ * Get the hostname of the pvr backend server
+ * @return hostname as ip address or alias. If backend does not
+ * utilize a server, return empty string.
+ */
+ const char* GetBackendHostname();
+
+ /*!
* Called by XBMC to assign the function pointers of this add-on to pClient.
* @param pClient The struct to assign the function pointers to.
*/
@@ -674,6 +681,8 @@ extern "C"
pClient->GetPlayingTime = GetPlayingTime;
pClient->GetBufferTimeStart = GetBufferTimeStart;
pClient->GetBufferTimeEnd = GetBufferTimeEnd;
+
+ pClient->GetBackendHostname = GetBackendHostname;
};
};
diff --git a/xbmc/addons/include/xbmc_pvr_types.h b/xbmc/addons/include/xbmc_pvr_types.h
index b218943534..8d78818e78 100644
--- a/xbmc/addons/include/xbmc_pvr_types.h
+++ b/xbmc/addons/include/xbmc_pvr_types.h
@@ -75,10 +75,10 @@ struct DemuxPacket;
#define PVR_STREAM_MAX_STREAMS 20
/* current PVR API version */
-#define XBMC_PVR_API_VERSION "1.9.2"
+#define XBMC_PVR_API_VERSION "1.9.3"
/* min. PVR API version */
-#define XBMC_PVR_MIN_API_VERSION "1.9.2"
+#define XBMC_PVR_MIN_API_VERSION "1.9.3"
#ifdef __cplusplus
extern "C" {
@@ -399,6 +399,7 @@ extern "C" {
time_t (__cdecl* GetPlayingTime)(void);
time_t (__cdecl* GetBufferTimeStart)(void);
time_t (__cdecl* GetBufferTimeEnd)(void);
+ const char* (__cdecl* GetBackendHostname)(void);
} PVRClient;
#ifdef __cplusplus
diff --git a/xbmc/interfaces/Builtins.cpp b/xbmc/interfaces/Builtins.cpp
index d99f047b2c..0c01c82793 100644
--- a/xbmc/interfaces/Builtins.cpp
+++ b/xbmc/interfaces/Builtins.cpp
@@ -96,6 +96,7 @@
#include <vector>
#include "settings/AdvancedSettings.h"
#include "settings/DisplaySettings.h"
+#include "powermanagement/PowerManager.h"
using namespace std;
using namespace XFILE;
@@ -244,6 +245,39 @@ bool CBuiltins::HasCommand(const std::string& execString)
return false;
}
+bool CBuiltins::IsSystemPowerdownCommand(const std::string& execString)
+{
+ std::string execute;
+ vector<string> params;
+ CUtil::SplitExecFunction(execString, execute, params);
+ StringUtils::ToLower(execute);
+
+ // Check if action is resulting in system powerdown.
+ if (execute == "reboot" ||
+ execute == "restart" ||
+ execute == "reset" ||
+ execute == "powerdown" ||
+ execute == "hibernate" ||
+ execute == "suspend" )
+ {
+ return true;
+ }
+ else if (execute == "shutdown")
+ {
+ switch (CSettings::Get().GetInt("powermanagement.shutdownstate"))
+ {
+ case POWERSTATE_SHUTDOWN:
+ case POWERSTATE_SUSPEND:
+ case POWERSTATE_HIBERNATE:
+ return true;
+
+ default:
+ return false;
+ }
+ }
+ return false;
+}
+
void CBuiltins::GetHelp(std::string &help)
{
help.clear();
diff --git a/xbmc/interfaces/Builtins.h b/xbmc/interfaces/Builtins.h
index e30385c68c..9488c02f63 100644
--- a/xbmc/interfaces/Builtins.h
+++ b/xbmc/interfaces/Builtins.h
@@ -26,6 +26,7 @@ class CBuiltins
{
public:
static bool HasCommand(const std::string& execString);
+ static bool IsSystemPowerdownCommand(const std::string& execString);
static void GetHelp(std::string &help);
static int Execute(const std::string& execString);
};
diff --git a/xbmc/network/Network.cpp b/xbmc/network/Network.cpp
index d0c80c0f5e..ed4c5d741c 100644
--- a/xbmc/network/Network.cpp
+++ b/xbmc/network/Network.cpp
@@ -159,19 +159,49 @@ int CNetwork::ParseHex(char *str, unsigned char *addr)
return len;
}
-std::string CNetwork::GetHostName(void)
+bool CNetwork::GetHostName(std::string& hostname)
{
char hostName[128];
if (gethostname(hostName, sizeof(hostName)))
- return "unknown";
+ return false;
- std::string hostStr;
#ifdef TARGET_WINDOWS
+ std::string hostStr;
g_charsetConverter.systemToUtf8(hostName, hostStr);
+ hostname = hostStr;
#else
- hostStr = hostName;
+ hostname = hostName;
#endif
- return hostStr;
+ return true;
+}
+
+bool CNetwork::IsLocalHost(const std::string& hostname)
+{
+ if (hostname.empty())
+ return false;
+
+ if (StringUtils::StartsWith(hostname, "127.")
+ || (hostname == "::1")
+ || StringUtils::EqualsNoCase(hostname, "localhost"))
+ return true;
+
+ std::string myhostname;
+ if (GetHostName(myhostname)
+ && StringUtils::EqualsNoCase(hostname, myhostname))
+ return true;
+
+ std::vector<CNetworkInterface*>& ifaces = GetInterfaceList();
+ std::vector<CNetworkInterface*>::const_iterator iter = ifaces.begin();
+ while (iter != ifaces.end())
+ {
+ CNetworkInterface* iface = *iter;
+ if (iface && iface->GetCurrentIPAddress() == hostname)
+ return true;
+
+ ++iter;
+ }
+
+ return false;
}
CNetworkInterface* CNetwork::GetFirstConnectedInterface()
diff --git a/xbmc/network/Network.h b/xbmc/network/Network.h
index e2cd39b62a..2bd8369be7 100644
--- a/xbmc/network/Network.h
+++ b/xbmc/network/Network.h
@@ -110,7 +110,7 @@ public:
virtual ~CNetwork();
// Return our hostname
- virtual std::string GetHostName(void);
+ virtual bool GetHostName(std::string& hostname);
// Return the list of interfaces
virtual std::vector<CNetworkInterface*>& GetInterfaceList(void) = 0;
@@ -146,6 +146,9 @@ public:
void StopServices(bool bWait);
static int ParseHex(char *str, unsigned char *addr);
+
+ // Return true if given name or ip address corresponds to localhost
+ bool IsLocalHost(const std::string& hostname);
};
#ifdef HAS_LINUX_NETWORK
diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp
index 7991b990a1..98c4d77eed 100644
--- a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp
+++ b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp
@@ -628,9 +628,9 @@ int CPeripheralCecAdapter::CecCommand(void *cbParam, const cec_command command)
{
adapter->m_bStarted = false;
if (adapter->m_configuration.bPowerOffOnStandby == 1)
- CApplicationMessenger::Get().Suspend();
+ g_application.ExecuteXBMCAction("Suspend");
else if (adapter->m_configuration.bShutdownOnStandby == 1)
- CApplicationMessenger::Get().Shutdown();
+ g_application.ExecuteXBMCAction("Shutdown");
}
break;
case CEC_OPCODE_SET_MENU_LANGUAGE:
diff --git a/xbmc/pvr/PVRManager.cpp b/xbmc/pvr/PVRManager.cpp
index a80bc81a6f..48beed5ea9 100644
--- a/xbmc/pvr/PVRManager.cpp
+++ b/xbmc/pvr/PVRManager.cpp
@@ -1414,6 +1414,26 @@ bool CPVRManager::IsIdle(void) const
return true;
}
+bool CPVRManager::CanSystemPowerdown(bool bAskUser /*= true*/) const
+{
+ bool bReturn(true);
+ if (IsStarted())
+ {
+ if (!m_addons->AllLocalBackendsIdle())
+ {
+ if (bAskUser)
+ {
+ // Inform user about PVR being busy. Ask if user wants to powerdown anyway.
+ bool bCanceled = false;
+ bReturn = CGUIDialogYesNo::ShowAndGetInput(19685, 19686, 0, 0, -1, -1, bCanceled, 10000);
+ }
+ else
+ bReturn = false; // do not powerdown (busy, but no user interaction requested).
+ }
+ }
+ return bReturn;
+}
+
void CPVRManager::ShowPlayerInfo(int iTimeout)
{
if (IsStarted() && m_guiInfo)
diff --git a/xbmc/pvr/PVRManager.h b/xbmc/pvr/PVRManager.h
index 205cc99970..72b17e7767 100644
--- a/xbmc/pvr/PVRManager.h
+++ b/xbmc/pvr/PVRManager.h
@@ -372,6 +372,18 @@ namespace PVR
bool IsIdle(void) const;
/*!
+ * @brief Check whether the system Kodi is running on can be powered down
+ * (shutdown/reboot/suspend/hibernate) without stopping any active
+ * recordings and/or without preventing the start of recordings
+ * sheduled for now + pvrpowermanagement.backendidletime.
+ * @param bAskUser True to informs user in case of potential
+ * data loss. User can decide to allow powerdown anyway. False to
+ * not to ask user and to not confirm power down.
+ * @return True if system can be safely powered down, false otherwise.
+ */
+ bool CanSystemPowerdown(bool bAskUser = true) const;
+
+ /*!
* @brief Set the current playing group, used to load the right channel.
* @param group The new group.
*/
diff --git a/xbmc/pvr/addons/PVRClient.cpp b/xbmc/pvr/addons/PVRClient.cpp
index e35db066e5..6491b36c0a 100644
--- a/xbmc/pvr/addons/PVRClient.cpp
+++ b/xbmc/pvr/addons/PVRClient.cpp
@@ -132,6 +132,7 @@ void CPVRClient::ResetProperties(int iClientId /* = PVR_INVALID_CLIENT_ID */)
m_strConnectionString = DEFAULT_INFO_STRING_VALUE;
m_strFriendlyName = DEFAULT_INFO_STRING_VALUE;
m_strBackendName = DEFAULT_INFO_STRING_VALUE;
+ m_strBackendHostname.clear();
m_bIsPlayingTV = false;
m_bIsPlayingRecording = false;
memset(&m_addonCapabilities, 0, sizeof(m_addonCapabilities));
@@ -353,7 +354,7 @@ bool CPVRClient::CheckAPIVersion(void)
bool CPVRClient::GetAddonProperties(void)
{
- std::string strBackendName, strConnectionString, strFriendlyName, strBackendVersion;
+ std::string strBackendName, strConnectionString, strFriendlyName, strBackendVersion, strBackendHostname;
PVR_ADDON_CAPABILITIES addonCapabilities;
/* get the capabilities */
@@ -384,12 +385,17 @@ bool CPVRClient::GetAddonProperties(void)
try { strBackendVersion = m_pStruct->GetBackendVersion(); }
catch (std::exception &e) { LogException(e, "GetBackendVersion()"); return false; }
+ /* backend hostname */
+ try { strBackendHostname = m_pStruct->GetBackendHostname(); }
+ catch (std::exception &e) { LogException(e, "GetBackendHostname()"); return false; }
+
/* update the members */
m_strBackendName = strBackendName;
m_strConnectionString = strConnectionString;
m_strFriendlyName = strFriendlyName;
m_strBackendVersion = strBackendVersion;
m_addonCapabilities = addonCapabilities;
+ m_strBackendHostname = strBackendHostname;
return true;
}
@@ -410,6 +416,11 @@ const std::string& CPVRClient::GetBackendVersion(void) const
return m_strBackendVersion;
}
+const std::string& CPVRClient::GetBackendHostname(void) const
+{
+ return m_strBackendHostname;
+}
+
const std::string& CPVRClient::GetConnectionString(void) const
{
return m_strConnectionString;
diff --git a/xbmc/pvr/addons/PVRClient.h b/xbmc/pvr/addons/PVRClient.h
index 179d85aaa1..77a3e5b3f2 100644
--- a/xbmc/pvr/addons/PVRClient.h
+++ b/xbmc/pvr/addons/PVRClient.h
@@ -129,6 +129,11 @@ namespace PVR
const std::string& GetBackendVersion(void) const;
/*!
+ * @brief the ip address or alias of the pvr backend server
+ */
+ const std::string& GetBackendHostname(void) const;
+
+ /*!
* @return The connection string reported by the backend.
*/
const std::string& GetConnectionString(void) const;
@@ -625,6 +630,7 @@ namespace PVR
PVR_ADDON_CAPABILITIES m_addonCapabilities; /*!< the cached add-on capabilities */
bool m_bGotAddonCapabilities; /*!< true if the add-on capabilities have already been fetched */
PVR_SIGNAL_STATUS m_qualityInfo; /*!< stream quality information */
+ std::string m_strBackendHostname; /*!< the cached backend hostname */
/* stored strings to make sure const char* members in PVR_PROPERTIES stay valid */
std::string m_strUserPath; /*!< @brief translated path to the user profile */
diff --git a/xbmc/pvr/addons/PVRClients.cpp b/xbmc/pvr/addons/PVRClients.cpp
index f8f933824b..d252e6d686 100644
--- a/xbmc/pvr/addons/PVRClients.cpp
+++ b/xbmc/pvr/addons/PVRClients.cpp
@@ -34,6 +34,7 @@
#include "pvr/recordings/PVRRecordings.h"
#include "pvr/timers/PVRTimers.h"
#include "cores/IPlayer.h"
+#include "network/Network.h"
using namespace ADDON;
using namespace PVR;
@@ -1371,3 +1372,33 @@ time_t CPVRClients::GetBufferTimeEnd() const
return time;
}
+
+bool CPVRClients::NextEventWithinBackendIdleTime(const CPVRTimers& timers)
+{
+ // timers going off soon?
+ const CDateTime now(CDateTime::GetUTCDateTime());
+ const CDateTimeSpan idle(
+ 0, 0, CSettings::Get().GetInt("pvrpowermanagement.backendidletime"), 0);
+ const CDateTime next(timers.GetNextEventTime());
+ const CDateTimeSpan delta(next - now);
+
+ return (delta <= idle);
+}
+
+bool CPVRClients::AllLocalBackendsIdle() const
+{
+ PVR_CLIENTMAP clients;
+ GetConnectedClients(clients);
+ for (PVR_CLIENTMAP_CITR itr = clients.begin(); itr != clients.end(); itr++)
+ {
+ CPVRTimers timers;
+ PVR_ERROR ret = itr->second->GetTimers(&timers);
+ if (ret == PVR_ERROR_NOT_IMPLEMENTED || ret != PVR_ERROR_NO_ERROR)
+ continue;
+
+ if (((timers.AmountActiveRecordings() > 0) || NextEventWithinBackendIdleTime(timers))
+ && g_application.getNetwork().IsLocalHost(itr->second->GetBackendHostname()))
+ return false;
+ }
+ return true;
+}
diff --git a/xbmc/pvr/addons/PVRClients.h b/xbmc/pvr/addons/PVRClients.h
index d10926ab5f..08719e2a12 100644
--- a/xbmc/pvr/addons/PVRClients.h
+++ b/xbmc/pvr/addons/PVRClients.h
@@ -552,6 +552,12 @@ namespace PVR
bool GetPlayingClient(PVR_CLIENT &client) const;
+ /*!
+ * @brief Checks whether all local pvr backends (if any) are idle (no recording active, ...).
+ * @return True if all local backends are idle or no local backends are connected, false otherwise.
+ */
+ bool AllLocalBackendsIdle() const;
+
time_t GetPlayingTime() const;
time_t GetBufferTimeStart() const;
time_t GetBufferTimeEnd() const;
@@ -621,6 +627,8 @@ namespace PVR
int GetClientId(const ADDON::AddonPtr client) const;
+ static bool NextEventWithinBackendIdleTime(const CPVRTimers& timers);
+
bool m_bChannelScanRunning; /*!< true when a channel scan is currently running, false otherwise */
bool m_bIsSwitchingChannels; /*!< true while switching channels */
int m_playingClientId; /*!< the ID of the client that is currently playing */
diff --git a/xbmc/windows/GUIWindowLoginScreen.cpp b/xbmc/windows/GUIWindowLoginScreen.cpp
index 765f65d99a..932a0501df 100644
--- a/xbmc/windows/GUIWindowLoginScreen.cpp
+++ b/xbmc/windows/GUIWindowLoginScreen.cpp
@@ -47,6 +47,7 @@
#include "guilib/LocalizeStrings.h"
#include "addons/AddonManager.h"
#include "view/ViewState.h"
+#include "pvr/PVRManager.h"
#define CONTROL_BIG_LIST 52
#define CONTROL_LABEL_HEADER 2
@@ -141,7 +142,8 @@ bool CGUIWindowLoginScreen::OnAction(const CAction &action)
{
std::string actionName = action.GetName();
StringUtils::ToLower(actionName);
- if (actionName.find("shutdown") != std::string::npos)
+ if ((actionName.find("shutdown") != std::string::npos) &&
+ PVR::g_PVRManager.CanSystemPowerdown())
CBuiltins::Execute(action.GetName());
return true;
}