2 * Copyright (C) 2005-2013 Team XBMC
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
10 * This Program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with XBMC; see the file COPYING. If not, see
17 * <http://www.gnu.org/licenses/>.
22 #include "PowerManager.h"
23 #include "Application.h"
24 #include "cores/AudioEngine/AEFactory.h"
25 #include "input/KeyboardStat.h"
26 #include "settings/Setting.h"
27 #include "settings/Settings.h"
28 #include "windowing/WindowingFactory.h"
29 #include "utils/log.h"
30 #include "utils/Weather.h"
31 #include "interfaces/Builtins.h"
32 #include "interfaces/AnnouncementManager.h"
33 #include "guilib/LocalizeStrings.h"
34 #include "guilib/GraphicContext.h"
35 #include "guilib/GUIWindowManager.h"
36 #include "dialogs/GUIDialogBusy.h"
37 #include "dialogs/GUIDialogKaiToast.h"
39 #if defined(TARGET_DARWIN)
40 #include "osx/CocoaPowerSyscall.h"
41 #elif defined(TARGET_ANDROID)
42 #include "android/AndroidPowerSyscall.h"
43 #elif defined(TARGET_POSIX)
44 #include "linux/FallbackPowerSyscall.h"
46 #include "linux/ConsoleUPowerSyscall.h"
47 #include "linux/ConsoleDeviceKitPowerSyscall.h"
48 #include "linux/LogindUPowerSyscall.h"
49 #include "linux/UPowerSyscall.h"
51 #include "linux/HALPowerSyscall.h"
54 #elif defined(TARGET_WINDOWS)
55 #include "powermanagement/windows/Win32PowerSyscall.h"
59 using namespace ANNOUNCEMENT;
61 CPowerManager g_powerManager;
63 CPowerManager::CPowerManager()
68 CPowerManager::~CPowerManager()
73 void CPowerManager::Initialize()
75 #if defined(TARGET_DARWIN)
76 m_instance = new CCocoaPowerSyscall();
77 #elif defined(TARGET_ANDROID)
78 m_instance = new CAndroidPowerSyscall();
79 #elif defined(TARGET_POSIX)
81 if (CConsoleUPowerSyscall::HasConsoleKitAndUPower())
82 m_instance = new CConsoleUPowerSyscall();
83 else if (CConsoleDeviceKitPowerSyscall::HasDeviceConsoleKit())
84 m_instance = new CConsoleDeviceKitPowerSyscall();
85 else if (CLogindUPowerSyscall::HasLogind())
86 m_instance = new CLogindUPowerSyscall();
87 else if (CUPowerSyscall::HasUPower())
88 m_instance = new CUPowerSyscall();
91 m_instance = new CHALPowerSyscall();
95 m_instance = new CFallbackPowerSyscall();
96 #elif defined(TARGET_WINDOWS)
97 m_instance = new CWin32PowerSyscall();
100 if (m_instance == NULL)
101 m_instance = new CNullPowerSyscall();
104 void CPowerManager::SetDefaults()
106 int defaultShutdown = CSettings::Get().GetInt("powermanagement.shutdownstate");
108 switch (defaultShutdown)
110 case POWERSTATE_QUIT:
111 case POWERSTATE_MINIMIZE:
112 // assume we can shutdown if --standalone is passed
113 if (g_application.IsStandAlone())
114 defaultShutdown = POWERSTATE_SHUTDOWN;
116 case POWERSTATE_HIBERNATE:
117 if (!g_powerManager.CanHibernate())
119 if (g_powerManager.CanSuspend())
120 defaultShutdown = POWERSTATE_SUSPEND;
122 defaultShutdown = g_powerManager.CanPowerdown() ? POWERSTATE_SHUTDOWN : POWERSTATE_QUIT;
125 case POWERSTATE_SUSPEND:
126 if (!g_powerManager.CanSuspend())
128 if (g_powerManager.CanHibernate())
129 defaultShutdown = POWERSTATE_HIBERNATE;
131 defaultShutdown = g_powerManager.CanPowerdown() ? POWERSTATE_SHUTDOWN : POWERSTATE_QUIT;
134 case POWERSTATE_SHUTDOWN:
135 if (!g_powerManager.CanPowerdown())
137 if (g_powerManager.CanSuspend())
138 defaultShutdown = POWERSTATE_SUSPEND;
140 defaultShutdown = g_powerManager.CanHibernate() ? POWERSTATE_HIBERNATE : POWERSTATE_QUIT;
145 ((CSettingInt*)CSettings::Get().GetSetting("powermanagement.shutdownstate"))->SetDefault(defaultShutdown);
148 bool CPowerManager::Powerdown()
150 if (CanPowerdown() && m_instance->Powerdown())
152 CGUIDialogBusy* dialog = (CGUIDialogBusy*)g_windowManager.GetWindow(WINDOW_DIALOG_BUSY);
162 bool CPowerManager::Suspend()
164 if (CanSuspend() && m_instance->Suspend())
166 CGUIDialogBusy* dialog = (CGUIDialogBusy*)g_windowManager.GetWindow(WINDOW_DIALOG_BUSY);
176 bool CPowerManager::Hibernate()
178 if (CanHibernate() && m_instance->Hibernate())
180 CGUIDialogBusy* dialog = (CGUIDialogBusy*)g_windowManager.GetWindow(WINDOW_DIALOG_BUSY);
189 bool CPowerManager::Reboot()
191 bool success = CanReboot() ? m_instance->Reboot() : false;
195 CAnnouncementManager::Announce(System, "xbmc", "OnRestart");
197 CGUIDialogBusy* dialog = (CGUIDialogBusy*)g_windowManager.GetWindow(WINDOW_DIALOG_BUSY);
205 bool CPowerManager::CanPowerdown()
207 return m_instance->CanPowerdown();
209 bool CPowerManager::CanSuspend()
211 return m_instance->CanSuspend();
213 bool CPowerManager::CanHibernate()
215 return m_instance->CanHibernate();
217 bool CPowerManager::CanReboot()
219 return m_instance->CanReboot();
221 int CPowerManager::BatteryLevel()
223 return m_instance->BatteryLevel();
225 void CPowerManager::ProcessEvents()
227 static int nesting = 0;
230 m_instance->PumpPowerEvents(this);
235 void CPowerManager::OnSleep()
237 CAnnouncementManager::Announce(System, "xbmc", "OnSleep");
238 CLog::Log(LOGNOTICE, "%s: Running sleep jobs", __FUNCTION__);
241 #if defined(HAS_LIRC) || defined(HAS_IRSERVERSUITE)
242 CLog::Log(LOGNOTICE, "%s: Stopping lirc", __FUNCTION__);
243 CBuiltins::Execute("LIRC.Stop");
246 g_application.SaveFileState(true);
247 g_application.StopPlaying();
248 g_application.StopShutdownTimer();
249 g_application.StopScreenSaverTimer();
250 g_application.CloseNetworkShares();
251 CAEFactory::Suspend();
254 void CPowerManager::OnWake()
256 CLog::Log(LOGNOTICE, "%s: Running resume jobs", __FUNCTION__);
259 g_application.ResetShutdownTimers();
261 CGUIDialogBusy* dialog = (CGUIDialogBusy*)g_windowManager.GetWindow(WINDOW_DIALOG_BUSY);
265 #if defined(HAS_SDL) || defined(TARGET_WINDOWS)
266 if (g_Windowing.IsFullScreen())
268 #if defined(TARGET_WINDOWS)
269 ShowWindow(g_hWnd,SW_RESTORE);
270 SetForegroundWindow(g_hWnd);
271 #elif !defined(TARGET_DARWIN_OSX)
272 // Hack to reclaim focus, thus rehiding system mouse pointer.
273 // Surely there's a better way?
274 g_graphicsContext.ToggleFullScreenRoot();
275 g_graphicsContext.ToggleFullScreenRoot();
278 g_application.ResetScreenSaver();
282 #if defined(HAS_LIRC) || defined(HAS_IRSERVERSUITE)
283 CLog::Log(LOGNOTICE, "%s: Restarting lirc", __FUNCTION__);
284 CBuiltins::Execute("LIRC.Start");
287 CAEFactory::Resume();
288 g_application.UpdateLibraries();
289 g_weatherManager.Refresh();
291 CAnnouncementManager::Announce(System, "xbmc", "OnWake");
294 void CPowerManager::OnLowBattery()
296 CLog::Log(LOGNOTICE, "%s: Running low battery jobs", __FUNCTION__);
298 CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Warning, g_localizeStrings.Get(13050), "");
300 CAnnouncementManager::Announce(System, "xbmc", "OnLowBattery");
303 void CPowerManager::SettingOptionsShutdownStatesFiller(const CSetting *setting, std::vector< std::pair<std::string, int> > &list, int ¤t)
305 if (g_powerManager.CanPowerdown())
306 list.push_back(make_pair(g_localizeStrings.Get(13005), POWERSTATE_SHUTDOWN));
307 if (g_powerManager.CanHibernate())
308 list.push_back(make_pair(g_localizeStrings.Get(13010), POWERSTATE_HIBERNATE));
309 if (g_powerManager.CanSuspend())
310 list.push_back(make_pair(g_localizeStrings.Get(13011), POWERSTATE_SUSPEND));
311 if (!g_application.IsStandAlone())
313 list.push_back(make_pair(g_localizeStrings.Get(13009), POWERSTATE_QUIT));
314 #if !defined(TARGET_DARWIN_IOS)
315 list.push_back(make_pair(g_localizeStrings.Get(13014), POWERSTATE_MINIMIZE));