OLD | NEW |
(Empty) | |
| 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 |
| 3 // BSD-style license that can be found in the LICENSE file. |
| 4 |
| 5 #include "embedders/openglui/android/eventloop.h" |
| 6 |
| 7 #include "embedders/openglui/common/log.h" |
| 8 |
| 9 EventLoop::EventLoop(android_app* application) |
| 10 : enabled_(false), |
| 11 quit_(false), |
| 12 application_(application), |
| 13 lifecycle_handler_(NULL), |
| 14 input_handler_(NULL) { |
| 15 application_->onAppCmd = ActivityCallback; |
| 16 application_->onInputEvent = InputCallback; |
| 17 application_->userData = this; |
| 18 } |
| 19 |
| 20 void EventLoop::Run(LifeCycleHandler* lifecycle_handler, |
| 21 InputHandler* input_handler) { |
| 22 int32_t result; |
| 23 int32_t events; |
| 24 android_poll_source* source; |
| 25 |
| 26 lifecycle_handler_ = lifecycle_handler; |
| 27 input_handler_ = input_handler; |
| 28 LOGI("Starting event loop"); |
| 29 while (true) { |
| 30 // If not enabled, block on events. If enabled, don't block |
| 31 // so we can do useful work in onStep. |
| 32 while ((result = ALooper_pollAll(enabled_ ? 0 : -1, |
| 33 NULL, |
| 34 &events, |
| 35 reinterpret_cast<void**>(&source))) >= 0) { |
| 36 if (source != NULL) { |
| 37 source->process(application_, source); |
| 38 } |
| 39 if (application_->destroyRequested) { |
| 40 return; |
| 41 } |
| 42 } |
| 43 if (enabled_ && !quit_) { |
| 44 LOGI("step"); |
| 45 if (lifecycle_handler_->OnStep() != 0) { |
| 46 quit_ = true; |
| 47 ANativeActivity_finish(application_->activity); |
| 48 } |
| 49 } |
| 50 } |
| 51 } |
| 52 |
| 53 // Called when we gain focus. |
| 54 void EventLoop::Activate() { |
| 55 LOGI("activate"); |
| 56 if (!enabled_ && application_->window != NULL) { |
| 57 quit_ = false; |
| 58 enabled_ = true; |
| 59 if (lifecycle_handler_->OnActivate() != 0) { |
| 60 quit_ = true; |
| 61 ANativeActivity_finish(application_->activity); |
| 62 } |
| 63 } |
| 64 } |
| 65 |
| 66 // Called when we lose focus. |
| 67 void EventLoop::Deactivate() { |
| 68 LOGI("deactivate"); |
| 69 if (enabled_) { |
| 70 lifecycle_handler_->OnDeactivate(); |
| 71 enabled_ = false; |
| 72 } |
| 73 } |
| 74 |
| 75 void EventLoop::ProcessActivityEvent(int32_t command) { |
| 76 switch (command) { |
| 77 case APP_CMD_CONFIG_CHANGED: |
| 78 lifecycle_handler_->OnConfigurationChanged(); |
| 79 break; |
| 80 case APP_CMD_INIT_WINDOW: |
| 81 lifecycle_handler_->OnCreateWindow(); |
| 82 break; |
| 83 case APP_CMD_DESTROY: |
| 84 lifecycle_handler_->OnDestroy(); |
| 85 break; |
| 86 case APP_CMD_GAINED_FOCUS: |
| 87 Activate(); |
| 88 lifecycle_handler_->OnGainedFocus(); |
| 89 break; |
| 90 case APP_CMD_LOST_FOCUS: |
| 91 lifecycle_handler_->OnLostFocus(); |
| 92 Deactivate(); |
| 93 break; |
| 94 case APP_CMD_LOW_MEMORY: |
| 95 lifecycle_handler_->OnLowMemory(); |
| 96 break; |
| 97 case APP_CMD_PAUSE: |
| 98 lifecycle_handler_->OnPause(); |
| 99 Deactivate(); |
| 100 break; |
| 101 case APP_CMD_RESUME: |
| 102 lifecycle_handler_->OnResume(); |
| 103 break; |
| 104 case APP_CMD_SAVE_STATE: |
| 105 lifecycle_handler_->OnSaveState(&application_->savedState, |
| 106 &application_->savedStateSize); |
| 107 break; |
| 108 case APP_CMD_START: |
| 109 lifecycle_handler_->OnStart(); |
| 110 break; |
| 111 case APP_CMD_STOP: |
| 112 lifecycle_handler_->OnStop(); |
| 113 break; |
| 114 case APP_CMD_TERM_WINDOW: |
| 115 lifecycle_handler_->OnDestroyWindow(); |
| 116 Deactivate(); |
| 117 break; |
| 118 default: |
| 119 break; |
| 120 } |
| 121 } |
| 122 |
| 123 bool EventLoop::OnTouchEvent(AInputEvent* event) { |
| 124 int32_t type = AMotionEvent_getAction(event); |
| 125 MotionEvent motion_event; |
| 126 switch (type) { |
| 127 case AMOTION_EVENT_ACTION_DOWN: |
| 128 motion_event = kMotionDown; |
| 129 break; |
| 130 case AMOTION_EVENT_ACTION_UP: |
| 131 motion_event = kMotionUp; |
| 132 break; |
| 133 case AMOTION_EVENT_ACTION_MOVE: |
| 134 motion_event = kMotionMove; |
| 135 break; |
| 136 case AMOTION_EVENT_ACTION_CANCEL: |
| 137 motion_event = kMotionCancel; |
| 138 break; |
| 139 case AMOTION_EVENT_ACTION_OUTSIDE: |
| 140 motion_event = kMotionOutside; |
| 141 break; |
| 142 case AMOTION_EVENT_ACTION_POINTER_DOWN: |
| 143 motion_event = kMotionPointerDown; |
| 144 break; |
| 145 case AMOTION_EVENT_ACTION_POINTER_UP: |
| 146 motion_event = kMotionPointerUp; |
| 147 break; |
| 148 default: |
| 149 return false; |
| 150 } |
| 151 // For now we just get the last coords. |
| 152 float move_x = AMotionEvent_getX(event, 0); |
| 153 float move_y = AMotionEvent_getY(event, 0); |
| 154 int64_t when = AMotionEvent_getEventTime(event); |
| 155 LOGI("Got motion event %d at %f, %f", type, move_x, move_y); |
| 156 |
| 157 if (input_handler_->OnMotionEvent(motion_event, when, move_x, move_y) != 0) { |
| 158 return false; |
| 159 } |
| 160 return true; |
| 161 } |
| 162 |
| 163 bool EventLoop::OnKeyEvent(AInputEvent* event) { |
| 164 int32_t type = AKeyEvent_getAction(event); |
| 165 KeyEvent key_event; |
| 166 switch (type) { |
| 167 case AKEY_EVENT_ACTION_DOWN: |
| 168 key_event = kKeyDown; |
| 169 break; |
| 170 case AKEY_EVENT_ACTION_UP: |
| 171 key_event = kKeyUp; |
| 172 break; |
| 173 case AKEY_EVENT_ACTION_MULTIPLE: |
| 174 key_event = kKeyMultiple; |
| 175 break; |
| 176 default: |
| 177 return false; |
| 178 } |
| 179 int32_t flags = AKeyEvent_getFlags(event); |
| 180 /* Get the key code of the key event. |
| 181 * This is the physical key that was pressed, not the Unicode character. */ |
| 182 int32_t key_code = AKeyEvent_getKeyCode(event); |
| 183 /* Get the meta key state. */ |
| 184 int32_t meta_state = AKeyEvent_getMetaState(event); |
| 185 /* Get the repeat count of the event. |
| 186 * For both key up an key down events, this is the number of times the key |
| 187 * has repeated with the first down starting at 0 and counting up from |
| 188 * there. For multiple key events, this is the number of down/up pairs |
| 189 * that have occurred. */ |
| 190 int32_t repeat = AKeyEvent_getRepeatCount(event); |
| 191 |
| 192 /* Get the time of the most recent key down event, in the |
| 193 * java.lang.System.nanoTime() time base. If this is a down event, |
| 194 * this will be the same as eventTime. |
| 195 * Note that when chording keys, this value is the down time of the most |
| 196 * recently pressed key, which may not be the same physical key of this |
| 197 * event. */ |
| 198 // TODO(gram): Use or remove this. |
| 199 // int64_t key_down_time = AKeyEvent_getDownTime(event); |
| 200 |
| 201 /* Get the time this event occurred, in the |
| 202 * java.lang.System.nanoTime() time base. */ |
| 203 int64_t when = AKeyEvent_getEventTime(event); |
| 204 |
| 205 LOGI("Got key event %d %d", type, key_code); |
| 206 if (input_handler_->OnKeyEvent(key_event, when, flags, key_code, |
| 207 meta_state, repeat) != 0) { |
| 208 return false; |
| 209 } |
| 210 return true; |
| 211 } |
| 212 |
| 213 int32_t EventLoop::ProcessInputEvent(AInputEvent* event) { |
| 214 int32_t event_type = AInputEvent_getType(event); |
| 215 LOGI("Got input event type %d", event_type); |
| 216 switch (event_type) { |
| 217 case AINPUT_EVENT_TYPE_MOTION: |
| 218 if (AInputEvent_getSource(event) == AINPUT_SOURCE_TOUCHSCREEN) { |
| 219 return OnTouchEvent(event); |
| 220 } |
| 221 break; |
| 222 case AINPUT_EVENT_TYPE_KEY: |
| 223 return OnKeyEvent(event); |
| 224 } |
| 225 return 0; |
| 226 } |
| 227 |
| 228 void EventLoop::ActivityCallback(android_app* application, int32_t command) { |
| 229 EventLoop* event_loop = reinterpret_cast<EventLoop*>(application->userData); |
| 230 event_loop->ProcessActivityEvent(command); |
| 231 } |
| 232 |
| 233 int32_t EventLoop::InputCallback(android_app* application, |
| 234 AInputEvent* event) { |
| 235 EventLoop* event_loop = reinterpret_cast<EventLoop*>(application->userData); |
| 236 return event_loop->ProcessInputEvent(event); |
| 237 } |
| 238 |
OLD | NEW |