1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Copyright (C) 2010 The Android Open Source Project 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Licensed under the Apache License, Version 2.0 (the "License"); 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * you may not use this file except in compliance with the License. 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * You may obtain a copy of the License at 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * http://www.apache.org/licenses/LICENSE-2.0 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Unless required by applicable law or agreed to in writing, software 11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * distributed under the License is distributed on an "AS IS" BASIS, 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * See the License for the specific language governing permissions and 14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * limitations under the License. 15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * 16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//BEGIN_INCLUDE(all) 19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <jni.h> 20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <errno.h> 21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <EGL/egl.h> 23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <GLES/gl.h> 24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <android/sensor.h> 26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <android/log.h> 27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <android_native_app_glue.h> 28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "native-activity", __VA_ARGS__)) 30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "native-activity", __VA_ARGS__)) 31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/** 33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Our saved state data. 34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstruct saved_state { 36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org float angle; 37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int32_t x; 38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int32_t y; 39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}; 40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/** 42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Shared state for our app. 43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstruct engine { 45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org struct android_app* app; 46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ASensorManager* sensorManager; 48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const ASensor* accelerometerSensor; 49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ASensorEventQueue* sensorEventQueue; 50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int animating; 52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EGLDisplay display; 53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EGLSurface surface; 54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EGLContext context; 55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int32_t width; 56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int32_t height; 57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org struct saved_state state; 58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}; 59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/** 61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Initialize an EGL context for the current display. 62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic int engine_init_display(struct engine* engine) { 64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // initialize OpenGL ES and EGL 65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* 67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Here specify the attributes of the desired configuration. 68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Below, we select an EGLConfig with at least 8 bits per color 69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * component compatible with on-screen windows 70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const EGLint attribs[] = { 72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EGL_BLUE_SIZE, 8, 74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EGL_GREEN_SIZE, 8, 75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EGL_RED_SIZE, 8, 76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EGL_NONE 77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org }; 78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EGLint w, h, dummy, format; 79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EGLint numConfigs; 80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EGLConfig config; 81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EGLSurface surface; 82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EGLContext context; 83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org eglInitialize(display, 0, 0); 87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* Here, the application chooses the configuration it desires. In this 89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * sample, we have a very simplified selection process, where we pick 90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * the first EGLConfig that matches our criteria */ 91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org eglChooseConfig(display, attribs, &config, 1, &numConfigs); 92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /* EGL_NATIVE_VISUAL_ID is an attribute of the EGLConfig that is 94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * guaranteed to be accepted by ANativeWindow_setBuffersGeometry(). 95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * As soon as we picked a EGLConfig, we can safely reconfigure the 96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * ANativeWindow buffers to match, using EGL_NATIVE_VISUAL_ID. */ 97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org eglGetConfigAttrib(display, config, EGL_NATIVE_VISUAL_ID, &format); 98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ANativeWindow_setBuffersGeometry(engine->app->window, 0, 0, format); 100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org surface = eglCreateWindowSurface(display, config, engine->app->window, NULL); 102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org context = eglCreateContext(display, config, NULL, NULL); 103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (eglMakeCurrent(display, surface, surface, context) == EGL_FALSE) { 105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LOGW("Unable to eglMakeCurrent"); 106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return -1; 107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org eglQuerySurface(display, surface, EGL_WIDTH, &w); 110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org eglQuerySurface(display, surface, EGL_HEIGHT, &h); 111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine->display = display; 113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine->context = context; 114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine->surface = surface; 115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine->width = w; 116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine->height = h; 117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine->state.angle = 0; 118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Initialize GL state. 120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST); 121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org glEnable(GL_CULL_FACE); 122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org glShadeModel(GL_SMOOTH); 123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org glDisable(GL_DEPTH_TEST); 124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/** 129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Just the current frame in the display. 130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic void engine_draw_frame(struct engine* engine) { 132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (engine->display == NULL) { 133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // No display. 134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return; 135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Just fill the screen with a color. 138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org glClearColor(((float)engine->state.x)/engine->width, engine->state.angle, 139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ((float)engine->state.y)/engine->height, 1); 140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org glClear(GL_COLOR_BUFFER_BIT); 141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org eglSwapBuffers(engine->display, engine->surface); 143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/** 146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Tear down the EGL context currently associated with the display. 147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic void engine_term_display(struct engine* engine) { 149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (engine->display != EGL_NO_DISPLAY) { 150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org eglMakeCurrent(engine->display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (engine->context != EGL_NO_CONTEXT) { 152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org eglDestroyContext(engine->display, engine->context); 153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (engine->surface != EGL_NO_SURFACE) { 155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org eglDestroySurface(engine->display, engine->surface); 156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org eglTerminate(engine->display); 158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine->animating = 0; 160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine->display = EGL_NO_DISPLAY; 161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine->context = EGL_NO_CONTEXT; 162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine->surface = EGL_NO_SURFACE; 163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/** 166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Process the next input event. 167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic int32_t engine_handle_input(struct android_app* app, AInputEvent* event) { 169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org struct engine* engine = (struct engine*)app->userData; 170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (AInputEvent_getType(event) == AINPUT_EVENT_TYPE_MOTION) { 171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine->animating = 1; 172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine->state.x = AMotionEvent_getX(event, 0); 173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine->state.y = AMotionEvent_getY(event, 0); 174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 1; 175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return 0; 177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/** 180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Process the next main command. 181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgstatic void engine_handle_cmd(struct android_app* app, int32_t cmd) { 183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org struct engine* engine = (struct engine*)app->userData; 184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org switch (cmd) { 185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case APP_CMD_SAVE_STATE: 186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // The system has asked us to save our current state. Do so. 187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine->app->savedState = malloc(sizeof(struct saved_state)); 188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *((struct saved_state*)engine->app->savedState) = engine->state; 189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine->app->savedStateSize = sizeof(struct saved_state); 190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case APP_CMD_INIT_WINDOW: 192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // The window is being shown, get it ready. 193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (engine->app->window != NULL) { 194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine_init_display(engine); 195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine_draw_frame(engine); 196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case APP_CMD_TERM_WINDOW: 199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // The window is being hidden or closed, clean it up. 200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine_term_display(engine); 201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case APP_CMD_GAINED_FOCUS: 203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // When our app gains focus, we start monitoring the accelerometer. 204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (engine->accelerometerSensor != NULL) { 205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ASensorEventQueue_enableSensor(engine->sensorEventQueue, 206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine->accelerometerSensor); 207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // We'd like to get 60 events per second (in us). 208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ASensorEventQueue_setEventRate(engine->sensorEventQueue, 209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine->accelerometerSensor, (1000L/60)*1000); 210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org case APP_CMD_LOST_FOCUS: 213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // When our app loses focus, we stop monitoring the accelerometer. 214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // This is to avoid consuming battery while not being used. 215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (engine->accelerometerSensor != NULL) { 216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ASensorEventQueue_disableSensor(engine->sensorEventQueue, 217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine->accelerometerSensor); 218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Also stop animating. 220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine->animating = 0; 221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine_draw_frame(engine); 222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org break; 223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/** 227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * This is the main entry point of a native application that is using 228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * android_native_app_glue. It runs in its own thread, with its own 229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * event loop for receiving input events and doing other things. 230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */ 231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid android_main(struct android_app* state) { 232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org struct engine engine; 233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Make sure glue isn't stripped. 235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org app_dummy(); 236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org memset(&engine, 0, sizeof(engine)); 238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org state->userData = &engine; 239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org state->onAppCmd = engine_handle_cmd; 240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org state->onInputEvent = engine_handle_input; 241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine.app = state; 242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Prepare to monitor accelerometer 244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine.sensorManager = ASensorManager_getInstance(); 245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine.accelerometerSensor = ASensorManager_getDefaultSensor(engine.sensorManager, 246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ASENSOR_TYPE_ACCELEROMETER); 247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine.sensorEventQueue = ASensorManager_createEventQueue(engine.sensorManager, 248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org state->looper, LOOPER_ID_USER, NULL, NULL); 249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (state->savedState != NULL) { 251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // We are starting with a previous saved state; restore from it. 252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine.state = *(struct saved_state*)state->savedState; 253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // loop waiting for stuff to do. 256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org while (1) { 258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Read all pending events. 259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int ident; 260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org int events; 261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org struct android_poll_source* source; 262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // If not animating, we will block forever waiting for events. 264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // If animating, we loop until all events are read, then continue 265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // to draw the next frame of animation. 266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org while ((ident=ALooper_pollAll(engine.animating ? 0 : -1, NULL, &events, 267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org (void**)&source)) >= 0) { 268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Process this event. 270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (source != NULL) { 271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org source->process(state, source); 272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // If a sensor has data, process it now. 275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (ident == LOOPER_ID_USER) { 276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (engine.accelerometerSensor != NULL) { 277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org ASensorEvent event; 278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org while (ASensorEventQueue_getEvents(engine.sensorEventQueue, 279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org &event, 1) > 0) { 280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org LOGI("accelerometer: x=%f y=%f z=%f", 281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org event.acceleration.x, event.acceleration.y, 282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org event.acceleration.z); 283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Check if we are exiting. 288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (state->destroyRequested != 0) { 289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine_term_display(&engine); 290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org return; 291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (engine.animating) { 295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Done with events; draw next animation frame. 296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine.state.angle += .01f; 297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (engine.state.angle > 1) { 298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine.state.angle = 0; 299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Drawing is throttled to the screen update rate, so there 302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // is no need to do timing here. 303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org engine_draw_frame(&engine); 304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org } 306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org} 307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//END_INCLUDE(all) 308