diff options
| -rw-r--r-- | core/java/android/app/Activity.java | 36 | ||||
| -rw-r--r-- | core/java/android/app/ActivityManager.java | 40 | ||||
| -rw-r--r-- | core/java/android/app/ActivityThread.java | 26 | ||||
| -rw-r--r-- | core/java/android/view/SurfaceView.java | 3 | ||||
| -rw-r--r-- | core/java/android/view/View.java | 10 | ||||
| -rw-r--r-- | core/res/res/values/dimens.xml | 4 | ||||
| -rw-r--r-- | native/glue/threaded_app/Android.mk | 18 | ||||
| -rw-r--r-- | native/glue/threaded_app/threaded_app.c | 338 | ||||
| -rw-r--r-- | native/include/android_glue/threaded_app.h | 197 |
9 files changed, 97 insertions, 575 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 985f591..f7ccc12 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -67,6 +67,8 @@ import android.view.View.OnCreateContextMenuListener; import android.view.ViewGroup.LayoutParams; import android.view.accessibility.AccessibilityEvent; import android.widget.AdapterView; +import android.widget.FrameLayout; +import android.widget.LinearLayout; import java.util.ArrayList; import java.util.HashMap; @@ -1204,19 +1206,37 @@ public class Activity extends ContextThemeWrapper * @see #onPause */ public boolean onCreateThumbnail(Bitmap outBitmap, Canvas canvas) { - final View view = mDecor; - if (view == null) { + if (mDecor == null) { return false; } - final int vw = view.getWidth(); - final int vh = view.getHeight(); - final int dw = outBitmap.getWidth(); - final int dh = outBitmap.getHeight(); + int paddingLeft = 0; + int paddingRight = 0; + int paddingTop = 0; + int paddingBottom = 0; + + // Find System window and use padding so we ignore space reserved for decorations + // like the status bar and such. + final FrameLayout top = (FrameLayout) mDecor; + for (int i = 0; i < top.getChildCount(); i++) { + View child = top.getChildAt(i); + if (child.isFitsSystemWindowsFlagSet()) { + paddingLeft = child.getPaddingLeft(); + paddingRight = child.getPaddingRight(); + paddingTop = child.getPaddingTop(); + paddingBottom = child.getPaddingBottom(); + break; + } + } + + final int visibleWidth = mDecor.getWidth() - paddingLeft - paddingRight; + final int visibleHeight = mDecor.getHeight() - paddingTop - paddingBottom; canvas.save(); - canvas.scale(((float)dw)/vw, ((float)dh)/vh); - view.draw(canvas); + canvas.scale( (float) outBitmap.getWidth() / visibleWidth, + (float) outBitmap.getHeight() / visibleHeight); + canvas.translate(-paddingLeft, -paddingTop); + mDecor.draw(canvas); canvas.restore(); return true; diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index eb7520f..d66e98b 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -285,24 +285,54 @@ public class ActivityManager { * @param maxNum The maximum number of entries to return in the list. The * actual number returned may be smaller, depending on how many tasks the * user has started. - * + * + * @param flags Optional flags + * @param receiver Optional receiver for delayed thumbnails + * * @return Returns a list of RunningTaskInfo records describing each of * the running tasks. * + * Some thumbnails may not be available at the time of this call. The optional + * receiver may be used to receive those thumbnails. + * * @throws SecurityException Throws SecurityException if the caller does * not hold the {@link android.Manifest.permission#GET_TASKS} permission. + * + * @hide */ - public List<RunningTaskInfo> getRunningTasks(int maxNum) + public List<RunningTaskInfo> getRunningTasks(int maxNum, int flags, IThumbnailReceiver receiver) throws SecurityException { try { - return (List<RunningTaskInfo>)ActivityManagerNative.getDefault() - .getTasks(maxNum, 0, null); + return ActivityManagerNative.getDefault().getTasks(maxNum, flags, receiver); } catch (RemoteException e) { // System dead, we will be dead too soon! return null; } } - + + /** + * Return a list of the tasks that are currently running, with + * the most recent being first and older ones after in order. Note that + * "running" does not mean any of the task's code is currently loaded or + * activity -- the task may have been frozen by the system, so that it + * can be restarted in its previous state when next brought to the + * foreground. + * + * @param maxNum The maximum number of entries to return in the list. The + * actual number returned may be smaller, depending on how many tasks the + * user has started. + * + * @return Returns a list of RunningTaskInfo records describing each of + * the running tasks. + * + * @throws SecurityException Throws SecurityException if the caller does + * not hold the {@link android.Manifest.permission#GET_TASKS} permission. + */ + public List<RunningTaskInfo> getRunningTasks(int maxNum) + throws SecurityException { + return getRunningTasks(maxNum, 0, null); + } + /** * Information you can retrieve about a particular Service that is * currently running in the system. diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 883366b..0fb2b49 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -115,6 +115,7 @@ final class RemoteServiceException extends AndroidRuntimeException { */ public final class ActivityThread { static final String TAG = "ActivityThread"; + private static final android.graphics.Bitmap.Config THUMBNAIL_FORMAT = Bitmap.Config.RGB_565; private static final boolean DEBUG = false; static final boolean localLOGV = DEBUG ? Config.LOGD : Config.LOGV; static final boolean DEBUG_BROADCAST = false; @@ -2210,13 +2211,24 @@ public final class ActivityThread { h = mThumbnailHeight; } - // XXX Only set hasAlpha if needed? - thumbnail = Bitmap.createBitmap(w, h, Bitmap.Config.RGB_565); - thumbnail.eraseColor(0); - Canvas cv = new Canvas(thumbnail); - if (!r.activity.onCreateThumbnail(thumbnail, cv)) { - thumbnail = null; + // On platforms where we don't want thumbnails, set dims to (0,0) + if ((w > 0) && (h > 0)) { + View topView = r.activity.getWindow().getDecorView(); + + // Maximize bitmap by capturing in native aspect. + if (topView.getWidth() >= topView.getHeight()) { + thumbnail = Bitmap.createBitmap(w, h, THUMBNAIL_FORMAT); + } else { + thumbnail = Bitmap.createBitmap(h, w, THUMBNAIL_FORMAT); + } + + thumbnail.eraseColor(0); + Canvas cv = new Canvas(thumbnail); + if (!r.activity.onCreateThumbnail(thumbnail, cv)) { + thumbnail = null; + } } + } catch (Exception e) { if (!mInstrumentation.onException(r.activity, e)) { throw new RuntimeException( @@ -2347,7 +2359,7 @@ public final class ActivityThread { if (info != null) { try { // First create a thumbnail for the activity... - //info.thumbnail = createThumbnailBitmap(r); + info.thumbnail = createThumbnailBitmap(r); info.description = r.activity.onCreateDescription(); } catch (Exception e) { if (!mInstrumentation.onException(r.activity, e)) { diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index c469bcc..54cb4ca 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -543,6 +543,9 @@ public class SurfaceView extends View { } if (creating || formatChanged || sizeChanged || visibleChanged || realSizeChanged) { + for (SurfaceHolder.Callback c : callbacks) { + c.surfaceChanged(mSurfaceHolder, mFormat, myWidth, myHeight); + } } if (redrawNeeded) { for (SurfaceHolder.Callback c : callbacks) { diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 11e5ad1..329b2e7 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -3005,6 +3005,16 @@ public class View implements Drawable.Callback, KeyEvent.Callback, Accessibility } /** + * Determine if this view has the FITS_SYSTEM_WINDOWS flag set. + * @return True if window has FITS_SYSTEM_WINDOWS set + * + * @hide + */ + public boolean isFitsSystemWindowsFlagSet() { + return (mViewFlags & FITS_SYSTEM_WINDOWS) == FITS_SYSTEM_WINDOWS; + } + + /** * Returns the visibility status for this view. * * @return One of {@link #VISIBLE}, {@link #INVISIBLE}, or {@link #GONE}. diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml index 99c0b3d..11f3e50 100644 --- a/core/res/res/values/dimens.xml +++ b/core/res/res/values/dimens.xml @@ -19,9 +19,9 @@ --> <resources> <!-- The width that is used when creating thumbnails of applications. --> - <dimen name="thumbnail_width">84dp</dimen> + <dimen name="thumbnail_width">0dp</dimen> <!-- The height that is used when creating thumbnails of applications. --> - <dimen name="thumbnail_height">63dp</dimen> + <dimen name="thumbnail_height">0dp</dimen> <!-- The standard size (both width and height) of an application icon that will be displayed in the app launcher and elsewhere. --> <dimen name="app_icon_size">48dip</dimen> diff --git a/native/glue/threaded_app/Android.mk b/native/glue/threaded_app/Android.mk deleted file mode 100644 index cfc9b2a..0000000 --- a/native/glue/threaded_app/Android.mk +++ /dev/null @@ -1,18 +0,0 @@ -BASE_PATH := $(call my-dir) -LOCAL_PATH:= $(call my-dir) - -include $(CLEAR_VARS) - -# our source files -# -LOCAL_SRC_FILES:= \ - threaded_app.c - -LOCAL_C_INCLUDES += \ - frameworks/base/native/include \ - frameworks/base/core/jni/android \ - dalvik/libnativehelper/include/nativehelper - -LOCAL_MODULE:= libthreaded_app - -include $(BUILD_STATIC_LIBRARY) diff --git a/native/glue/threaded_app/threaded_app.c b/native/glue/threaded_app/threaded_app.c deleted file mode 100644 index 452c735..0000000 --- a/native/glue/threaded_app/threaded_app.c +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include <jni.h> - -#include <errno.h> -#include <fcntl.h> -#include <string.h> -#include <unistd.h> -#include <sys/resource.h> - -#include <android_glue/threaded_app.h> - -#include <android/log.h> - -#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "threaded_app", __VA_ARGS__)) -#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "threaded_app", __VA_ARGS__)) - -int8_t android_app_read_cmd(struct android_app* android_app) { - int8_t cmd; - if (read(android_app->msgread, &cmd, sizeof(cmd)) == sizeof(cmd)) { - return cmd; - } else { - LOGW("No data on command pipe!"); - } - return -1; -} - -int32_t android_app_exec_cmd(struct android_app* android_app, int8_t cmd) { - switch (cmd) { - case APP_CMD_INPUT_CHANGED: - LOGI("APP_CMD_INPUT_CHANGED\n"); - pthread_mutex_lock(&android_app->mutex); - if (android_app->inputQueue != NULL) { - AInputQueue_detachLooper(android_app->inputQueue); - } - android_app->inputQueue = android_app->pendingInputQueue; - if (android_app->inputQueue != NULL) { - LOGI("Attaching input queue to looper"); - AInputQueue_attachLooper(android_app->inputQueue, - android_app->looper, NULL, (void*)LOOPER_ID_EVENT); - } - pthread_cond_broadcast(&android_app->cond); - pthread_mutex_unlock(&android_app->mutex); - break; - - case APP_CMD_WINDOW_CHANGED: - LOGI("APP_CMD_WINDOW_CHANGED\n"); - pthread_mutex_lock(&android_app->mutex); - android_app->window = android_app->pendingWindow; - pthread_cond_broadcast(&android_app->cond); - pthread_mutex_unlock(&android_app->mutex); - break; - - case APP_CMD_START: - case APP_CMD_RESUME: - case APP_CMD_PAUSE: - case APP_CMD_STOP: - LOGI("activityState=%d\n", cmd); - pthread_mutex_lock(&android_app->mutex); - android_app->activityState = cmd; - pthread_cond_broadcast(&android_app->cond); - pthread_mutex_unlock(&android_app->mutex); - break; - - case APP_CMD_WINDOW_REDRAW_NEEDED: - LOGI("APP_CMD_WINDOW_REDRAW_NEEDED\n"); - pthread_mutex_lock(&android_app->mutex); - android_app->redrawNeeded = 0; - pthread_cond_broadcast(&android_app->cond); - pthread_mutex_unlock(&android_app->mutex); - break; - - case APP_CMD_CONTENT_RECT_CHANGED: - LOGI("APP_CMD_CONTENT_RECT_CHANGED\n"); - android_app->contentRect = android_app->pendingContentRect; - break; - - case APP_CMD_DESTROY: - LOGI("APP_CMD_DESTROY\n"); - android_app->destroyRequested = 1; - break; - } - - return android_app->destroyRequested ? 0 : 1; -} - -static void android_app_destroy(struct android_app* android_app) { - LOGI("android_app_destroy!"); - pthread_mutex_lock(&android_app->mutex); - if (android_app->inputQueue != NULL) { - AInputQueue_detachLooper(android_app->inputQueue); - } - android_app->destroyed = 1; - pthread_cond_broadcast(&android_app->cond); - pthread_mutex_unlock(&android_app->mutex); - // Can't touch android_app object after this. -} - -static void* android_app_entry(void* param) { - struct android_app* android_app = (struct android_app*)param; - - ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); - ALooper_addFd(looper, android_app->msgread, POLLIN, NULL, (void*)LOOPER_ID_MAIN); - android_app->looper = looper; - - pthread_mutex_lock(&android_app->mutex); - android_app->running = 1; - pthread_cond_broadcast(&android_app->cond); - pthread_mutex_unlock(&android_app->mutex); - - android_main(android_app); - - android_app_destroy(android_app); - return NULL; -} - -// -------------------------------------------------------------------- -// Native activity interaction (called from main thread) -// -------------------------------------------------------------------- - -static struct android_app* android_app_create(ANativeActivity* activity) { - struct android_app* android_app = (struct android_app*)malloc(sizeof(struct android_app)); - memset(android_app, 0, sizeof(struct android_app)); - android_app->activity = activity; - - pthread_mutex_init(&android_app->mutex, NULL); - pthread_cond_init(&android_app->cond, NULL); - - int msgpipe[2]; - if (pipe(msgpipe)) { - LOGI("could not create pipe: %s", strerror(errno)); - } - android_app->msgread = msgpipe[0]; - android_app->msgwrite = msgpipe[1]; - int result = fcntl(android_app->msgread, F_SETFL, O_NONBLOCK); - if (result != 0) LOGW("Could not make message read pipe " - "non-blocking: %s", strerror(errno)); - result = fcntl(android_app->msgwrite, F_SETFL, O_NONBLOCK); - if (result != 0) LOGW("Could not make message write pipe " - "non-blocking: %s", strerror(errno)); - - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - pthread_create(&android_app->thread, &attr, android_app_entry, android_app); - - // Wait for thread to start. - pthread_mutex_lock(&android_app->mutex); - while (!android_app->running) { - pthread_cond_wait(&android_app->cond, &android_app->mutex); - } - pthread_mutex_unlock(&android_app->mutex); - - return android_app; -} - -static void android_app_write_cmd(struct android_app* android_app, int8_t cmd) { - if (write(android_app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd)) { - LOGI("Failure writing android_app cmd: %s\n", strerror(errno)); - } -} - -static void android_app_set_input(struct android_app* android_app, AInputQueue* inputQueue) { - pthread_mutex_lock(&android_app->mutex); - android_app->pendingInputQueue = inputQueue; - android_app_write_cmd(android_app, APP_CMD_INPUT_CHANGED); - while (android_app->inputQueue != android_app->pendingInputQueue) { - pthread_cond_wait(&android_app->cond, &android_app->mutex); - } - pthread_mutex_unlock(&android_app->mutex); -} - -static void android_app_set_window(struct android_app* android_app, ANativeWindow* window) { - pthread_mutex_lock(&android_app->mutex); - android_app->pendingWindow = window; - android_app_write_cmd(android_app, APP_CMD_WINDOW_CHANGED); - while (android_app->window != android_app->pendingWindow) { - pthread_cond_wait(&android_app->cond, &android_app->mutex); - } - pthread_mutex_unlock(&android_app->mutex); -} - -static void android_app_set_activity_state(struct android_app* android_app, int8_t cmd) { - pthread_mutex_lock(&android_app->mutex); - android_app_write_cmd(android_app, cmd); - while (android_app->activityState != cmd) { - pthread_cond_wait(&android_app->cond, &android_app->mutex); - } - pthread_mutex_unlock(&android_app->mutex); -} - -static void android_app_wait_redraw(struct android_app* android_app) { - pthread_mutex_lock(&android_app->mutex); - android_app->redrawNeeded = 1; - android_app_write_cmd(android_app, APP_CMD_WINDOW_REDRAW_NEEDED); - while (android_app->redrawNeeded) { - pthread_cond_wait(&android_app->cond, &android_app->mutex); - } - pthread_mutex_unlock(&android_app->mutex); -} - -static void android_app_set_content_rect(struct android_app* android_app, const ARect* rect) { - pthread_mutex_lock(&android_app->mutex); - android_app->pendingContentRect = *rect; - android_app_write_cmd(android_app, APP_CMD_CONTENT_RECT_CHANGED); - pthread_mutex_unlock(&android_app->mutex); -} - -static void android_app_free(struct android_app* android_app) { - pthread_mutex_lock(&android_app->mutex); - android_app_write_cmd(android_app, APP_CMD_DESTROY); - while (!android_app->destroyed) { - pthread_cond_wait(&android_app->cond, &android_app->mutex); - } - pthread_mutex_unlock(&android_app->mutex); - - close(android_app->msgread); - close(android_app->msgwrite); - pthread_cond_destroy(&android_app->cond); - pthread_mutex_destroy(&android_app->mutex); - free(android_app); -} - -static void onDestroy(ANativeActivity* activity) { - LOGI("Destroy: %p\n", activity); - android_app_free((struct android_app*)activity->instance); -} - -static void onStart(ANativeActivity* activity) { - LOGI("Start: %p\n", activity); - android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_START); -} - -static void onResume(ANativeActivity* activity) { - LOGI("Resume: %p\n", activity); - android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_RESUME); -} - -static void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen) { - LOGI("SaveInstanceState: %p\n", activity); - return NULL; -} - -static void onPause(ANativeActivity* activity) { - LOGI("Pause: %p\n", activity); - android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_PAUSE); -} - -static void onStop(ANativeActivity* activity) { - LOGI("Stop: %p\n", activity); - android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_STOP); -} - -static void onLowMemory(ANativeActivity* activity) { - LOGI("LowMemory: %p\n", activity); - android_app_write_cmd((struct android_app*)activity->instance, - APP_CMD_LOW_MEMORY); -} - -static void onWindowFocusChanged(ANativeActivity* activity, int focused) { - LOGI("WindowFocusChanged: %p -- %d\n", activity, focused); - android_app_write_cmd((struct android_app*)activity->instance, - focused ? APP_CMD_GAINED_FOCUS : APP_CMD_LOST_FOCUS); -} - -static void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* window) { - LOGI("NativeWindowCreated: %p -- %p\n", activity, window); - android_app_set_window((struct android_app*)activity->instance, window); -} - -static void onNativeWindowResized(ANativeActivity* activity, ANativeWindow* window) { - LOGI("NativeWindowResized: %p -- %p\n", activity, window); - android_app_write_cmd((struct android_app*)activity->instance, - APP_CMD_WINDOW_RESIZED); -} - -static void onNativeWindowRedrawNeeded(ANativeActivity* activity, ANativeWindow* window) { - LOGI("NativeWindowRedrawNeeded: %p -- %p\n", activity, window); - android_app_wait_redraw((struct android_app*)activity->instance); -} - -static void onContentRectChanged(ANativeActivity* activity, const ARect* rect) { - LOGI("ContentRectChanged: %p -- (%d,%d)-(%d,%d)\n", activity, rect->left, - rect->top, rect->right, rect->bottom); - android_app_set_content_rect((struct android_app*)activity->instance, rect); -} - -static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* window) { - LOGI("NativeWindowDestroyed: %p -- %p\n", activity, window); - android_app_set_window((struct android_app*)activity->instance, NULL); -} - -static void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue) { - LOGI("InputQueueCreated: %p -- %p\n", activity, queue); - android_app_set_input((struct android_app*)activity->instance, queue); -} - -static void onInputQueueDestroyed(ANativeActivity* activity, AInputQueue* queue) { - LOGI("InputQueueDestroyed: %p -- %p\n", activity, queue); - android_app_set_input((struct android_app*)activity->instance, NULL); -} - -void ANativeActivity_onCreate(ANativeActivity* activity, - void* savedState, size_t savedStateSize) { - LOGI("Creating: %p\n", activity); - activity->callbacks->onDestroy = onDestroy; - activity->callbacks->onStart = onStart; - activity->callbacks->onResume = onResume; - activity->callbacks->onSaveInstanceState = onSaveInstanceState; - activity->callbacks->onPause = onPause; - activity->callbacks->onStop = onStop; - activity->callbacks->onWindowFocusChanged = onWindowFocusChanged; - activity->callbacks->onNativeWindowCreated = onNativeWindowCreated; - activity->callbacks->onNativeWindowResized = onNativeWindowResized; - activity->callbacks->onNativeWindowRedrawNeeded = onNativeWindowRedrawNeeded; - activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed; - activity->callbacks->onInputQueueCreated = onInputQueueCreated; - activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed; - activity->callbacks->onContentRectChanged = onContentRectChanged; - activity->callbacks->onLowMemory = onLowMemory; - - activity->instance = android_app_create(activity); -} diff --git a/native/include/android_glue/threaded_app.h b/native/include/android_glue/threaded_app.h deleted file mode 100644 index 2b58e9c..0000000 --- a/native/include/android_glue/threaded_app.h +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (C) 2010 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -#include <poll.h> -#include <pthread.h> -#include <sched.h> - -#include <android/native_activity.h> -#include <android/looper.h> - -/** - * This is the interface for the standard glue code of a threaded - * application. In this model, the application's code is running - * in its own thread separate from the main thread of the process. - * It is not required that this thread be associated with the Java - * VM, although it will need to be in order to make JNI calls any - * Java objects. - */ -struct android_app { - // The application can place a pointer to its own state object - // here if it likes. - void* userData; - - // The ANativeActivity object instance that this app is running in. - ANativeActivity* activity; - - // The ALooper associated with the app's thread. - ALooper* looper; - - // When non-NULL, this is the input queue from which the app will - // receive user input events. - AInputQueue* inputQueue; - - // When non-NULL, this is the window surface that the app can draw in. - ANativeWindow* window; - - // Current content rectangle of the window; this is the area where the - // window's content should be placed to be seen by the user. - ARect contentRect; - - // Current state of the app's activity. May be either APP_CMD_START, - // APP_CMD_RESUME, APP_CMD_PAUSE, or APP_CMD_STOP; see below. - int activityState; - - // ------------------------------------------------- - // Below are "private" implementation of the glue code. - - pthread_mutex_t mutex; - pthread_cond_t cond; - - int msgread; - int msgwrite; - - pthread_t thread; - - // This is non-zero when the application's NativeActivity is being - // destroyed and waiting for the app thread to complete. - int destroyRequested; - - int running; - int destroyed; - int redrawNeeded; - AInputQueue* pendingInputQueue; - ANativeWindow* pendingWindow; - ARect pendingContentRect; -}; - -enum { - /** - * Looper data ID of commands coming from the app's main thread. - * These can be retrieved and processed with android_app_read_cmd() - * and android_app_exec_cmd(). - */ - LOOPER_ID_MAIN = 1, - - /** - * Looper data ID of events coming from the AInputQueue of the - * application's window. These can be read via the inputQueue - * object of android_app. - */ - LOOPER_ID_EVENT = 2 -}; - -enum { - /** - * Command from main thread: the AInputQueue has changed. Upon processing - * this command, android_app->inputQueue will be updated to the new queue - * (or NULL). - */ - APP_CMD_INPUT_CHANGED, - - /** - * Command from main thread: the ANativeWindow has changed. Upon processing - * this command, android_app->window will be updated to the new window surface - * (or NULL). - */ - APP_CMD_WINDOW_CHANGED, - - /** - * Command from main thread: the current ANativeWindow has been resized. - * Please redraw with its new size. - */ - APP_CMD_WINDOW_RESIZED, - - /** - * Command from main thread: the system needs that the current ANativeWindow - * be redrawn. You should redraw the window before handing this to - * android_app_exec_cmd() in order to avoid transient drawing glitches. - */ - APP_CMD_WINDOW_REDRAW_NEEDED, - - /** - * Command from main thread: the content area of the window has changed, - * such as from the soft input window being shown or hidden. You can - * find the new content rect in android_app::contentRect. - */ - APP_CMD_CONTENT_RECT_CHANGED, - - /** - * Command from main thread: the app's activity window has gained - * input focus. - */ - APP_CMD_GAINED_FOCUS, - - /** - * Command from main thread: the app's activity window has lost - * input focus. - */ - APP_CMD_LOST_FOCUS, - - /** - * Command from main thread: the system is running low on memory. - * Try to reduce your memory use. - */ - APP_CMD_LOW_MEMORY, - - /** - * Command from main thread: the app's activity has been started. - */ - APP_CMD_START, - - /** - * Command from main thread: the app's activity has been resumed. - */ - APP_CMD_RESUME, - - /** - * Command from main thread: the app's activity has been paused. - */ - APP_CMD_PAUSE, - - /** - * Command from main thread: the app's activity has been stopped. - */ - APP_CMD_STOP, - - /** - * Command from main thread: the app's activity is being destroyed, - * and waiting for the app thread to clean up and exit before proceeding. - */ - APP_CMD_DESTROY, -}; - -/** - * Call when ALooper_pollAll() returns LOOPER_ID_MAIN, reading the next - * app command message. - */ -int8_t android_app_read_cmd(struct android_app* android_app); - -/** - * Call with the command returned by android_app_read_cmd() to do the - * default processing of the given command. - * - * Important: returns 0 if the app should exit. You must ALWAYS check for - * a zero return and, if found, exit your android_main() function. - */ -int32_t android_app_exec_cmd(struct android_app* android_app, int8_t cmd); - -/** - * This is the function that application code must implement, representing - * the main entry to the app. - */ -extern void android_main(struct android_app* app); |
