| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "embedders/openglui/android/eventloop.h" | 5 #include "embedders/openglui/android/eventloop.h" |
| 6 | 6 |
| 7 #include <time.h> |
| 7 #include "embedders/openglui/common/log.h" | 8 #include "embedders/openglui/common/log.h" |
| 8 | 9 |
| 9 /* | 10 /* |
| 10 * The Android lifecycle events are: | 11 * The Android lifecycle events are: |
| 11 * | 12 * |
| 12 * OnCreate: In NDK this is the call to android_main | 13 * OnCreate: In NDK this is the call to android_main |
| 13 * | 14 * |
| 14 * OnStart: technically, called to initiate the “visible” lifespan of the | 15 * OnStart: technically, called to initiate the “visible” lifespan of the |
| 15 * app; at any time between OnStart and OnStop, the app may be visible. | 16 * app; at any time between OnStart and OnStop, the app may be visible. |
| 16 * We can either be OnResume’d or OnStop’ped from this state. Note that | 17 * We can either be OnResume’d or OnStop’ped from this state. Note that |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 147 * 9. In OnDestroy, release all other resources. | 148 * 9. In OnDestroy, release all other resources. |
| 148 */ | 149 */ |
| 149 EventLoop::EventLoop(android_app* application) | 150 EventLoop::EventLoop(android_app* application) |
| 150 : enabled_(false), | 151 : enabled_(false), |
| 151 quit_(false), | 152 quit_(false), |
| 152 isResumed_(false), | 153 isResumed_(false), |
| 153 hasSurface_(false), | 154 hasSurface_(false), |
| 154 hasFocus_(false), | 155 hasFocus_(false), |
| 155 application_(application), | 156 application_(application), |
| 156 lifecycle_handler_(NULL), | 157 lifecycle_handler_(NULL), |
| 157 input_handler_(NULL) { | 158 input_handler_(NULL), |
| 159 sensor_manager_(NULL), |
| 160 sensor_event_queue_(NULL), |
| 161 sensor_poll_source_() { |
| 158 application_->onAppCmd = ActivityCallback; | 162 application_->onAppCmd = ActivityCallback; |
| 159 application_->onInputEvent = InputCallback; | 163 application_->onInputEvent = InputCallback; |
| 160 application_->userData = this; | 164 application_->userData = this; |
| 161 } | 165 } |
| 162 | 166 |
| 167 static int64_t getTimeInMillis() { |
| 168 struct timespec res; |
| 169 clock_gettime(CLOCK_REALTIME, &res); |
| 170 return 1000 * res.tv_sec + res.tv_nsec / 1000000; |
| 171 } |
| 172 |
| 163 void EventLoop::Run(LifeCycleHandler* lifecycle_handler, | 173 void EventLoop::Run(LifeCycleHandler* lifecycle_handler, |
| 164 InputHandler* input_handler) { | 174 InputHandler* input_handler) { |
| 165 int32_t result; | 175 int32_t result; |
| 166 int32_t events; | 176 int32_t events; |
| 167 android_poll_source* source; | 177 android_poll_source* source; |
| 168 | 178 |
| 169 lifecycle_handler_ = lifecycle_handler; | 179 lifecycle_handler_ = lifecycle_handler; |
| 170 input_handler_ = input_handler; | 180 input_handler_ = input_handler; |
| 181 int64_t last_frame_time = getTimeInMillis(); |
| 171 if (lifecycle_handler_->OnStart() == 0) { | 182 if (lifecycle_handler_->OnStart() == 0) { |
| 172 LOGI("Starting event loop"); | 183 LOGI("Starting event loop"); |
| 173 while (!quit_) { | 184 while (!quit_) { |
| 174 // If not enabled, block indefinitely on events. If enabled, block | 185 // If not enabled, block indefinitely on events. If enabled, block |
| 175 // briefly so we can do useful work in onStep. Ultimately this is | 186 // briefly so we can do useful work in onStep, but only long |
| 176 // where we would want to look at elapsed time since the last call | 187 // enough that we can still do work at 60fps if possible. |
| 177 // to onStep completed and use a delay that gives us ~60fps. | 188 int64_t next_frame_time = last_frame_time + (1000/60); |
| 178 while ((result = ALooper_pollAll(enabled_ ? (1000/60) : -1, NULL, | 189 int64_t next_frame_delay = next_frame_time - getTimeInMillis(); |
| 190 if (next_frame_delay < 0) next_frame_delay = 0; |
| 191 while ((result = ALooper_pollAll(enabled_ ? next_frame_delay : -1, NULL, |
| 179 &events, reinterpret_cast<void**>(&source))) >= 0) { | 192 &events, reinterpret_cast<void**>(&source))) >= 0) { |
| 180 if (source != NULL) { | 193 if (source != NULL) { |
| 181 source->process(application_, source); | 194 source->process(application_, source); |
| 182 } | 195 } |
| 183 if (application_->destroyRequested) { | 196 if (application_->destroyRequested) { |
| 184 return; | 197 return; |
| 185 } | 198 } |
| 186 } | 199 } |
| 187 if (enabled_ && !quit_) { | 200 if (enabled_ && !quit_) { |
| 188 LOGI("step"); | 201 int64_t now = getTimeInMillis(); |
| 189 if (lifecycle_handler_->OnStep() != 0) { | 202 if (now >= next_frame_time) { |
| 190 quit_ = true; | 203 LOGI("step"); |
| 204 last_frame_time = now; |
| 205 if (lifecycle_handler_->OnStep() != 0) { |
| 206 quit_ = true; |
| 207 } |
| 191 } | 208 } |
| 192 } | 209 } |
| 193 } | 210 } |
| 194 } | 211 } |
| 195 ANativeActivity_finish(application_->activity); | 212 ANativeActivity_finish(application_->activity); |
| 196 } | 213 } |
| 197 | 214 |
| 215 void EventLoop::EnableSensorEvents() { |
| 216 sensor_poll_source_.id = LOOPER_ID_USER; |
| 217 sensor_poll_source_.app = application_; |
| 218 sensor_poll_source_.process = SensorCallback; |
| 219 sensor_manager_ = ASensorManager_getInstance(); |
| 220 if (sensor_manager_ != NULL) { |
| 221 sensor_event_queue_ = ASensorManager_createEventQueue( |
| 222 sensor_manager_, application_->looper, |
| 223 LOOPER_ID_USER, NULL, &sensor_poll_source_); |
| 224 |
| 225 sensor_ = ASensorManager_getDefaultSensor(sensor_manager_, |
| 226 ASENSOR_TYPE_ACCELEROMETER); |
| 227 if (sensor_ != NULL) { |
| 228 int32_t min_delay = ASensor_getMinDelay(sensor_); |
| 229 if (ASensorEventQueue_enableSensor(sensor_event_queue_, sensor_) < 0 || |
| 230 ASensorEventQueue_setEventRate(sensor_event_queue_, sensor_, |
| 231 min_delay) < 0) { |
| 232 LOGE("Error while activating sensor."); |
| 233 DisableSensorEvents(); |
| 234 return; |
| 235 } |
| 236 LOGI("Activating sensor:"); |
| 237 LOGI("Name : %s", ASensor_getName(sensor_)); |
| 238 LOGI("Vendor : %s", ASensor_getVendor(sensor_)); |
| 239 LOGI("Resolution : %f", ASensor_getResolution(sensor_)); |
| 240 LOGI("Min Delay : %d", min_delay); |
| 241 } else { |
| 242 LOGI("No sensor"); |
| 243 } |
| 244 } |
| 245 } |
| 246 |
| 247 void EventLoop::DisableSensorEvents() { |
| 248 if (sensor_ != NULL) { |
| 249 if (ASensorEventQueue_disableSensor(sensor_event_queue_, sensor_) < 0) { |
| 250 LOGE("Error while deactivating sensor."); |
| 251 } |
| 252 sensor_ = NULL; |
| 253 } |
| 254 if (sensor_event_queue_ != NULL) { |
| 255 ASensorManager_destroyEventQueue(sensor_manager_, |
| 256 sensor_event_queue_); |
| 257 sensor_event_queue_ = NULL; |
| 258 } |
| 259 sensor_manager_ = NULL; |
| 260 } |
| 261 |
| 198 void EventLoop::ProcessActivityEvent(int32_t command) { | 262 void EventLoop::ProcessActivityEvent(int32_t command) { |
| 199 switch (command) { | 263 switch (command) { |
| 200 case APP_CMD_INIT_WINDOW: | 264 case APP_CMD_INIT_WINDOW: |
| 201 if (lifecycle_handler_->Activate() != 0) { | 265 if (lifecycle_handler_->Activate() != 0) { |
| 202 quit_ = true; | 266 quit_ = true; |
| 203 } else { | 267 } else { |
| 204 hasSurface_ = true; | 268 hasSurface_ = true; |
| 205 } | 269 } |
| 206 break; | 270 break; |
| 207 case APP_CMD_CONFIG_CHANGED: | 271 case APP_CMD_CONFIG_CHANGED: |
| 208 lifecycle_handler_->OnConfigurationChanged(); | 272 lifecycle_handler_->OnConfigurationChanged(); |
| 209 break; | 273 break; |
| 210 case APP_CMD_DESTROY: | 274 case APP_CMD_DESTROY: |
| 211 hasFocus_ = false; | 275 hasFocus_ = false; |
| 212 lifecycle_handler_->FreeAllResources(); | 276 lifecycle_handler_->FreeAllResources(); |
| 213 break; | 277 break; |
| 214 case APP_CMD_GAINED_FOCUS: | 278 case APP_CMD_GAINED_FOCUS: |
| 215 hasFocus_ = true; | 279 hasFocus_ = true; |
| 216 if (hasSurface_ && isResumed_ && hasFocus_) { | 280 if (hasSurface_ && isResumed_ && hasFocus_) { |
| 217 enabled_ = (lifecycle_handler_->Resume() == 0); | 281 enabled_ = (lifecycle_handler_->Resume() == 0); |
| 282 if (enabled_) { |
| 283 EnableSensorEvents(); |
| 284 } |
| 218 } | 285 } |
| 219 break; | 286 break; |
| 220 case APP_CMD_LOST_FOCUS: | 287 case APP_CMD_LOST_FOCUS: |
| 221 hasFocus_ = false; | 288 hasFocus_ = false; |
| 222 enabled_ = false; | 289 enabled_ = false; |
| 290 DisableSensorEvents(); |
| 223 lifecycle_handler_->Pause(); | 291 lifecycle_handler_->Pause(); |
| 224 break; | 292 break; |
| 225 case APP_CMD_LOW_MEMORY: | 293 case APP_CMD_LOW_MEMORY: |
| 226 lifecycle_handler_->OnLowMemory(); | 294 lifecycle_handler_->OnLowMemory(); |
| 227 break; | 295 break; |
| 228 case APP_CMD_PAUSE: | 296 case APP_CMD_PAUSE: |
| 229 isResumed_ = false; | 297 isResumed_ = false; |
| 230 enabled_ = false; | 298 enabled_ = false; |
| 299 DisableSensorEvents(); |
| 231 lifecycle_handler_->Pause(); | 300 lifecycle_handler_->Pause(); |
| 232 break; | 301 break; |
| 233 case APP_CMD_RESUME: | 302 case APP_CMD_RESUME: |
| 234 isResumed_ = true; | 303 isResumed_ = true; |
| 235 break; | 304 break; |
| 236 case APP_CMD_SAVE_STATE: | 305 case APP_CMD_SAVE_STATE: |
| 237 lifecycle_handler_->OnSaveState(&application_->savedState, | 306 lifecycle_handler_->OnSaveState(&application_->savedState, |
| 238 &application_->savedStateSize); | 307 &application_->savedStateSize); |
| 239 break; | 308 break; |
| 240 case APP_CMD_START: | 309 case APP_CMD_START: |
| 241 break; | 310 break; |
| 242 case APP_CMD_STOP: | 311 case APP_CMD_STOP: |
| 243 hasFocus_ = false; | 312 hasFocus_ = false; |
| 244 lifecycle_handler_->Deactivate(); | 313 lifecycle_handler_->Deactivate(); |
| 245 break; | 314 break; |
| 246 case APP_CMD_TERM_WINDOW: | 315 case APP_CMD_TERM_WINDOW: |
| 247 hasFocus_ = false; | 316 hasFocus_ = false; |
| 248 hasSurface_ = false; | 317 hasSurface_ = false; |
| 249 enabled_ = false; | 318 enabled_ = false; |
| 319 DisableSensorEvents(); |
| 250 lifecycle_handler_->Pause(); | 320 lifecycle_handler_->Pause(); |
| 251 break; | 321 break; |
| 252 default: | 322 default: |
| 253 break; | 323 break; |
| 254 } | 324 } |
| 255 } | 325 } |
| 256 | 326 |
| 327 void EventLoop::ProcessSensorEvent() { |
| 328 ASensorEvent event; |
| 329 while (ASensorEventQueue_getEvents(sensor_event_queue_, &event, 1) > 0) { |
| 330 switch (event.type) { |
| 331 case ASENSOR_TYPE_ACCELEROMETER: |
| 332 input_handler_->OnAccelerometerEvent(event.vector.x, |
| 333 event.vector.y, event.vector.z); |
| 334 break; |
| 335 } |
| 336 } |
| 337 } |
| 338 |
| 257 bool EventLoop::OnTouchEvent(AInputEvent* event) { | 339 bool EventLoop::OnTouchEvent(AInputEvent* event) { |
| 258 int32_t type = AMotionEvent_getAction(event); | 340 int32_t type = AMotionEvent_getAction(event); |
| 259 MotionEvent motion_event; | 341 MotionEvent motion_event; |
| 260 switch (type) { | 342 switch (type) { |
| 261 case AMOTION_EVENT_ACTION_DOWN: | 343 case AMOTION_EVENT_ACTION_DOWN: |
| 262 motion_event = kMotionDown; | 344 motion_event = kMotionDown; |
| 263 break; | 345 break; |
| 264 case AMOTION_EVENT_ACTION_UP: | 346 case AMOTION_EVENT_ACTION_UP: |
| 265 motion_event = kMotionUp; | 347 motion_event = kMotionUp; |
| 266 break; | 348 break; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 303 break; | 385 break; |
| 304 case AKEY_EVENT_ACTION_UP: | 386 case AKEY_EVENT_ACTION_UP: |
| 305 key_event = kKeyUp; | 387 key_event = kKeyUp; |
| 306 break; | 388 break; |
| 307 case AKEY_EVENT_ACTION_MULTIPLE: | 389 case AKEY_EVENT_ACTION_MULTIPLE: |
| 308 key_event = kKeyMultiple; | 390 key_event = kKeyMultiple; |
| 309 break; | 391 break; |
| 310 default: | 392 default: |
| 311 return false; | 393 return false; |
| 312 } | 394 } |
| 313 int32_t flags = AKeyEvent_getFlags(event); | |
| 314 /* Get the key code of the key event. | 395 /* Get the key code of the key event. |
| 315 * This is the physical key that was pressed, not the Unicode character. */ | 396 * This is the physical key that was pressed, not the Unicode character. */ |
| 316 int32_t key_code = AKeyEvent_getKeyCode(event); | 397 int32_t key_code = AKeyEvent_getKeyCode(event); |
| 317 /* Get the meta key state. */ | 398 /* Get the meta key state. */ |
| 318 int32_t meta_state = AKeyEvent_getMetaState(event); | 399 int32_t meta_state = AKeyEvent_getMetaState(event); |
| 319 /* Get the repeat count of the event. | 400 /* Get the repeat count of the event. |
| 320 * For both key up an key down events, this is the number of times the key | 401 * For both key up an key down events, this is the number of times the key |
| 321 * has repeated with the first down starting at 0 and counting up from | 402 * has repeated with the first down starting at 0 and counting up from |
| 322 * there. For multiple key events, this is the number of down/up pairs | 403 * there. For multiple key events, this is the number of down/up pairs |
| 323 * that have occurred. */ | 404 * that have occurred. */ |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 368 EventLoop* event_loop = reinterpret_cast<EventLoop*>(application->userData); | 449 EventLoop* event_loop = reinterpret_cast<EventLoop*>(application->userData); |
| 369 event_loop->ProcessActivityEvent(command); | 450 event_loop->ProcessActivityEvent(command); |
| 370 } | 451 } |
| 371 | 452 |
| 372 int32_t EventLoop::InputCallback(android_app* application, | 453 int32_t EventLoop::InputCallback(android_app* application, |
| 373 AInputEvent* event) { | 454 AInputEvent* event) { |
| 374 EventLoop* event_loop = reinterpret_cast<EventLoop*>(application->userData); | 455 EventLoop* event_loop = reinterpret_cast<EventLoop*>(application->userData); |
| 375 return event_loop->ProcessInputEvent(event); | 456 return event_loop->ProcessInputEvent(event); |
| 376 } | 457 } |
| 377 | 458 |
| 459 void EventLoop::SensorCallback(android_app* application, |
| 460 android_poll_source* source) { |
| 461 EventLoop* event_loop = reinterpret_cast<EventLoop*>(application->userData); |
| 462 event_loop->ProcessSensorEvent(); |
| 463 } |
| 464 |
| OLD | NEW |