File: AndroidJniHelper.h

package info (click to toggle)
jazz2-native 3.5.0-2
  • links: PTS, VCS
  • area: contrib
  • in suites: forky, sid
  • size: 16,912 kB
  • sloc: cpp: 172,557; xml: 113; python: 36; makefile: 5; sh: 2
file content (362 lines) | stat: -rw-r--r-- 10,320 bytes parent folder | download
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
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
#pragma once

#include "../../Primitives/Rect.h"

#include <jni.h>
#include <android/api-level.h>
#include <android_native_app_glue.h>

#include <Containers/String.h>

using namespace Death::Containers;

namespace nCine
{
	class AndroidApplication;
}

namespace nCine::Backends
{
	/// Class for setting up JNI and initialize requests classes
	class AndroidJniHelper
	{
		friend class nCine::AndroidApplication;

	public:
		inline static unsigned int SdkVersion() { return sdkVersion_; }

		static JNIEnv *jniEnv;

		AndroidJniHelper() = delete;
		~AndroidJniHelper() = delete;

		static bool CheckAndClearExceptions();

	private:
		static JavaVM* javaVM_;
		static unsigned int sdkVersion_;

		/// Attaches the Java virtual machine to make use of JNI
		static void AttachJVM(struct android_app* state);
		/// Detaches the Java virtual machine
		static void DetachJVM();
		static void InitializeClasses();

		static String ExceptionToString(JNIEnv* env, jthrowable exception);
	};

	/// Base class for handling of JNI requests to the Android API
	class AndroidJniClass
	{
	public:
		AndroidJniClass()
			: javaObject_(nullptr) {}
		explicit AndroidJniClass(jobject javaObject);
		virtual ~AndroidJniClass();

		/// Move constructor
		AndroidJniClass(AndroidJniClass&& other);
		/// Move assignment operator
		AndroidJniClass& operator=(AndroidJniClass&& other);

		/// Deleted copy constructor
		AndroidJniClass(const AndroidJniClass&) = delete;
		/// Deleted assignment operator
		AndroidJniClass& operator=(const AndroidJniClass&) = delete;

		inline bool IsNull() const {
			return javaObject_ == nullptr;
		}
		inline jobject javaObject() const {
			return javaObject_;
		}

		static jclass findClass(const char* name);
		static jmethodID getStaticMethodID(jclass javaClass, const char* name, const char* signature);
		static jmethodID getMethodID(jclass javaClass, const char* name, const char* signature);
		static jfieldID getStaticFieldID(jclass javaClass, const char* name, const char* signature);

	protected:
		jobject javaObject_;

		friend class AndroidJniHelper;
	};

	/// Handles JNI requests to `android.os.Build.VERSION`
	class AndroidJniClass_Version
	{
	public:
		static int sdkInt();
		static String deviceBrand();
		static String deviceManufacturer();
		static String deviceModel();
	};

	/// Handles JNI requests to `android.view.InputDevice.MotionRange`
	class AndroidJniClass_MotionRange : public AndroidJniClass
	{
	public:
		static void init();
		explicit AndroidJniClass_MotionRange(jobject javaObject);
		float getMin() const;
		float getRange() const;
		
	private:
		static jclass javaClass_;
		static jmethodID midGetMin_;
		static jmethodID midGetRange_;
	};

	/// A class to handle JNI requests to `android.os.VibrationEffect`
	class AndroidJniClass_VibrationEffect : public AndroidJniClass
	{
	public:
		static void init();
		explicit AndroidJniClass_VibrationEffect(jobject javaObject)
			: AndroidJniClass(javaObject) {}
		static AndroidJniClass_VibrationEffect createOneShot(long milliseconds, int amplitude);

	private:
		static jclass javaClass_;
		static jmethodID midCreateOneShot_;
	};

