lib/android: intro our very own NitActivity
[nit.git] / lib / android / nit_activity.nit
1 # This file is part of NIT (http://www.nitlanguage.org).
2 #
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
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
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.
14
15 # Some documentation of this module has been adapted from the
16 # Android Open Source Project.
17
18 # Core implementation of `app.nit` on Android using a custom Java entry point
19 #
20 # This module is implemented in 3 languages:
21 #
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`.
27 #
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`.
31 #
32 # * The Nit code defines the `Activity` class with the callbacks from Android.
33 # The callback methods should be redefined by user modules.
34 #
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 "NitActivity.java"
40 android_activity "nit.app.NitActivity"
41 end
42
43 import platform
44 import log
45 import activities
46 import bundle
47 import dalvik
48
49 in "C body" `{
50
51 #include <jni.h>
52 #include <android/log.h>
53
54 // Nit's App running instance
55 App global_app;
56
57 // Java VM that launched this program
58 JavaVM *global_jvm;
59
60 // JNI callback on loading this program
61 jint JNI_OnLoad(JavaVM *vm, void *reserved) {
62 // Set aside the Java VM
63 global_jvm = vm;
64
65 // Invoke Nit system and main
66 main(0, NULL);
67
68 return JNI_VERSION_1_2;
69 }
70
71 /*
72 * Implementations of NitActivity.java native methods
73 */
74
75 JNIEXPORT jint JNICALL Java_nit_app_NitActivity_nitRegisterActivity
76 (JNIEnv *env, jobject java_activity)
77 {
78 Activity nit_activity = App_register_activity(global_app, java_activity);
79 Activity_incr_ref(nit_activity);
80 return (jint)(void*)nit_activity;
81 }
82
83 JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnCreate
84 (JNIEnv *env, jobject java_activity, jint nit_activity, jobject saved_state)
85 {
86 Activity_on_create((Activity)nit_activity, saved_state);
87 }
88
89 JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnStart
90 (JNIEnv *env, jobject java_activity, jint nit_activity)
91 {
92 Activity_on_start((Activity)nit_activity);
93 }
94
95 JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnRestart
96 (JNIEnv *env, jobject java_activity, jint nit_activity)
97 {
98 Activity_on_restart((Activity)nit_activity);
99 }
100
101 JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnResume
102 (JNIEnv *env, jobject java_activity, jint nit_activity)
103 {
104 Activity_on_resume((Activity)nit_activity);
105 }
106
107 JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnPause
108 (JNIEnv *env, jobject java_activity, jint nit_activity)
109 {
110 Activity_on_pause((Activity)nit_activity);
111 }
112
113 JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnStop
114 (JNIEnv *env, jobject java_activity, jint nit_activity)
115 {
116 Activity_on_stop((Activity)nit_activity);
117 }
118
119 JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnDestroy
120 (JNIEnv *env, jobject java_activity, jint nit_activity)
121 {
122 Activity_on_destroy((Activity)nit_activity);
123 }
124
125 JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnSaveInstanceState
126 (JNIEnv *env, jobject java_activity, jint nit_activity, jobject saved_state)
127 {
128 Activity_on_save_instance_state((Activity)nit_activity, saved_state);
129 }
130
131 JNIEXPORT void JNICALL Java_nit_app_NitActivity_nitOnRestoreInstanceState
132 (JNIEnv *env, jobject java_activity, jint nit_activity, jobject saved_state)
133 {
134 Activity_on_restore_instance_state((Activity)nit_activity, saved_state);
135 }
136 `}
137
138 # Wrapper to our Java `NitActivity`
139 extern class NativeNitActivity in "Java" `{ nit.app.NitActivity `}
140 super NativeActivity
141 end
142
143 redef class Sys
144 redef fun jvm `{ return global_jvm; `}
145 end
146
147 redef class App
148 # Known activities
149 var activities = new Array[Activity]
150
151 # The main Java Activity of this application
152 redef fun native_activity do return activities.first.native
153
154 redef fun setup do set_global_app
155
156 # Register app in C
157 private fun set_global_app import register_activity,
158 Activity.on_create, Activity.on_destroy,
159 Activity.on_start, Activity.on_restart, Activity.on_stop,
160 Activity.on_pause, Activity.on_resume,
161 Activity.on_save_instance_state, Activity.on_restore_instance_state `{
162 App_incr_ref(recv);
163 global_app = recv;
164 `}
165
166 # Create the Nit side to this new `native` Java activity, and return it to Java
167 private fun register_activity(native: NativeNitActivity): Activity
168 do
169 native = native.new_global_ref
170 var activity = new Activity(native)
171 activities.add activity
172 return activity
173 end
174 end
175
176 # An Android activity
177 #
178 # You must implement the callbacks (prefixed with `on_`) to follow the
179 # standard Android life-cycle.
180 class Activity
181 # Native Java activity
182 var native: NativeActivity
183
184 # Notification from Android, the activity is created
185 #
186 # Do your normal static set up here.
187 #
188 # If available, `save_state` contains the activity's previous state
189 # as registered by `on_save_instance_state`.
190 #
191 # Followed by `on_start`.
192 fun on_create(save_state: NativeBundle) do end
193
194 # Notification from Android, the activity has been restarted
195 #
196 # Followed by `on_start`.
197 fun on_restart do end
198
199 # Notification from Android, the activity has been started
200 #
201 # Followed by `on_resume` or `on_stop`.
202 fun on_start do end
203
204 # Notification from Android, the activity has been resumed
205 #
206 # Followed by `on_pause`
207 fun on_resume do end
208
209 # Notification from Android, the activity has been paused
210 #
211 # Followed by `on_resume` or `on_stop`.
212 fun on_pause do end
213
214 # Notification from Android, the activity has been stopped
215 #
216 # Followed by `on_restart` or `on_destroy`.
217 fun on_stop do end
218
219 # Notification from Android, the activity is being destroyed
220 #
221 # Clean up and exit.
222 fun on_destroy
223 do
224 native.delete_global_ref
225 app.activities.remove self
226 end
227
228 # Notification from Android, the activity is being re-initialized from a `save_state`
229 #
230 # Occurs after `on_start`.
231 fun on_restore_instance_state(save_state: NativeBundle) do end
232
233 # Notification from Android, the activity may be stopped, save state
234 #
235 # Occurs before `on_stop` and, without guarantee, before or after `on_pause`.
236 fun on_save_instance_state(save_state: NativeBundle) do end
237
238 # Notification from Android, the system is running low on memory
239 #
240 # Try to reduce your memory use.
241 fun on_low_memory do end
242
243 # Notification from Android, the current window of the activity has lost or gained focus
244 fun on_window_focus_changed(has_focus: Bool) do end
245
246 # Notification from Android, the current device configuration has changed
247 fun on_configuration_changed do end
248 end
249
250 # Set up global data in C and leave it to Android to callback Java, which we relay to Nit
251 app.setup