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