	/// A class to handle JNI requests to `android.os.Vibrator`
	class AndroidJniClass_Vibrator : public AndroidJniClass
	{
	public:
		static void init();
		AndroidJniClass_Vibrator()
			: AndroidJniClass() {}
		explicit AndroidJniClass_Vibrator(jobject javaObject)
			: AndroidJniClass(javaObject) {}

		void cancel() const;
		void vibrate(const AndroidJniClass_VibrationEffect& vibe) const;

	private:
		static jclass javaClass_;
		static jmethodID midCancel_;
		static jmethodID midVibrate_;
	};

	/// A class to handle JNI requests to `android.os.VibratorManager`
	class AndroidJniClass_VibratorManager : public AndroidJniClass
	{
	public:
		static void init();
		explicit AndroidJniClass_VibratorManager(jobject javaObject);

		void cancel() const;
		int getVibratorIds(int* destination, int maxSize) const;
		AndroidJniClass_Vibrator getVibrator(int vibratorId) const;

	private:
		static jclass javaClass_;
		static jmethodID midCancel_;
		static jmethodID midGetVibratorIds_;
		static jmethodID midGetVibrator_;
	};

	/// Handles JNI requests to `android.view.InputDevice`
	class AndroidJniClass_InputDevice : public AndroidJniClass
	{
	public:
		static void init();
		explicit AndroidJniClass_InputDevice(jobject javaObject)
			: AndroidJniClass(javaObject) {}
		static AndroidJniClass_InputDevice getDevice(int deviceId);
		static int getDeviceIds(int* destination, int maxSize);
		int getName(char* destination, int maxStringSize) const;
		int getDescriptor(char* destination, int maxStringSize) const;
		int getProductId() const;
		int getVendorId() const;
		AndroidJniClass_MotionRange getMotionRange(int axis) const;
		int getSources() const;
		void hasKeys(const int* buttons, const int length, bool* bools) const;
		AndroidJniClass_VibratorManager getVibratorManager() const;

	private:
		static jclass javaClass_;
		static jmethodID midGetDevice_;
		static jmethodID midGetDeviceIds_;
		static jmethodID midGetName_;
		static jmethodID midGetDescriptor_;
		static jmethodID midGetVendorId_;
		static jmethodID midGetProductId_;
		static jmethodID midGetMotionRange_;
		static jmethodID midGetSources_;
		static jmethodID midHasKeys_;
		static jmethodID midGetVibratorManager_;
	};

	/// Handles JNI requests to `android.view.KeyCharacterMap`
	class AndroidJniClass_KeyCharacterMap : public AndroidJniClass
	{
	public:
		static void init();
		explicit AndroidJniClass_KeyCharacterMap(jobject javaObject)
			: AndroidJniClass(javaObject) {}
		static bool deviceHasKey(int button);

	private:
		static jclass javaClass_;
		static jmethodID midDeviceHasKey_;
	};

	/// Handles JNI requests to `android.view.KeyEvent`
	class AndroidJniClass_KeyEvent : public AndroidJniClass
	{
	public:
		static void init();

		AndroidJniClass_KeyEvent(int action, int code);
		AndroidJniClass_KeyEvent(long long int downTime, long long int eventTime, int action, int code, int repeat, int metaState, int deviceId, int scancode, int flags, int source);

		int getUnicodeChar(int metaState) const;
		inline int getUnicodeChar() const { return getUnicodeChar(0); }
		int getCharacters(char* destination, int maxStringSize) const;
		bool isPrintingKey() const;

	private:
		static jclass javaClass_;
		static jmethodID midConstructor_;
		static jmethodID midConstructor2_;
		static jmethodID midGetUnicodeCharMetaState_;
		static jmethodID midGetUnicodeChar_;
		static jmethodID midGetCharacters_;
		static jmethodID midIsPrintingKey_;
	};
	
	/// Handles JNI requests to `android.view.Display.Mode`
	class AndroidJniClass_DisplayMode : public AndroidJniClass
	{
	public:
		static void init();

