Merge branch 'gingerbread' into gingerbread-release

This commit is contained in:
The Android Automerger
2010-09-08 08:25:14 -07:00
11 changed files with 208 additions and 98 deletions

View File

@@ -176,5 +176,13 @@
</intent-filter> </intent-filter>
</receiver> </receiver>
<service android:name="BadBehaviorActivity$BadService" /> <service android:name="BadBehaviorActivity$BadService" />
<activity android:name="ConfigurationViewer" android:label="Configuration">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.TEST" />
</intent-filter>
</activity>
</application> </application>
</manifest> </manifest>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2007 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.
-->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<TextView
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollHorizontally="true"
android:textSize="18sp"
/>
</ScrollView>

View File

@@ -0,0 +1,71 @@
/*
* Copyright (C) 2007 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.
*/
package com.android.development;
import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.widget.TextView;
public class ConfigurationViewer extends Activity {
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.configuration_viewer);
Configuration c = getResources().getConfiguration();
DisplayMetrics m = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(m);
TextView tv = (TextView)findViewById(R.id.text);
String s = "Configuration\n"
+ "\n"
+ "fontScale=" + c.fontScale + "\n"
+ "hardKeyboardHidden=" + c.hardKeyboardHidden + "\n"
+ "keyboard=" + c.keyboard + "\n"
+ "locale=" + c.locale + "\n"
+ "mcc=" + c.mcc + "\n"
+ "mnc=" + c.mnc + "\n"
+ "navigation=" + c.navigation + "\n"
+ "navigationHidden=" + c.navigationHidden + "\n"
+ "orientation=" + c.orientation + "\n"
+ "screenLayout=0x" + Integer.toHexString(c.screenLayout) + "\n"
+ "touchscreen=" + c.touchscreen + "\n"
+ "uiMode=0x" + Integer.toHexString(c.uiMode) + "\n"
+ "\n"
+ "DisplayMetrics\n"
+ "\n"
+ "density=" + m.density + "\n"
+ "densityDpi=" + m.densityDpi + "\n"
+ "heightPixels=" + m.heightPixels + "\n"
+ "scaledDensity=" + m.scaledDensity + "\n"
+ "widthPixels=" + m.widthPixels + "\n"
+ "xdpi=" + m.xdpi + "\n"
+ "ydpi=" + m.ydpi + "\n"
;
tv.setText(s);
// Also log it for bugreport purposes.
Log.d("ConfigurationViewer", s);
}
}

View File

