1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
|
/*
* Copyright (C) 2005-2018 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 "application/ApplicationComponents.h"
#include "application/ApplicationEnums.h"
#include "application/ApplicationPlayerCallback.h"
#include "application/ApplicationSettingsHandling.h"
#include "guilib/IMsgTargetCallback.h"
#include "guilib/IWindowManagerCallback.h"
#include "messaging/IMessageTarget.h"
#include "playlists/PlayListTypes.h"
#include "threads/SystemClock.h"
#include "utils/GlobalsHandling.h"
#include "utils/Stopwatch.h"
#include "windowing/Resolution.h"
#include "windowing/XBMC_events.h"
#include <atomic>
#include <chrono>
#include <deque>
#include <memory>
#include <string>
#include <vector>
class CAction;
class CAppInboundProtocol;
class CBookmark;
class CFileItem;
class CFileItemList;
class CGUIComponent;
class CInertialScrollingHandler;
class CKey;
class CSeekHandler;
class CServiceManager;
class CSettingsComponent;
class CSplash;
class CWinSystemBase;
namespace ADDON
{
class CSkinInfo;
class IAddon;
typedef std::shared_ptr<IAddon> AddonPtr;
class CAddonInfo;
}
namespace ANNOUNCEMENT
{
class CAnnouncementManager;
}
namespace MEDIA_DETECT
{
class CAutorun;
}
namespace PLAYLIST
{
class CPlayList;
}
namespace ActiveAE
{
class CActiveAE;
}
namespace VIDEO
{
class CVideoInfoScanner;
}
namespace MUSIC_INFO
{
class CMusicInfoScanner;
}
class CApplication : public IWindowManagerCallback,
public IMsgTargetCallback,
public KODI::MESSAGING::IMessageTarget,
public CApplicationComponents,
public CApplicationPlayerCallback,
public CApplicationSettingsHandling
{
friend class CAppInboundProtocol;
public:
// If playback time of current item is greater than this value, ACTION_PREV_ITEM will seek to start
// of currently playing item, otherwise it will seek to start of the previous item in playlist
static const unsigned int ACTION_PREV_ITEM_THRESHOLD = 3; // seconds;
CApplication(void);
~CApplication(void) override;
bool Create();
bool Initialize();
int Run();
bool Cleanup();
void FrameMove(bool processEvents, bool processGUI = true) override;
void Render() override;
bool IsInitialized() const { return !m_bInitializing; }
bool IsStopping() const { return m_bStop; }
bool CreateGUI();
bool InitWindow(RESOLUTION res = RES_INVALID);
bool Stop(int exitCode);
const std::string& CurrentFile();
CFileItem& CurrentFileItem();
std::shared_ptr<CFileItem> CurrentFileItemPtr();
const CFileItem& CurrentUnstackedItem();
bool OnMessage(CGUIMessage& message) override;
std::string GetCurrentPlayer();
int GetMessageMask() override;
void OnApplicationMessage(KODI::MESSAGING::ThreadMessage* pMsg) override;
bool PlayMedia(CFileItem& item, const std::string& player, PLAYLIST::Id playlistId);
bool ProcessAndStartPlaylist(const std::string& strPlayList,
PLAYLIST::CPlayList& playlist,
PLAYLIST::Id playlistId,
int track = 0);
bool PlayFile(CFileItem item, const std::string& player, bool bRestart = false);
void StopPlaying();
void Restart(bool bSamePosition = true);
void DelayedPlayerRestart();
void CheckDelayedPlayerRestart();
bool IsPlayingFullScreenVideo() const;
bool IsFullScreen();
bool OnAction(const CAction &action);
void CloseNetworkShares();
void ConfigureAndEnableAddons();
void ShowAppMigrationMessage();
void Process() override;
void ProcessSlow();
/*!
\brief Returns the total time in fractional seconds of the currently playing media
Beware that this method returns fractional seconds whereas IPlayer::GetTotalTime() returns milliseconds.
*/
double GetTotalTime() const;
/*!
\brief Returns the current time in fractional seconds of the currently playing media
Beware that this method returns fractional seconds whereas IPlayer::GetTime() returns milliseconds.
*/
double GetTime() const;
float GetPercentage() const;
// Get the percentage of data currently cached/buffered (aq/vq + FileCache) from the input stream if applicable.
float GetCachePercentage() const;
void SeekPercentage(float percent);
void SeekTime( double dTime = 0.0 );
void UpdateLibraries();
void UpdateCurrentPlayArt();
bool ExecuteXBMCAction(std::string action, const CGUIListItemPtr &item = NULL);
#ifdef HAS_DVD_DRIVE
std::unique_ptr<MEDIA_DETECT::CAutorun> m_Autorun;
#endif
std::string m_strPlayListFile;
bool IsAppFocused() const { return m_AppFocused; }
bool GetRenderGUI() const override;
bool SetLanguage(const std::string &strLanguage);
bool LoadLanguage(bool reload);
void SetLoggingIn(bool switchingProfiles);
std::unique_ptr<CServiceManager> m_ServiceManager;
/*!
\brief Locks calls from outside kodi (e.g. python) until framemove is processed.
*/
void LockFrameMoveGuard();
/*!
\brief Unlocks calls from outside kodi (e.g. python).
*/
void UnlockFrameMoveGuard();
protected:
bool OnSettingsSaving() const override;
void PlaybackCleanup();
// inbound protocol
bool OnEvent(XBMC_Event& newEvent);
std::shared_ptr<ANNOUNCEMENT::CAnnouncementManager> m_pAnnouncementManager;
std::unique_ptr<CGUIComponent> m_pGUI;
std::unique_ptr<CWinSystemBase> m_pWinSystem;
std::unique_ptr<ActiveAE::CActiveAE> m_pActiveAE;
std::shared_ptr<CAppInboundProtocol> m_pAppPort;
std::deque<XBMC_Event> m_portEvents;
CCriticalSection m_portSection;
// timer information
CStopWatch m_restartPlayerTimer;
CStopWatch m_frameTime;
CStopWatch m_slowTimer;
XbmcThreads::EndTime<> m_guiRefreshTimer;
std::string m_prevMedia;
bool m_bInitializing = true;
int m_nextPlaylistItem = -1;
std::chrono::time_point<std::chrono::steady_clock> m_lastRenderTime;
bool m_skipGuiRender = false;
std::unique_ptr<MUSIC_INFO::CMusicInfoScanner> m_musicInfoScanner;
bool PlayStack(CFileItem& item, bool bRestart);
void HandlePortEvents();
std::unique_ptr<CInertialScrollingHandler> m_pInertialScrollingHandler;
std::vector<std::shared_ptr<ADDON::CAddonInfo>>
m_incompatibleAddons; /*!< Result of addon migration (incompatible addon infos) */
public:
bool m_bStop{false};
bool m_AppFocused{true};
private:
void PrintStartupLog();
void ResetCurrentItem();
mutable CCriticalSection m_critSection; /*!< critical section for all changes to this class, except for changes to triggers */
CCriticalSection m_frameMoveGuard; /*!< critical section for synchronizing GUI actions from inside and outside (python) */
std::atomic_uint m_WaitingExternalCalls; /*!< counts threads which are waiting to be processed in FrameMove */
unsigned int m_ProcessedExternalCalls = 0; /*!< counts calls which are processed during one "door open" cycle in FrameMove */
unsigned int m_ProcessedExternalDecay = 0; /*!< counts to close door after a few frames of no python activity */
int m_ExitCode{EXITCODE_QUIT};
};
XBMC_GLOBAL_REF(CApplication,g_application);
#define g_application XBMC_GLOBAL_USE(CApplication)
|