1 /*
2  *  Copyright (C) 2012-2018 Team Kodi
3  *  This file is part of Kodi - https://kodi.tv
4  *
5  *  SPDX-License-Identifier: GPL-2.0-or-later
6  *  See LICENSES/README.md for more information.
7  */
8 
9 #pragma once
10 
11 #include "IActivityHandler.h"
12 #include "IInputHandler.h"
13 #include "JNIMainActivity.h"
14 #include "JNIXBMCAudioManagerOnAudioFocusChangeListener.h"
15 #include "JNIXBMCDisplayManagerDisplayListener.h"
16 #include "JNIXBMCMainView.h"
17 #include "JNIXBMCMediaSession.h"
18 #include "interfaces/IAnnouncer.h"
19 #include "platform/xbmc.h"
20 #include "threads/Event.h"
21 #include "utils/Geometry.h"
22 
23 #include <map>
24 #include <math.h>
25 #include <memory>
26 #include <string>
27 #include <vector>
28 
29 #include <android/native_activity.h>
30 #include <androidjni/Activity.h>
31 #include <androidjni/AudioManager.h>
32 #include <androidjni/BroadcastReceiver.h>
33 #include <androidjni/SurfaceHolder.h>
34 #include <androidjni/View.h>
35 #include <pthread.h>
36 
37 // forward declares
38 class CJNIWakeLock;
39 class CAESinkAUDIOTRACK;
40 class CVariant;
41 class IInputDeviceCallbacks;
42 class IInputDeviceEventHandler;
43 class CVideoSyncAndroid;
44 class CJNIActivityManager;
45 
46 typedef struct _JNIEnv JNIEnv;
47 
48 struct androidIcon
49 {
50   unsigned int width;
51   unsigned int height;
52   void *pixels;
53 };
54 
55 struct androidPackage
56 {
57   std::string packageName;
58   std::string packageLabel;
59   int icon;
60 };
61 
62 class CActivityResultEvent : public CEvent
63 {
64 public:
CActivityResultEvent(int requestcode)65   explicit CActivityResultEvent(int requestcode)
66     : m_requestcode(requestcode), m_resultcode(0)
67   {}
GetRequestCode()68   int GetRequestCode() const { return m_requestcode; }
GetResultCode()69   int GetResultCode() const { return m_resultcode; }
SetResultCode(int resultcode)70   void SetResultCode(int resultcode) { m_resultcode = resultcode; }
GetResultData()71   CJNIIntent GetResultData() const { return m_resultdata; }
SetResultData(const CJNIIntent & resultdata)72   void SetResultData(const CJNIIntent &resultdata) { m_resultdata = resultdata; }
73 
74 protected:
75   int m_requestcode;
76   CJNIIntent m_resultdata;
77   int m_resultcode;
78 };
79 
80 class CXBMCApp
81     : public IActivityHandler
82     , public CJNIMainActivity
83     , public CJNIBroadcastReceiver
84     , public ANNOUNCEMENT::IAnnouncer
85     , public CJNISurfaceHolderCallback
86 {
87 public:
88   explicit CXBMCApp(ANativeActivity* nativeActivity, IInputHandler& inputhandler);
89   ~CXBMCApp() override;
get()90   static CXBMCApp* get() { return m_xbmcappinstance; }
91 
92   // IAnnouncer IF
93   void Announce(ANNOUNCEMENT::AnnouncementFlag flag,
94                 const std::string& sender,
95                 const std::string& message,
96                 const CVariant& data) override;
97 
98   void onReceive(CJNIIntent intent) override;
99   void onNewIntent(CJNIIntent intent) override;
100   void onActivityResult(int requestCode, int resultCode, CJNIIntent resultData) override;
101   void onVolumeChanged(int volume) override;
102   virtual void onAudioFocusChange(int focusChange);
103   void doFrame(int64_t frameTimeNanos) override;
104   void onVisibleBehindCanceled() override;
105 
106   // implementation of CJNIInputManagerInputDeviceListener
107   void onInputDeviceAdded(int deviceId) override;
108   void onInputDeviceChanged(int deviceId) override;
109   void onInputDeviceRemoved(int deviceId) override;
110 
111   // implementation of DisplayManager::DisplayListener
112   void onDisplayAdded(int displayId) override;
113   void onDisplayChanged(int displayId) override;
114   void onDisplayRemoved(int displayId) override;
getDisplayListener()115   jni::jhobject getDisplayListener() { return m_displayListener.get_raw(); }
116 
isValid()117   bool isValid() { return m_activity != NULL; }
getActivity()118   const ANativeActivity *getActivity() const { return m_activity; }
119 
120   void onStart() override;
121   void onResume() override;
122   void onPause() override;
123   void onStop() override;
124   void onDestroy() override;
125 
126   void onSaveState(void **data, size_t *size) override;
127   void onConfigurationChanged() override;
128   void onLowMemory() override;
129 
130   void onCreateWindow(ANativeWindow* window) override;
131   void onResizeWindow() override;
132   void onDestroyWindow() override;
133   void onGainFocus() override;
134   void onLostFocus() override;
135 
136   void Initialize();
137   void Deinitialize();
138 
139   static ANativeWindow* GetNativeWindow(int timeout);
140   static int SetBuffersGeometry(int width, int height, int format);
141   static int android_printf(const char *format, ...);
142 
143   static int GetBatteryLevel();
144   static bool EnableWakeLock(bool on);
HasFocus()145   static bool HasFocus() { return m_hasFocus; }
146   static bool IsHeadsetPlugged();
147   static bool IsHDMIPlugged();
148 
149   static bool StartActivity(const std::string &package, const std::string &intent = std::string(), const std::string &dataType = std::string(), const std::string &dataURI = std::string());
150   static std::vector <androidPackage> GetApplications();
151 
152   /*!
153    * \brief If external storage is available, it returns the path for the external storage (for the specified type)
154    * \param path will contain the path of the external storage (for the specified type)
155    * \param type optional type. Possible values are "", "files", "music", "videos", "pictures", "photos, "downloads"
156    * \return true if external storage is available and a valid path has been stored in the path parameter
157    */
158   static bool GetExternalStorage(std::string &path, const std::string &type = "");
159   static bool GetStorageUsage(const std::string &path, std::string &usage);
160   static int GetMaxSystemVolume();
161   static float GetSystemVolume();
162   static void SetSystemVolume(float percent);
163 
164   static void SetRefreshRate(float rate);
165   static void SetDisplayMode(int mode, float rate);
166   static int GetDPI();
167 
168   static CRect MapRenderToDroid(const CRect& srcRect);
169   static int WaitForActivityResult(const CJNIIntent &intent, int requestCode, CJNIIntent& result);
170 
171   // Playback callbacks
172   void OnPlayBackStarted();
173   void OnPlayBackPaused();
174   void OnPlayBackStopped();
175 
176   // Info callback
177   void UpdateSessionMetadata();
178   void UpdateSessionState();
179 
180   // input device methods
181   static void RegisterInputDeviceCallbacks(IInputDeviceCallbacks* handler);
182   static void UnregisterInputDeviceCallbacks();
183   static const CJNIViewInputDevice GetInputDevice(int deviceId);
184   static std::vector<int> GetInputDeviceIds();
185 
186   static void RegisterInputDeviceEventHandler(IInputDeviceEventHandler* handler);
187   static void UnregisterInputDeviceEventHandler();
188   static bool onInputDeviceEvent(const AInputEvent* event);
189 
190   static void InitFrameCallback(CVideoSyncAndroid *syncImpl);
191   static void DeinitFrameCallback();
192 
193   // Application slow ping
194   void ProcessSlow();
195 
196   static bool WaitVSync(unsigned int milliSeconds);
197   static int64_t GetNextFrameTime();
198   static float GetFrameLatencyMs();
199 
200   bool getVideosurfaceInUse();
201   void setVideosurfaceInUse(bool videosurfaceInUse);
202 
203   bool GetMemoryInfo(long& availMem, long& totalMem);
204 protected:
205   // limit who can access Volume
206   friend class CAESinkAUDIOTRACK;
207 
208   static int GetMaxSystemVolume(JNIEnv *env);
209   bool AcquireAudioFocus();
210   bool ReleaseAudioFocus();
211   static void RequestVisibleBehind(bool requested);
212 
213 private:
214   static CXBMCApp* m_xbmcappinstance;
215   CJNIXBMCAudioManagerOnAudioFocusChangeListener m_audioFocusListener;
216   CJNIXBMCDisplayManagerDisplayListener m_displayListener;
217   static std::unique_ptr<CJNIXBMCMainView> m_mainView;
218   std::unique_ptr<jni::CJNIXBMCMediaSession> m_mediaSession;
219   static bool HasLaunchIntent(const std::string &package);
220   std::string GetFilenameFromIntent(const CJNIIntent &intent);
221 
222   void run();
223   void stop();
224   void SetupEnv();
225   static void SetRefreshRateCallback(CVariant *rate);
226   static void SetDisplayModeCallback(CVariant *mode);
227   static void RegisterDisplayListener(CVariant*);
228 
229   static ANativeActivity *m_activity;
230   IInputHandler& m_inputHandler;
231   static CJNIWakeLock *m_wakeLock;
232   static int m_batteryLevel;
233   static bool m_hasFocus;
234   static bool m_headsetPlugged;
235   static bool m_hdmiPlugged;
236   static bool m_hdmiReportedState;
237   static bool m_hdmiSource;
238   static IInputDeviceCallbacks* m_inputDeviceCallbacks;
239   static IInputDeviceEventHandler* m_inputDeviceEventHandler;
240   static bool m_hasReqVisible;
241   bool m_videosurfaceInUse;
242   bool m_firstrun;
243   bool m_exiting;
244   bool m_bResumePlayback = false;
245   pthread_t m_thread;
246   static CCriticalSection m_applicationsMutex;
247   static CCriticalSection m_activityResultMutex;
248   static std::vector<androidPackage> m_applications;
249   static std::vector<CActivityResultEvent*> m_activityResultEvents;
250 
251   static ANativeWindow* m_window;
252 
253   static CVideoSyncAndroid* m_syncImpl;
254   static CEvent m_vsyncEvent;
255   static CEvent m_displayChangeEvent;
256 
257   std::unique_ptr<CJNIActivityManager> m_activityManager;
258 
259   void XBMC_Pause(bool pause);
260   void XBMC_Stop();
261   bool XBMC_DestroyDisplay();
262   bool XBMC_SetupDisplay();
263 
264   static uint32_t m_playback_state;
265   static int64_t m_frameTimeNanos;
266   static float m_refreshRate;
267 
268 public:
269   // CJNISurfaceHolderCallback interface
270   void surfaceChanged(CJNISurfaceHolder holder, int format, int width, int height) override;
271   void surfaceCreated(CJNISurfaceHolder holder) override;
272   void surfaceDestroyed(CJNISurfaceHolder holder) override;
273 };
274