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 # Android service support for _app.nit_ centered around the class `Service`
17 extra_java_files
"nit.app.NitService"
18 android_manifest_application
"""<service android:name="nit.app.NitService"></service>"""
21 import android
::nit_activity
24 // Nit's App running instance, declared in `nit_activity
`
25 extern App global_app;
27 JNIEXPORT jlong JNICALL Java_nit_app_NitService_nitNewService
28 (JNIEnv *env, jobject java_service)
30 // Pin a ref to the Java service in the Java GC
31 java_service = (*env)->NewGlobalRef(env, java_service);
33 // Create the service in Nit and pin it in the Nit GC
34 Service nit_service = App_register_service(global_app, java_service);
36 // FIXME replace the previous call to register_service by
37 // the following line when #1941 is fixed:
38 //Service nit_service = new_Service(java_service);
40 Service_incr_ref(nit_service);
42 return (jlong)(void*)nit_service;
45 JNIEXPORT jint JNICALL Java_nit_app_NitService_nitOnStartCommand
46 (JNIEnv *env, jobject java_service, jlong nit_service, jobject intent, jint flags, jint id)
48 return Service_on_start_command((Service)nit_service, intent, flags, id);
51 JNIEXPORT void JNICALL Java_nit_app_NitService_nitOnCreate
52 (JNIEnv *env, jobject java_service, jlong nit_service)
54 Service_on_create((Service)nit_service);
57 JNIEXPORT void JNICALL Java_nit_app_NitService_nitOnDestroy
58 (JNIEnv *env, jobject java_service, jlong nit_service)
60 Service_on_destroy((Service)nit_service);
62 // Unpin the service instances in both Nit and Java
63 java_service = Service_native((Service)nit_service);
64 (*env)->DeleteGlobalRef(env, java_service);
65 Service_decr_ref(nit_service);
71 # Current instance of `Service`, if any
72 var service
: nullable Service = null
74 # Launch `Service` in the background, it will be set as `service` when ready
75 fun start_service
do native_context
.start_service
77 # Register a service from Java/C
79 # FIXME remove when #1941 is fixed
80 private fun register_service
(java_service
: NativeService): Service
82 return new Service(java_service
.new_global_ref
)
85 # Prioritize an activity context if one is running, fallback on a service
86 redef fun native_context
88 if activities
.not_empty
then return super
91 assert service
!= null
95 # Dummy method to force the compilation of callbacks from C
97 # The callbacks are used in the launch of a Nit service from C code.
98 private fun force_service_callbacks_in_c
import Service, register_service
,
99 Service.on_start_command
, Service.on_create
, Service.on_destroy
, Service.native
`{ `}
105 # Call the dummy method to force their compilation in global compilation
106 force_service_callbacks_in_c
110 # Android service with its life-cycle callbacks
112 # Java service with the Android context of this service
113 var native: NativeService
115 # The service has been created
116 fun on_create do app.service = self
118 # The service received a start command (may happen more then once per service)
120 # Should return either `start_sticky
`, `start_not_sticky
` or `start_redeliver_intent
`.
121 fun on_start_command(intent: JavaObject, flags, id: Int): Int do return start_sticky
123 # The service is being destroyed
124 fun on_destroy do app.service = null
127 # Wrapper of Java class `android
.app
.Service`
128 extern class NativeService in "Java" `{ android.app.Service `}
131 redef fun new_global_ref
import sys
, Sys.jni_env
`{
132 Sys sys = NativeService_sys(self);
133 JNIEnv *env = Sys_jni_env(sys);
134 return (*env)->NewGlobalRef(env, self);
138 redef class NativeContext
139 private fun start_service
in "Java" `{
140 android.content.Intent intent =
141 new android.content.Intent(self, nit.app.NitService.class);
142 self.startService(intent);
146 # The service is explicitly started and stopped, it is restarted if stopped by the system
148 # Return value of `Service::on_start_command`.
149 fun start_sticky
: Int in "Java" `{ return android.app.Service.START_STICKY; `}
151 # The service may be stopped by the system and will not be restarted
153 # Return value of `Service::on_start_command
`.
154 fun start_not_sticky: Int in "Java" `{ return android.app.Service.START_NOT_STICKY; `}
156 # The service is explicitly started and stopped, it is restarted with the last intent if stopped by the system
158 # Return value of `Service::on_start_command`.
159 fun start_redeliver_intent
: Int in "Java" `{ return android.app.Service.START_REDELIVER_INTENT; `}