From af33791132d2c8177e3ac760773ef1caf70e5e82 Mon Sep 17 00:00:00 2001 From: Sylvain CECCHETTO Date: Tue, 31 Mar 2020 18:07:00 +0200 Subject: [tvOS] Implement PowerManager::OnSleep/OnWake --- cmake/treedata/darwin_embedded/tvos/tvos.txt | 1 + xbmc/platform/darwin/tvos/XBMCController.mm | 96 ++++++---------------- .../darwin/tvos/powermanagement/CMakeLists.txt | 5 ++ .../tvos/powermanagement/TVOSPowerSyscall.cpp | 95 +++++++++++++++++++++ .../darwin/tvos/powermanagement/TVOSPowerSyscall.h | 46 +++++++++++ xbmc/windowing/tvos/WinSystemTVOS.mm | 2 + 6 files changed, 172 insertions(+), 73 deletions(-) create mode 100644 xbmc/platform/darwin/tvos/powermanagement/CMakeLists.txt create mode 100644 xbmc/platform/darwin/tvos/powermanagement/TVOSPowerSyscall.cpp create mode 100644 xbmc/platform/darwin/tvos/powermanagement/TVOSPowerSyscall.h diff --git a/cmake/treedata/darwin_embedded/tvos/tvos.txt b/cmake/treedata/darwin_embedded/tvos/tvos.txt index d8745c02ff..1335e6694f 100755 --- a/cmake/treedata/darwin_embedded/tvos/tvos.txt +++ b/cmake/treedata/darwin_embedded/tvos/tvos.txt @@ -1,4 +1,5 @@ xbmc/platform/darwin/tvos platform/tvos xbmc/platform/darwin/tvos/filesystem platform/darwin/tvos/filesystem xbmc/platform/darwin/tvos/input platform/darwin/tvos/input +xbmc/platform/darwin/tvos/powermanagement platform/darwin/tvos/powermanagement xbmc/windowing/tvos windowing/tvos diff --git a/xbmc/platform/darwin/tvos/XBMCController.mm b/xbmc/platform/darwin/tvos/XBMCController.mm index 900f6f508a..d6381513f7 100644 --- a/xbmc/platform/darwin/tvos/XBMCController.mm +++ b/xbmc/platform/darwin/tvos/XBMCController.mm @@ -21,6 +21,7 @@ #include "network/Network.h" #include "network/NetworkServices.h" #include "platform/xbmc.h" +#include "powermanagement/PowerManager.h" #include "pvr/PVRManager.h" #include "settings/AdvancedSettings.h" #include "settings/SettingsComponent.h" @@ -37,6 +38,7 @@ #import "platform/darwin/tvos/input/LibInputHandler.h" #import "platform/darwin/tvos/input/LibInputRemote.h" #import "platform/darwin/tvos/input/LibInputTouch.h" +#include "platform/darwin/tvos/powermanagement/TVOSPowerSyscall.h" #import #import @@ -193,52 +195,37 @@ XBMCController* g_xbmcController; - (void)enterBackground { + CLog::Log(LOGDEBUG, "%s", __PRETTY_FUNCTION__); + m_bgTask = [self enableBackGroundTask]; m_bgTaskActive = YES; - CLog::Log(LOGNOTICE, "%s: Running sleep jobs", __FUNCTION__); + // We need this hack, without it we stay stuck forever in + // CPowerManager::OnSleep() + // CApplication::StopPlaying() + // CGUIWindowManager::ProcessRenderLoop + if (CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow() == WINDOW_SLIDESHOW || + CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO || + CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow() == WINDOW_FULLSCREEN_GAME || + CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow() == WINDOW_VISUALISATION) + CServiceBroker::GetGUI()->GetWindowManager().PreviousWindow(); - // if we were interrupted, already paused here - // else if user background us or lock screen, only pause video here, audio keep playing. - if (g_application.GetAppPlayer().IsPlayingVideo() && !g_application.GetAppPlayer().IsPaused()) - { - m_isPlayingBeforeInactive = YES; - m_lastUsedPlayer = g_application.GetAppPlayer().GetCurrentPlayer(); - m_playingFileItemBeforeBackground = - std::make_unique(g_application.CurrentFileItem()); - CApplicationMessenger::GetInstance().SendMsg(TMSG_MEDIA_PAUSE_IF_PLAYING); - g_application.CurrentFileItem().m_lStartOffset = g_application.GetAppPlayer().GetTime() - 2.50; - } + CServiceBroker::GetNetwork().GetServices().Stop(true); + + dynamic_cast(CServiceBroker::GetPowerManager().GetPowerSyscall()) + ->SetOnPause(); + CServiceBroker::GetPowerManager().ProcessEvents(); CWinSystemTVOS* winSystem = dynamic_cast(CServiceBroker::GetWinSystem()); winSystem->OnAppFocusChange(false); - // Media was paused, Full background shutdown, so stop now. - // Only do for PVR? leave regular media paused? - if (g_application.GetAppPlayer().IsPaused()) - { - if (CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow() == WINDOW_SLIDESHOW || - CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow() == WINDOW_FULLSCREEN_VIDEO || - CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow() == WINDOW_FULLSCREEN_GAME || - CServiceBroker::GetGUI()->GetWindowManager().GetActiveWindow() == WINDOW_VISUALISATION) - CServiceBroker::GetGUI()->GetWindowManager().PreviousWindow(); - - g_application.StopPlaying(); - } - - CServiceBroker::GetPVRManager().OnSleep(); - CServiceBroker::GetActiveAE()->Suspend(); - CServiceBroker::GetNetwork().GetServices().Stop(true); - - // if (!m_isPlayingBeforeInactive) - g_application.CloseNetworkShares(); - m_bgTaskActive = NO; [self disableBackGroundTask:m_bgTask]; } - (void)enterForeground { + CLog::Log(LOGDEBUG, "%s", __PRETTY_FUNCTION__); // stop background task (if running) if (m_bgTaskActive) { @@ -268,50 +255,13 @@ XBMCController* g_xbmcController; while (!g_application.IsInitialized()) usleep(50 * 1000); - CServiceBroker::GetNetwork().WaitForNet(); - CServiceBroker::GetNetwork().GetServices().Start(); - - if (CServiceBroker::GetActiveAE()) - if (CServiceBroker::GetActiveAE()->IsSuspended()) - CServiceBroker::GetActiveAE()->Resume(); - - CServiceBroker::GetPVRManager().OnWake(); - CWinSystemTVOS* winSystem = dynamic_cast(CServiceBroker::GetWinSystem()); winSystem->OnAppFocusChange(true); - // when we come back, restore playing if we were. - if (m_isPlayingBeforeInactive) - { - if (m_playingFileItemBeforeBackground->IsLiveTV()) - { - CLog::Log(LOGDEBUG, "%s: Live TV was playing before suspend. Restart channel", - __PRETTY_FUNCTION__); - // Restart player with lastused FileItem - g_application.PlayFile(*m_playingFileItemBeforeBackground, m_lastUsedPlayer, true); - } - else - { - if (g_application.GetAppPlayer().IsPaused() && g_application.GetAppPlayer().HasPlayer()) - { - CApplicationMessenger::GetInstance().SendMsg(TMSG_MEDIA_UNPAUSE); - } - else - { - g_application.PlayFile(*m_playingFileItemBeforeBackground, m_lastUsedPlayer, true); - } - } - m_playingFileItemBeforeBackground = std::make_unique(); - m_lastUsedPlayer = ""; - m_isPlayingBeforeInactive = NO; - } - - // do not update if we are already updating - if (!(g_application.IsVideoScanning() || g_application.IsMusicScanning())) - g_application.UpdateLibraries(); - - // this will fire only if we are already alive and have 'menu'ed out and back - CServiceBroker::GetAnnouncementManager()->Announce(ANNOUNCEMENT::System, "xbmc", "OnWake"); + dynamic_cast(CServiceBroker::GetPowerManager().GetPowerSyscall()) + ->SetOnResume(); + CServiceBroker::GetPowerManager().ProcessEvents(); + CServiceBroker::GetNetwork().GetServices().Start(); // this handles what to do if we got pushed // into foreground by a topshelf item select/play diff --git a/xbmc/platform/darwin/tvos/powermanagement/CMakeLists.txt b/xbmc/platform/darwin/tvos/powermanagement/CMakeLists.txt new file mode 100644 index 0000000000..77a4fad56b --- /dev/null +++ b/xbmc/platform/darwin/tvos/powermanagement/CMakeLists.txt @@ -0,0 +1,5 @@ +set(SOURCES TVOSPowerSyscall.cpp) + +set(HEADERS TVOSPowerSyscall.h) + +core_add_library(platform_tvos_powermanagement) \ No newline at end of file diff --git a/xbmc/platform/darwin/tvos/powermanagement/TVOSPowerSyscall.cpp b/xbmc/platform/darwin/tvos/powermanagement/TVOSPowerSyscall.cpp new file mode 100644 index 0000000000..88785acb4a --- /dev/null +++ b/xbmc/platform/darwin/tvos/powermanagement/TVOSPowerSyscall.cpp @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2012-2020 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "TVOSPowerSyscall.h" + +#include "utils/log.h" + +IPowerSyscall* CTVOSPowerSyscall::CreateInstance() +{ + return new CTVOSPowerSyscall; +} + +void CTVOSPowerSyscall::Register() +{ + IPowerSyscall::RegisterPowerSyscall(CTVOSPowerSyscall::CreateInstance); +} + +bool CTVOSPowerSyscall::Powerdown() +{ + return false; +} + +bool CTVOSPowerSyscall::Suspend() +{ + return false; +} + +bool CTVOSPowerSyscall::Hibernate() +{ + return false; +} + +bool CTVOSPowerSyscall::Reboot() +{ + return false; +} + +bool CTVOSPowerSyscall::CanPowerdown() +{ + return false; +} + +bool CTVOSPowerSyscall::CanSuspend() +{ + return false; +} + +bool CTVOSPowerSyscall::CanHibernate() +{ + return false; +} + +bool CTVOSPowerSyscall::CanReboot() +{ + return false; +} + +int CTVOSPowerSyscall::BatteryLevel() +{ + return 0; +} + +bool CTVOSPowerSyscall::PumpPowerEvents(IPowerEventsCallback* callback) +{ + switch (m_state) + { + case SUSPENDED: + callback->OnSleep(); + CLog::Log(LOGDEBUG, "%s: OnSleep called", __FUNCTION__); + break; + case RESUMED: + callback->OnWake(); + CLog::Log(LOGDEBUG, "%s: OnWake called", __FUNCTION__); + break; + default: + return false; + } + m_state = REPORTED; + return true; +} + +void CTVOSPowerSyscall::SetOnPause() +{ + m_state = SUSPENDED; +} + +void CTVOSPowerSyscall::SetOnResume() +{ + m_state = RESUMED; +} \ No newline at end of file diff --git a/xbmc/platform/darwin/tvos/powermanagement/TVOSPowerSyscall.h b/xbmc/platform/darwin/tvos/powermanagement/TVOSPowerSyscall.h new file mode 100644 index 0000000000..b8272dd195 --- /dev/null +++ b/xbmc/platform/darwin/tvos/powermanagement/TVOSPowerSyscall.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2012-2020 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#pragma once + +#include "powermanagement/IPowerSyscall.h" + +class CTVOSPowerSyscall : public CPowerSyscallWithoutEvents +{ +public: + CTVOSPowerSyscall() = default; + ~CTVOSPowerSyscall() override = default; + + static IPowerSyscall* CreateInstance(); + static void Register(); + + bool Powerdown() override; + bool Suspend() override; + bool Hibernate() override; + bool Reboot() override; + + bool CanPowerdown() override; + bool CanSuspend() override; + bool CanHibernate() override; + bool CanReboot() override; + int BatteryLevel() override; + + bool PumpPowerEvents(IPowerEventsCallback* callback) override; + + void SetOnPause(); + void SetOnResume(); + +private: + enum STATE : unsigned int + { + REPORTED = 0, + SUSPENDED = 1, + RESUMED = 2, + }; + STATE m_state = REPORTED; +}; \ No newline at end of file diff --git a/xbmc/windowing/tvos/WinSystemTVOS.mm b/xbmc/windowing/tvos/WinSystemTVOS.mm index 8c2fe096e6..9cbc8d71f0 100644 --- a/xbmc/windowing/tvos/WinSystemTVOS.mm +++ b/xbmc/windowing/tvos/WinSystemTVOS.mm @@ -36,6 +36,7 @@ #import "platform/darwin/DarwinUtils.h" #import "platform/darwin/tvos/TVOSDisplayManager.h" #import "platform/darwin/tvos/XBMCController.h" +#include "platform/darwin/tvos/powermanagement/TVOSPowerSyscall.h" #include #include @@ -135,6 +136,7 @@ CWinSystemTVOS::CWinSystemTVOS() : CWinSystemBase(), m_lostDeviceTimer(this) m_winEvents.reset(new CWinEventsTVOS()); CAESinkDARWINTVOS::Register(); + CTVOSPowerSyscall::Register(); } CWinSystemTVOS::~CWinSystemTVOS() -- cgit v1.2.3