@@ -623,10 +623,10 @@ typedef struct AInputQueue AInputQueue;
/* /*
* Add this input queue to a looper for processing. See * Add this input queue to a looper for processing. See
* ALooper_addFd() for information on the callback and data params. * ALooper_addFd() for information on the ident, callback, and data params.
*/ */
void AInputQueue_attachLooper(AInputQueue* queue, ALooper* looper, void AInputQueue_attachLooper(AInputQueue* queue, ALooper* looper,
ALooper_callbackFunc* callback, void* data); int ident, ALooper_callbackFunc* callback, void* data);
/* /*
* Remove the input queue from the looper it is currently attached to. * Remove the input queue from the looper it is currently attached to.
@@ -662,64 +662,6 @@ int32_t AInputQueue_preDispatchEvent(AInputQueue* queue, AInputEvent* event);
*/ */
void AInputQueue_finishEvent(AInputQueue* queue, AInputEvent* event, int handled); void AInputQueue_finishEvent(AInputQueue* queue, AInputEvent* event, int handled);
/*
* Input devices.
*
* These functions provide a mechanism for querying the set of available input devices
* and their characteristics and capabilities.
*/
struct AInputDevice;
typedef struct AInputDevice AInputDevice;
/*
* Populates the supplied array with the ids of all input devices in the system.
* Sets nActual to the actual number of devices.
* Returns zero if enumeration was successful.
* Returns non-zero if the actual number of devices is greater than nMax, in which case the
* client should call the method again with a larger id buffer.
*/
int32_t AInputDevice_getDeviceIds(int32_t* idBuf, size_t nMax, size_t* nActual);
/*
* Acquires a device by id.
* Returns NULL if the device was not found.
*
* Note: The returned object must be freed using AInputDevice_release when no longer needed.
*/
AInputDevice* AInputDevice_acquire(int32_t deviceId);
/*
* Releases a device previously acquired by AInputDevice_acquire.
* If device is NULL, this function does nothing.
*/
void AInputDevice_release(AInputDevice* device);
/*
* Gets the name of an input device.
*
* Note: The caller should copy the name into a private buffer since the returned pointer
* will become invalid when the device object is released.
*/
const char* AInputDevice_getName(AInputDevice* device);
/*
* Gets the combination of input sources provided by the input device.
*/
uint32_t AInputDevice_getSources(AInputDevice* device);
/*
* Gets the keyboard type.
*/
int32_t AInputDevice_getKeyboardType(AInputDevice* device);
/* Gets the minimum value, maximum value, flat position and error tolerance for a
* particular motion coodinate.
* Returns zero if the device supports the specified motion range. */
int32_t AInputDevice_getMotionRange(AInputDevice* device, int32_t rangeType,
float* outMin, float* outMax, float* outFlat, float* outFuzz);
//TODO hasKey, keymap stuff, etc...
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@@ -111,7 +111,7 @@ enum {
* *
* Returns ALOPER_POLL_ERROR if an error occurred. * Returns ALOPER_POLL_ERROR if an error occurred.
* *
* Returns a value >= 0 containing a file descriptor if it has data * Returns a value >= 0 containing an identifier if its file descriptor has data
* and it has no callback function (requiring the caller here to handle it). * and it has no callback function (requiring the caller here to handle it).
* In this (and only this) case outEvents and outData will contain the poll * In this (and only this) case outEvents and outData will contain the poll
* events and data associated with the fd. * events and data associated with the fd.
@@ -145,10 +145,12 @@ void ALooper_release(ALooper* looper);
* descriptor was previously added, it is replaced. * descriptor was previously added, it is replaced.
* *
* "fd" is the file descriptor to be added. * "fd" is the file descriptor to be added.
* "ident" is an identifier for this event, which is returned from
* ALooper_pollOnce(). Must be >= 0, or ALOOPER_POLL_CALLBACK if
* providing a non-NULL callback.
* "events" are the poll events to wake up on. Typically this is POLLIN. * "events" are the poll events to wake up on. Typically this is POLLIN.
* "callback" is the function to call when there is an event on the file * "callback" is the function to call when there is an event on the file
* descriptor. * descriptor.
* "id" is an identifier to associated with this file descriptor, or 0.
* "data" is a private data pointer to supply to the callback. * "data" is a private data pointer to supply to the callback.
* *
* There are two main uses of this function: * There are two main uses of this function:
@@ -156,13 +158,13 @@ void ALooper_release(ALooper* looper);
* (1) If "callback" is non-NULL, then * (1) If "callback" is non-NULL, then
* this function will be called when there is data on the file descriptor. It * this function will be called when there is data on the file descriptor. It
* should execute any events it has pending, appropriately reading from the * should execute any events it has pending, appropriately reading from the
* file descriptor. * file descriptor. The 'ident' is ignored in this case.
* *
* (2) If "callback" is NULL, the fd will be returned by ALooper_pollOnce * (2) If "callback" is NULL, the 'ident' will be returned by ALooper_pollOnce
* when it has data available, requiring the caller to take care of processing * when its file descriptor has data available, requiring the caller to take
* it. * care of processing it.
*/ */
void ALooper_addFd(ALooper* looper, int fd, int events, void ALooper_addFd(ALooper* looper, int fd, int ident, int events,
ALooper_callbackFunc* callback, void* data); ALooper_callbackFunc* callback, void* data);
/** /**

View File

@@ -166,7 +166,7 @@ ASensor const* ASensorManager_getDefaultSensor(ASensorManager* manager, int type
* Creates a new sensor event queue and associate it with a looper. * Creates a new sensor event queue and associate it with a looper.
*/ */
ASensorEventQueue* ASensorManager_createEventQueue(ASensorManager* manager, ASensorEventQueue* ASensorManager_createEventQueue(ASensorManager* manager,
ALooper* looper, ALooper_callbackFunc* callback, void* data); ALooper* looper, int ident, ALooper_callbackFunc* callback, void* data);
/* /*
* Destroys the event queue and free all resources associated to it. * Destroys the event queue and free all resources associated to it.

View File

@@ -17,9 +17,10 @@
//BEGIN_INCLUDE(all) //BEGIN_INCLUDE(all)
#include <jni.h> #include <jni.h>
#include <errno.h> #include <errno.h>
#include <android/sensor.h>
#include <android_native_app_glue.h> #include <android_native_app_glue.h>
#include "glutils.h" #include "glutils.h"
@@ -39,6 +40,10 @@ struct saved_state {
struct engine { struct engine {
struct android_app* app; struct android_app* app;
ASensorManager* sensorManager;
const ASensor* accelerometerSensor;
ASensorEventQueue* sensorEventQueue;
int animating; int animating;
EGLDisplay display; EGLDisplay display;
EGLSurface surface; EGLSurface surface;
@@ -151,20 +156,40 @@ static void engine_handle_cmd(struct android_app* app, int32_t cmd) {
struct engine* engine = (struct engine*)app->userData; struct engine* engine = (struct engine*)app->userData;
switch (cmd) { switch (cmd) {
case APP_CMD_SAVE_STATE: case APP_CMD_SAVE_STATE:
// The system has asked us to save our current state. Do so.
engine->app->savedState = malloc(sizeof(struct saved_state)); engine->app->savedState = malloc(sizeof(struct saved_state));
*((struct saved_state*)engine->app->savedState) = engine->state; *((struct saved_state*)engine->app->savedState) = engine->state;
engine->app->savedStateSize = sizeof(struct saved_state); engine->app->savedStateSize = sizeof(struct saved_state);
break; break;
case APP_CMD_INIT_WINDOW: case APP_CMD_INIT_WINDOW:
// The window is being shown, get it ready.
if (engine->app->window != NULL) { if (engine->app->window != NULL) {
engine_init_display(engine); engine_init_display(engine);
engine_draw_frame(engine); engine_draw_frame(engine);
} }
break; break;
case APP_CMD_TERM_WINDOW: case APP_CMD_TERM_WINDOW:
// The window is being hidden or closed, clean it up.
engine_term_display(engine); engine_term_display(engine);
break; break;
case APP_CMD_GAINED_FOCUS:
// When our app gains focus, we start monitoring the accelerometer.
if (engine->accelerometerSensor != NULL) {
ASensorEventQueue_enableSensor(engine->sensorEventQueue,
engine->accelerometerSensor);
// We'd like to get 60 events per second (in us).
ASensorEventQueue_setEventRate(engine->sensorEventQueue,
engine->accelerometerSensor, (1000L/60)*1000);
}
break;
case APP_CMD_LOST_FOCUS: case APP_CMD_LOST_FOCUS:
// When our app loses focus, we stop monitoring the accelerometer.
// This is to avoid consuming battery while not being used.
if (engine->accelerometerSensor != NULL) {
ASensorEventQueue_disableSensor(engine->sensorEventQueue,
engine->accelerometerSensor);
}
// Also stop animating.
engine->animating = 0; engine->animating = 0;
engine_draw_frame(engine); engine_draw_frame(engine);
break; break;
@@ -188,6 +213,13 @@ void android_main(struct android_app* state) {
state->onInputEvent = engine_handle_input; state->onInputEvent = engine_handle_input;
engine.app = state; engine.app = state;
// Prepare to monitor accelerometer
engine.sensorManager = ASensorManager_getInstance();
engine.accelerometerSensor = ASensorManager_getDefaultSensor(engine.sensorManager,
ASENSOR_TYPE_ACCELEROMETER);
engine.sensorEventQueue = ASensorManager_createEventQueue(engine.sensorManager,
state->looper, LOOPER_ID_USER, NULL, NULL);
if (state->savedState != NULL) { if (state->savedState != NULL) {
// We are starting with a previous saved state; restore from it. // We are starting with a previous saved state; restore from it.
engine.state = *(struct saved_state*)state->savedState; engine.state = *(struct saved_state*)state->savedState;
@@ -197,19 +229,32 @@ void android_main(struct android_app* state) {
while (1) { while (1) {
// Read all pending events. // Read all pending events.
int fd; int ident;
int events; int events;
struct android_poll_source* source; struct android_poll_source* source;
// If not animating, we will block forever waiting for events. // If not animating, we will block forever waiting for events.
// If animating, we loop until all events are read, then continue // If animating, we loop until all events are read, then continue
// to draw the next frame of animation. // to draw the next frame of animation.
while ((fd=ALooper_pollAll(engine.animating ? 0 : -1, &events, while ((ident=ALooper_pollAll(engine.animating ? 0 : -1, &events,
(void**)&source)) >= 0) { (void**)&source)) >= 0) {
// Process this event. // Process this event.
if (source != NULL) { if (source != NULL) {
source->process(state); source->process(state, source);
}
// If a sensor has data, process it now.
if (ident == LOOPER_ID_USER) {
if (engine.accelerometerSensor != NULL) {
ASensorEvent event;
while (ASensorEventQueue_getEvents(engine.sensorEventQueue,
&event, 1) > 0) {
LOGI("accelerometer: x=%f y=%f z=%f",
event.acceleration.x, event.acceleration.y,
event.acceleration.z);
}
}
} }
// Check if we are exiting. // Check if we are exiting.

View File

@@ -469,19 +469,19 @@ void android_main(struct android_app* state) {
while (1) { while (1) {
// Read all pending events. // Read all pending events.
int fd; int ident;
int events; int events;
struct android_poll_source* source; struct android_poll_source* source;
// If not animating, we will block forever waiting for events. // If not animating, we will block forever waiting for events.
// If animating, we loop until all events are read, then continue // If animating, we loop until all events are read, then continue
// to draw the next frame of animation. // to draw the next frame of animation.
while ((fd=ALooper_pollAll(engine.animating ? 0 : -1, &events, while ((ident=ALooper_pollAll(engine.animating ? 0 : -1, &events,
(void**)&source)) >= 0) { (void**)&source)) >= 0) {
// Process this event. // Process this event.
if (source != NULL) { if (source != NULL) {
source->process(state); source->process(state, source);
} }
// Check if we are exiting. // Check if we are exiting.

View File

@@ -89,7 +89,8 @@ void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd) {
if (android_app->inputQueue != NULL) { if (android_app->inputQueue != NULL) {
LOGI("Attaching input queue to looper"); LOGI("Attaching input queue to looper");
AInputQueue_attachLooper(android_app->inputQueue, AInputQueue_attachLooper(android_app->inputQueue,
android_app->looper, NULL, &android_app->inputPollSource); android_app->looper, LOOPER_ID_INPUT, NULL,
&android_app->inputPollSource);
} }
pthread_cond_broadcast(&android_app->cond); pthread_cond_broadcast(&android_app->cond);
pthread_mutex_unlock(&android_app->mutex); pthread_mutex_unlock(&android_app->mutex);
@@ -178,7 +179,7 @@ static void android_app_destroy(struct android_app* android_app) {
// Can't touch android_app object after this. // Can't touch android_app object after this.
} }
static void process_input(struct android_app* app) { static void process_input(struct android_app* app, struct android_poll_source* source) {
AInputEvent* event = NULL; AInputEvent* event = NULL;
if (AInputQueue_getEvent(app->inputQueue, &event) >= 0) { if (AInputQueue_getEvent(app->inputQueue, &event) >= 0) {
LOGI("New input event: type=%d\n", AInputEvent_getType(event)); LOGI("New input event: type=%d\n", AInputEvent_getType(event));
@@ -193,7 +194,7 @@ static void process_input(struct android_app* app) {
} }
} }
static void process_cmd(struct android_app* app) { static void process_cmd(struct android_app* app, struct android_poll_source* source) {
int8_t cmd = android_app_read_cmd(app); int8_t cmd = android_app_read_cmd(app);
android_app_pre_exec_cmd(app, cmd); android_app_pre_exec_cmd(app, cmd);
if (app->onAppCmd != NULL) app->onAppCmd(app, cmd); if (app->onAppCmd != NULL) app->onAppCmd(app, cmd);
@@ -216,7 +217,8 @@ static void* android_app_entry(void* param) {
android_app->inputPollSource.process = process_input; android_app->inputPollSource.process = process_input;
ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS); ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
ALooper_addFd(looper, android_app->msgread, POLLIN, NULL, &android_app->cmdPollSource); ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN, POLLIN, NULL,
&android_app->cmdPollSource);
android_app->looper = looper; android_app->looper = looper;
pthread_mutex_lock(&android_app->mutex); pthread_mutex_lock(&android_app->mutex);

View File

@@ -59,25 +59,26 @@ extern "C"
* *
* - input events coming from the AInputQueue attached to the activity. * - input events coming from the AInputQueue attached to the activity.
* *
* Each of these correspond to an ALooper callback that returns a "data" * Each of these correspond to an ALooper identifier returned by
* value of LOOPER_ID_MAIN and LOOPER_ID_INPUT, respectively. * ALooper_pollOnce with values of LOOPER_ID_MAIN and LOOPER_ID_INPUT,
* respectively.
* *
* Your application can use the same ALooper to listen to additionnal * Your application can use the same ALooper to listen to additional
* file-descriptors. * file-descriptors. They can either be callback based, or with return
* identifiers starting with LOOPER_ID_USER.
* *
* 4/ Whenever you receive a LOOPER_ID_MAIN event from the ALooper, your * 4/ Whenever you receive a LOOPER_ID_MAIN or LOOPER_ID_INPUT event,
* code should call the function android_app_read_cmd() to read the * the returned data will point to an android_poll_source structure. You
* command value and act upon it. This is normally done by calling * can call the process() function on it, and fill in android_app->onAppCmd
* android_app_exec_cmd() directly. * and android_app->onInputEvent to be called for your own processing
* of the event.
* *
* XXX: MAKE THIS STUFF MORE CLEAR !! * Alternatively, you can call the low-level functions to read and process
* * the data directly... look at the process_cmd() and process_input()
* 5/ Whenever you receive a LOOPER_ID_INPUT event from the ALooper, you * implementations in the glue to see how to do this.
* should read one event from the AInputQueue with AInputQueue_getEvent().
* *
* See the sample named "native-activity" that comes with the NDK with a * See the sample named "native-activity" that comes with the NDK with a
* full usage example. * full usage example. Also look at the JavaDoc of NativeActivity.
*
*/ */
struct android_app; struct android_app;
@@ -91,12 +92,12 @@ struct android_poll_source {
// LOOPER_ID_INPUT. // LOOPER_ID_INPUT.
int32_t id; int32_t id;
// The android_app this fd is associated with. // The android_app this ident is associated with.
struct android_app* app; struct android_app* app;
// Function to call to perform the standard processing of data from // Function to call to perform the standard processing of data from
// this source. // this source.
void (*process)(struct android_app* app); void (*process)(struct android_app* app, struct android_poll_source* source);
}; };
/** /**
@@ -185,7 +186,9 @@ struct android_app {
enum { enum {
/** /**
* Looper data ID of commands coming from the app's main thread. * Looper data ID of commands coming from the app's main thread, which
* is returned as an identifier from ALooper_pollOnce(). The data for this
* identifier is a pointer to an android_poll_source structure.
* These can be retrieved and processed with android_app_read_cmd() * These can be retrieved and processed with android_app_read_cmd()
* and android_app_exec_cmd(). * and android_app_exec_cmd().
*/ */
@@ -193,10 +196,17 @@ enum {
/** /**
* Looper data ID of events coming from the AInputQueue of the * Looper data ID of events coming from the AInputQueue of the
* application's window. These can be read via the inputQueue * application's window, which is returned as an identifier from
* ALooper_pollOnce(). The data for this identifier is a pointer to an
* android_poll_source structure. These can be read via the inputQueue
* object of android_app. * object of android_app.
*/ */
LOOPER_ID_INPUT = 2 LOOPER_ID_INPUT = 2,
/**
* Start of user-defined ALooper identifiers.
*/
LOOPER_ID_USER = 3,
}; };
enum { enum {