1 /*
2 * Copyright (C) 2017 Christian Browet
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 #include "JNIXBMCMediaSession.h"
10
11 #include "AndroidKey.h"
12 #include "Application.h"
13 #include "CompileInfo.h"
14 #include "XBMCApp.h"
15 #include "input/Key.h"
16 #include "messaging/ApplicationMessenger.h"
17
18 #include <androidjni/Context.h>
19 #include <androidjni/KeyEvent.h>
20 #include <androidjni/jutils-details.hpp>
21
22 using namespace jni;
23
24 static std::string s_className = std::string(CCompileInfo::GetClass()) + "/XBMCMediaSession";
25
CJNIXBMCMediaSession()26 CJNIXBMCMediaSession::CJNIXBMCMediaSession()
27 : CJNIBase(s_className)
28 {
29 m_object = new_object(CJNIContext::getClassLoader().loadClass(GetDotClassName(s_className)));
30 m_object.setGlobal();
31
32 add_instance(m_object, this);
33 }
34
CJNIXBMCMediaSession(const CJNIXBMCMediaSession & other)35 CJNIXBMCMediaSession::CJNIXBMCMediaSession(const CJNIXBMCMediaSession& other)
36 : CJNIBase(other)
37 {
38 add_instance(m_object, this);
39 }
40
~CJNIXBMCMediaSession()41 CJNIXBMCMediaSession::~CJNIXBMCMediaSession()
42 {
43 remove_instance(this);
44 }
45
RegisterNatives(JNIEnv * env)46 void CJNIXBMCMediaSession::RegisterNatives(JNIEnv* env)
47 {
48 jclass cClass = env->FindClass(s_className.c_str());
49 if(cClass)
50 {
51 JNINativeMethod methods[] =
52 {
53 {"_onPlayRequested", "()V", (void*)&CJNIXBMCMediaSession::_onPlayRequested},
54 {"_onPauseRequested", "()V", (void*)&CJNIXBMCMediaSession::_onPauseRequested},
55 {"_onNextRequested", "()V", (void*)&CJNIXBMCMediaSession::_onNextRequested},
56 {"_onPreviousRequested", "()V", (void*)&CJNIXBMCMediaSession::_onPreviousRequested},
57 {"_onForwardRequested", "()V", (void*)&CJNIXBMCMediaSession::_onForwardRequested},
58 {"_onRewindRequested", "()V", (void*)&CJNIXBMCMediaSession::_onRewindRequested},
59 {"_onStopRequested", "()V", (void*)&CJNIXBMCMediaSession::_onStopRequested},
60 {"_onSeekRequested", "(J)V", (void*)&CJNIXBMCMediaSession::_onSeekRequested},
61 {"_onMediaButtonEvent", "(Landroid/content/Intent;)Z", (void*)&CJNIXBMCMediaSession::_onMediaButtonEvent},
62 };
63
64 env->RegisterNatives(cClass, methods, sizeof(methods)/sizeof(methods[0]));
65 }
66 }
67
activate(bool state)68 void CJNIXBMCMediaSession::activate(bool state)
69 {
70 if (state == m_isActive)
71 return;
72
73 call_method<void>(m_object,
74 "activate", "(Z)V",
75 (jboolean)state);
76 m_isActive = state;
77 }
78
updatePlaybackState(const CJNIPlaybackState & state)79 void CJNIXBMCMediaSession::updatePlaybackState(const CJNIPlaybackState& state)
80 {
81 call_method<void>(m_object,
82 "updatePlaybackState", "(Landroid/media/session/PlaybackState;)V",
83 state.get_raw());
84 }
85
updateMetadata(const CJNIMediaMetadata & myData)86 void CJNIXBMCMediaSession::updateMetadata(const CJNIMediaMetadata& myData)
87 {
88 call_method<void>(m_object,
89 "updateMetadata", "(Landroid/media/MediaMetadata;)V",
90 myData.get_raw());
91 }
92
updateIntent(const CJNIIntent & intent)93 void CJNIXBMCMediaSession::updateIntent(const CJNIIntent& intent)
94 {
95 call_method<void>(m_object,
96 "updateIntent", "(Landroid/content/Intent;)V",
97 intent.get_raw());
98 }
99
OnPlayRequested()100 void CJNIXBMCMediaSession::OnPlayRequested()
101 {
102 if (g_application.GetAppPlayer().IsPlaying())
103 {
104 if (g_application.GetAppPlayer().IsPaused())
105 KODI::MESSAGING::CApplicationMessenger::GetInstance().PostMsg(TMSG_GUI_ACTION, WINDOW_INVALID, -1, static_cast<void*>(new CAction(ACTION_PAUSE)));
106 }
107 }
108
OnPauseRequested()109 void CJNIXBMCMediaSession::OnPauseRequested()
110 {
111 if (g_application.GetAppPlayer().IsPlaying())
112 {
113 if (!g_application.GetAppPlayer().IsPaused())
114 KODI::MESSAGING::CApplicationMessenger::GetInstance().PostMsg(TMSG_GUI_ACTION, WINDOW_INVALID, -1, static_cast<void*>(new CAction(ACTION_PAUSE)));
115 }
116 }
117
OnNextRequested()118 void CJNIXBMCMediaSession::OnNextRequested()
119 {
120 if (g_application.GetAppPlayer().IsPlaying())
121 KODI::MESSAGING::CApplicationMessenger::GetInstance().PostMsg(TMSG_GUI_ACTION, WINDOW_INVALID, -1, static_cast<void*>(new CAction(ACTION_NEXT_ITEM)));
122 }
123
OnPreviousRequested()124 void CJNIXBMCMediaSession::OnPreviousRequested()
125 {
126 if (g_application.GetAppPlayer().IsPlaying())
127 KODI::MESSAGING::CApplicationMessenger::GetInstance().PostMsg(TMSG_GUI_ACTION, WINDOW_INVALID, -1, static_cast<void*>(new CAction(ACTION_PREV_ITEM)));
128 }
129
OnForwardRequested()130 void CJNIXBMCMediaSession::OnForwardRequested()
131 {
132 if (g_application.GetAppPlayer().IsPlaying())
133 {
134 if (!g_application.GetAppPlayer().IsPaused())
135 KODI::MESSAGING::CApplicationMessenger::GetInstance().PostMsg(TMSG_GUI_ACTION, WINDOW_INVALID, -1, static_cast<void*>(new CAction(ACTION_PLAYER_FORWARD)));
136 }
137 }
138
OnRewindRequested()139 void CJNIXBMCMediaSession::OnRewindRequested()
140 {
141 if (g_application.GetAppPlayer().IsPlaying())
142 {
143 if (!g_application.GetAppPlayer().IsPaused())
144 KODI::MESSAGING::CApplicationMessenger::GetInstance().PostMsg(TMSG_GUI_ACTION, WINDOW_INVALID, -1, static_cast<void*>(new CAction(ACTION_PLAYER_REWIND)));
145 }
146 }
147
OnStopRequested()148 void CJNIXBMCMediaSession::OnStopRequested()
149 {
150 if (g_application.GetAppPlayer().IsPlaying())
151 KODI::MESSAGING::CApplicationMessenger::GetInstance().PostMsg(TMSG_GUI_ACTION, WINDOW_INVALID, -1, static_cast<void*>(new CAction(ACTION_STOP)));
152 }
153
OnSeekRequested(int64_t pos)154 void CJNIXBMCMediaSession::OnSeekRequested(int64_t pos)
155 {
156 g_application.SeekTime(pos / 1000.0);
157 }
158
OnMediaButtonEvent(const CJNIIntent & intent)159 bool CJNIXBMCMediaSession::OnMediaButtonEvent(const CJNIIntent& intent)
160 {
161 if (CXBMCApp::HasFocus())
162 {
163 CXBMCApp::get()->onReceive(intent);
164 return true;
165 }
166 return false;
167 }
168
isActive() const169 bool CJNIXBMCMediaSession::isActive() const
170 {
171 return m_isActive;
172 }
173
174 /**********************/
175
_onPlayRequested(JNIEnv * env,jobject thiz)176 void CJNIXBMCMediaSession::_onPlayRequested(JNIEnv* env, jobject thiz)
177 {
178 (void)env;
179
180 CJNIXBMCMediaSession *inst = find_instance(thiz);
181 if (inst)
182 inst->OnPlayRequested();
183 }
184
_onPauseRequested(JNIEnv * env,jobject thiz)185 void CJNIXBMCMediaSession::_onPauseRequested(JNIEnv* env, jobject thiz)
186 {
187 (void)env;
188
189 CJNIXBMCMediaSession *inst = find_instance(thiz);
190 if (inst)
191 inst->OnPauseRequested();
192 }
193
_onNextRequested(JNIEnv * env,jobject thiz)194 void CJNIXBMCMediaSession::_onNextRequested(JNIEnv* env, jobject thiz)
195 {
196 (void)env;
197
198 CJNIXBMCMediaSession *inst = find_instance(thiz);
199 if (inst)
200 inst->OnNextRequested();
201 }
202
_onPreviousRequested(JNIEnv * env,jobject thiz)203 void CJNIXBMCMediaSession::_onPreviousRequested(JNIEnv* env, jobject thiz)
204 {
205 (void)env;
206
207 CJNIXBMCMediaSession *inst = find_instance(thiz);
208 if (inst)
209 inst->OnPreviousRequested();
210 }
211
_onForwardRequested(JNIEnv * env,jobject thiz)212 void CJNIXBMCMediaSession::_onForwardRequested(JNIEnv* env, jobject thiz)
213 {
214 (void)env;
215
216 CJNIXBMCMediaSession *inst = find_instance(thiz);
217 if (inst)
218 inst->OnForwardRequested();
219 }
220
_onRewindRequested(JNIEnv * env,jobject thiz)221 void CJNIXBMCMediaSession::_onRewindRequested(JNIEnv* env, jobject thiz)
222 {
223 (void)env;
224
225 CJNIXBMCMediaSession *inst = find_instance(thiz);
226 if (inst)
227 inst->OnRewindRequested();
228 }
229
_onStopRequested(JNIEnv * env,jobject thiz)230 void CJNIXBMCMediaSession::_onStopRequested(JNIEnv* env, jobject thiz)
231 {
232 (void)env;
233
234 CJNIXBMCMediaSession *inst = find_instance(thiz);
235 if (inst)
236 inst->OnStopRequested();
237 }
238
_onSeekRequested(JNIEnv * env,jobject thiz,jlong pos)239 void CJNIXBMCMediaSession::_onSeekRequested(JNIEnv* env, jobject thiz, jlong pos)
240 {
241 (void)env;
242
243 CJNIXBMCMediaSession *inst = find_instance(thiz);
244 if (inst)
245 inst->OnSeekRequested(pos);
246 }
247
_onMediaButtonEvent(JNIEnv * env,jobject thiz,jobject intent)248 bool CJNIXBMCMediaSession::_onMediaButtonEvent(JNIEnv* env, jobject thiz, jobject intent)
249 {
250 (void)env;
251
252 CJNIXBMCMediaSession *inst = find_instance(thiz);
253 if (inst)
254 return inst->OnMediaButtonEvent(CJNIIntent(jhobject::fromJNI(intent)));
255 return false;
256 }
257
258