1 # This file is part of NIT (http://www.nitlanguage.org).
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 # Some documentation of this module has been adapted from the
16 # Android Open Source Project.
18 # Core implementation of `app.nit` on Android using a custom Java entry point
20 # This module is implemented in 3 languages:
22 # * The Java code, in `NitActivity.java` acts as the entry point registered
23 # to the Android OS. It relays most of the Android callbacks to C.
24 # In theory, there may be more than one instance of `NitActivity` alive at
25 # a given time. They hold a reference to the corresponding Nit `Activity`
26 # in the attribute `nitActivity`.
28 # * The C code is defined in the top part of this source file. It acts as a
29 # glue between Java and Nit by relaying calls between both languages.
30 # It keeps a global variables reference to the Java VM and the Nit `App`.
32 # * The Nit code defines the `Activity` class with the callbacks from Android.
33 # The callback methods should be redefined by user modules.
35 # The main is invoked when the native library is dynamically linked by
36 # the Java virtual machine. For this reason, the main _must_ execute quickly,
37 # on the main UI thread at least.
38 module nit_activity
is
39 extra_java_files
"nit.app.NitActivity"
40 android_activity
"nit.app.NitActivity"
53 #include <android/log.h>
55 // Nit's App running instance
58 // Java VM that launched this program
61 // JNI callback on loading this program
62 jint JNI_OnLoad(JavaVM *vm, void *reserved) {
63 // Set aside the Java VM
66 // Invoke Nit system and main
67 int main(int argc, char ** argv);
70 return JNI_VERSION_1_2;
74 * Implementations of NitActivity.java native methods
77 JNIEXPORT jint JNICALL Java_nit_app_NitActivity_nitRegisterActivity
78 (JNIEnv *env, jobject java_activity)
80 Activity nit_activity = App_register_activity(global_app, java_activity);
81 Activity_incr_ref(nit_activity);
82 return (jint)(void*)nit_activity;
85 JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnCreate
86 (JNIEnv *env, jobject java_activity, jint nit_activity, jobject saved_state)
88 Activity_on_create((Activity)nit_activity, saved_state);
91 JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnStart
92 (JNIEnv *env, jobject java_activity, jint nit_activity)
94 Activity_on_start((Activity)nit_activity);
97 JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnRestart
98 (JNIEnv *env, jobject java_activity, jint nit_activity)
100 Activity_on_restart((Activity)nit_activity);
103 JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnResume
104 (JNIEnv *env, jobject java_activity, jint nit_activity)
106 Activity_on_resume((Activity)nit_activity);
109 JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnPause
110 (JNIEnv *env, jobject java_activity, jint nit_activity)
112 Activity_on_pause((Activity)nit_activity);
115 JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnStop
116 (JNIEnv *env, jobject java_activity, jint nit_activity)
118 Activity_on_stop((Activity)nit_activity);
121 JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnDestroy
122 (JNIEnv *env, jobject java_activity, jint nit_activity)
124 Activity_on_destroy((Activity)nit_activity);
127 JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnSaveInstanceState
128 (JNIEnv *env, jobject java_activity, jint nit_activity, jobject saved_state)
130 Activity_on_save_instance_state((Activity)nit_activity, saved_state);
133 JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnRestoreInstanceState
134 (JNIEnv *env, jobject java_activity, jint nit_activity, jobject saved_state)
136 Activity_on_restore_instance_state((Activity)nit_activity, saved_state);
139 JNIEXPORT jboolean JNICALL Java_nit_app_NitActivity_nitOnBackPressed
140 (JNIEnv *env, jobject java_activity, jint nit_activity)
142 return (jboolean)Activity_on_back_pressed((Activity)nit_activity);
145 JNIEXPORT jboolean JNICALL Java_nit_app_NitActivity_nitOnKeyDown
146 (JNIEnv *env, jobject java_activity, jint nit_activity, jint keyCode, jobject event)
148 return (jboolean)Activity_on_key_down((Activity)nit_activity, keyCode, event);
151 JNIEXPORT jboolean JNICALL Java_nit_app_NitActivity_nitOnKeyLongPress
152 (JNIEnv *env, jobject java_activity, jint nit_activity, jint keyCode, jobject event)
154 return (jboolean)Activity_on_key_long_press((Activity)nit_activity, keyCode, event);
157 JNIEXPORT jboolean JNICALL Java_nit_app_NitActivity_nitOnKeyMultiple
158 (JNIEnv *env, jobject java_activity, jint nit_activity, jint keyCode, jint count, jobject event)
160 return (jboolean)Activity_on_key_multiple((Activity)nit_activity, keyCode, count, event);
163 JNIEXPORT jboolean JNICALL Java_nit_app_NitActivity_nitOnKeyUp
164 (JNIEnv *env, jobject java_activity, jint nit_activity, jint keyCode, jobject event)
166 return (jboolean)Activity_on_key_up((Activity)nit_activity, keyCode, event);
170 # Wrapper to our Java `NitActivity`
171 extern class NativeNitActivity in "Java" `{ nit.app.NitActivity `}
176 redef fun jvm `{ return global_jvm; `}
181 var activities
= new Array[Activity]
183 # The main Java Activity of this application
184 redef fun native_activity
do return activities
.first
.native
186 redef fun setup
do set_global_app
189 private fun set_global_app
import register_activity
,
190 Activity.on_create
, Activity.on_destroy
,
191 Activity.on_start
, Activity.on_restart
, Activity.on_stop
,
192 Activity.on_pause
, Activity.on_resume
,
193 Activity.on_save_instance_state
, Activity.on_restore_instance_state
,
194 Activity.on_back_pressed
,
195 Activity.on_key_down
, Activity.on_key_long_press
,
196 Activity.on_key_multiple
, Activity.on_key_up
`{
201 # Create the Nit side to this new `native` Java activity, and return it to Java
202 private fun register_activity
(native
: NativeNitActivity): Activity
204 native
= native
.new_global_ref
205 var activity
= new Activity(native
)
206 activities
.add activity
211 redef class AppComponent
212 # The application is starting or restarting, it is visible to the user
215 # The application is being destroyed
216 fun on_destroy
do end
219 # An Android activity
221 # You must implement the callbacks (prefixed with `on_`) to follow the
222 # standard Android life-cycle.
224 # Native Java activity
225 var native
: NativeActivity
227 # Notification from Android, the activity is created
229 # Do your normal static set up here.
231 # If available, `save_state` contains the activity's previous state
232 # as registered by `on_save_instance_state`.
234 # Followed by `on_start`.
235 fun on_create
(save_state
: NativeBundle)
241 # Notification from Android, the activity has been restarted
243 # Followed by `on_start`.
244 fun on_restart
do app
.on_restart
246 # Notification from Android, the activity has been started
248 # Followed by `on_resume` or `on_stop`.
249 fun on_start
do app
.on_start
251 # Notification from Android, the activity has been resumed
253 # Followed by `on_pause`
254 fun on_resume
do app
.on_resume
256 # Notification from Android, the activity has been paused
258 # Followed by `on_resume` or `on_stop`.
259 fun on_pause
do app
.on_pause
261 # Notification from Android, the activity has been stopped
263 # Followed by `on_restart` or `on_destroy`.
264 fun on_stop
do app
.on_stop
266 # Notification from Android, the activity is being destroyed
273 native
.delete_global_ref
274 app
.activities
.remove
self
277 # Notification from Android, the activity is being re-initialized from a `save_state`
279 # Occurs after `on_start`.
280 fun on_restore_instance_state
(save_state
: NativeBundle) do end
282 # Notification from Android, the activity may be stopped, save state
284 # Occurs before `on_stop` and, without guarantee, before or after `on_pause`.
285 fun on_save_instance_state
(save_state
: NativeBundle) do app
.on_save_state
287 # Notification from Android, the system is running low on memory
289 # Try to reduce your memory use.
290 fun on_low_memory
do force_garbage_collection
292 # Notification from Android, the current window of the activity has lost or gained focus
293 fun on_window_focus_changed
(has_focus
: Bool) do end
295 # Notification from Android, the current device configuration has changed
296 fun on_configuration_changed
do end
298 # The back key has been pressed
300 # Return `true` if the event has been handled.
301 fun on_back_pressed
: Bool do return false
303 # A key has been pressed
305 # Return `true` if the event has been handled.
306 fun on_key_down
(key_code
: Int, event
: NativeKeyEvent): Bool do return false
308 # A key has been long pressed
310 # Return `true` if the event has been handled.
311 fun on_key_long_press
(key_code
: Int, event
: NativeKeyEvent): Bool do return false
313 # Multiple down/up pairs of the same key have occurred in a row
315 # Return `true` if the event has been handled.
316 fun on_key_multiple
(key_code
, count
: Int, event
: NativeKeyEvent): Bool do return false
318 # A key has been released
320 # Return `true` if the event has been handled.
321 fun on_key_up
(key_code
: Int, event
: NativeKeyEvent): Bool do return false
324 # Set up global data in C and leave it to Android to callback Java, which we relay to Nit