		AndroidJniClass_DisplayMode()
			: AndroidJniClass() {}
		explicit AndroidJniClass_DisplayMode(jobject javaObject)
			: AndroidJniClass(javaObject) {}

		int getPhysicalHeight() const;
		int getPhysicalWidth() const;
		float getRefreshRate() const;

	private:
		static jclass javaClass_;
		static jmethodID midGetPhysicalHeight_;
		static jmethodID midGetPhysicalWidth_;
		static jmethodID midGetRefreshRate_;
	};

	/// Handles JNI requests to `android.view.Display`
	class AndroidJniClass_Display : public AndroidJniClass
	{
	public:
		static void init();

		AndroidJniClass_Display()
			: AndroidJniClass() {}
		explicit AndroidJniClass_Display(jobject javaObject)
			: AndroidJniClass(javaObject) {}

		AndroidJniClass_DisplayMode getMode() const;
		int getName(char* destination, int maxStringSize) const;
		int getSupportedModes(AndroidJniClass_DisplayMode* destination, int maxSize) const;

	private:
		static jclass javaClass_;
		static jmethodID midGetMode_;
		static jmethodID midGetName_;
		static jmethodID midGetSupportedModes_;
	};

	/// Handles JNI requests to `android.app.Activity`
	class AndroidJniWrap_Activity
	{
	public:
		static void init(struct android_app* state);
		static void finishAndRemoveTask();
		static String getPackageName();
		static String getPreferredLanguage();
		static bool isScreenRound();
		static bool hasExternalStoragePermission();
		static void requestExternalStoragePermission();
		static void setActivityEnabled(StringView activity, bool enable);
		static bool openUrl(StringView url);
		static jobject getDecorView();
		static Recti getVisibleBounds();

	private:
		static jobject activityObject_;
		static jmethodID midFinishAndRemoveTask_;
		static jmethodID midGetPackageName_;
		static jmethodID midGetPreferredLanguage_;
		static jmethodID midIsScreenRound_;
		static jmethodID midHasExternalStoragePermission_;
		static jmethodID midRequestExternalStoragePermission_;
		static jmethodID midSetActivityEnabled_;
		static jmethodID midOpenUrl_;
		static jmethodID midGetWindow_;

		static jmethodID midGetDecorView_;
		static jclass rectClass_;
		static jmethodID midRectInit_;
		static jfieldID fidRectLeft_;
		static jfieldID fidRectTop_;
		static jfieldID fidRectRight_;
		static jfieldID fidRectBottom_;
		static jmethodID midGetWindowVisibleDisplayFrame_;
	};

	/// Handles JNI requests to `android.view.inputmethod.InputMethodManager`
	class AndroidJniWrap_InputMethodManager
	{
	public:
		static void init(struct android_app* state);
		static void shutdown();

		static void toggleSoftInput();
		static bool showSoftInput();
		static bool hideSoftInput();

	private:
		static jobject inputMethodManagerObject_;
		static jmethodID midToggleSoftInput_;
		static jmethodID midShowSoftInput_;
		static jmethodID midHideSoftInput_;
		static jmethodID midGetWindowToken_;

		static const int SHOW_IMPLICIT = 1;
		static const int HIDE_IMPLICIT_ONLY = 1;
	};

	/// Handles JNI requests to `android.hardware.display.DisplayManager`
	class AndroidJniWrap_DisplayManager
	{
	public:
		static void init(struct android_app* state);
		static void shutdown();

		static AndroidJniClass_Display getDisplay(int displayId);
		static int getDisplays(AndroidJniClass_Display* destination, int maxSize);

	private:
		static jobject displayManagerObject_;
		static jmethodID midGetDisplay_;
		static jmethodID midGetDisplays_;
	};

	/// Handles JNI requests to `android.provider.Settings.Secure`
	class AndroidJniWrap_Secure
	{
	public:
		static void init(struct android_app* state);

		static StringView getAndroidId();

	private:
		static String androidId_;
	};
}