[Test] Added tests for CUtil::SplitParams
[xbmc.git] / xbmc / windowing / android / WinSystemAndroid.cpp
blobf5b92b136b1df7e563f678ba8870331ab642e741
1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include "WinSystemAndroid.h"
11 #include "OSScreenSaverAndroid.h"
12 #include "ServiceBroker.h"
13 #include "WinEventsAndroid.h"
14 #include "addons/interfaces/platform/android/System.h"
15 #include "cores/RetroPlayer/process/android/RPProcessInfoAndroid.h"
16 #include "cores/RetroPlayer/rendering/VideoRenderers/RPRendererOpenGLES.h"
17 #include "cores/VideoPlayer/DVDCodecs/Audio/DVDAudioCodecAndroidMediaCodec.h"
18 #include "cores/VideoPlayer/DVDCodecs/Video/DVDVideoCodecAndroidMediaCodec.h"
19 #include "cores/VideoPlayer/Process/android/ProcessInfoAndroid.h"
20 #include "cores/VideoPlayer/VideoRenderers/HwDecRender/RendererMediaCodec.h"
21 #include "cores/VideoPlayer/VideoRenderers/HwDecRender/RendererMediaCodecSurface.h"
22 #include "guilib/DispResource.h"
23 #include "rendering/gles/ScreenshotSurfaceGLES.h"
24 #include "settings/DisplaySettings.h"
25 #include "settings/Settings.h"
26 #include "settings/SettingsComponent.h"
27 #include "utils/HDRCapabilities.h"
28 #include "utils/log.h"
29 #include "windowing/GraphicContext.h"
30 #include "windowing/Resolution.h"
32 #include "platform/android/activity/XBMCApp.h"
33 #include "platform/android/media/decoderfilter/MediaCodecDecoderFilterManager.h"
34 #include "platform/android/media/drm/MediaDrmCryptoSession.h"
36 #include <float.h>
37 #include <memory>
38 #include <mutex>
39 #include <string.h>
41 #include "system_egl.h"
43 #include <EGL/eglplatform.h>
45 using namespace KODI;
46 using namespace std::chrono_literals;
48 CWinSystemAndroid::CWinSystemAndroid()
50 m_displayWidth = 0;
51 m_displayHeight = 0;
53 m_stereo_mode = RENDER_STEREO_MODE_OFF;
55 m_dispResetTimer = new CTimer(this);
57 m_android = nullptr;
59 m_winEvents = std::make_unique<CWinEventsAndroid>();
62 CWinSystemAndroid::~CWinSystemAndroid()
64 delete m_dispResetTimer;
67 bool CWinSystemAndroid::InitWindowSystem()
69 m_nativeDisplay = EGL_DEFAULT_DISPLAY;
71 m_android = new CAndroidUtils();
73 m_decoderFilterManager = new(CMediaCodecDecoderFilterManager);
74 CServiceBroker::RegisterDecoderFilterManager(m_decoderFilterManager);
76 CDVDVideoCodecAndroidMediaCodec::Register();
77 CDVDAudioCodecAndroidMediaCodec::Register();
79 CLinuxRendererGLES::Register();
80 RETRO::CRPProcessInfoAndroid::Register();
81 RETRO::CRPProcessInfoAndroid::RegisterRendererFactory(new RETRO::CRendererFactoryOpenGLES);
82 CRendererMediaCodec::Register();
83 CRendererMediaCodecSurface::Register();
84 ADDON::Interface_Android::Register();
85 DRM::CMediaDrmCryptoSession::Register();
86 VIDEOPLAYER::CProcessInfoAndroid::Register();
88 CScreenshotSurfaceGLES::Register();
90 return CWinSystemBase::InitWindowSystem();
93 bool CWinSystemAndroid::DestroyWindowSystem()
95 CLog::Log(LOGINFO, "CWinSystemAndroid::{}", __FUNCTION__);
97 delete m_android;
98 m_android = nullptr;
100 CServiceBroker::RegisterDecoderFilterManager(nullptr);
101 delete m_decoderFilterManager;
102 m_decoderFilterManager = nullptr;
104 return true;
107 bool CWinSystemAndroid::CreateNewWindow(const std::string& name,
108 bool fullScreen,
109 RESOLUTION_INFO& res)
111 m_nWidth = res.iWidth;
112 m_nHeight = res.iHeight;
113 m_displayWidth = res.iScreenWidth;
114 m_displayHeight = res.iScreenHeight;
115 m_fRefreshRate = res.fRefreshRate;
117 m_dispResetTimer->Stop();
118 m_HdmiModeTriggered = false;
120 m_stereo_mode = CServiceBroker::GetWinSystem()->GetGfxContext().GetStereoMode();
121 m_bFullScreen = fullScreen;
123 m_nativeWindow = CXBMCApp::Get().GetNativeWindow(2000);
124 if (!m_nativeWindow)
126 CLog::Log(LOGERROR, "CWinSystemAndroid::CreateNewWindow: failed");
127 return false;
130 m_android->SetNativeResolution(res);
132 m_bWindowCreated = true;
133 return true;
136 bool CWinSystemAndroid::DestroyWindow()
138 CLog::Log(LOGINFO, "CWinSystemAndroid::{}", __FUNCTION__);
139 m_nativeWindow.reset();
140 m_bWindowCreated = false;
141 return true;
144 void CWinSystemAndroid::UpdateResolutions()
146 UpdateResolutions(true);
149 void CWinSystemAndroid::UpdateResolutions(bool bUpdateDesktopRes)
151 CWinSystemBase::UpdateResolutions();
153 std::vector<RESOLUTION_INFO> resolutions;
154 if (!m_android->ProbeResolutions(resolutions) || resolutions.empty())
156 CLog::Log(LOGWARNING, "CWinSystemAndroid::{} failed.", __FUNCTION__);
159 const RESOLUTION_INFO resWindow = CDisplaySettings::GetInstance().GetResolutionInfo(RES_WINDOW);
161 RESOLUTION_INFO resDesktop;
162 if (bUpdateDesktopRes)
164 // ProbeResolutions includes already all resolutions.
165 // Only get desktop resolution so we can replace Kodi's desktop res.
166 RESOLUTION_INFO curDisplay;
167 if (m_android->GetNativeResolution(&curDisplay))
168 resDesktop = curDisplay;
170 else
172 // Do not replace Kodi's desktop res, just update the data.
173 resDesktop = CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP);
176 CDisplaySettings::GetInstance().ClearCustomResolutions();
178 for (auto& res : resolutions)
180 CServiceBroker::GetWinSystem()->GetGfxContext().ResetOverscan(res);
181 CDisplaySettings::GetInstance().AddResolutionInfo(res);
183 if (resDesktop.iScreenWidth == res.iScreenWidth &&
184 resDesktop.iScreenHeight == res.iScreenHeight &&
185 (resDesktop.dwFlags & D3DPRESENTFLAG_MODEMASK) == (res.dwFlags & D3DPRESENTFLAG_MODEMASK) &&
186 std::fabs(resDesktop.fRefreshRate - res.fRefreshRate) < FLT_EPSILON)
188 CDisplaySettings::GetInstance().GetResolutionInfo(RES_DESKTOP) = res;
191 if (resWindow.iScreenWidth == res.iScreenWidth &&
192 resWindow.iScreenHeight == res.iScreenHeight &&
193 (resWindow.dwFlags & D3DPRESENTFLAG_MODEMASK) == (res.dwFlags & D3DPRESENTFLAG_MODEMASK) &&
194 std::fabs(resWindow.fRefreshRate - res.fRefreshRate) < FLT_EPSILON)
196 CDisplaySettings::GetInstance().GetResolutionInfo(RES_WINDOW) = res;
200 CDisplaySettings::GetInstance().ApplyCalibrations();
203 void CWinSystemAndroid::OnTimeout()
205 m_HdmiModeTriggered = true;
208 void CWinSystemAndroid::InitiateModeChange()
210 auto delay =
211 std::chrono::milliseconds(CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(
212 "videoscreen.delayrefreshchange") *
213 100);
215 if (delay < 2000ms)
216 delay = 2000ms;
217 m_dispResetTimer->Stop();
218 m_dispResetTimer->Start(delay);
220 SetHdmiState(false);
223 void CWinSystemAndroid::SetHdmiState(bool connected)
225 std::unique_lock<CCriticalSection> lock(m_resourceSection);
226 CLog::Log(LOGDEBUG, "CWinSystemAndroid::SetHdmiState: state: {}", static_cast<int>(connected));
228 if (connected)
230 if (m_dispResetTimer->IsRunning())
232 // We stop the timer if OS supports HDMI_AUDIO_PLUG intent
233 // and configured delay is smaller than the time HDMI_PLUG took.
234 // Note that timer is always started with minimum of 2 seconds
235 // regardless if the configured delay is smaller
236 if (m_dispResetTimer->GetElapsedMilliseconds() >=
237 CServiceBroker::GetSettingsComponent()->GetSettings()->GetInt(
238 "videoscreen.delayrefreshchange") *
239 100)
240 m_dispResetTimer->Stop();
241 else
242 return;
245 for (auto resource : m_resources)
246 resource->OnResetDisplay();
247 m_dispResetTimer->Stop();
248 m_HdmiModeTriggered = false;
250 else
252 for (auto resource : m_resources)
253 resource->OnLostDisplay();
257 void CWinSystemAndroid::UpdateDisplayModes()
259 // re-fetch display modes
260 m_android->UpdateDisplayModes();
262 if (m_nativeWindow)
264 // update display settings
265 UpdateResolutions(false);
269 bool CWinSystemAndroid::Minimize()
271 return CXBMCApp::Get().moveTaskToBack(true);
274 bool CWinSystemAndroid::Hide()
276 return false;
279 bool CWinSystemAndroid::Show(bool raise)
281 return false;
284 void CWinSystemAndroid::Register(IDispResource *resource)
286 std::unique_lock<CCriticalSection> lock(m_resourceSection);
287 m_resources.push_back(resource);
290 void CWinSystemAndroid::Unregister(IDispResource *resource)
292 std::unique_lock<CCriticalSection> lock(m_resourceSection);
293 std::vector<IDispResource*>::iterator i = find(m_resources.begin(), m_resources.end(), resource);
294 if (i != m_resources.end())
295 m_resources.erase(i);
298 void CWinSystemAndroid::MessagePush(XBMC_Event *newEvent)
300 dynamic_cast<CWinEventsAndroid&>(*m_winEvents).MessagePush(newEvent);
303 bool CWinSystemAndroid::MessagePump()
305 return m_winEvents->MessagePump();
308 bool CWinSystemAndroid::IsHDRDisplay()
310 return m_android->IsHDRDisplay();
313 std::unique_ptr<WINDOWING::IOSScreenSaver> CWinSystemAndroid::GetOSScreenSaverImpl()
315 std::unique_ptr<KODI::WINDOWING::IOSScreenSaver> ret(new COSScreenSaverAndroid());
316 return ret;
319 CHDRCapabilities CWinSystemAndroid::GetDisplayHDRCapabilities() const
321 return CAndroidUtils::GetDisplayHDRCapabilities();
324 float CWinSystemAndroid::GetGuiSdrPeakLuminance() const
326 const auto settings = CServiceBroker::GetSettingsComponent()->GetSettings();
327 const int guiSdrPeak = settings->GetInt(CSettings::SETTING_VIDEOSCREEN_GUISDRPEAKLUMINANCE);
329 return ((0.7f * guiSdrPeak + 30.0f) / 100.0f);