Merge change 20126
* changes:
Removing SyncColumns from Contact - they were put there by accident.
diff --git a/api/current.xml b/api/current.xml
index f65b5ce..c4cac83 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -145940,6 +145940,19 @@
visibility="public"
>
</method>
+<method name="findPointerIndex"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="pointerId" type="int">
+</parameter>
+</method>
<method name="getAction"
return="int"
abstract="false"
@@ -146031,7 +146044,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="pointer" type="int">
+<parameter name="pointerIndex" type="int">
</parameter>
<parameter name="pos" type="int">
</parameter>
@@ -146059,7 +146072,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="pointer" type="int">
+<parameter name="pointerIndex" type="int">
</parameter>
<parameter name="pos" type="int">
</parameter>
@@ -146087,7 +146100,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="pointer" type="int">
+<parameter name="pointerIndex" type="int">
</parameter>
<parameter name="pos" type="int">
</parameter>
@@ -146115,7 +146128,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="pointer" type="int">
+<parameter name="pointerIndex" type="int">
</parameter>
<parameter name="pos" type="int">
</parameter>
@@ -146153,6 +146166,19 @@
visibility="public"
>
</method>
+<method name="getPointerId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="index" type="int">
+</parameter>
+</method>
<method name="getPressure"
return="float"
abstract="false"
@@ -146174,7 +146200,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="pointer" type="int">
+<parameter name="pointerIndex" type="int">
</parameter>
</method>
<method name="getRawX"
@@ -146220,7 +146246,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="pointer" type="int">
+<parameter name="pointerIndex" type="int">
</parameter>
</method>
<method name="getX"
@@ -146244,7 +146270,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="pointer" type="int">
+<parameter name="pointerIndex" type="int">
</parameter>
</method>
<method name="getXPrecision"
@@ -146279,7 +146305,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="pointer" type="int">
+<parameter name="pointerIndex" type="int">
</parameter>
</method>
<method name="getYPrecision"
@@ -146615,7 +146641,7 @@
visibility="public"
>
</field>
-<field name="ACTION_POINTER_MASK"
+<field name="ACTION_POINTER_ID_MASK"
type="int"
transient="false"
volatile="false"
@@ -146626,7 +146652,7 @@
visibility="public"
>
</field>
-<field name="ACTION_POINTER_SHIFT"
+<field name="ACTION_POINTER_ID_SHIFT"
type="int"
transient="false"
volatile="false"
diff --git a/cmds/stagefright/record.cpp b/cmds/stagefright/record.cpp
index d8db8b3..cd54958 100644
--- a/cmds/stagefright/record.cpp
+++ b/cmds/stagefright/record.cpp
@@ -114,8 +114,8 @@
assert(success);
sp<MetaData> enc_meta = new MetaData;
- // enc_meta->setCString(kKeyMIMEType, "video/3gpp");
- enc_meta->setCString(kKeyMIMEType, "video/mp4v-es");
+ enc_meta->setCString(kKeyMIMEType, "video/3gpp");
+ // enc_meta->setCString(kKeyMIMEType, "video/mp4v-es");
enc_meta->setInt32(kKeyWidth, width);
enc_meta->setInt32(kKeyHeight, height);
@@ -129,7 +129,8 @@
MPEG4Writer writer("/sdcard/output.mp4");
writer.addSource(enc_meta, encoder);
writer.start();
- sleep(120);
+ sleep(20);
+ printf("stopping now.\n");
writer.stop();
#else
encoder->start();
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 1d53eab..70aceeb 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -693,39 +693,6 @@
return mLaunchComponent.flattenToShortString().startsWith("com.android.browser/");
}
- /*
- * Menu.
- */
-
- @Override
- public boolean onCreateOptionsMenu(Menu menu) {
- // Show search settings menu item if anyone handles the intent for it
- Intent settingsIntent = new Intent(SearchManager.INTENT_ACTION_SEARCH_SETTINGS);
- settingsIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
- PackageManager pm = getContext().getPackageManager();
- ActivityInfo activityInfo = settingsIntent.resolveActivityInfo(pm, 0);
- if (activityInfo != null) {
- settingsIntent.setClassName(activityInfo.applicationInfo.packageName,
- activityInfo.name);
- CharSequence label = activityInfo.loadLabel(getContext().getPackageManager());
- menu.add(Menu.NONE, Menu.NONE, Menu.NONE, label)
- .setIcon(android.R.drawable.ic_menu_preferences)
- .setAlphabeticShortcut('P')
- .setIntent(settingsIntent);
- return true;
- }
- return super.onCreateOptionsMenu(menu);
- }
-
- @Override
- public boolean onMenuOpened(int featureId, Menu menu) {
- // The menu shows up above the IME, regardless of whether it is in front
- // of the drop-down or not. This looks weird when there is no IME, so
- // we make sure it is visible.
- mSearchAutoComplete.ensureImeVisible();
- return super.onMenuOpened(featureId, menu);
- }
-
/**
* Listeners of various types
*/
diff --git a/core/java/android/app/SuggestionsAdapter.java b/core/java/android/app/SuggestionsAdapter.java
index 4a00e48..bd4e66e 100644
--- a/core/java/android/app/SuggestionsAdapter.java
+++ b/core/java/android/app/SuggestionsAdapter.java
@@ -658,7 +658,14 @@
if (col == NONE) {
return null;
}
- return cursor.getString(col);
+ try {
+ return cursor.getString(col);
+ } catch (Exception e) {
+ Log.e(LOG_TAG,
+ "unexpected error retrieving valid column from cursor, "
+ + "did the remote process die?", e);
+ return null;
+ }
}
}
diff --git a/core/java/android/provider/Browser.java b/core/java/android/provider/Browser.java
index b95e4e1..92bc814 100644
--- a/core/java/android/provider/Browser.java
+++ b/core/java/android/provider/Browser.java
@@ -107,7 +107,8 @@
public static final String[] HISTORY_PROJECTION = new String[] {
BookmarkColumns._ID, BookmarkColumns.URL, BookmarkColumns.VISITS,
BookmarkColumns.DATE, BookmarkColumns.BOOKMARK, BookmarkColumns.TITLE,
- BookmarkColumns.FAVICON, BookmarkColumns.THUMBNAIL };
+ BookmarkColumns.FAVICON, BookmarkColumns.THUMBNAIL,
+ BookmarkColumns.TOUCH_ICON };
/* these indices dependent on HISTORY_PROJECTION */
public static final int HISTORY_PROJECTION_ID_INDEX = 0;
@@ -121,6 +122,10 @@
* @hide
*/
public static final int HISTORY_PROJECTION_THUMBNAIL_INDEX = 7;
+ /**
+ * @hide
+ */
+ public static final int HISTORY_PROJECTION_TOUCH_ICON_INDEX = 8;
/* columns needed to determine whether to truncate history */
public static final String[] TRUNCATE_HISTORY_PROJECTION = new String[] {
@@ -521,6 +526,10 @@
* @hide
*/
public static final String THUMBNAIL = "thumbnail";
+ /**
+ * @hide
+ */
+ public static final String TOUCH_ICON = "touch_icon";
}
public static class SearchColumns implements BaseColumns {
diff --git a/core/java/android/provider/Calendar.java b/core/java/android/provider/Calendar.java
index 75bd989..489d936 100644
--- a/core/java/android/provider/Calendar.java
+++ b/core/java/android/provider/Calendar.java
@@ -217,6 +217,13 @@
* <P>Type: INTEGER (boolean)</P>
*/
public static final String HIDDEN = "hidden";
+
+ /**
+ * The owner account for this calendar, based on the calendar feed.
+ * This will be different from the _SYNC_ACCOUNT for delegated calendars.
+ * <P>Type: String</P>
+ */
+ public static final String OWNER_ACCOUNT = "ownerAccount";
}
public interface AttendeesColumns {
@@ -458,6 +465,14 @@
* <P>Type: INTEGER (long; millis since epoch)</P>
*/
public static final String LAST_DATE = "lastDate";
+
+ /**
+ * Whether the event has attendee information. True if the event
+ * has full attendee data, false if the event has information about
+ * self only.
+ * <P>Type: INTEGER (boolean)</P>
+ */
+ public static final String HAS_ATTENDEE_DATA = "hasAttendeeData";
}
/**
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index ae84e1e..d41d2d1 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -19,6 +19,7 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.os.SystemClock;
+import android.util.Log;
/**
* Object used to report movement (mouse, pen, finger, trackball) events. This
@@ -26,6 +27,8 @@
* it is being used for.
*/
public final class MotionEvent implements Parcelable {
+ static final boolean DEBUG_POINTERS = false;
+
/**
* Bit mask of the parts of the action code that are the action itself.
*/
@@ -68,58 +71,67 @@
/**
* A non-primary pointer has gone down. The bits in
- * {@link #ACTION_POINTER_MASK} indicate which pointer changed.
+ * {@link #ACTION_POINTER_ID_MASK} indicate which pointer changed.
*/
public static final int ACTION_POINTER_DOWN = 5;
/**
- * The primary pointer has gone done.
+ * Synonym for {@link #ACTION_POINTER_DOWN} with
+ * {@link #ACTION_POINTER_ID_MASK} of 0: the primary pointer has gone done.
*/
public static final int ACTION_POINTER_1_DOWN = ACTION_POINTER_DOWN | 0x0000;
/**
- * The secondary pointer has gone done.
+ * Synonym for {@link #ACTION_POINTER_DOWN} with
+ * {@link #ACTION_POINTER_ID_MASK} of 1: the secondary pointer has gone done.
*/
public static final int ACTION_POINTER_2_DOWN = ACTION_POINTER_DOWN | 0x0100;
/**
- * The tertiary pointer has gone done.
+ * Synonym for {@link #ACTION_POINTER_DOWN} with
+ * {@link #ACTION_POINTER_ID_MASK} of 2: the tertiary pointer has gone done.
*/
public static final int ACTION_POINTER_3_DOWN = ACTION_POINTER_DOWN | 0x0200;
/**
* A non-primary pointer has gone up. The bits in
- * {@link #ACTION_POINTER_MASK} indicate which pointer changed.
+ * {@link #ACTION_POINTER_ID_MASK} indicate which pointer changed.
*/
public static final int ACTION_POINTER_UP = 6;
/**
- * The primary pointer has gone up.
+ * Synonym for {@link #ACTION_POINTER_UP} with
+ * {@link #ACTION_POINTER_ID_MASK} of 0: the primary pointer has gone up.
*/
public static final int ACTION_POINTER_1_UP = ACTION_POINTER_UP | 0x0000;
/**
- * The secondary pointer has gone up.
+ * Synonym for {@link #ACTION_POINTER_UP} with
+ * {@link #ACTION_POINTER_ID_MASK} of 1: the secondary pointer has gone up.
*/
public static final int ACTION_POINTER_2_UP = ACTION_POINTER_UP | 0x0100;
/**
- * The tertiary pointer has gone up.
+ * Synonym for {@link #ACTION_POINTER_UP} with
+ * {@link #ACTION_POINTER_ID_MASK} of 2: the tertiary pointer has gone up.
*/
public static final int ACTION_POINTER_3_UP = ACTION_POINTER_UP | 0x0200;
/**
* Bits in the action code that represent a pointer ID, used with
* {@link #ACTION_POINTER_DOWN} and {@link #ACTION_POINTER_UP}. Pointer IDs
- * start at 0, with 0 being the primary (first) pointer in the motion.
+ * start at 0, with 0 being the primary (first) pointer in the motion. Note
+ * that this not <em>not</em> an index into the array of pointer values,
+ * which is compacted to only contain pointers that are down; the pointer
+ * ID for a particular index can be found with {@link #findPointerIndex}.
*/
- public static final int ACTION_POINTER_MASK = 0xff00;
+ public static final int ACTION_POINTER_ID_MASK = 0xff00;
/**
* Bit shift for the action bits holding the pointer identifier as
- * defined by {@link #ACTION_POINTER_MASK}.
+ * defined by {@link #ACTION_POINTER_ID_MASK}.
*/
- public static final int ACTION_POINTER_SHIFT = 8;
+ public static final int ACTION_POINTER_ID_SHIFT = 8;
private static final boolean TRACK_RECYCLED_LOCATION = false;
@@ -144,18 +156,6 @@
public static final int EDGE_RIGHT = 0x00000008;
/**
- * This is the part of the state data that holds the finger identifier
- * for the sample.
- */
- static private final int STATE_FINGER_ID_MASK = 0xff;
-
- /**
- * Special value for STATE_FINGER_ID_MASK indicating that the finger
- * is not down in that sample.
- */
- static private final int STATE_FINGER_ID_NONE = 0xff;
-
- /**
* Offset for the sample's X coordinate.
* @hide
*/
@@ -212,8 +212,8 @@
private int mNumPointers;
private int mNumSamples;
- // Array of (mNumSamples * mNumPointers) size of control data.
- private int[] mStateSamples;
+ // Array of mNumPointers size of identifiers for each pointer of data.
+ private int[] mPointerIdentifiers;
// Array of (mNumSamples * mNumPointers * NUM_SAMPLE_DATA) size of event data.
private float[] mDataSamples;
// Array of mNumSamples size of time stamps.
@@ -224,7 +224,7 @@
private boolean mRecycled;
private MotionEvent() {
- mStateSamples = new int[BASE_AVAIL_POINTERS*BASE_AVAIL_SAMPLES];
+ mPointerIdentifiers = new int[BASE_AVAIL_POINTERS];
mDataSamples = new float[BASE_AVAIL_POINTERS*BASE_AVAIL_SAMPLES*NUM_SAMPLE_DATA];
mTimeSamples = new long[BASE_AVAIL_SAMPLES];
}
@@ -256,16 +256,11 @@
* @param action The kind of action being performed -- one of either
* {@link #ACTION_DOWN}, {@link #ACTION_MOVE}, {@link #ACTION_UP}, or
* {@link #ACTION_CANCEL}.
- * @param x The X coordinate of this event.
- * @param y The Y coordinate of this event.
- * @param pressure The current pressure of this event. The pressure generally
- * ranges from 0 (no pressure at all) to 1 (normal pressure), however
- * values higher than 1 may be generated depending on the calibration of
- * the input device.
- * @param size A scaled value of the approximate size of the area being pressed when
- * touched with the finger. The actual value in pixels corresponding to the finger
- * touch is normalized with a device specific range of values
- * and scaled to a value between 0 and 1.
+ * @param pointers The number of points that will be in this event.
+ * @param inPointerIds An array of <em>pointers</em> values providing
+ * an identifier for each pointer.
+ * @param inData An array of <em>pointers*NUM_SAMPLE_DATA</em> of initial
+ * data samples for the event.
* @param metaState The state of any meta / modifier keys that were in effect when
* the event was generated.
* @param xPrecision The precision of the X coordinate being reported.
@@ -279,7 +274,7 @@
* @hide
*/
static public MotionEvent obtainNano(long downTime, long eventTime, long eventTimeNano,
- int action, int pointers, float[] inData, int metaState,
+ int action, int pointers, int[] inPointerIds, float[] inData, int metaState,
float xPrecision, float yPrecision, int deviceId, int edgeFlags) {
MotionEvent ev = obtain();
ev.mDeviceId = deviceId;
@@ -295,17 +290,25 @@
ev.mNumPointers = pointers;
ev.mNumSamples = 1;
- float[] data = ev.mDataSamples;
- System.arraycopy(inData, 0, data, 0, pointers * NUM_SAMPLE_DATA);
-
- int[] state = ev.mStateSamples;
- while (pointers > 0) {
- pointers--;
- state[pointers] = pointers;
- }
-
+ System.arraycopy(inPointerIds, 0, ev.mPointerIdentifiers, 0, pointers);
+ System.arraycopy(inData, 0, ev.mDataSamples, 0, pointers * NUM_SAMPLE_DATA);
ev.mTimeSamples[0] = eventTime;
+ if (DEBUG_POINTERS) {
+ StringBuilder sb = new StringBuilder(128);
+ sb.append("New:");
+ for (int i=0; i<pointers; i++) {
+ sb.append(" #");
+ sb.append(ev.mPointerIdentifiers[i]);
+ sb.append("(");
+ sb.append(ev.mDataSamples[(i*NUM_SAMPLE_DATA) + SAMPLE_X]);
+ sb.append(",");
+ sb.append(ev.mDataSamples[(i*NUM_SAMPLE_DATA) + SAMPLE_Y]);
+ sb.append(")");
+ }
+ Log.v("MotionEvent", sb.toString());
+ }
+
return ev;
}
@@ -355,8 +358,8 @@
ev.mNumPointers = 1;
ev.mNumSamples = 1;
- int[] state = ev.mStateSamples;
- state[0] = 0;
+ int[] pointerIds = ev.mPointerIdentifiers;
+ pointerIds[0] = 0;
float[] data = ev.mDataSamples;
data[SAMPLE_X] = ev.mRawX = x;
data[SAMPLE_Y] = ev.mRawY = y;
@@ -415,8 +418,8 @@
ev.mNumPointers = 1;
ev.mNumSamples = 1;
- int[] state = ev.mStateSamples;
- state[0] = 0;
+ int[] pointerIds = ev.mPointerIdentifiers;
+ pointerIds[0] = 0;
float[] data = ev.mDataSamples;
data[SAMPLE_X] = ev.mRawX = x;
data[SAMPLE_Y] = ev.mRawY = y;
@@ -459,8 +462,8 @@
ev.mNumPointers = 1;
ev.mNumSamples = 1;
- int[] state = ev.mStateSamples;
- state[0] = 0;
+ int[] pointerIds = ev.mPointerIdentifiers;
+ pointerIds[0] = 0;
float[] data = ev.mDataSamples;
data[SAMPLE_X] = ev.mRawX = x;
data[SAMPLE_Y] = ev.mRawY = y;
@@ -508,21 +511,21 @@
ev.mXPrecision = o.mXPrecision;
ev.mYPrecision = o.mYPrecision;
- final int NT = ev.mNumSamples = o.mNumSamples;
- if (ev.mTimeSamples.length >= NT) {
- System.arraycopy(o.mTimeSamples, 0, ev.mTimeSamples, 0, NT);
+ final int NS = ev.mNumSamples = o.mNumSamples;
+ if (ev.mTimeSamples.length >= NS) {
+ System.arraycopy(o.mTimeSamples, 0, ev.mTimeSamples, 0, NS);
} else {
ev.mTimeSamples = (long[])o.mTimeSamples.clone();
}
- final int NS = (ev.mNumPointers=o.mNumPointers) * NT;
- if (ev.mStateSamples.length >= NS) {
- System.arraycopy(o.mStateSamples, 0, ev.mStateSamples, 0, NS);
+ final int NP = (ev.mNumPointers=o.mNumPointers);
+ if (ev.mPointerIdentifiers.length >= NP) {
+ System.arraycopy(o.mPointerIdentifiers, 0, ev.mPointerIdentifiers, 0, NP);
} else {
- ev.mStateSamples = (int[])o.mStateSamples.clone();
+ ev.mPointerIdentifiers = (int[])o.mPointerIdentifiers.clone();
}
- final int ND = NS * NUM_SAMPLE_DATA;
+ final int ND = NP * NS * NUM_SAMPLE_DATA;
if (ev.mDataSamples.length >= ND) {
System.arraycopy(o.mDataSamples, 0, ev.mDataSamples, 0, ND);
} else {
@@ -593,6 +596,38 @@
}
/**
+ * {@link #getX(int)} for the first pointer index (may be an
+ * arbitrary pointer identifier).
+ */
+ public final float getX() {
+ return mDataSamples[SAMPLE_X];
+ }
+
+ /**
+ * {@link #getY(int)} for the first pointer index (may be an
+ * arbitrary pointer identifier).
+ */
+ public final float getY() {
+ return mDataSamples[SAMPLE_Y];
+ }
+
+ /**
+ * {@link #getPressure(int)} for the first pointer index (may be an
+ * arbitrary pointer identifier).
+ */
+ public final float getPressure() {
+ return mDataSamples[SAMPLE_PRESSURE];
+ }
+
+ /**
+ * {@link #getSize(int)} for the first pointer index (may be an
+ * arbitrary pointer identifier).
+ */
+ public final float getSize() {
+ return mDataSamples[SAMPLE_SIZE];
+ }
+
+ /**
* The number of pointers of data contained in this event. Always
* >= 1.
*/
@@ -601,80 +636,91 @@
}
/**
- * {@link #getX(int)} for the first pointer (pointer 0).
+ * Return the pointer identifier associated with a particular pointer
+ * data index is this event. The identifier tells you the actual pointer
+ * number associated with the data, accounting for individual pointers
+ * going up and down since the start of the current gesture.
+ * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
+ * (the first pointer that is down) to {@link #getPointerCount()}-1.
*/
- public final float getX() {
- return mDataSamples[SAMPLE_X];
+ public final int getPointerId(int index) {
+ return mPointerIdentifiers[index];
}
-
+
/**
- * {@link #getY(int)} for the first pointer (pointer 0).
+ * Given a pointer identifier, find the index of its data in the event.
+ *
+ * @param pointerId The identifier of the pointer to be found.
+ * @return Returns either the index of the pointer (for use with
+ * {@link #getX(int) et al.), or -1 if there is no data available for
+ * that pointer identifier.
*/
- public final float getY() {
- return mDataSamples[SAMPLE_Y];
+ public final int findPointerIndex(int pointerId) {
+ int i = mNumPointers;
+ while (i > 0) {
+ i--;
+ if (mPointerIdentifiers[i] == pointerId) {
+ return i;
+ }
+ }
+ return -1;
}
-
+
/**
- * {@link #getPressure(int)} for the first pointer (pointer 0).
- */
- public final float getPressure() {
- return mDataSamples[SAMPLE_PRESSURE];
- }
-
- /**
- * {@link #getSize(int)} for the first pointer (pointer 0).
- */
- public final float getSize() {
- return mDataSamples[SAMPLE_SIZE];
- }
-
- /**
- * Returns the X coordinate of this event for the given pointer.
+ * Returns the X coordinate of this event for the given pointer
+ * <em>index</em> (use {@link #getPointerId(int)} to find the pointer
+ * identifier for this index).
* Whole numbers are pixels; the
* value may have a fraction for input devices that are sub-pixel precise.
- * @param pointer The desired pointer to retrieve. Value may be from 0
- * (the first pointer) to {@link #getPointerCount()}-1.
+ * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
+ * (the first pointer that is down) to {@link #getPointerCount()}-1.
*/
- public final float getX(int pointer) {
- return mDataSamples[(pointer*NUM_SAMPLE_DATA) + SAMPLE_X];
+ public final float getX(int pointerIndex) {
+ return mDataSamples[(pointerIndex*NUM_SAMPLE_DATA) + SAMPLE_X];
}
/**
- * Returns the Y coordinate of this event for the given pointer.
+ * Returns the Y coordinate of this event for the given pointer
+ * <em>index</em> (use {@link #getPointerId(int)} to find the pointer
+ * identifier for this index).
* Whole numbers are pixels; the
* value may have a fraction for input devices that are sub-pixel precise.
- * @param pointer The desired pointer to retrieve. Value may be from 0
- * (the first pointer) to {@link #getPointerCount()}-1.
+ * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
+ * (the first pointer that is down) to {@link #getPointerCount()}-1.
*/
- public final float getY(int pointer) {
- return mDataSamples[(pointer*NUM_SAMPLE_DATA) + SAMPLE_Y];
+ public final float getY(int pointerIndex) {
+ return mDataSamples[(pointerIndex*NUM_SAMPLE_DATA) + SAMPLE_Y];
}
/**
- * Returns the current pressure of this event for the given pointer.
+ * Returns the current pressure of this event for the given pointer
+ * <em>index</em> (use {@link #getPointerId(int)} to find the pointer
+ * identifier for this index).
* The pressure generally
* ranges from 0 (no pressure at all) to 1 (normal pressure), however
* values higher than 1 may be generated depending on the calibration of
* the input device.
- * @param pointer The desired pointer to retrieve. Value may be from 0
- * (the first pointer) to {@link #getPointerCount()}-1.
+ * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
+ * (the first pointer that is down) to {@link #getPointerCount()}-1.
*/
- public final float getPressure(int pointer) {
- return mDataSamples[(pointer*NUM_SAMPLE_DATA) + SAMPLE_PRESSURE];
+ public final float getPressure(int pointerIndex) {
+ return mDataSamples[(pointerIndex*NUM_SAMPLE_DATA) + SAMPLE_PRESSURE];
}
/**
- * Returns a scaled value of the approximate size for the given pointer,
- * representing the area of the screen being pressed.
- * The actual value in pixels corresponding to the
+ * Returns a scaled value of the approximate size for the given pointer
+ * <em>index</em> (use {@link #getPointerId(int)} to find the pointer
+ * identifier for this index).
+ * This represents some approximation of the area of the screen being
+ * pressed; the actual value in pixels corresponding to the
* touch is normalized with the device specific range of values
* and scaled to a value between 0 and 1. The value of size can be used to
* determine fat touch events.
- * @param pointer The desired pointer to retrieve. Value may be from 0
- * (the first pointer) to {@link #getPointerCount()}-1.
+ * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
+ * (the first pointer that is down) to {@link #getPointerCount()}-1.
*/
- public final float getSize(int pointer) {
- return mDataSamples[(pointer*NUM_SAMPLE_DATA) + SAMPLE_SIZE];
+ public final float getSize(int pointerIndex) {
+ return mDataSamples[(pointerIndex*NUM_SAMPLE_DATA) + SAMPLE_SIZE];
}
/**
@@ -758,99 +804,107 @@
}
/**
- * {@link #getHistoricalX(int)} for the first pointer (pointer 0).
+ * {@link #getHistoricalX(int)} for the first pointer index (may be an
+ * arbitrary pointer identifier).
*/
public final float getHistoricalX(int pos) {
return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) + SAMPLE_X];
}
/**
- * {@link #getHistoricalY(int)} for the first pointer (pointer 0).
+ * {@link #getHistoricalY(int)} for the first pointer index (may be an
+ * arbitrary pointer identifier).
*/
public final float getHistoricalY(int pos) {
return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) + SAMPLE_Y];
}
/**
- * {@link #getHistoricalPressure(int)} for the first pointer (pointer 0).
+ * {@link #getHistoricalPressure(int)} for the first pointer index (may be an
+ * arbitrary pointer identifier).
*/
public final float getHistoricalPressure(int pos) {
return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) + SAMPLE_PRESSURE];
}
/**
- * {@link #getHistoricalSize(int)} for the first pointer (pointer 0).
+ * {@link #getHistoricalSize(int)} for the first pointer index (may be an
+ * arbitrary pointer identifier).
*/
public final float getHistoricalSize(int pos) {
return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers) + SAMPLE_SIZE];
}
/**
- * Returns a historical X coordinate that occurred between this event
- * and the previous event for the given pointer. Only applies to ACTION_MOVE events.
+ * Returns a historical X coordinate, as per {@link #getX(int)}, that
+ * occurred between this event and the previous event for the given pointer.
+ * Only applies to ACTION_MOVE events.
*
- * @param pointer The desired pointer to retrieve. Value may be from 0
- * (the first pointer) to {@link #getPointerCount()}-1.
+ * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
+ * (the first pointer that is down) to {@link #getPointerCount()}-1.
* @param pos Which historical value to return; must be less than
* {@link #getHistorySize}
*
* @see #getHistorySize
* @see #getX
*/
- public final float getHistoricalX(int pointer, int pos) {
+ public final float getHistoricalX(int pointerIndex, int pos) {
return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers)
- + (pointer * NUM_SAMPLE_DATA) + SAMPLE_X];
+ + (pointerIndex * NUM_SAMPLE_DATA) + SAMPLE_X];
}
/**
- * Returns a historical Y coordinate that occurred between this event
- * and the previous event for the given pointer. Only applies to ACTION_MOVE events.
+ * Returns a historical Y coordinate, as per {@link #getY(int)}, that
+ * occurred between this event and the previous event for the given pointer.
+ * Only applies to ACTION_MOVE events.
*
- * @param pointer The desired pointer to retrieve. Value may be from 0
- * (the first pointer) to {@link #getPointerCount()}-1.
+ * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
+ * (the first pointer that is down) to {@link #getPointerCount()}-1.
* @param pos Which historical value to return; must be less than
* {@link #getHistorySize}
*
* @see #getHistorySize
* @see #getY
*/
- public final float getHistoricalY(int pointer, int pos) {
+ public final float getHistoricalY(int pointerIndex, int pos) {
return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers)
- + (pointer * NUM_SAMPLE_DATA) + SAMPLE_Y];
+ + (pointerIndex * NUM_SAMPLE_DATA) + SAMPLE_Y];
}
/**
- * Returns a historical pressure coordinate that occurred between this event
- * and the previous event for the given pointer. Only applies to ACTION_MOVE events.
+ * Returns a historical pressure coordinate, as per {@link #getPressure(int)},
+ * that occurred between this event and the previous event for the given
+ * pointer. Only applies to ACTION_MOVE events.
*
+ * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
+ * (the first pointer that is down) to {@link #getPointerCount()}-1.
* @param pos Which historical value to return; must be less than
* {@link #getHistorySize}
- *
- * @param pointer The desired pointer to retrieve. Value may be from 0
- * (the first pointer) to {@link #getPointerCount()}-1.
+ *
* @see #getHistorySize
* @see #getPressure
*/
- public final float getHistoricalPressure(int pointer, int pos) {
+ public final float getHistoricalPressure(int pointerIndex, int pos) {
return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers)
- + (pointer * NUM_SAMPLE_DATA) + SAMPLE_PRESSURE];
+ + (pointerIndex * NUM_SAMPLE_DATA) + SAMPLE_PRESSURE];
}
/**
- * Returns a historical size coordinate that occurred between this event
- * and the previous event for the given pointer. Only applies to ACTION_MOVE events.
+ * Returns a historical size coordinate, as per {@link #getSize(int)}, that
+ * occurred between this event and the previous event for the given pointer.
+ * Only applies to ACTION_MOVE events.
*
+ * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
+ * (the first pointer that is down) to {@link #getPointerCount()}-1.
* @param pos Which historical value to return; must be less than
* {@link #getHistorySize}
- *
- * @param pointer The desired pointer to retrieve. Value may be from 0
- * (the first pointer) to {@link #getPointerCount()}-1.
+ *
* @see #getHistorySize
* @see #getSize
*/
- public final float getHistoricalSize(int pointer, int pos) {
+ public final float getHistoricalSize(int pointerIndex, int pos) {
return mDataSamples[((pos + 1) * NUM_SAMPLE_DATA * mNumPointers)
- + (pointer * NUM_SAMPLE_DATA) + SAMPLE_SIZE];
+ + (pointerIndex * NUM_SAMPLE_DATA) + SAMPLE_SIZE];
}
/**
@@ -938,7 +992,6 @@
*/
public final void addBatch(long eventTime, float x, float y,
float pressure, float size, int metaState) {
- int[] states = mStateSamples;
float[] data = mDataSamples;
long[] times = mTimeSamples;
@@ -946,14 +999,8 @@
final int NS = mNumSamples;
final int NI = NP*NS;
final int ND = NI * NUM_SAMPLE_DATA;
- if (states.length < (NI+NP)) {
- // The state and data arrays are sized together, since their
- // size is always a fixed factor from each other.
- final int NEW_NI = NP * (NS+BASE_AVAIL_SAMPLES);
- int[] newState = new int[NEW_NI];
- System.arraycopy(states, 0, newState, 0, NI);
- mStateSamples = states = newState;
- final int NEW_ND = NEW_NI * NUM_SAMPLE_DATA;
+ if (data.length <= ND) {
+ final int NEW_ND = ND + (NP * (BASE_AVAIL_SAMPLES * NUM_SAMPLE_DATA));
float[] newData = new float[NEW_ND];
System.arraycopy(data, 0, newData, 0, ND);
mDataSamples = data = newData;
@@ -996,7 +1043,6 @@
* @hide
*/
public final void addBatch(long eventTime, float[] inData, int metaState) {
- int[] states = mStateSamples;
float[] data = mDataSamples;
long[] times = mTimeSamples;
@@ -1004,14 +1050,8 @@
final int NS = mNumSamples;
final int NI = NP*NS;
final int ND = NI * NUM_SAMPLE_DATA;
- if (states.length < (NI+NP)) {
- // The state and data arrays are sized together, since their
- // size is always a fixed factor from each other.
- final int NEW_NI = NP * (NS+BASE_AVAIL_SAMPLES);
- int[] newState = new int[NEW_NI];
- System.arraycopy(states, 0, newState, 0, NI);
- mStateSamples = states = newState;
- final int NEW_ND = NEW_NI * NUM_SAMPLE_DATA;
+ if (data.length <= ND) {
+ final int NEW_ND = ND + (NP * (BASE_AVAIL_SAMPLES * NUM_SAMPLE_DATA));
float[] newData = new float[NEW_ND];
System.arraycopy(data, 0, newData, 0, ND);
mDataSamples = data = newData;
@@ -1034,6 +1074,21 @@
mRawX = inData[SAMPLE_X];
mRawY = inData[SAMPLE_Y];
mMetaState |= metaState;
+
+ if (DEBUG_POINTERS) {
+ StringBuilder sb = new StringBuilder(128);
+ sb.append("Add:");
+ for (int i=0; i<mNumPointers; i++) {
+ sb.append(" #");
+ sb.append(mPointerIdentifiers[i]);
+ sb.append("(");
+ sb.append(mDataSamples[(i*NUM_SAMPLE_DATA) + SAMPLE_X]);
+ sb.append(",");
+ sb.append(mDataSamples[(i*NUM_SAMPLE_DATA) + SAMPLE_Y]);
+ sb.append(")");
+ }
+ Log.v("MotionEvent", sb.toString());
+ }
}
@Override
@@ -1074,13 +1129,13 @@
final int NI = NP*NS;
if (NI > 0) {
int i;
- int[] state = mStateSamples;
- for (i=0; i<NI; i++) {
+ int[] state = mPointerIdentifiers;
+ for (i=0; i<NP; i++) {
out.writeInt(state[i]);
}
- final int NI4 = NI*NUM_SAMPLE_DATA;
+ final int ND = NI*NUM_SAMPLE_DATA;
float[] history = mDataSamples;
- for (i=0; i<NI4; i++) {
+ for (i=0; i<ND; i++) {
out.writeFloat(history[i]);
}
long[] times = mTimeSamples;
@@ -1107,19 +1162,19 @@
mNumSamples = NS;
final int NI = NP*NS;
if (NI > 0) {
- final int NI4 = NI*4;
- int[] state = mStateSamples;
- if (state.length < NI) {
- mStateSamples = state = new int[NI];
+ int[] ids = mPointerIdentifiers;
+ if (ids.length < NP) {
+ mPointerIdentifiers = ids = new int[NP];
}
- for (int i=0; i<NI; i++) {
- state[i] = in.readInt();
+ for (int i=0; i<NP; i++) {
+ ids[i] = in.readInt();
}
float[] history = mDataSamples;
- if (history.length < NI4) {
- mDataSamples = history = new float[NI4];
+ final int ND = NI*NUM_SAMPLE_DATA;
+ if (history.length < ND) {
+ mDataSamples = history = new float[ND];
}
- for (int i=0; i<NI4; i++) {
+ for (int i=0; i<ND; i++) {
history[i] = in.readFloat();
}
long[] times = mTimeSamples;
diff --git a/core/java/android/view/RawInputEvent.java b/core/java/android/view/RawInputEvent.java
index 30da83e..db024b4 100644
--- a/core/java/android/view/RawInputEvent.java
+++ b/core/java/android/view/RawInputEvent.java
@@ -13,6 +13,8 @@
public static final int CLASS_ALPHAKEY = 0x00000002;
public static final int CLASS_TOUCHSCREEN = 0x00000004;
public static final int CLASS_TRACKBALL = 0x00000008;
+ public static final int CLASS_TOUCHSCREEN_MT = 0x00000010;
+ public static final int CLASS_DPAD = 0x00000020;
// More special classes for QueuedEvent below.
public static final int CLASS_CONFIGURATION_CHANGED = 0x10000000;
@@ -158,8 +160,21 @@
public static final int ABS_TOOL_WIDTH = 0x1c;
public static final int ABS_VOLUME = 0x20;
public static final int ABS_MISC = 0x28;
+ public static final int ABS_MT_TOUCH_MAJOR = 0x30;
+ public static final int ABS_MT_TOUCH_MINOR = 0x31;
+ public static final int ABS_MT_WIDTH_MAJOR = 0x32;
+ public static final int ABS_MT_WIDTH_MINOR = 0x33;
+ public static final int ABS_MT_ORIENTATION = 0x34;
+ public static final int ABS_MT_POSITION_X = 0x35;
+ public static final int ABS_MT_POSITION_Y = 0x36;
+ public static final int ABS_MT_TOOL_TYPE = 0x37;
+ public static final int ABS_MT_BLOB_ID = 0x38;
public static final int ABS_MAX = 0x3f;
+ public static final int SYN_REPORT = 0;
+ public static final int SYN_CONFIG = 1;
+ public static final int SYN_MT_REPORT = 2;
+
public int deviceId;
public int type;
public int scancode;
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index e6ccd70..06581c1 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -615,6 +615,11 @@
mCallbackProxy.onReceivedIcon(icon);
}
+ // Called by JNI when an apple-touch-icon attribute was found.
+ private void didReceiveTouchIconUrl(String url) {
+ mCallbackProxy.onReceivedTouchIconUrl(url);
+ }
+
/**
* Request a new window from the client.
* @return The BrowserFrame object stored in the new WebView.
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index ed77ce8..b2277cb 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -104,6 +104,7 @@
private static final int ADD_MESSAGE_TO_CONSOLE = 129;
private static final int GEOLOCATION_PERMISSIONS_SHOW_PROMPT = 130;
private static final int GEOLOCATION_PERMISSIONS_HIDE_PROMPT = 131;
+ private static final int RECEIVED_TOUCH_ICON_URL = 132;
// Message triggered by the client to resume execution
private static final int NOTIFY = 200;
@@ -244,6 +245,13 @@
}
break;
+ case RECEIVED_TOUCH_ICON_URL:
+ if (mWebChromeClient != null) {
+ mWebChromeClient.onReceivedTouchIconUrl(mWebView,
+ (String) msg.obj);
+ }
+ break;
+
case RECEIVED_TITLE:
if (mWebChromeClient != null) {
mWebChromeClient.onReceivedTitle(mWebView,
@@ -1054,6 +1062,21 @@
sendMessage(obtainMessage(RECEIVED_ICON, icon));
}
+ /* package */ void onReceivedTouchIconUrl(String url) {
+ // We should have a current item but we do not want to crash so check
+ // for null.
+ WebHistoryItem i = mBackForwardList.getCurrentItem();
+ if (i != null) {
+ i.setTouchIconUrl(url);
+ }
+ // Do an unsynchronized quick check to avoid posting if no callback has
+ // been set.
+ if (mWebChromeClient == null) {
+ return;
+ }
+ sendMessage(obtainMessage(RECEIVED_TOUCH_ICON_URL, url));
+ }
+
public void onReceivedTitle(String title) {
// Do an unsynchronized quick check to avoid posting if no callback has
// been set.
diff --git a/core/java/android/webkit/JWebCoreJavaBridge.java b/core/java/android/webkit/JWebCoreJavaBridge.java
index 2d7376c..21bcdf17 100644
--- a/core/java/android/webkit/JWebCoreJavaBridge.java
+++ b/core/java/android/webkit/JWebCoreJavaBridge.java
@@ -186,6 +186,13 @@
}
/**
+ * Returns the path of the plugin data directory
+ */
+ private String getPluginSharedDataDirectory() {
+ return PluginManager.getInstance(null).getPluginSharedDataDirectory();
+ }
+
+ /**
* setSharedTimer
* @param timemillis The relative time when the timer should fire
*/
diff --git a/core/java/android/webkit/PluginManager.java b/core/java/android/webkit/PluginManager.java
index e4a44b92..370d3d2 100644
--- a/core/java/android/webkit/PluginManager.java
+++ b/core/java/android/webkit/PluginManager.java
@@ -154,4 +154,8 @@
}
return directories.toArray(new String[directories.size()]);
}
+
+ String getPluginSharedDataDirectory() {
+ return mContext.getDir("plugins", 0).getPath();
+ }
}
diff --git a/core/java/android/webkit/WebChromeClient.java b/core/java/android/webkit/WebChromeClient.java
index d52406d..c10bc97 100644
--- a/core/java/android/webkit/WebChromeClient.java
+++ b/core/java/android/webkit/WebChromeClient.java
@@ -45,6 +45,14 @@
public void onReceivedIcon(WebView view, Bitmap icon) {}
/**
+ * Notify the host application of the url for an apple-touch-icon.
+ * @param view The WebView that initiated the callback.
+ * @param url The icon url.
+ * @hide pending council approval
+ */
+ public void onReceivedTouchIconUrl(WebView view, String url) {}
+
+ /**
* A callback interface used by the host application to notify
* the current page that its custom view has been dismissed.
*
diff --git a/core/java/android/webkit/WebHistoryItem.java b/core/java/android/webkit/WebHistoryItem.java
index fd26b98..abd8237 100644
--- a/core/java/android/webkit/WebHistoryItem.java
+++ b/core/java/android/webkit/WebHistoryItem.java
@@ -39,6 +39,8 @@
private Bitmap mFavicon;
// The pre-flattened data used for saving the state.
private byte[] mFlattenedData;
+ // The apple-touch-icon url for use when adding the site to the home screen
+ private String mTouchIconUrl;
/**
* Basic constructor that assigns a unique id to the item. Called by JNI
@@ -127,6 +129,14 @@
}
/**
+ * Return the touch icon url.
+ * @hide
+ */
+ public String getTouchIconUrl() {
+ return mTouchIconUrl;
+ }
+
+ /**
* Set the favicon.
* @param icon A Bitmap containing the favicon for this history item.
* Note: The VM ensures 32-bit atomic read/write operations so we don't have
@@ -137,6 +147,14 @@
}
/**
+ * Set the touch icon url.
+ * @hide
+ */
+ /*package*/ void setTouchIconUrl(String url) {
+ mTouchIconUrl = url;
+ }
+
+ /**
* Get the pre-flattened data.
* Note: The VM ensures 32-bit atomic read/write operations so we don't have
* to synchronize this method.
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 3b81eed..444ef54 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -2003,6 +2003,15 @@
}
/**
+ * Get the touch icon url for the apple-touch-icon <link> element.
+ * @hide
+ */
+ public String getTouchIconUrl() {
+ WebHistoryItem h = mCallbackProxy.getBackForwardList().getCurrentItem();
+ return h != null ? h.getTouchIconUrl() : null;
+ }
+
+ /**
* Get the progress for the current page.
* @return The progress for the current page between 0 and 100.
*/
diff --git a/graphics/java/android/renderscript/ProgramVertex.java b/graphics/java/android/renderscript/ProgramVertex.java
index a6fdf1f..c4f7759 100644
--- a/graphics/java/android/renderscript/ProgramVertex.java
+++ b/graphics/java/android/renderscript/ProgramVertex.java
@@ -38,8 +38,8 @@
mID = 0;
}
- public void bindAllocation(int slot, MatrixAllocation va) {
- mRS.nProgramVertexBindAllocation(mID, slot, va.mAlloc.mID);
+ public void bindAllocation(MatrixAllocation va) {
+ mRS.nProgramVertexBindAllocation(mID, va.mAlloc.mID);
}
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 5fb7f08..0fb450e 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -164,9 +164,8 @@
native void nProgramFragmentDestroy(int pgm);
native void nProgramVertexDestroy(int pv);
- native void nProgramVertexBindAllocation(int pv, int slot, int mID);
+ native void nProgramVertexBindAllocation(int pv, int mID);
native void nProgramVertexBegin(int inID, int outID);
- native void nProgramVertexSetType(int slot, int mID);
native void nProgramVertexSetTextureMatrixEnable(boolean enable);
native void nProgramVertexAddLight(int id);
native int nProgramVertexCreate();
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 73380b8..e2a8a27 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -909,19 +909,11 @@
}
static void
-nProgramVertexBindAllocation(JNIEnv *_env, jobject _this, jint vpv, jint slot, jint a)
+nProgramVertexBindAllocation(JNIEnv *_env, jobject _this, jint vpv, jint a)
{
RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
LOG_API("nProgramVertexBindAllocation, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramVertex)vpv, slot, (RsAllocation)a);
- rsProgramVertexBindAllocation((RsProgramFragment)vpv, slot, (RsAllocation)a);
-}
-
-static void
-nProgramVertexSetType(JNIEnv *_env, jobject _this, jint slot, jint t)
-{
- RsContext con = (RsContext)(_env->GetIntField(_this, gContextId));
- LOG_API("nProgramVertexSetType, con(%p), vpf(%p), slot(%i), a(%p)", con, (RsProgramVertex)vpv, slot, (RsType)t);
- rsProgramVertexSetType(slot, (RsType)t);
+ rsProgramVertexBindAllocation((RsProgramFragment)vpv, (RsAllocation)a);
}
static void
@@ -1186,9 +1178,8 @@
{"nProgramFragmentDestroy", "(I)V", (void*)nProgramFragmentDestroy },
{"nProgramVertexDestroy", "(I)V", (void*)nProgramVertexDestroy },
-{"nProgramVertexBindAllocation", "(III)V", (void*)nProgramVertexBindAllocation },
+{"nProgramVertexBindAllocation", "(II)V", (void*)nProgramVertexBindAllocation },
{"nProgramVertexBegin", "(II)V", (void*)nProgramVertexBegin },
-{"nProgramVertexSetType", "(II)V", (void*)nProgramVertexSetType },
{"nProgramVertexSetTextureMatrixEnable", "(Z)V", (void*)nProgramVertexSetTextureMatrixEnable },
{"nProgramVertexAddLight", "(I)V", (void*)nProgramVertexAddLight },
{"nProgramVertexCreate", "()I", (void*)nProgramVertexCreate },
diff --git a/include/media/stagefright/OMXDecoder.h b/include/media/stagefright/OMXDecoder.h
index e76fd4c..c6b7cb3 100644
--- a/include/media/stagefright/OMXDecoder.h
+++ b/include/media/stagefright/OMXDecoder.h
@@ -91,8 +91,10 @@
sp<IOMX> mOMX;
IOMX::node_id mNode;
char *mComponentName;
+ char *mMIME;
bool mIsMP3;
bool mIsAVC;
+ bool mIsEncoder;
uint32_t mQuirks;
MediaSource *mSource;
@@ -132,6 +134,7 @@
OMXDecoder(OMXClient *client, IOMX::node_id node,
const char *mime, const char *codec,
+ bool is_encoder,
uint32_t quirks);
void setPortStatus(OMX_U32 port_index, PortStatus status);
@@ -148,6 +151,7 @@
OMX_COLOR_FORMATTYPE colorFormat);
void setVideoOutputFormat(const char *mime, OMX_U32 width, OMX_U32 height);
+ void setVideoInputFormat(const char *mime, OMX_U32 width, OMX_U32 height);
void setup();
void dumpPortDefinition(OMX_U32 port_index);
diff --git a/include/ui/EventHub.h b/include/ui/EventHub.h
index d62fd7d..bffba07 100644
--- a/include/ui/EventHub.h
+++ b/include/ui/EventHub.h
@@ -55,7 +55,9 @@
CLASS_KEYBOARD = 0x00000001,
CLASS_ALPHAKEY = 0x00000002,
CLASS_TOUCHSCREEN = 0x00000004,
- CLASS_TRACKBALL = 0x00000008
+ CLASS_TRACKBALL = 0x00000008,
+ CLASS_TOUCHSCREEN_MT= 0x00000010,
+ CLASS_DPAD = 0x00000020
};
uint32_t getDeviceClasses(int32_t deviceId) const;
@@ -122,6 +124,7 @@
};
device_t* getDevice(int32_t deviceId) const;
+ bool hasKeycode(device_t* device, int keycode) const;
// Protect all internal state.
mutable Mutex mLock;
diff --git a/libs/rs/java/Fall/src/com/android/fall/rs/FallRS.java b/libs/rs/java/Fall/src/com/android/fall/rs/FallRS.java
index ef875fc..833bed0 100644
--- a/libs/rs/java/Fall/src/com/android/fall/rs/FallRS.java
+++ b/libs/rs/java/Fall/src/com/android/fall/rs/FallRS.java
@@ -21,6 +21,7 @@
import android.renderscript.ScriptC;
import android.renderscript.ProgramFragment;
import android.renderscript.ProgramStore;
+import android.renderscript.ProgramVertex;
import android.renderscript.Allocation;
import android.renderscript.Sampler;
import android.renderscript.ProgramVertex;
@@ -79,7 +80,7 @@
mResources = res;
initRS();
}
-
+
public void destroy() {
mScript.destroy();
mSampler.destroy();
@@ -126,7 +127,7 @@
}
private void createMesh() {
-
+
}
private void createScriptStructures() {
@@ -210,7 +211,7 @@
ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null);
pvb.setTextureMatrixEnable(true);
mPvBackground = pvb.create();
- mPvBackground.bindAllocation(0, mPvOrthoAlloc);
+ mPvBackground.bindAllocation(mPvOrthoAlloc);
mPvBackground.setName("PVBackground");
}
}
diff --git a/libs/rs/java/Film/src/com/android/film/FilmRS.java b/libs/rs/java/Film/src/com/android/film/FilmRS.java
index e598e0c..74f88c4 100644
--- a/libs/rs/java/Film/src/com/android/film/FilmRS.java
+++ b/libs/rs/java/Film/src/com/android/film/FilmRS.java
@@ -240,8 +240,8 @@
initState();
mPVA = new ProgramVertex.MatrixAllocation(mRS);
- mPVBackground.bindAllocation(0, mPVA);
- mPVImages.bindAllocation(0, mPVA);
+ mPVBackground.bindAllocation(mPVA);
+ mPVImages.bindAllocation(mPVA);
mPVA.setupProjectionNormalized(320, 480);
diff --git a/libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java b/libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java
index 4ff7365..8160a41 100644
--- a/libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java
+++ b/libs/rs/java/Grass/src/com/android/grass/rs/GrassRS.java
@@ -265,7 +265,7 @@
ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null);
pvb.setTextureMatrixEnable(true);
mPvBackground = pvb.create();
- mPvBackground.bindAllocation(0, mPvOrthoAlloc);
+ mPvBackground.bindAllocation(mPvOrthoAlloc);
mPvBackground.setName("PVBackground");
}
}
diff --git a/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java b/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java
index f6cf419..32a8f3c 100644
--- a/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java
+++ b/libs/rs/java/Rollo/src/com/android/rollo/RolloRS.java
@@ -168,7 +168,7 @@
ProgramVertex.Builder pvb = new ProgramVertex.Builder(mRS, null, null);
mPV = pvb.create();
mPV.setName("PV");
- mPV.bindAllocation(0, mPVAlloc);
+ mPV.bindAllocation(mPVAlloc);
mPVOrthoAlloc = new ProgramVertex.MatrixAllocation(mRS);
mPVOrthoAlloc.setupOrthoWindow(mWidth, mHeight);
@@ -176,7 +176,7 @@
pvb.setTextureMatrixEnable(true);
mPVOrtho = pvb.create();
mPVOrtho.setName("PVOrtho");
- mPVOrtho.bindAllocation(0, mPVOrthoAlloc);
+ mPVOrtho.bindAllocation(mPVOrthoAlloc);
mRS.contextBindProgramVertex(mPV);
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index e118ace..05a8c37 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -409,15 +409,9 @@
ProgramVertexBindAllocation {
param RsProgramVertex vpgm
- param uint32_t slot
param RsAllocation constants
}
-ProgramVertexSetType {
- param uint32_t slot
- param RsType constants
- }
-
ProgramVertexSetTextureMatrixEnable {
param bool enable
}
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index ca277ef..ecfbf83 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -501,23 +501,25 @@
return texAlloc;
}
-
void rsi_AllocationData(Context *rsc, RsAllocation va, const void *data)
{
Allocation *a = static_cast<Allocation *>(va);
a->data(data);
+ rsc->allocationCheck(a);
}
void rsi_Allocation1DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t count, const void *data)
{
Allocation *a = static_cast<Allocation *>(va);
a->subData(xoff, count, data);
+ rsc->allocationCheck(a);
}
void rsi_Allocation2DSubData(Context *rsc, RsAllocation va, uint32_t xoff, uint32_t yoff, uint32_t w, uint32_t h, const void *data)
{
Allocation *a = static_cast<Allocation *>(va);
a->subData(xoff, yoff, w, h, data);
+ rsc->allocationCheck(a);
}
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index e52b0e0..46bd892 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -85,10 +85,15 @@
bool Context::runRootScript()
{
+#if RS_LOG_TIMES
+ struct timespec beginTime;
+ clock_gettime(CLOCK_MONOTONIC, &beginTime);
+#endif
+
rsAssert(mRootScript->mEnviroment.mIsRoot);
- glColor4f(1,1,1,1);
- glEnable(GL_LIGHT0);
+ //glColor4f(1,1,1,1);
+ //glEnable(GL_LIGHT0);
glViewport(0, 0, mWidth, mHeight);
glDepthMask(GL_TRUE);
@@ -102,19 +107,34 @@
glClear(GL_COLOR_BUFFER_BIT);
glClear(GL_DEPTH_BUFFER_BIT);
- return runScript(mRootScript.get(), 0);
+#if RS_LOG_TIMES
+ struct timespec startTime;
+ clock_gettime(CLOCK_MONOTONIC, &startTime);
+#endif
+ bool ret = runScript(mRootScript.get(), 0);
+
+#if RS_LOG_TIMES
+ struct timespec endTime;
+ clock_gettime(CLOCK_MONOTONIC, &endTime);
+
+ int t1 = ((unsigned long)startTime.tv_nsec - (unsigned long)beginTime.tv_nsec) / 1000 / 1000;
+ int t2 = ((unsigned long)endTime.tv_nsec - (unsigned long)startTime.tv_nsec) / 1000 / 1000;
+ LOGE("times %i, %i", t1, t2);
+#endif
+
+ return ret;
}
void Context::setupCheck()
{
if (mFragmentStore.get()) {
- mFragmentStore->setupGL();
+ mFragmentStore->setupGL(&mStateFragmentStore);
}
if (mFragment.get()) {
- mFragment->setupGL();
+ mFragment->setupGL(&mStateFragment);
}
if (mVertex.get()) {
- mVertex->setupGL();
+ mVertex->setupGL(&mStateVertex);
}
}
@@ -245,7 +265,6 @@
} else {
mFragmentStore.set(pfs);
}
- mFragmentStore->setupGL();
}
void Context::setFragment(ProgramFragment *pf)
@@ -255,7 +274,13 @@
} else {
mFragment.set(pf);
}
- mFragment->setupGL();
+}
+
+void Context::allocationCheck(const Allocation *a)
+{
+ mVertex->checkUpdatedAllocation(a);
+ mFragment->checkUpdatedAllocation(a);
+ mFragmentStore->checkUpdatedAllocation(a);
}
void Context::setVertex(ProgramVertex *pv)
@@ -265,7 +290,6 @@
} else {
mVertex.set(pv);
}
- mVertex->setupGL();
}
void Context::assignName(ObjectBase *obj, const char *name, uint32_t len)
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index a00b8e8..1f8352c 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -45,7 +45,7 @@
namespace android {
namespace renderscript {
-class Context
+class Context
{
public:
Context(Device *, Surface *);
@@ -86,6 +86,7 @@
const ProgramVertex * getVertex() {return mVertex.get();}
void setupCheck();
+ void allocationCheck(const Allocation *);
void assignName(ObjectBase *obj, const char *name, uint32_t len);
void removeName(ObjectBase *obj);
diff --git a/libs/rs/rsProgram.cpp b/libs/rs/rsProgram.cpp
index 5a83fb7..6606daa 100644
--- a/libs/rs/rsProgram.cpp
+++ b/libs/rs/rsProgram.cpp
@@ -34,12 +34,19 @@
}
-void Program::setAllocation(Allocation *alloc)
+void Program::bindAllocation(Allocation *alloc)
{
mConstants.set(alloc);
mDirty = true;
}
+void Program::checkUpdatedAllocation(const Allocation *alloc)
+{
+ if (mConstants.get() == alloc) {
+ mDirty = true;
+ }
+}
+
void Program::setupGL()
{
diff --git a/libs/rs/rsProgram.h b/libs/rs/rsProgram.h
index 913fdd2..251072f 100644
--- a/libs/rs/rsProgram.h
+++ b/libs/rs/rsProgram.h
@@ -33,10 +33,12 @@
virtual ~Program();
- void setAllocation(Allocation *);
+ void bindAllocation(Allocation *);
virtual void setupGL();
+ void checkUpdatedAllocation(const Allocation *);
+
protected:
// Components not listed in "in" will be passed though
// unless overwritten by components in out.
@@ -45,8 +47,7 @@
ObjectBaseRef<Allocation> mConstants;
- bool mDirty;
-
+ mutable bool mDirty;
};
diff --git a/libs/rs/rsProgramFragment.cpp b/libs/rs/rsProgramFragment.cpp
index 628f93e..ea507dc 100644
--- a/libs/rs/rsProgramFragment.cpp
+++ b/libs/rs/rsProgramFragment.cpp
@@ -39,8 +39,13 @@
{
}
-void ProgramFragment::setupGL()
+void ProgramFragment::setupGL(ProgramFragmentState *state)
{
+ if ((state->mLast.get() == this) && !mDirty) {
+ return;
+ }
+ state->mLast.set(this);
+
for (uint32_t ct=0; ct < MAX_TEXTURE; ct++) {
glActiveTexture(GL_TEXTURE0 + ct);
if (!(mTextureEnableMask & (1 << ct)) || !mTextures[ct].get()) {
@@ -90,8 +95,8 @@
}
}
-
glActiveTexture(GL_TEXTURE0);
+ mDirty = false;
}
@@ -104,6 +109,7 @@
//LOGE("bindtex %i %p", slot, a);
mTextures[slot].set(a);
+ mDirty = true;
}
void ProgramFragment::bindSampler(uint32_t slot, Sampler *s)
@@ -114,6 +120,7 @@
}
mSamplers[slot].set(s);
+ mDirty = true;
}
void ProgramFragment::setType(uint32_t slot, const Element *e, uint32_t dim)
@@ -190,7 +197,7 @@
ProgramFragment *pf = static_cast<ProgramFragment *>(vpf);
pf->bindTexture(slot, static_cast<Allocation *>(a));
if (pf == rsc->getFragment()) {
- pf->setupGL();
+ //pf->setupGL();
}
}
@@ -200,7 +207,7 @@
pf->bindSampler(slot, static_cast<Sampler *>(s));
if (pf == rsc->getFragment()) {
- pf->setupGL();
+ //pf->setupGL();
}
}
diff --git a/libs/rs/rsProgramFragment.h b/libs/rs/rsProgramFragment.h
index 896d8dd..57fb6a5 100644
--- a/libs/rs/rsProgramFragment.h
+++ b/libs/rs/rsProgramFragment.h
@@ -23,19 +23,19 @@
namespace android {
namespace renderscript {
+class ProgramFragmentState;
class ProgramFragment : public Program
{
public:
const static uint32_t MAX_TEXTURE = 2;
- const static uint32_t MAX_CONSTANTS = 2;
ProgramFragment(Element *in, Element *out);
virtual ~ProgramFragment();
- virtual void setupGL();
+ virtual void setupGL(ProgramFragmentState *);
@@ -53,7 +53,7 @@
// Texture lookups go though a sampler which in effect converts normalized
// coordinates into type specific. Multiple samples may also be taken
// and filtered.
- //
+ //
// Constants are strictly accessed by programetic loads.
ObjectBaseRef<Allocation> mTextures[MAX_TEXTURE];
ObjectBaseRef<Sampler> mSamplers[MAX_TEXTURE];
@@ -61,21 +61,12 @@
uint32_t mTextureDimensions[MAX_TEXTURE];
- ObjectBaseRef<Allocation> mConstants[MAX_CONSTANTS];
- ObjectBaseRef<Type> mConstantTypes[MAX_CONSTANTS];
-
-
// Hacks to create a program for now
RsTexEnvMode mEnvModes[MAX_TEXTURE];
uint32_t mTextureEnableMask;
-
-
-
-
-
};
-class ProgramFragmentState
+class ProgramFragmentState
{
public:
ProgramFragmentState();
@@ -87,6 +78,8 @@
ObjectBaseRef<Type> mTextureTypes[ProgramFragment::MAX_TEXTURE];
ObjectBaseRef<ProgramFragment> mDefault;
Vector<ProgramFragment *> mPrograms;
+
+ ObjectBaseRef<ProgramFragment> mLast;
};
diff --git a/libs/rs/rsProgramFragmentStore.cpp b/libs/rs/rsProgramFragmentStore.cpp
index 9ee270f..27f4015 100644
--- a/libs/rs/rsProgramFragmentStore.cpp
+++ b/libs/rs/rsProgramFragmentStore.cpp
@@ -48,8 +48,13 @@
{
}
-void ProgramFragmentStore::setupGL()
+void ProgramFragmentStore::setupGL(ProgramFragmentStoreState *state)
{
+ if (state->mLast.get() == this) {
+ return;
+ }
+ state->mLast.set(this);
+
glColorMask(mColorRWriteEnable,
mColorGWriteEnable,
mColorBWriteEnable,
@@ -123,7 +128,7 @@
void ProgramFragmentStore::setBlendFunc(RsBlendSrcFunc src, RsBlendDstFunc dst)
{
mBlendEnable = true;
- if ((src == RS_BLEND_SRC_ONE) &&
+ if ((src == RS_BLEND_SRC_ONE) &&
(dst == RS_BLEND_DST_ZERO)) {
mBlendEnable = false;
}
diff --git a/libs/rs/rsProgramFragmentStore.h b/libs/rs/rsProgramFragmentStore.h
index bd3a9f4..0de5c3a 100644
--- a/libs/rs/rsProgramFragmentStore.h
+++ b/libs/rs/rsProgramFragmentStore.h
@@ -23,18 +23,15 @@
namespace android {
namespace renderscript {
+class ProgramFragmentStoreState;
class ProgramFragmentStore : public Program
{
public:
-
-
-
ProgramFragmentStore(Element *in, Element *out);
virtual ~ProgramFragmentStore();
- virtual void setupGL();
-
+ virtual void setupGL(ProgramFragmentStoreState *);
void setDepthFunc(RsDepthFunc);
void setDepthMask(bool);
@@ -55,21 +52,14 @@
int32_t mBlendSrc;
int32_t mBlendDst;
-
-
bool mDepthTestEnable;
bool mDepthWriteEnable;
int32_t mDepthFunc;
-
-
bool mStencilTestEnable;
-
-
-
};
-class ProgramFragmentStoreState
+class ProgramFragmentStoreState
{
public:
ProgramFragmentStoreState();
@@ -77,6 +67,9 @@
void init(Context *rsc, int32_t w, int32_t h);
ObjectBaseRef<ProgramFragmentStore> mDefault;
+ ObjectBaseRef<ProgramFragmentStore> mLast;
+
+
ProgramFragmentStore *mPFS;
};
diff --git a/libs/rs/rsProgramVertex.cpp b/libs/rs/rsProgramVertex.cpp
index 792135d..c66e488 100644
--- a/libs/rs/rsProgramVertex.cpp
+++ b/libs/rs/rsProgramVertex.cpp
@@ -44,9 +44,14 @@
LOGV("%6.2f, %6.2f, %6.2f, %6.2f", f[3], f[7], f[11], f[15]);
}
-void ProgramVertex::setupGL()
+void ProgramVertex::setupGL(ProgramVertexState *state)
{
- const float *f = static_cast<const float *>(mConstants[0]->getPtr());
+ if ((state->mLast.get() == this) && !mDirty) {
+ return;
+ }
+ state->mLast.set(this);
+
+ const float *f = static_cast<const float *>(mConstants->getPtr());
glMatrixMode(GL_TEXTURE);
if (mTextureMatrixEnable) {
@@ -72,7 +77,7 @@
} else {
glDisable(GL_LIGHTING);
}
-
+
if (!f) {
LOGE("Must bind constants to vertex program");
}
@@ -81,16 +86,8 @@
glLoadMatrixf(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET]);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET]);
-}
-void ProgramVertex::setConstantType(uint32_t slot, const Type *t)
-{
- mConstantTypes[slot].set(t);
-}
-
-void ProgramVertex::bindAllocation(uint32_t slot, Allocation *a)
-{
- mConstants[slot].set(a);
+ mDirty = false;
}
void ProgramVertex::addLight(const Light *l)
@@ -103,20 +100,23 @@
void ProgramVertex::setProjectionMatrix(const rsc_Matrix *m) const
{
- float *f = static_cast<float *>(mConstants[0]->getPtr());
+ float *f = static_cast<float *>(mConstants->getPtr());
memcpy(&f[RS_PROGRAM_VERTEX_PROJECTION_OFFSET], m, sizeof(rsc_Matrix));
+ mDirty = true;
}
void ProgramVertex::setModelviewMatrix(const rsc_Matrix *m) const
{
- float *f = static_cast<float *>(mConstants[0]->getPtr());
+ float *f = static_cast<float *>(mConstants->getPtr());
memcpy(&f[RS_PROGRAM_VERTEX_MODELVIEW_OFFSET], m, sizeof(rsc_Matrix));
+ mDirty = true;
}
void ProgramVertex::setTextureMatrix(const rsc_Matrix *m) const
{
- float *f = static_cast<float *>(mConstants[0]->getPtr());
+ float *f = static_cast<float *>(mConstants->getPtr());
memcpy(&f[RS_PROGRAM_VERTEX_TEXTURE_OFFSET], m, sizeof(rsc_Matrix));
+ mDirty = true;
}
@@ -139,8 +139,8 @@
mDefaultAlloc.set(alloc);
mDefault.set(pv);
- pv->bindAllocation(0, alloc);
-
+ pv->bindAllocation(alloc);
+
Matrix m;
m.loadOrtho(0,w, h,0, -1,1);
alloc->subData(RS_PROGRAM_VERTEX_PROJECTION_OFFSET, 16, &m.m[0]);
@@ -167,15 +167,10 @@
return pv;
}
-void rsi_ProgramVertexBindAllocation(Context *rsc, RsProgramVertex vpgm, uint32_t slot, RsAllocation constants)
+void rsi_ProgramVertexBindAllocation(Context *rsc, RsProgramVertex vpgm, RsAllocation constants)
{
ProgramVertex *pv = static_cast<ProgramVertex *>(vpgm);
- pv->bindAllocation(slot, static_cast<Allocation *>(constants));
-}
-
-void rsi_ProgramVertexSetType(Context *rsc, uint32_t slot, RsType constants)
-{
- rsc->mStateVertex.mPV->setConstantType(slot, static_cast<const Type *>(constants));
+ pv->bindAllocation(static_cast<Allocation *>(constants));
}
void rsi_ProgramVertexSetTextureMatrixEnable(Context *rsc, bool enable)
diff --git a/libs/rs/rsProgramVertex.h b/libs/rs/rsProgramVertex.h
index da5ed81..c9ce7aa 100644
--- a/libs/rs/rsProgramVertex.h
+++ b/libs/rs/rsProgramVertex.h
@@ -23,21 +23,19 @@
namespace android {
namespace renderscript {
+class ProgramVertexState;
class ProgramVertex : public Program
{
public:
- const static uint32_t MAX_CONSTANTS = 2;
const static uint32_t MAX_LIGHTS = 8;
ProgramVertex(Element *in, Element *out);
virtual ~ProgramVertex();
- virtual void setupGL();
+ virtual void setupGL(ProgramVertexState *state);
- void setConstantType(uint32_t slot, const Type *);
- void bindAllocation(uint32_t slot, Allocation *);
void setTextureMatrixEnable(bool e) {mTextureMatrixEnable = e;}
void addLight(const Light *);
@@ -46,21 +44,15 @@
void setTextureMatrix(const rsc_Matrix *) const;
protected:
- bool mDirty;
uint32_t mLightCount;
-
- ObjectBaseRef<Allocation> mConstants[MAX_CONSTANTS];
- ObjectBaseRef<const Type> mConstantTypes[MAX_CONSTANTS];
ObjectBaseRef<const Light> mLights[MAX_LIGHTS];
-
// Hacks to create a program for now
bool mTextureMatrixEnable;
-
};
-class ProgramVertexState
+class ProgramVertexState
{
public:
ProgramVertexState();
@@ -69,8 +61,9 @@
void init(Context *rsc, int32_t w, int32_t h);
ObjectBaseRef<ProgramVertex> mDefault;
+ ObjectBaseRef<ProgramVertex> mLast;
ObjectBaseRef<Allocation> mDefaultAlloc;
-
+
ProgramVertex *mPV;
diff --git a/libs/rs/rsUtils.h b/libs/rs/rsUtils.h
index b13e88f..f0e4750 100644
--- a/libs/rs/rsUtils.h
+++ b/libs/rs/rsUtils.h
@@ -17,12 +17,13 @@
#ifndef ANDROID_RS_UTILS_H
#define ANDROID_RS_UTILS_H
-#define LOG_NDEBUG 0
+#define LOG_NDEBUG 0
#define LOG_TAG "rs"
#include <utils/Log.h>
#include <utils/Vector.h>
#include <stdlib.h>
#include <pthread.h>
+#include <time.h>
#include <EGL/egl.h>
#include <math.h>
@@ -38,6 +39,8 @@
#define rsAssert(v) while(0)
#endif
+#define RS_LOG_TIMES 0
+
template<typename T>
T rsMin(T in1, T in2)
{
diff --git a/libs/ui/EventHub.cpp b/libs/ui/EventHub.cpp
index 59c9476..27334b7 100644
--- a/libs/ui/EventHub.cpp
+++ b/libs/ui/EventHub.cpp
@@ -16,6 +16,7 @@
//#define LOG_NDEBUG 0
#include <ui/EventHub.h>
+#include <ui/KeycodeLabels.h>
#include <hardware_legacy/power.h>
#include <cutils/properties.h>
@@ -58,6 +59,18 @@
#define SEQ_SHIFT 16
#define id_to_index(id) ((id&ID_MASK)+1)
+#ifndef ABS_MT_TOUCH_MAJOR
+#define ABS_MT_TOUCH_MAJOR 0x30 /* Major axis of touching ellipse */
+#endif
+
+#ifndef ABS_MT_POSITION_X
+#define ABS_MT_POSITION_X 0x35 /* Center X ellipse position */
+#endif
+
+#ifndef ABS_MT_POSITION_Y
+#define ABS_MT_POSITION_Y 0x36 /* Center Y ellipse position */
+#endif
+
namespace android {
static const char *WAKE_LOCK_ID = "KeyEvents";
@@ -590,6 +603,8 @@
mFDs[mFDCount].events = POLLIN;
// figure out the kinds of events the device reports
+
+ // See if this is a keyboard, and classify it.
uint8_t key_bitmask[(KEY_MAX+1)/8];
memset(key_bitmask, 0, sizeof(key_bitmask));
LOGV("Getting keys...");
@@ -601,15 +616,11 @@
for (int i=0; i<((BTN_MISC+7)/8); i++) {
if (key_bitmask[i] != 0) {
device->classes |= CLASS_KEYBOARD;
- // 'Q' key support = cheap test of whether this is an alpha-capable kbd
- if (test_bit(KEY_Q, key_bitmask)) {
- device->classes |= CLASS_ALPHAKEY;
- }
break;
}
}
if ((device->classes & CLASS_KEYBOARD) != 0) {
- device->keyBitmask = new uint8_t[(KEY_MAX+1)/8];
+ device->keyBitmask = new uint8_t[sizeof(key_bitmask)];
if (device->keyBitmask != NULL) {
memcpy(device->keyBitmask, key_bitmask, sizeof(key_bitmask));
} else {
@@ -619,6 +630,8 @@
}
}
}
+
+ // See if this is a trackball.
if (test_bit(BTN_MOUSE, key_bitmask)) {
uint8_t rel_bitmask[(REL_MAX+1)/8];
memset(rel_bitmask, 0, sizeof(rel_bitmask));
@@ -630,16 +643,22 @@
}
}
}
- if (test_bit(BTN_TOUCH, key_bitmask)) {
- uint8_t abs_bitmask[(ABS_MAX+1)/8];
- memset(abs_bitmask, 0, sizeof(abs_bitmask));
- LOGV("Getting absolute controllers...");
- if (ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask) >= 0)
- {
- if (test_bit(ABS_X, abs_bitmask) && test_bit(ABS_Y, abs_bitmask)) {
- device->classes |= CLASS_TOUCHSCREEN;
- }
- }
+
+ uint8_t abs_bitmask[(ABS_MAX+1)/8];
+ memset(abs_bitmask, 0, sizeof(abs_bitmask));
+ LOGV("Getting absolute controllers...");
+ ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(abs_bitmask)), abs_bitmask);
+
+ // Is this a new modern multi-touch driver?
+ if (test_bit(ABS_MT_TOUCH_MAJOR, abs_bitmask)
+ && test_bit(ABS_MT_POSITION_X, abs_bitmask)
+ && test_bit(ABS_MT_POSITION_Y, abs_bitmask)) {
+ device->classes |= CLASS_TOUCHSCREEN | CLASS_TOUCHSCREEN_MT;
+
+ // Is this an old style single-touch driver?
+ } else if (test_bit(BTN_TOUCH, key_bitmask)
+ && test_bit(ABS_X, abs_bitmask) && test_bit(ABS_Y, abs_bitmask)) {
+ device->classes |= CLASS_TOUCHSCREEN;
}
#ifdef EV_SW
@@ -658,9 +677,6 @@
}
#endif
- LOGI("New device: path=%s name=%s id=0x%x (of 0x%x) index=%d fd=%d classes=0x%x\n",
- deviceName, name, device->id, mNumDevicesById, mFDCount, fd, device->classes);
-
if ((device->classes&CLASS_KEYBOARD) != 0) {
char devname[101];
char tmpfn[101];
@@ -707,10 +723,27 @@
sprintf(propName, "hw.keyboards.%u.devname", publicID);
property_set(propName, devname);
- LOGI("New keyboard: publicID=%d device->id=%d devname='%s' propName='%s' keylayout='%s'\n",
+ // 'Q' key support = cheap test of whether this is an alpha-capable kbd
+ if (hasKeycode(device, kKeyCodeQ)) {
+ device->classes |= CLASS_ALPHAKEY;
+ }
+
+ // See if this has a DPAD.
+ if (hasKeycode(device, kKeyCodeDpadUp) &&
+ hasKeycode(device, kKeyCodeDpadDown) &&
+ hasKeycode(device, kKeyCodeDpadLeft) &&
+ hasKeycode(device, kKeyCodeDpadRight) &&
+ hasKeycode(device, kKeyCodeDpadCenter)) {
+ device->classes |= CLASS_DPAD;
+ }
+
+ LOGI("New keyboard: publicID=%d device->id=0x%x devname='%s' propName='%s' keylayout='%s'\n",
publicID, device->id, devname, propName, keylayoutFilename);
}
+ LOGI("New device: path=%s name=%s id=0x%x (of 0x%x) index=%d fd=%d classes=0x%x\n",
+ deviceName, name, device->id, mNumDevicesById, mFDCount, fd, device->classes);
+
LOGV("Adding device %s %p at %d, id = %d, classes = 0x%x\n",
deviceName, device, mFDCount, devid, device->classes);
@@ -723,6 +756,25 @@
return 0;
}
+bool EventHub::hasKeycode(device_t* device, int keycode) const
+{
+ if (device->keyBitmask == NULL || device->layoutMap == NULL) {
+ return false;
+ }
+
+ Vector<int32_t> scanCodes;
+ device->layoutMap->findScancodes(keycode, &scanCodes);
+ const size_t N = scanCodes.size();
+ for (size_t i=0; i<N && i<=KEY_MAX; i++) {
+ int32_t sc = scanCodes.itemAt(i);
+ if (sc >= 0 && sc <= KEY_MAX && test_bit(sc, device->keyBitmask)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
int EventHub::close_device(const char *deviceName)
{
AutoMutex _l(mLock);
diff --git a/libs/ui/Surface.cpp b/libs/ui/Surface.cpp
index a4710aa..c73909f 100644
--- a/libs/ui/Surface.cpp
+++ b/libs/ui/Surface.cpp
@@ -108,6 +108,9 @@
status_t SurfaceBuffer::writeToParcel(Parcel* reply,
android_native_buffer_t const* buffer)
{
+ if (buffer == NULL) {
+ return BAD_VALUE;
+ }
reply->writeInt32(buffer->width);
reply->writeInt32(buffer->height);
reply->writeInt32(buffer->stride);
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 6bdf282..b53bb29 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -342,7 +342,12 @@
++offset;
}
- assert(offset + 3 < size);
+ // assert(offset + 3 < size);
+ if (offset + 3 >= size) {
+ // XXX assume the entire first chunk of data is the codec specific
+ // data.
+ offset = size;
+ }
mCodecSpecificDataSize = offset;
mCodecSpecificData = malloc(offset);
diff --git a/media/libstagefright/OMXDecoder.cpp b/media/libstagefright/OMXDecoder.cpp
index 780cd2e..3ea3d01 100644
--- a/media/libstagefright/OMXDecoder.cpp
+++ b/media/libstagefright/OMXDecoder.cpp
@@ -76,9 +76,12 @@
{ "audio/3gpp", "OMX.PV.amrencnb" },
{ "audio/mp4a-latm", "OMX.PV.aacenc" },
{ "video/mp4v-es", "OMX.qcom.video.encoder.mpeg4" },
+ { "video/mp4v-es", "OMX.TI.Video.encoder" },
{ "video/mp4v-es", "OMX.PV.mpeg4enc" },
{ "video/3gpp", "OMX.qcom.video.encoder.h263" },
+ { "video/3gpp", "OMX.TI.Video.encoder" },
{ "video/3gpp", "OMX.PV.h263enc" },
+ { "video/avc", "OMX.TI.Video.encoder" },
{ "video/avc", "OMX.PV.avcenc" },
};
@@ -158,7 +161,8 @@
quirks |= kMeasuresTimeInMilliseconds;
}
- OMXDecoder *decoder = new OMXDecoder(client, node, mime, codec, quirks);
+ OMXDecoder *decoder = new OMXDecoder(
+ client, node, mime, codec, createEncoder, quirks);
uint32_t type;
const void *data;
@@ -166,7 +170,7 @@
if (meta->findData(kKeyESDS, &type, &data, &size)) {
ESDS esds((const char *)data, size);
assert(esds.InitCheck() == OK);
-
+
const void *codec_specific_data;
size_t codec_specific_data_size;
esds.getCodecSpecificInfo(
@@ -211,13 +215,16 @@
OMXDecoder::OMXDecoder(OMXClient *client, IOMX::node_id node,
const char *mime, const char *codec,
+ bool is_encoder,
uint32_t quirks)
: mClient(client),
mOMX(mClient->interface()),
mNode(node),
mComponentName(strdup(codec)),
+ mMIME(strdup(mime)),
mIsMP3(!strcasecmp(mime, "audio/mpeg")),
mIsAVC(!strcasecmp(mime, "video/avc")),
+ mIsEncoder(is_encoder),
mQuirks(quirks),
mSource(NULL),
mCodecSpecificDataIterator(mCodecSpecificData.begin()),
@@ -252,6 +259,9 @@
assert(err == OK);
mNode = 0;
+ free(mMIME);
+ mMIME = NULL;
+
free(mComponentName);
mComponentName = NULL;
}
@@ -512,6 +522,27 @@
// The following assertion is violated by TI's video decoder.
// assert(format.nIndex == index);
+#if 1
+ LOGI("portIndex: %ld, index: %ld, eCompressionFormat=%d eColorFormat=%d",
+ portIndex,
+ index, format.eCompressionFormat, format.eColorFormat);
+#endif
+
+ if (!strcmp("OMX.TI.Video.encoder", mComponentName)) {
+ if (portIndex == kPortIndexInput
+ && colorFormat == format.eColorFormat) {
+ // eCompressionFormat does not seem right.
+ found = true;
+ break;
+ }
+ if (portIndex == kPortIndexOutput
+ && compressionFormat == format.eCompressionFormat) {
+ // eColorFormat does not seem right.
+ found = true;
+ break;
+ }
+ }
+
if (format.eCompressionFormat == compressionFormat
&& format.eColorFormat == colorFormat) {
found = true;
@@ -525,6 +556,7 @@
return UNKNOWN_ERROR;
}
+ LOGI("found a match.");
status_t err = mOMX->set_parameter(
mNode, OMX_IndexParamVideoPortFormat,
&format, sizeof(format));
@@ -532,7 +564,83 @@
return err;
}
-#if 1
+void OMXDecoder::setVideoInputFormat(
+ const char *mime, OMX_U32 width, OMX_U32 height) {
+ LOGI("setVideoInputFormat width=%ld, height=%ld", width, height);
+
+ OMX_VIDEO_CODINGTYPE compressionFormat = OMX_VIDEO_CodingUnused;
+ if (!strcasecmp("video/avc", mMIME)) {
+ compressionFormat = OMX_VIDEO_CodingAVC;
+ } else if (!strcasecmp("video/mp4v-es", mMIME)) {
+ compressionFormat = OMX_VIDEO_CodingMPEG4;
+ } else if (!strcasecmp("video/3gpp", mMIME)) {
+ compressionFormat = OMX_VIDEO_CodingH263;
+ } else {
+ LOGE("Not a supported video mime type: %s", mime);
+ assert(!"Should not be here. Not a supported video mime type.");
+ }
+
+ OMX_COLOR_FORMATTYPE colorFormat =
+ 0 ? OMX_COLOR_FormatYCbYCr : OMX_COLOR_FormatCbYCrY;
+
+ setVideoPortFormatType(
+ kPortIndexInput, OMX_VIDEO_CodingUnused,
+ colorFormat);
+
+ setVideoPortFormatType(
+ kPortIndexOutput, compressionFormat, OMX_COLOR_FormatUnused);
+
+ OMX_PARAM_PORTDEFINITIONTYPE def;
+ OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
+
+ def.nSize = sizeof(def);
+ def.nVersion.s.nVersionMajor = 1;
+ def.nVersion.s.nVersionMinor = 1;
+ def.nPortIndex = kPortIndexOutput;
+
+ status_t err = mOMX->get_parameter(
+ mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+
+ assert(err == NO_ERROR);
+
+ assert(def.eDomain == OMX_PortDomainVideo);
+
+ video_def->nFrameWidth = width;
+ video_def->nFrameHeight = height;
+
+ video_def->eCompressionFormat = compressionFormat;
+ video_def->eColorFormat = OMX_COLOR_FormatUnused;
+
+ err = mOMX->set_parameter(
+ mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+ assert(err == NO_ERROR);
+
+ ////////////////////////////////////////////////////////////////////////////
+
+ def.nSize = sizeof(def);
+ def.nVersion.s.nVersionMajor = 1;
+ def.nVersion.s.nVersionMinor = 1;
+ def.nPortIndex = kPortIndexInput;
+
+ err = mOMX->get_parameter(
+ mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+ assert(err == NO_ERROR);
+
+ def.nBufferSize = (width * height * 2); // (width * height * 3) / 2;
+ LOGI("setting nBufferSize = %ld", def.nBufferSize);
+
+ assert(def.eDomain == OMX_PortDomainVideo);
+
+ video_def->nFrameWidth = width;
+ video_def->nFrameHeight = height;
+ video_def->eCompressionFormat = OMX_VIDEO_CodingUnused;
+ video_def->eColorFormat = colorFormat;
+
+ err = mOMX->set_parameter(
+ mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
+ assert(err == NO_ERROR);
+}
+
void OMXDecoder::setVideoOutputFormat(
const char *mime, OMX_U32 width, OMX_U32 height) {
LOGI("setVideoOutputFormat width=%ld, height=%ld", width, height);
@@ -541,7 +649,8 @@
// Enabling this code appears to be the right thing(tm), but,...
// the TI decoder then loses the ability to output YUV420 and only outputs
// YCbYCr (16bit)
- if (!strcasecmp("video/avc", mime)) {
+ if (!strcmp("OMX.TI.Video.Decoder", mComponentName)
+ && !strcasecmp("video/avc", mime)) {
OMX_PARAM_COMPONENTROLETYPE role;
role.nSize = sizeof(role);
role.nVersion.s.nVersionMajor = 1;
@@ -565,6 +674,7 @@
} else if (!strcasecmp("video/3gpp", mime)) {
compressionFormat = OMX_VIDEO_CodingH263;
} else {
+ LOGE("Not a supported video mime type: %s", mime);
assert(!"Should not be here. Not a supported video mime type.");
}
@@ -604,12 +714,10 @@
OMX_PARAM_PORTDEFINITIONTYPE def;
OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
- bool is_encoder = strstr(mComponentName, ".encoder.") != NULL; // XXX
-
def.nSize = sizeof(def);
def.nVersion.s.nVersionMajor = 1;
def.nVersion.s.nVersionMinor = 1;
- def.nPortIndex = is_encoder ? kPortIndexOutput : kPortIndexInput;
+ def.nPortIndex = kPortIndexInput;
status_t err = mOMX->get_parameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
@@ -625,7 +733,7 @@
#endif
assert(def.eDomain == OMX_PortDomainVideo);
-
+
video_def->nFrameWidth = width;
video_def->nFrameHeight = height;
@@ -640,14 +748,14 @@
def.nSize = sizeof(def);
def.nVersion.s.nVersionMajor = 1;
def.nVersion.s.nVersionMinor = 1;
- def.nPortIndex = is_encoder ? kPortIndexInput : kPortIndexOutput;
+ def.nPortIndex = kPortIndexOutput;
err = mOMX->get_parameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
assert(err == NO_ERROR);
assert(def.eDomain == OMX_PortDomainVideo);
-
+
#if 0
def.nBufferSize =
(((width + 15) & -16) * ((height + 15) & -16) * 3) / 2; // YUV420
@@ -661,176 +769,6 @@
assert(err == NO_ERROR);
}
-#else
-static void hexdump(const void *_data, size_t size) {
- char line[256];
- char tmp[16];
-
- const uint8_t *data = (const uint8_t *)_data;
- size_t offset = 0;
- while (offset < size) {
- sprintf(line, "0x%04x ", offset);
-
- size_t n = size - offset;
- if (n > 16) {
- n = 16;
- }
-
- for (size_t i = 0; i < 16; ++i) {
- if (i == 8) {
- strcat(line, " ");
- }
-
- if (offset + i < size) {
- sprintf(tmp, "%02x ", data[offset + i]);
- strcat(line, tmp);
- } else {
- strcat(line, " ");
- }
- }
-
- strcat(line, " ");
-
- for (size_t i = 0; i < n; ++i) {
- if (isprint(data[offset + i])) {
- sprintf(tmp, "%c", data[offset + i]);
- strcat(line, tmp);
- } else {
- strcat(line, ".");
- }
- }
-
- LOGI(line);
-
- offset += 16;
- }
-}
-
-static void DumpPortDefinitionType(const void *_param) {
- OMX_PARAM_PORTDEFINITIONTYPE *param = (OMX_PARAM_PORTDEFINITIONTYPE *)_param;
-
- LOGI("nPortIndex=%ld eDir=%s nBufferCountActual=%ld nBufferCountMin=%ld nBufferSize=%ld", param->nPortIndex, param->eDir == OMX_DirInput ? "input" : "output",
- param->nBufferCountActual, param->nBufferCountMin, param->nBufferSize);
-
- if (param->eDomain == OMX_PortDomainVideo) {
- OMX_VIDEO_PORTDEFINITIONTYPE *video = ¶m->format.video;
- LOGI("nFrameWidth=%ld nFrameHeight=%ld nStride=%ld nSliceHeight=%ld nBitrate=%ld xFramerate=%ld eCompressionFormat=%d eColorFormat=%d",
- video->nFrameWidth, video->nFrameHeight, video->nStride, video->nSliceHeight, video->nBitrate, video->xFramerate, video->eCompressionFormat, video->eColorFormat);
- } else {
- hexdump(param, param->nSize);
- }
-}
-
-void OMXDecoder::setVideoOutputFormat(
- const char *mime, OMX_U32 width, OMX_U32 height) {
- LOGI("setVideoOutputFormat width=%ld, height=%ld", width, height);
-
-#if 0
- // Enabling this code appears to be the right thing(tm), but,...
- // the decoder then loses the ability to output YUV420 and only outputs
- // YCbYCr (16bit)
- {
- OMX_PARAM_COMPONENTROLETYPE role;
- role.nSize = sizeof(role);
- role.nVersion.s.nVersionMajor = 1;
- role.nVersion.s.nVersionMinor = 1;
- strncpy((char *)role.cRole, "video_decoder.avc",
- OMX_MAX_STRINGNAME_SIZE - 1);
- role.cRole[OMX_MAX_STRINGNAME_SIZE - 1] = '\0';
-
- status_t err = mOMX->set_parameter(
- mNode, OMX_IndexParamStandardComponentRole,
- &role, sizeof(role));
- assert(err == OK);
- }
-#endif
-
- setVideoPortFormatType(
- kPortIndexInput, OMX_VIDEO_CodingAVC, OMX_COLOR_FormatUnused);
-
-#if 1
- {
- OMX_VIDEO_PARAM_PORTFORMATTYPE format;
- format.nSize = sizeof(format);
- format.nVersion.s.nVersionMajor = 1;
- format.nVersion.s.nVersionMinor = 1;
- format.nPortIndex = kPortIndexOutput;
- format.nIndex = 0;
-
- status_t err = mOMX->get_parameter(
- mNode, OMX_IndexParamVideoPortFormat,
- &format, sizeof(format));
- assert(err == OK);
-
- LOGI("XXX MyOMX_GetParameter OMX_IndexParamVideoPortFormat");
- hexdump(&format, format.nSize);
-
- assert(format.eCompressionFormat == OMX_VIDEO_CodingUnused);
- assert(format.eColorFormat == OMX_COLOR_FormatYUV420Planar
- || format.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar
- || format.eColorFormat == OMX_COLOR_FormatCbYCrY);
-
- err = mOMX->set_parameter(
- mNode, OMX_IndexParamVideoPortFormat,
- &format, sizeof(format));
- assert(err == OK);
- }
-#endif
-
- OMX_PORT_PARAM_TYPE ptype;
- ptype.nSize = sizeof(ptype);
- ptype.nVersion.s.nVersionMajor = 1;
- ptype.nVersion.s.nVersionMinor = 1;
-
- status_t err = mOMX->get_parameter(
- mNode, OMX_IndexParamVideoInit, &ptype, sizeof(ptype));
- assert(err == OK);
-
- LOGI("XXX MyOMX_GetParameter OMX_IndexParamVideoInit");
- hexdump(&ptype, ptype.nSize);
-
- OMX_PARAM_PORTDEFINITIONTYPE def;
- def.nSize = sizeof(def);
- def.nVersion.s.nVersionMajor = 1;
- def.nVersion.s.nVersionMinor = 1;
- def.nPortIndex = kPortIndexInput;
-
- err = mOMX->get_parameter(
- mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
- assert(err == OK);
-
- LOGI("XXX MyOMX_GetParameter OMX_IndexParamPortDefinition");
- DumpPortDefinitionType(&def);
-
- OMX_VIDEO_PORTDEFINITIONTYPE *video_def = &def.format.video;
- video_def->nFrameWidth = width;
- video_def->nFrameHeight = height;
-
- err = mOMX->set_parameter(
- mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
- assert(err == OK);
-
- ////////////////////////////////////////////////////////////////////////////
-
- def.nPortIndex = kPortIndexOutput;
-
- err = mOMX->get_parameter(
- mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
- assert(err == OK);
-
- LOGI("XXX MyOMX_GetParameter OMX_IndexParamPortDefinition");
- DumpPortDefinitionType(&def);
-
- video_def->nFrameWidth = width;
- video_def->nFrameHeight = height;
-
- err = mOMX->set_parameter(
- mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
- assert(err == OK);
-}
-
-#endif
-
void OMXDecoder::setup() {
const sp<MetaData> &meta = mSource->getFormat();
@@ -848,7 +786,11 @@
success = success && meta->findInt32(kKeyHeight, &height);
assert(success);
- setVideoOutputFormat(mime, width, height);
+ if (mIsEncoder) {
+ setVideoInputFormat(mime, width, height);
+ } else {
+ setVideoOutputFormat(mime, width, height);
+ }
}
// dumpPortDefinition(0);
@@ -1253,7 +1195,7 @@
if (mShutdownInitiated) {
return;
}
-
+
if (mState == OMX_StateLoaded) {
return;
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
index 4adb04e..d8867d3 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/MediaPlayerPerformance.java
@@ -342,7 +342,6 @@
File h263MemoryOut = new File(MEDIA_MEMORY_OUTPUT);
Writer output = new BufferedWriter(new FileWriter(h263MemoryOut, true));
output.write("H263 Video Playback Only\n");
- getMemoryWriteToLog(output);
for (int i = 0; i < NUM_STRESS_LOOP; i++) {
mediaStressPlayback(MediaNames.VIDEO_HIGHRES_H263);
getMemoryWriteToLog(output);
@@ -363,7 +362,6 @@
File h264MemoryOut = new File(MEDIA_MEMORY_OUTPUT);
Writer output = new BufferedWriter(new FileWriter(h264MemoryOut, true));
output.write("H264 Video Playback only\n");
- getMemoryWriteToLog(output);
for (int i = 0; i < NUM_STRESS_LOOP; i++) {
mediaStressPlayback(MediaNames.VIDEO_H264_AMR);
getMemoryWriteToLog(output);
@@ -384,7 +382,6 @@
File wmvMemoryOut = new File(MEDIA_MEMORY_OUTPUT);
Writer output = new BufferedWriter(new FileWriter(wmvMemoryOut, true));
output.write("WMV video playback only\n");
- getMemoryWriteToLog(output);
for (int i = 0; i < NUM_STRESS_LOOP; i++) {
mediaStressPlayback(MediaNames.VIDEO_WMV);
getMemoryWriteToLog(output);
@@ -405,7 +402,6 @@
File videoH263RecordOnlyMemoryOut = new File(MEDIA_MEMORY_OUTPUT);
Writer output = new BufferedWriter(new FileWriter(videoH263RecordOnlyMemoryOut, true));
output.write("H263 video record only\n");
- getMemoryWriteToLog(output);
for (int i = 0; i < NUM_STRESS_LOOP; i++) {
stressVideoRecord(20, 352, 288, MediaRecorder.VideoEncoder.H263,
MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_VIDEO_3GP, true);
@@ -427,7 +423,6 @@
File videoMp4RecordOnlyMemoryOut = new File(MEDIA_MEMORY_OUTPUT);
Writer output = new BufferedWriter(new FileWriter(videoMp4RecordOnlyMemoryOut, true));
output.write("MPEG4 video record only\n");
- getMemoryWriteToLog(output);
for (int i = 0; i < NUM_STRESS_LOOP; i++) {
stressVideoRecord(20, 352, 288, MediaRecorder.VideoEncoder.MPEG_4_SP,
MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_VIDEO_3GP, true);
@@ -450,7 +445,6 @@
File videoRecordAudioMemoryOut = new File(MEDIA_MEMORY_OUTPUT);
Writer output = new BufferedWriter(new FileWriter(videoRecordAudioMemoryOut, true));
output.write("Audio and h263 video record\n");
- getMemoryWriteToLog(output);
for (int i = 0; i < NUM_STRESS_LOOP; i++) {
stressVideoRecord(20, 352, 288, MediaRecorder.VideoEncoder.H263,
MediaRecorder.OutputFormat.MPEG_4, MediaNames.RECORDED_VIDEO_3GP, false);
@@ -472,7 +466,6 @@
File audioOnlyMemoryOut = new File(MEDIA_MEMORY_OUTPUT);
Writer output = new BufferedWriter(new FileWriter(audioOnlyMemoryOut, true));
output.write("Audio record only\n");
- getMemoryWriteToLog(output);
for (int i = 0; i < NUM_STRESS_LOOP; i++) {
stressAudioRecord(MediaNames.RECORDER_OUTPUT);
getMemoryWriteToLog(output);
diff --git a/opengl/tests/angeles/app-linux.c b/opengl/tests/angeles/app-linux.c
index 7d0d320..6be4876 100644
--- a/opengl/tests/angeles/app-linux.c
+++ b/opengl/tests/angeles/app-linux.c
@@ -132,6 +132,7 @@
};
EGLint numConfigs = -1;
+ EGLint n = 0;
EGLint majorVersion;
EGLint minorVersion;
EGLConfig config;
@@ -148,15 +149,43 @@
egl_error("eglInitialize");
eglGetConfigs(dpy, NULL, 0, &numConfigs);
- egl_error("eglGetConfigs");
- fprintf(stderr,"num configs %d\n", numConfigs);
+
+ // Get all the "potential match" configs...
+ EGLConfig* const configs = malloc(sizeof(EGLConfig)*numConfigs);
+ eglChooseConfig(dpy, s_configAttribs, configs, numConfigs, &n);
+ config = configs[0];
+ if (n > 1) {
+ // if there is more than one candidate, go through the list
+ // and pick one that matches our framebuffer format
+ int fbSzA = 0; // should not hardcode
+ int fbSzR = 5; // should not hardcode
+ int fbSzG = 6; // should not hardcode
+ int fbSzB = 5; // should not hardcode
+ int i;
+ for (i=0 ; i<n ; i++) {
+ EGLint r,g,b,a;
+ eglGetConfigAttrib(dpy, configs[i], EGL_RED_SIZE, &r);
+ eglGetConfigAttrib(dpy, configs[i], EGL_GREEN_SIZE, &g);
+ eglGetConfigAttrib(dpy, configs[i], EGL_BLUE_SIZE, &b);
+ eglGetConfigAttrib(dpy, configs[i], EGL_ALPHA_SIZE, &a);
+ if (fbSzA == a && fbSzR == r && fbSzG == g && fbSzB == b) {
+ config = configs[i];
+ break;
+ }
+ }
+ }
+ free(configs);
- eglChooseConfig(dpy, s_configAttribs, &config, 1, &numConfigs);
- egl_error("eglChooseConfig");
+
+ //eglGetConfigs(dpy, NULL, 0, &numConfigs);
+ //egl_error("eglGetConfigs");
+ //fprintf(stderr,"num configs %d\n", numConfigs);
+ //eglChooseConfig(dpy, s_configAttribs, &config, 1, &numConfigs);
+ //egl_error("eglChooseConfig");
surface = eglCreateWindowSurface(dpy, config,
android_createDisplaySurface(), NULL);
- egl_error("eglMapWindowSurface");
+ egl_error("eglCreateWindowSurface");
fprintf(stderr,"surface = %p\n", surface);
diff --git a/opengl/tests/fillrate/Android.mk b/opengl/tests/fillrate/Android.mk
new file mode 100644
index 0000000..a7d30c2
--- /dev/null
+++ b/opengl/tests/fillrate/Android.mk
@@ -0,0 +1,17 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ fillrate.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ libcutils \
+ libEGL \
+ libGLESv1_CM \
+ libui
+
+LOCAL_MODULE:= test-opengl-fillrate
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_EXECUTABLE)
diff --git a/opengl/tests/fillrate/fillrate.cpp b/opengl/tests/fillrate/fillrate.cpp
new file mode 100644
index 0000000..c814e8d
--- /dev/null
+++ b/opengl/tests/fillrate/fillrate.cpp
@@ -0,0 +1,149 @@
+/*
+**
+** Copyright 2006, 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.
+*/
+
+#define LOG_TAG "fillrate"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <EGL/egl.h>
+#include <GLES/gl.h>
+#include <GLES/glext.h>
+
+#include <utils/StopWatch.h>
+#include <ui/FramebufferNativeWindow.h>
+
+using namespace android;
+
+int main(int argc, char** argv)
+{
+ EGLint configAttribs[] = {
+ EGL_DEPTH_SIZE, 0,
+ EGL_NONE
+ };
+
+ EGLint numConfigs = -1, n=0;
+ EGLint majorVersion;
+ EGLint minorVersion;
+ EGLConfig config;
+ EGLContext context;
+ EGLSurface surface;
+ EGLint w, h;
+
+ EGLDisplay dpy;
+
+ dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ eglInitialize(dpy, &majorVersion, &minorVersion);
+
+ // Get all the "potential match" configs...
+ eglGetConfigs(dpy, NULL, 0, &numConfigs);
+ EGLConfig* const configs = (EGLConfig*)malloc(sizeof(EGLConfig)*numConfigs);
+ eglChooseConfig(dpy, configAttribs, configs, numConfigs, &n);
+ config = configs[0];
+ if (n > 1) {
+ // if there is more than one candidate, go through the list
+ // and pick one that matches our framebuffer format
+ int fbSzA = 0; // should not hardcode
+ int fbSzR = 5; // should not hardcode
+ int fbSzG = 6; // should not hardcode
+ int fbSzB = 5; // should not hardcode
+ int i;
+ for (i=0 ; i<n ; i++) {
+ EGLint r,g,b,a;
+ eglGetConfigAttrib(dpy, configs[i], EGL_RED_SIZE, &r);
+ eglGetConfigAttrib(dpy, configs[i], EGL_GREEN_SIZE, &g);
+ eglGetConfigAttrib(dpy, configs[i], EGL_BLUE_SIZE, &b);
+ eglGetConfigAttrib(dpy, configs[i], EGL_ALPHA_SIZE, &a);
+ if (fbSzA == a && fbSzR == r && fbSzG == g && fbSzB == b) {
+ config = configs[i];
+ break;
+ }
+ }
+ }
+ free(configs);
+
+ surface = eglCreateWindowSurface(dpy, config,
+ android_createDisplaySurface(), NULL);
+ context = eglCreateContext(dpy, config, NULL, NULL);
+ eglMakeCurrent(dpy, surface, surface, context);
+ eglQuerySurface(dpy, surface, EGL_WIDTH, &w);
+ eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
+
+ printf("w=%d, h=%d\n", w, h);
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glDisable(GL_DITHER);
+ glDisable(GL_BLEND);
+ glEnable(GL_TEXTURE_2D);
+ glColor4f(1,1,1,1);
+
+ uint32_t* t32 = (uint32_t*)malloc(512*512*4);
+ for (int y=0 ; y<512 ; y++) {
+ for (int x=0 ; x<512 ; x++) {
+ t32[x+y*512] = 0x10FFFFFF;
+ }
+ }
+
+ const GLfloat vertices[4][2] = {
+ { 0, 0 },
+ { 0, h },
+ { w, h },
+ { w, 0 }
+ };
+
+ const GLfloat texCoords[4][2] = {
+ { 0, 0 },
+ { 0, 1 },
+ { 1, 1 },
+ { 1, 0 }
+ };
+
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 512, 512, 0, GL_RGBA, GL_UNSIGNED_BYTE, t32);
+
+ glViewport(0, 0, w, h);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrthof(0, w, 0, h, 0, 1);
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ glVertexPointer(2, GL_FIXED, 0, vertices);
+ glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
+
+ glClearColor(1,0,0,0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ eglSwapBuffers(dpy, surface);
+
+ for (int c=1 ; c<32 ; c++) {
+ glClear(GL_COLOR_BUFFER_BIT);
+ nsecs_t now = systemTime();
+ for (int i=0 ; i<c ; i++) {
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ }
+ eglSwapBuffers(dpy, surface);
+ nsecs_t t = systemTime() - now;
+ printf("%lld\t%d\t%f\n", t, c, (double(t)/c)/1000000.0);
+ }
+ return 0;
+}
diff --git a/opengl/tests/textures/textures.c b/opengl/tests/textures/textures.c
index 214291b..d877e74 100644
--- a/opengl/tests/textures/textures.c
+++ b/opengl/tests/textures/textures.c
@@ -31,7 +31,7 @@
EGL_NONE
};
- EGLint numConfigs = -1;
+ EGLint numConfigs = -1, n=0;
EGLint majorVersion;
EGLint minorVersion;
EGLConfig config;
@@ -43,7 +43,36 @@
dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(dpy, &majorVersion, &minorVersion);
- eglChooseConfig(dpy, s_configAttribs, &config, 1, &numConfigs);
+
+ // Get all the "potential match" configs...
+ eglGetConfigs(dpy, NULL, 0, &numConfigs);
+ EGLConfig* const configs = malloc(sizeof(EGLConfig)*numConfigs);
+ eglChooseConfig(dpy, s_configAttribs, configs, numConfigs, &n);
+ config = configs[0];
+ if (n > 1) {
+ // if there is more than one candidate, go through the list
+ // and pick one that matches our framebuffer format
+ int fbSzA = 0; // should not hardcode
+ int fbSzR = 5; // should not hardcode
+ int fbSzG = 6; // should not hardcode
+ int fbSzB = 5; // should not hardcode
+ int i;
+ for (i=0 ; i<n ; i++) {
+ EGLint r,g,b,a;
+ eglGetConfigAttrib(dpy, configs[i], EGL_RED_SIZE, &r);
+ eglGetConfigAttrib(dpy, configs[i], EGL_GREEN_SIZE, &g);
+ eglGetConfigAttrib(dpy, configs[i], EGL_BLUE_SIZE, &b);
+ eglGetConfigAttrib(dpy, configs[i], EGL_ALPHA_SIZE, &a);
+ if (fbSzA == a && fbSzR == r && fbSzG == g && fbSzB == b) {
+ config = configs[i];
+ break;
+ }
+ }
+ }
+ free(configs);
+
+
+
surface = eglCreateWindowSurface(dpy, config,
android_createDisplaySurface(), NULL);
context = eglCreateContext(dpy, config, NULL, NULL);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 835c683..6a1f6f8 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -432,7 +432,7 @@
} finally {
db.endTransaction();
}
- upgradeVersion = 36;
+ upgradeVersion = 37;
}
if (upgradeVersion == 37) {
diff --git a/services/java/com/android/server/InputDevice.java b/services/java/com/android/server/InputDevice.java
index 0ac5740..cb23c45 100644
--- a/services/java/com/android/server/InputDevice.java
+++ b/services/java/com/android/server/InputDevice.java
@@ -23,11 +23,13 @@
import android.view.WindowManagerPolicy;
public class InputDevice {
+ static final boolean DEBUG_POINTERS = false;
+
/** Amount that trackball needs to move in order to generate a key event. */
static final int TRACKBALL_MOVEMENT_THRESHOLD = 6;
/** Maximum number of pointers we will track and report. */
- static final int MAX_POINTERS = 2;
+ static final int MAX_POINTERS = 10;
final int id;
final int classes;
@@ -51,100 +53,316 @@
float yMoveScale;
MotionEvent currentMove = null;
boolean changed = false;
- boolean mLastAnyDown = false;
long mDownTime = 0;
- final boolean[] mLastDown = new boolean[MAX_POINTERS];
- final boolean[] mDown = new boolean[MAX_POINTERS];
+
+ // The currently assigned pointer IDs, corresponding to the last data.
+ int[] mPointerIds = new int[MAX_POINTERS];
+
+ // This is the last generated pointer data, ordered to match
+ // mPointerIds.
+ int mLastNumPointers = 0;
final int[] mLastData = new int[MotionEvent.NUM_SAMPLE_DATA * MAX_POINTERS];
- final int[] mCurData = new int[MotionEvent.NUM_SAMPLE_DATA * MAX_POINTERS];
+
+ // This is the next set of pointer data being generated. It is not
+ // in any known order, and will be propagated in to mLastData
+ // as part of mapping it to the appropriate pointer IDs.
+ // Note that we have one extra sample of data here, to help clients
+ // avoid doing bounds checking.
+ int mNextNumPointers = 0;
+ final int[] mNextData = new int[(MotionEvent.NUM_SAMPLE_DATA * MAX_POINTERS)
+ + MotionEvent.NUM_SAMPLE_DATA];
+
+ // Temporary data structures for doing the pointer ID mapping.
+ final int[] mLast2Next = new int[MAX_POINTERS];
+ final int[] mNext2Last = new int[MAX_POINTERS];
+ final long[] mNext2LastDistance = new long[MAX_POINTERS];
+
+ // Temporary data structure for generating the final motion data.
final float[] mReportData = new float[MotionEvent.NUM_SAMPLE_DATA * MAX_POINTERS];
+ // This is not used here, but can be used by callers for state tracking.
+ int mAddingPointerOffset = 0;
+ final boolean[] mDown = new boolean[MAX_POINTERS];
+
MotionState(int mx, int my) {
xPrecision = mx;
yPrecision = my;
xMoveScale = mx != 0 ? (1.0f/mx) : 1.0f;
yMoveScale = my != 0 ? (1.0f/my) : 1.0f;
+ for (int i=0; i<MAX_POINTERS; i++) {
+ mPointerIds[i] = i;
+ }
+ }
+
+ private boolean assignPointer(int nextIndex, boolean allowOverlap) {
+ final int lastNumPointers = mLastNumPointers;
+ final int[] next2Last = mNext2Last;
+ final long[] next2LastDistance = mNext2LastDistance;
+ final int[] last2Next = mLast2Next;
+ final int[] lastData = mLastData;
+ final int[] nextData = mNextData;
+ final int id = nextIndex * MotionEvent.NUM_SAMPLE_DATA;
+
+ if (DEBUG_POINTERS) Log.v("InputDevice", "assignPointer: nextIndex="
+ + nextIndex + " dataOff=" + id);
+ final int x1 = nextData[id + MotionEvent.SAMPLE_X];
+ final int y1 = nextData[id + MotionEvent.SAMPLE_Y];
+
+ long bestDistance = -1;
+ int bestIndex = -1;
+ for (int j=0; j<lastNumPointers; j++) {
+ if (!allowOverlap && last2Next[j] < 0) {
+ continue;
+ }
+ final int jd = j * MotionEvent.NUM_SAMPLE_DATA;
+ final int xd = lastData[jd + MotionEvent.SAMPLE_X] - x1;
+ final int yd = lastData[jd + MotionEvent.SAMPLE_Y] - y1;
+ final long distance = xd*(long)xd + yd*(long)yd;
+ if (j == 0 || distance < bestDistance) {
+ bestDistance = distance;
+ bestIndex = j;
+ }
+ }
+
+ if (DEBUG_POINTERS) Log.v("InputDevice", "New index " + nextIndex
+ + " best old index=" + bestIndex + " (distance="
+ + bestDistance + ")");
+ next2Last[nextIndex] = bestIndex;
+ next2LastDistance[nextIndex] = bestDistance;
+
+ if (bestIndex < 0) {
+ return true;
+ }
+
+ if (last2Next[bestIndex] == -1) {
+ last2Next[bestIndex] = nextIndex;
+ return false;
+ }
+
+ if (DEBUG_POINTERS) Log.v("InputDevice", "Old index " + bestIndex
+ + " has multiple best new pointers!");
+
+ last2Next[bestIndex] = -2;
+ return true;
+ }
+
+ private int updatePointerIdentifiers() {
+ final int[] lastData = mLastData;
+ final int[] nextData = mNextData;
+ final int nextNumPointers = mNextNumPointers;
+ final int lastNumPointers = mLastNumPointers;
+
+ if (nextNumPointers == 1 && lastNumPointers == 1) {
+ System.arraycopy(nextData, 0, lastData, 0,
+ MotionEvent.NUM_SAMPLE_DATA);
+ return -1;
+ }
+
+ // Clear our old state.
+ final int[] last2Next = mLast2Next;
+ for (int i=0; i<lastNumPointers; i++) {
+ last2Next[i] = -1;
+ }
+
+ if (DEBUG_POINTERS) Log.v("InputDevice",
+ "Update pointers: lastNumPointers=" + lastNumPointers
+ + " nextNumPointers=" + nextNumPointers);
+
+ // Figure out the closes new points to the previous points.
+ final int[] next2Last = mNext2Last;
+ final long[] next2LastDistance = mNext2LastDistance;
+ boolean conflicts = false;
+ for (int i=0; i<nextNumPointers; i++) {
+ conflicts |= assignPointer(i, true);
+ }
+
+ // Resolve ambiguities in pointer mappings, when two or more
+ // new pointer locations find their best previous location is
+ // the same.
+ if (conflicts) {
+ if (DEBUG_POINTERS) Log.v("InputDevice", "Resolving conflicts");
+
+ for (int i=0; i<lastNumPointers; i++) {
+ if (last2Next[i] != -2) {
+ continue;
+ }
+
+ // Note that this algorithm is far from perfect. Ideally
+ // we should do something like the one described at
+ // http://portal.acm.org/citation.cfm?id=997856
+
+ if (DEBUG_POINTERS) Log.v("InputDevice",
+ "Resolving last index #" + i);
+
+ int numFound;
+ do {
+ numFound = 0;
+ long worstDistance = 0;
+ int worstJ = -1;
+ for (int j=0; j<nextNumPointers; j++) {
+ if (next2Last[j] != i) {
+ continue;
+ }
+ numFound++;
+ if (worstDistance < next2LastDistance[j]) {
+ worstDistance = next2LastDistance[j];
+ worstJ = j;
+ }
+ }
+
+ if (worstJ >= 0) {
+ if (DEBUG_POINTERS) Log.v("InputDevice",
+ "Worst new pointer: " + worstJ
+ + " (distance=" + worstDistance + ")");
+ if (assignPointer(worstJ, false)) {
+ // In this case there is no last pointer
+ // remaining for this new one!
+ next2Last[worstJ] = -1;
+ }
+ }
+ } while (numFound > 2);
+ }
+ }
+
+ int retIndex = -1;
+
+ if (lastNumPointers < nextNumPointers) {
+ // We have one or more new pointers that are down. Create a
+ // new pointer identifier for one of them.
+ if (DEBUG_POINTERS) Log.v("InputDevice", "Adding new pointer");
+ int nextId = 0;
+ int i=0;
+ while (i < lastNumPointers) {
+ if (mPointerIds[i] > nextId) {
+ // Found a hole, insert the pointer here.
+ if (DEBUG_POINTERS) Log.v("InputDevice",
+ "Inserting new pointer at hole " + i);
+ System.arraycopy(mPointerIds, i, mPointerIds,
+ i+1, lastNumPointers-i);
+ System.arraycopy(lastData, i*MotionEvent.NUM_SAMPLE_DATA,
+ lastData, (i+1)*MotionEvent.NUM_SAMPLE_DATA,
+ (lastNumPointers-i)*MotionEvent.NUM_SAMPLE_DATA);
+ break;
+ }
+ i++;
+ nextId++;
+ }
+
+ if (DEBUG_POINTERS) Log.v("InputDevice",
+ "New pointer id " + nextId + " at index " + i);
+
+ mLastNumPointers++;
+ retIndex = i;
+ mPointerIds[i] = nextId;
+
+ // And assign this identifier to the first new pointer.
+ for (int j=0; j<nextNumPointers; j++) {
+ if (next2Last[j] < 0) {
+ if (DEBUG_POINTERS) Log.v("InputDevice",
+ "Assigning new id to new pointer index " + j);
+ next2Last[j] = i;
+ break;
+ }
+ }
+ }
+
+ // Propagate all of the current data into the appropriate
+ // location in the old data to match the pointer ID that was
+ // assigned to it.
+ for (int i=0; i<nextNumPointers; i++) {
+ int lastIndex = next2Last[i];
+ if (lastIndex >= 0) {
+ if (DEBUG_POINTERS) Log.v("InputDevice",
+ "Copying next pointer index " + i
+ + " to last index " + lastIndex);
+ System.arraycopy(nextData, i*MotionEvent.NUM_SAMPLE_DATA,
+ lastData, lastIndex*MotionEvent.NUM_SAMPLE_DATA,
+ MotionEvent.NUM_SAMPLE_DATA);
+ }
+ }
+
+ if (lastNumPointers > nextNumPointers) {
+ // One or more pointers has gone up. Find the first one,
+ // and adjust accordingly.
+ if (DEBUG_POINTERS) Log.v("InputDevice", "Removing old pointer");
+ for (int i=0; i<lastNumPointers; i++) {
+ if (last2Next[i] == -1) {
+ if (DEBUG_POINTERS) Log.v("InputDevice",
+ "Removing old pointer at index " + i);
+ retIndex = i;
+ break;
+ }
+ }
+ }
+
+ return retIndex;
+ }
+
+ void removeOldPointer(int index) {
+ final int lastNumPointers = mLastNumPointers;
+ if (index >= 0 && index < lastNumPointers) {
+ System.arraycopy(mPointerIds, index+1, mPointerIds,
+ index, lastNumPointers-index-1);
+ System.arraycopy(mLastData, (index+1)*MotionEvent.NUM_SAMPLE_DATA,
+ mLastData, (index)*MotionEvent.NUM_SAMPLE_DATA,
+ (lastNumPointers-index-1)*MotionEvent.NUM_SAMPLE_DATA);
+ mLastNumPointers--;
+ }
}
MotionEvent generateAbsMotion(InputDevice device, long curTime,
long curTimeNano, Display display, int orientation,
int metaState) {
- final float[] scaled = mReportData;
- final int[] cur = mCurData;
-
- boolean anyDown = false;
- int firstDownChanged = -1;
- int numPointers = 0;
- for (int i=0; i<MAX_POINTERS; i++) {
- boolean d = mDown[i];
- anyDown |= d;
- if (d != mLastDown[i] && firstDownChanged < 0) {
- firstDownChanged = i;
- mLastDown[i] = mDown[i];
- d = true;
- }
-
- if (d) {
- final int src = i * MotionEvent.NUM_SAMPLE_DATA;
- final int dest = numPointers * MotionEvent.NUM_SAMPLE_DATA;
- numPointers++;
- scaled[dest + MotionEvent.SAMPLE_X] = cur[src + MotionEvent.SAMPLE_X];
- scaled[dest + MotionEvent.SAMPLE_Y] = cur[src + MotionEvent.SAMPLE_Y];
- scaled[dest + MotionEvent.SAMPLE_PRESSURE] = cur[src + MotionEvent.SAMPLE_PRESSURE];
- scaled[dest + MotionEvent.SAMPLE_SIZE] = cur[src + MotionEvent.SAMPLE_SIZE];
- }
+ if (mNextNumPointers <= 0 && mLastNumPointers <= 0) {
+ return null;
}
- if (numPointers <= 0) {
- return null;
+ final int lastNumPointers = mLastNumPointers;
+ final int nextNumPointers = mNextNumPointers;
+ if (mNextNumPointers > MAX_POINTERS) {
+ Log.w("InputDevice", "Number of pointers " + mNextNumPointers
+ + " exceeded maximum of " + MAX_POINTERS);
+ mNextNumPointers = MAX_POINTERS;
+ }
+
+ int upOrDownPointer = updatePointerIdentifiers();
+
+ final float[] reportData = mReportData;
+ final int[] rawData = mLastData;
+
+ final int numPointers = mLastNumPointers;
+
+ if (DEBUG_POINTERS) Log.v("InputDevice", "Processing "
+ + numPointers + " pointers (going from " + lastNumPointers
+ + " to " + nextNumPointers + ")");
+
+ for (int i=0; i<numPointers; i++) {
+ final int pos = i * MotionEvent.NUM_SAMPLE_DATA;
+ reportData[pos + MotionEvent.SAMPLE_X] = rawData[pos + MotionEvent.SAMPLE_X];
+ reportData[pos + MotionEvent.SAMPLE_Y] = rawData[pos + MotionEvent.SAMPLE_Y];
+ reportData[pos + MotionEvent.SAMPLE_PRESSURE] = rawData[pos + MotionEvent.SAMPLE_PRESSURE];
+ reportData[pos + MotionEvent.SAMPLE_SIZE] = rawData[pos + MotionEvent.SAMPLE_SIZE];
}
int action;
int edgeFlags = 0;
- if (anyDown != mLastAnyDown) {
- final AbsoluteInfo absX = device.absX;
- final AbsoluteInfo absY = device.absY;
- if (anyDown && absX != null && absY != null) {
- // We don't let downs start unless we are
- // inside of the screen. There are two reasons for
- // this: to avoid spurious touches when holding
- // the edges of the device near the touchscreen,
- // and to avoid reporting events if there are virtual
- // keys on the touchscreen outside of the display
- // area.
- // Note that we are only looking at the first pointer,
- // since what we are handling here is the first pointer
- // going down, and this is the coordinate that will be
- // used to dispatch the event.
- if (cur[MotionEvent.SAMPLE_X] < absX.minValue
- || cur[MotionEvent.SAMPLE_X] > absX.maxValue
- || cur[MotionEvent.SAMPLE_Y] < absY.minValue
- || cur[MotionEvent.SAMPLE_Y] > absY.maxValue) {
- if (false) Log.v("InputDevice", "Rejecting ("
- + cur[MotionEvent.SAMPLE_X] + ","
- + cur[MotionEvent.SAMPLE_Y] + "): outside of ("
- + absX.minValue + "," + absY.minValue
- + ")-(" + absX.maxValue + ","
- + absY.maxValue + ")");
- return null;
+ if (nextNumPointers != lastNumPointers) {
+ if (nextNumPointers > lastNumPointers) {
+ if (lastNumPointers == 0) {
+ action = MotionEvent.ACTION_DOWN;
+ mDownTime = curTime;
+ } else {
+ action = MotionEvent.ACTION_POINTER_DOWN
+ | (upOrDownPointer << MotionEvent.ACTION_POINTER_ID_SHIFT);
}
- }
- mLastAnyDown = anyDown;
- if (anyDown) {
- action = MotionEvent.ACTION_DOWN;
- mDownTime = curTime;
} else {
- action = MotionEvent.ACTION_UP;
- }
- currentMove = null;
- } else if (firstDownChanged >= 0) {
- if (mDown[firstDownChanged]) {
- action = MotionEvent.ACTION_POINTER_DOWN
- | (firstDownChanged << MotionEvent.ACTION_POINTER_SHIFT);
- } else {
- action = MotionEvent.ACTION_POINTER_UP
- | (firstDownChanged << MotionEvent.ACTION_POINTER_SHIFT);
+ if (numPointers == 1) {
+ action = MotionEvent.ACTION_UP;
+ } else {
+ action = MotionEvent.ACTION_POINTER_UP
+ | (upOrDownPointer << MotionEvent.ACTION_POINTER_ID_SHIFT);
+ }
}
currentMove = null;
} else {
@@ -170,42 +388,42 @@
final int j = i * MotionEvent.NUM_SAMPLE_DATA;
if (absX != null) {
- scaled[j + MotionEvent.SAMPLE_X] =
- ((scaled[j + MotionEvent.SAMPLE_X]-absX.minValue)
+ reportData[j + MotionEvent.SAMPLE_X] =
+ ((reportData[j + MotionEvent.SAMPLE_X]-absX.minValue)
/ absX.range) * w;
}
if (absY != null) {
- scaled[j + MotionEvent.SAMPLE_Y] =
- ((scaled[j + MotionEvent.SAMPLE_Y]-absY.minValue)
+ reportData[j + MotionEvent.SAMPLE_Y] =
+ ((reportData[j + MotionEvent.SAMPLE_Y]-absY.minValue)
/ absY.range) * h;
}
if (absPressure != null) {
- scaled[j + MotionEvent.SAMPLE_PRESSURE] =
- ((scaled[j + MotionEvent.SAMPLE_PRESSURE]-absPressure.minValue)
+ reportData[j + MotionEvent.SAMPLE_PRESSURE] =
+ ((reportData[j + MotionEvent.SAMPLE_PRESSURE]-absPressure.minValue)
/ (float)absPressure.range);
}
if (absSize != null) {
- scaled[j + MotionEvent.SAMPLE_SIZE] =
- ((scaled[j + MotionEvent.SAMPLE_SIZE]-absSize.minValue)
+ reportData[j + MotionEvent.SAMPLE_SIZE] =
+ ((reportData[j + MotionEvent.SAMPLE_SIZE]-absSize.minValue)
/ (float)absSize.range);
}
switch (orientation) {
case Surface.ROTATION_90: {
- final float temp = scaled[MotionEvent.SAMPLE_X];
- scaled[j + MotionEvent.SAMPLE_X] = scaled[j + MotionEvent.SAMPLE_Y];
- scaled[j + MotionEvent.SAMPLE_Y] = w-temp;
+ final float temp = reportData[MotionEvent.SAMPLE_X];
+ reportData[j + MotionEvent.SAMPLE_X] = reportData[j + MotionEvent.SAMPLE_Y];
+ reportData[j + MotionEvent.SAMPLE_Y] = w-temp;
break;
}
case Surface.ROTATION_180: {
- scaled[j + MotionEvent.SAMPLE_X] = w-scaled[j + MotionEvent.SAMPLE_X];
- scaled[j + MotionEvent.SAMPLE_Y] = h-scaled[j + MotionEvent.SAMPLE_Y];
+ reportData[j + MotionEvent.SAMPLE_X] = w-reportData[j + MotionEvent.SAMPLE_X];
+ reportData[j + MotionEvent.SAMPLE_Y] = h-reportData[j + MotionEvent.SAMPLE_Y];
break;
}
case Surface.ROTATION_270: {
- final float temp = scaled[i + MotionEvent.SAMPLE_X];
- scaled[j + MotionEvent.SAMPLE_X] = h-scaled[j + MotionEvent.SAMPLE_Y];
- scaled[j + MotionEvent.SAMPLE_Y] = temp;
+ final float temp = reportData[i + MotionEvent.SAMPLE_X];
+ reportData[j + MotionEvent.SAMPLE_X] = h-reportData[j + MotionEvent.SAMPLE_Y];
+ reportData[j + MotionEvent.SAMPLE_Y] = temp;
break;
}
}
@@ -214,24 +432,24 @@
// We only consider the first pointer when computing the edge
// flags, since they are global to the event.
if (action == MotionEvent.ACTION_DOWN) {
- if (scaled[MotionEvent.SAMPLE_X] <= 0) {
+ if (reportData[MotionEvent.SAMPLE_X] <= 0) {
edgeFlags |= MotionEvent.EDGE_LEFT;
- } else if (scaled[MotionEvent.SAMPLE_X] >= dispW) {
+ } else if (reportData[MotionEvent.SAMPLE_X] >= dispW) {
edgeFlags |= MotionEvent.EDGE_RIGHT;
}
- if (scaled[MotionEvent.SAMPLE_Y] <= 0) {
+ if (reportData[MotionEvent.SAMPLE_Y] <= 0) {
edgeFlags |= MotionEvent.EDGE_TOP;
- } else if (scaled[MotionEvent.SAMPLE_Y] >= dispH) {
+ } else if (reportData[MotionEvent.SAMPLE_Y] >= dispH) {
edgeFlags |= MotionEvent.EDGE_BOTTOM;
}
}
if (currentMove != null) {
if (false) Log.i("InputDevice", "Adding batch x="
- + scaled[MotionEvent.SAMPLE_X]
- + " y=" + scaled[MotionEvent.SAMPLE_Y]
+ + reportData[MotionEvent.SAMPLE_X]
+ + " y=" + reportData[MotionEvent.SAMPLE_Y]
+ " to " + currentMove);
- currentMove.addBatch(curTime, scaled, metaState);
+ currentMove.addBatch(curTime, reportData, metaState);
if (WindowManagerPolicy.WATCH_POINTER) {
Log.i("KeyInputQueue", "Updating: " + currentMove);
}
@@ -239,37 +457,53 @@
}
MotionEvent me = MotionEvent.obtainNano(mDownTime, curTime,
- curTimeNano, action, numPointers, scaled, metaState,
- xPrecision, yPrecision, device.id, edgeFlags);
+ curTimeNano, action, numPointers, mPointerIds, reportData,
+ metaState, xPrecision, yPrecision, device.id, edgeFlags);
if (action == MotionEvent.ACTION_MOVE) {
currentMove = me;
}
+
+ if (nextNumPointers < lastNumPointers) {
+ removeOldPointer(upOrDownPointer);
+ }
+
return me;
}
+ boolean hasMore() {
+ return mLastNumPointers != mNextNumPointers;
+ }
+
+ void finish() {
+ mNextNumPointers = mAddingPointerOffset = 0;
+ mNextData[MotionEvent.SAMPLE_PRESSURE] = 0;
+ }
+
MotionEvent generateRelMotion(InputDevice device, long curTime,
long curTimeNano, int orientation, int metaState) {
final float[] scaled = mReportData;
// For now we only support 1 pointer with relative motions.
- scaled[MotionEvent.SAMPLE_X] = mCurData[MotionEvent.SAMPLE_X];
- scaled[MotionEvent.SAMPLE_Y] = mCurData[MotionEvent.SAMPLE_Y];
+ scaled[MotionEvent.SAMPLE_X] = mNextData[MotionEvent.SAMPLE_X];
+ scaled[MotionEvent.SAMPLE_Y] = mNextData[MotionEvent.SAMPLE_Y];
scaled[MotionEvent.SAMPLE_PRESSURE] = 1.0f;
scaled[MotionEvent.SAMPLE_SIZE] = 0;
int edgeFlags = 0;
int action;
- if (mDown[0] != mLastDown[0]) {
- mCurData[MotionEvent.SAMPLE_X] =
- mCurData[MotionEvent.SAMPLE_Y] = 0;
- mLastDown[0] = mDown[0];
- if (mDown[0]) {
+ if (mNextNumPointers != mLastNumPointers) {
+ mNextData[MotionEvent.SAMPLE_X] =
+ mNextData[MotionEvent.SAMPLE_Y] = 0;
+ if (mNextNumPointers > 0 && mLastNumPointers == 0) {
action = MotionEvent.ACTION_DOWN;
mDownTime = curTime;
- } else {
+ } else if (mNextNumPointers == 0) {
action = MotionEvent.ACTION_UP;
+ } else {
+ action = MotionEvent.ACTION_MOVE;
}
+ mLastNumPointers = mNextNumPointers;
currentMove = null;
} else {
action = MotionEvent.ACTION_MOVE;
@@ -310,7 +544,7 @@
}
MotionEvent me = MotionEvent.obtainNano(mDownTime, curTime,
- curTimeNano, action, 1, scaled, metaState,
+ curTimeNano, action, 1, mPointerIds, scaled, metaState,
xPrecision, yPrecision, device.id, edgeFlags);
if (action == MotionEvent.ACTION_MOVE) {
currentMove = me;
diff --git a/services/java/com/android/server/KeyInputQueue.java b/services/java/com/android/server/KeyInputQueue.java
index e0ee7ed..cfb3e35 100644
--- a/services/java/com/android/server/KeyInputQueue.java
+++ b/services/java/com/android/server/KeyInputQueue.java
@@ -49,6 +49,7 @@
static final String TAG = "KeyInputQueue";
static final boolean DEBUG_VIRTUAL_KEYS = false;
+ static final boolean DEBUG_POINTERS = false;
private static final String EXCLUDED_DEVICES_PATH = "etc/excluded-input-devices.xml";
@@ -326,6 +327,10 @@
config.navigation
= Configuration.NAVIGATION_TRACKBALL;
//Log.i("foo", "***** HAVE TRACKBALL!");
+ } else if ((d.classes&RawInputEvent.CLASS_DPAD) != 0) {
+ config.navigation
+ = Configuration.NAVIGATION_DPAD;
+ //Log.i("foo", "***** HAVE DPAD!");
}
}
}
@@ -364,9 +369,9 @@
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_URGENT_DISPLAY);
- try {
- RawInputEvent ev = new RawInputEvent();
- while (true) {
+ RawInputEvent ev = new RawInputEvent();
+ while (true) {
+ try {
InputDevice di;
// block, doesn't release the monitor
@@ -465,49 +470,81 @@
? KeyEvent.FLAG_WOKE_HERE : 0));
} else if (ev.type == RawInputEvent.EV_KEY) {
if (ev.scancode == RawInputEvent.BTN_TOUCH &&
- (classes&RawInputEvent.CLASS_TOUCHSCREEN) != 0) {
+ (classes&(RawInputEvent.CLASS_TOUCHSCREEN
+ |RawInputEvent.CLASS_TOUCHSCREEN_MT))
+ == RawInputEvent.CLASS_TOUCHSCREEN) {
di.mAbs.changed = true;
di.mAbs.mDown[0] = ev.value != 0;
} else if (ev.scancode == RawInputEvent.BTN_2 &&
- (classes&RawInputEvent.CLASS_TOUCHSCREEN) != 0) {
+ (classes&(RawInputEvent.CLASS_TOUCHSCREEN
+ |RawInputEvent.CLASS_TOUCHSCREEN_MT))
+ == RawInputEvent.CLASS_TOUCHSCREEN) {
di.mAbs.changed = true;
di.mAbs.mDown[1] = ev.value != 0;
} else if (ev.scancode == RawInputEvent.BTN_MOUSE &&
(classes&RawInputEvent.CLASS_TRACKBALL) != 0) {
di.mRel.changed = true;
- di.mRel.mDown[0] = ev.value != 0;
+ di.mRel.mNextNumPointers = ev.value != 0 ? 1 : 0;
send = true;
}
} else if (ev.type == RawInputEvent.EV_ABS &&
+ (classes&RawInputEvent.CLASS_TOUCHSCREEN_MT) != 0) {
+ if (ev.scancode == RawInputEvent.ABS_MT_TOUCH_MAJOR) {
+ di.mAbs.changed = true;
+ di.mAbs.mNextData[di.mAbs.mAddingPointerOffset
+ + MotionEvent.SAMPLE_PRESSURE] = ev.value;
+ } else if (ev.scancode == RawInputEvent.ABS_MT_POSITION_X) {
+ di.mAbs.changed = true;
+ di.mAbs.mNextData[di.mAbs.mAddingPointerOffset
+ + MotionEvent.SAMPLE_X] = ev.value;
+ if (DEBUG_POINTERS) Log.v(TAG, "MT @"
+ + di.mAbs.mAddingPointerOffset
+ + " X:" + ev.value);
+ } else if (ev.scancode == RawInputEvent.ABS_MT_POSITION_Y) {
+ di.mAbs.changed = true;
+ di.mAbs.mNextData[di.mAbs.mAddingPointerOffset
+ + MotionEvent.SAMPLE_Y] = ev.value;
+ if (DEBUG_POINTERS) Log.v(TAG, "MT @"
+ + di.mAbs.mAddingPointerOffset
+ + " Y:" + ev.value);
+ } else if (ev.scancode == RawInputEvent.ABS_MT_WIDTH_MAJOR) {
+ di.mAbs.changed = true;
+ di.mAbs.mNextData[di.mAbs.mAddingPointerOffset
+ + MotionEvent.SAMPLE_SIZE] = ev.value;
+ }
+
+ } else if (ev.type == RawInputEvent.EV_ABS &&
(classes&RawInputEvent.CLASS_TOUCHSCREEN) != 0) {
// Finger 1
if (ev.scancode == RawInputEvent.ABS_X) {
di.mAbs.changed = true;
- di.mAbs.mCurData[MotionEvent.SAMPLE_X] = ev.value;
+ di.mAbs.mNextData[MotionEvent.SAMPLE_X] = ev.value;
} else if (ev.scancode == RawInputEvent.ABS_Y) {
di.mAbs.changed = true;
- di.mAbs.mCurData[MotionEvent.SAMPLE_Y] = ev.value;
+ di.mAbs.mNextData[MotionEvent.SAMPLE_Y] = ev.value;
} else if (ev.scancode == RawInputEvent.ABS_PRESSURE) {
di.mAbs.changed = true;
- di.mAbs.mCurData[MotionEvent.SAMPLE_PRESSURE] = ev.value;
- di.mAbs.mCurData[MotionEvent.NUM_SAMPLE_DATA
+ di.mAbs.mNextData[MotionEvent.SAMPLE_PRESSURE] = ev.value;
+ di.mAbs.mNextData[MotionEvent.NUM_SAMPLE_DATA
+ MotionEvent.SAMPLE_PRESSURE] = ev.value;
} else if (ev.scancode == RawInputEvent.ABS_TOOL_WIDTH) {
di.mAbs.changed = true;
- di.mAbs.mCurData[MotionEvent.SAMPLE_SIZE] = ev.value;
- di.mAbs.mCurData[MotionEvent.NUM_SAMPLE_DATA
+ di.mAbs.mNextData[MotionEvent.SAMPLE_SIZE] = ev.value;
+ di.mAbs.mNextData[MotionEvent.NUM_SAMPLE_DATA
+ MotionEvent.SAMPLE_SIZE] = ev.value;
// Finger 2
} else if (ev.scancode == RawInputEvent.ABS_HAT0X) {
di.mAbs.changed = true;
- di.mAbs.mCurData[MotionEvent.NUM_SAMPLE_DATA
- + MotionEvent.SAMPLE_X] = ev.value;
+ di.mAbs.mNextData[(di.mAbs.mDown[0] ?
+ MotionEvent.NUM_SAMPLE_DATA : 0)
+ + MotionEvent.SAMPLE_X] = ev.value;
} else if (ev.scancode == RawInputEvent.ABS_HAT0Y) {
di.mAbs.changed = true;
- di.mAbs.mCurData[MotionEvent.NUM_SAMPLE_DATA
- + MotionEvent.SAMPLE_Y] = ev.value;
+ di.mAbs.mNextData[(di.mAbs.mDown[0] ?
+ MotionEvent.NUM_SAMPLE_DATA : 0)
+ + MotionEvent.SAMPLE_Y] = ev.value;
}
} else if (ev.type == RawInputEvent.EV_REL &&
@@ -515,14 +552,40 @@
// Add this relative movement into our totals.
if (ev.scancode == RawInputEvent.REL_X) {
di.mRel.changed = true;
- di.mRel.mCurData[MotionEvent.SAMPLE_X] += ev.value;
+ di.mRel.mNextData[MotionEvent.SAMPLE_X] += ev.value;
} else if (ev.scancode == RawInputEvent.REL_Y) {
di.mRel.changed = true;
- di.mRel.mCurData[MotionEvent.SAMPLE_Y] += ev.value;
+ di.mRel.mNextData[MotionEvent.SAMPLE_Y] += ev.value;
}
}
- if (send || ev.type == RawInputEvent.EV_SYN) {
+ if (ev.type == RawInputEvent.EV_SYN
+ && ev.scancode == RawInputEvent.SYN_MT_REPORT
+ && di.mAbs != null) {
+ di.mAbs.changed = true;
+ if (di.mAbs.mNextData[MotionEvent.SAMPLE_PRESSURE] > 0) {
+ // If the value is <= 0, the pointer is not
+ // down, so keep it in the count.
+
+ if (di.mAbs.mNextData[di.mAbs.mAddingPointerOffset
+ + MotionEvent.SAMPLE_PRESSURE] != 0) {
+ final int num = di.mAbs.mNextNumPointers+1;
+ di.mAbs.mNextNumPointers = num;
+ if (DEBUG_POINTERS) Log.v(TAG,
+ "MT_REPORT: now have " + num + " pointers");
+ final int newOffset = (num <= InputDevice.MAX_POINTERS)
+ ? (num * MotionEvent.NUM_SAMPLE_DATA)
+ : (InputDevice.MAX_POINTERS *
+ MotionEvent.NUM_SAMPLE_DATA);
+ di.mAbs.mAddingPointerOffset = newOffset;
+ di.mAbs.mNextData[newOffset
+ + MotionEvent.SAMPLE_PRESSURE] = 0;
+ } else {
+ if (DEBUG_POINTERS) Log.v(TAG, "MT_REPORT: no pointer");
+ }
+ }
+ } else if (send || (ev.type == RawInputEvent.EV_SYN
+ && ev.scancode == RawInputEvent.SYN_REPORT)) {
if (mDisplay != null) {
if (!mHaveGlobalMetaState) {
computeGlobalMetaStateLocked();
@@ -534,72 +597,21 @@
if (ms.changed) {
ms.changed = false;
- boolean doMotion = true;
-
- // Look for virtual buttons.
- VirtualKey vk = mPressedVirtualKey;
- if (vk != null) {
- doMotion = false;
- if (!ms.mDown[0]) {
- mPressedVirtualKey = null;
- ms.mLastDown[0] = ms.mDown[0];
- if (DEBUG_VIRTUAL_KEYS) Log.v(TAG,
- "Generate key up for: " + vk.scancode);
- KeyEvent event = newKeyEvent(di,
- di.mKeyDownTime, curTime, false,
- vk.lastKeycode,
- 0, vk.scancode,
- KeyEvent.FLAG_VIRTUAL_HARD_KEY);
- mHapticFeedbackCallback.virtualKeyFeedback(event);
- addLocked(di, curTimeNano, ev.flags,
- RawInputEvent.CLASS_KEYBOARD,
- event);
- } else if (isInsideDisplay(di)) {
- // Whoops the pointer has moved into
- // the display area! Cancel the
- // virtual key and start a pointer
- // motion.
- mPressedVirtualKey = null;
- if (DEBUG_VIRTUAL_KEYS) Log.v(TAG,
- "Cancel key up for: " + vk.scancode);
- KeyEvent event = newKeyEvent(di,
- di.mKeyDownTime, curTime, false,
- vk.lastKeycode,
- 0, vk.scancode,
- KeyEvent.FLAG_CANCELED |
- KeyEvent.FLAG_VIRTUAL_HARD_KEY);
- mHapticFeedbackCallback.virtualKeyFeedback(event);
- addLocked(di, curTimeNano, ev.flags,
- RawInputEvent.CLASS_KEYBOARD,
- event);
- doMotion = true;
- for (int i=InputDevice.MAX_POINTERS-1; i>=0; i--) {
- ms.mLastDown[i] = false;
- }
- }
+ if ((classes&(RawInputEvent.CLASS_TOUCHSCREEN
+ |RawInputEvent.CLASS_TOUCHSCREEN_MT))
+ == RawInputEvent.CLASS_TOUCHSCREEN) {
+ ms.mNextNumPointers = 0;
+ if (ms.mDown[0]) ms.mNextNumPointers++;
+ if (ms.mDown[1]) ms.mNextNumPointers++;
}
- if (doMotion && ms.mDown[0] && !ms.mLastDown[0]) {
- vk = findSoftButton(di);
- if (vk != null) {
- doMotion = false;
- mPressedVirtualKey = vk;
- vk.lastKeycode = scancodeToKeycode(
- di.id, vk.scancode);
- ms.mLastDown[0] = ms.mDown[0];
- di.mKeyDownTime = curTime;
- if (DEBUG_VIRTUAL_KEYS) Log.v(TAG,
- "Generate key down for: " + vk.scancode
- + " (keycode=" + vk.lastKeycode + ")");
- KeyEvent event = newKeyEvent(di,
- di.mKeyDownTime, curTime, true,
- vk.lastKeycode, 0,
- vk.scancode,
- KeyEvent.FLAG_VIRTUAL_HARD_KEY);
- mHapticFeedbackCallback.virtualKeyFeedback(event);
- addLocked(di, curTimeNano, ev.flags,
- RawInputEvent.CLASS_KEYBOARD,
- event);
- }
+
+ boolean doMotion = !monitorVirtualKey(di,
+ ev, curTime, curTimeNano);
+
+ if (doMotion && ms.mNextNumPointers > 0
+ && ms.mLastNumPointers == 0) {
+ doMotion = !generateVirtualKeyDown(di,
+ ev, curTime, curTimeNano);
}
if (doMotion) {
@@ -607,22 +619,26 @@
// multiple events here, for example
// if two fingers change up/down state
// at the same time.
- me = ms.generateAbsMotion(di, curTime,
- curTimeNano, mDisplay,
- mOrientation, mGlobalMetaState);
- if (false) Log.v(TAG, "Absolute: x="
- + di.mAbs.mCurData[MotionEvent.SAMPLE_X]
- + " y="
- + di.mAbs.mCurData[MotionEvent.SAMPLE_Y]
- + " ev=" + me);
- if (me != null) {
- if (WindowManagerPolicy.WATCH_POINTER) {
- Log.i(TAG, "Enqueueing: " + me);
+ do {
+ me = ms.generateAbsMotion(di, curTime,
+ curTimeNano, mDisplay,
+ mOrientation, mGlobalMetaState);
+ if (false) Log.v(TAG, "Absolute: x="
+ + di.mAbs.mNextData[MotionEvent.SAMPLE_X]
+ + " y="
+ + di.mAbs.mNextData[MotionEvent.SAMPLE_Y]
+ + " ev=" + me);
+ if (me != null) {
+ if (WindowManagerPolicy.WATCH_POINTER) {
+ Log.i(TAG, "Enqueueing: " + me);
+ }
+ addLocked(di, curTimeNano, ev.flags,
+ RawInputEvent.CLASS_TOUCHSCREEN, me);
}
- addLocked(di, curTimeNano, ev.flags,
- RawInputEvent.CLASS_TOUCHSCREEN, me);
- }
+ } while (ms.hasMore());
}
+
+ ms.finish();
}
ms = di.mRel;
@@ -633,22 +649,24 @@
curTimeNano,
mOrientation, mGlobalMetaState);
if (false) Log.v(TAG, "Relative: x="
- + di.mRel.mCurData[MotionEvent.SAMPLE_X]
+ + di.mRel.mNextData[MotionEvent.SAMPLE_X]
+ " y="
- + di.mRel.mCurData[MotionEvent.SAMPLE_Y]
+ + di.mRel.mNextData[MotionEvent.SAMPLE_Y]
+ " ev=" + me);
if (me != null) {
addLocked(di, curTimeNano, ev.flags,
RawInputEvent.CLASS_TRACKBALL, me);
}
+
+ ms.finish();
}
}
}
}
- }
- } catch (RuntimeException exc) {
- Log.e(TAG, "InputReaderThread uncaught exception", exc);
+ } catch (RuntimeException exc) {
+ Log.e(TAG, "InputReaderThread uncaught exception", exc);
+ }
}
}
};
@@ -661,13 +679,13 @@
return true;
}
- if (absm.mCurData[MotionEvent.SAMPLE_X] >= absx.minValue
- && absm.mCurData[MotionEvent.SAMPLE_X] <= absx.maxValue
- && absm.mCurData[MotionEvent.SAMPLE_Y] >= absy.minValue
- && absm.mCurData[MotionEvent.SAMPLE_Y] <= absy.maxValue) {
+ if (absm.mNextData[MotionEvent.SAMPLE_X] >= absx.minValue
+ && absm.mNextData[MotionEvent.SAMPLE_X] <= absx.maxValue
+ && absm.mNextData[MotionEvent.SAMPLE_Y] >= absy.minValue
+ && absm.mNextData[MotionEvent.SAMPLE_Y] <= absy.maxValue) {
if (DEBUG_VIRTUAL_KEYS) Log.v(TAG, "Input ("
- + absm.mCurData[MotionEvent.SAMPLE_X]
- + "," + absm.mCurData[MotionEvent.SAMPLE_Y]
+ + absm.mNextData[MotionEvent.SAMPLE_X]
+ + "," + absm.mNextData[MotionEvent.SAMPLE_Y]
+ ") inside of display");
return true;
}
@@ -675,28 +693,24 @@
return false;
}
- private VirtualKey findSoftButton(InputDevice dev) {
+ private VirtualKey findVirtualKey(InputDevice dev) {
final int N = mVirtualKeys.size();
if (N <= 0) {
return null;
}
- if (isInsideDisplay(dev)) {
- return null;
- }
-
final InputDevice.MotionState absm = dev.mAbs;
for (int i=0; i<N; i++) {
VirtualKey sb = mVirtualKeys.get(i);
sb.computeHitRect(dev, mDisplayWidth, mDisplayHeight);
if (DEBUG_VIRTUAL_KEYS) Log.v(TAG, "Hit test ("
- + absm.mCurData[MotionEvent.SAMPLE_X] + ","
- + absm.mCurData[MotionEvent.SAMPLE_Y] + ") in code "
+ + absm.mNextData[MotionEvent.SAMPLE_X] + ","
+ + absm.mNextData[MotionEvent.SAMPLE_Y] + ") in code "
+ sb.scancode + " - (" + sb.hitLeft
+ "," + sb.hitTop + ")-(" + sb.hitRight + ","
+ sb.hitBottom + ")");
- if (sb.checkHit(absm.mCurData[MotionEvent.SAMPLE_X],
- absm.mCurData[MotionEvent.SAMPLE_Y])) {
+ if (sb.checkHit(absm.mNextData[MotionEvent.SAMPLE_X],
+ absm.mNextData[MotionEvent.SAMPLE_Y])) {
if (DEBUG_VIRTUAL_KEYS) Log.v(TAG, "Hit!");
return sb;
}
@@ -705,6 +719,97 @@
return null;
}
+ private boolean generateVirtualKeyDown(InputDevice di, RawInputEvent ev,
+ long curTime, long curTimeNano) {
+ if (isInsideDisplay(di)) {
+ // Didn't consume event.
+ return false;
+ }
+
+
+ VirtualKey vk = findVirtualKey(di);
+ if (vk != null) {
+ final InputDevice.MotionState ms = di.mAbs;
+ mPressedVirtualKey = vk;
+ vk.lastKeycode = scancodeToKeycode(di.id, vk.scancode);
+ ms.mLastNumPointers = ms.mNextNumPointers;
+ di.mKeyDownTime = curTime;
+ if (DEBUG_VIRTUAL_KEYS) Log.v(TAG,
+ "Generate key down for: " + vk.scancode
+ + " (keycode=" + vk.lastKeycode + ")");
+ KeyEvent event = newKeyEvent(di, di.mKeyDownTime, curTime, true,
+ vk.lastKeycode, 0, vk.scancode,
+ KeyEvent.FLAG_VIRTUAL_HARD_KEY);
+ mHapticFeedbackCallback.virtualKeyFeedback(event);
+ addLocked(di, curTimeNano, ev.flags, RawInputEvent.CLASS_KEYBOARD,
+ event);
+ }
+
+ // We always consume the event, even if we didn't
+ // generate a key event. There are two reasons for
+ // this: to avoid spurious touches when holding
+ // the edges of the device near the touchscreen,
+ // and to avoid reporting events if there are virtual
+ // keys on the touchscreen outside of the display
+ // area.
+ // Note that for all of this we are only looking at the
+ // first pointer, since what we are handling here is the
+ // first pointer going down, and this is the coordinate
+ // that will be used to dispatch the event.
+ if (false) {
+ final InputDevice.AbsoluteInfo absx = di.absX;
+ final InputDevice.AbsoluteInfo absy = di.absY;
+ final InputDevice.MotionState absm = di.mAbs;
+ Log.v(TAG, "Rejecting ("
+ + absm.mNextData[MotionEvent.SAMPLE_X] + ","
+ + absm.mNextData[MotionEvent.SAMPLE_Y] + "): outside of ("
+ + absx.minValue + "," + absy.minValue
+ + ")-(" + absx.maxValue + ","
+ + absx.maxValue + ")");
+ }
+ return true;
+ }
+
+ private boolean monitorVirtualKey(InputDevice di, RawInputEvent ev,
+ long curTime, long curTimeNano) {
+ VirtualKey vk = mPressedVirtualKey;
+ if (vk == null) {
+ return false;
+ }
+
+ final InputDevice.MotionState ms = di.mAbs;
+ if (ms.mNextNumPointers <= 0) {
+ mPressedVirtualKey = null;
+ ms.mLastNumPointers = 0;
+ if (DEBUG_VIRTUAL_KEYS) Log.v(TAG, "Generate key up for: " + vk.scancode);
+ KeyEvent event = newKeyEvent(di, di.mKeyDownTime, curTime, false,
+ vk.lastKeycode, 0, vk.scancode,
+ KeyEvent.FLAG_VIRTUAL_HARD_KEY);
+ mHapticFeedbackCallback.virtualKeyFeedback(event);
+ addLocked(di, curTimeNano, ev.flags, RawInputEvent.CLASS_KEYBOARD,
+ event);
+ return true;
+
+ } else if (isInsideDisplay(di)) {
+ // Whoops the pointer has moved into
+ // the display area! Cancel the
+ // virtual key and start a pointer
+ // motion.
+ mPressedVirtualKey = null;
+ if (DEBUG_VIRTUAL_KEYS) Log.v(TAG, "Cancel key up for: " + vk.scancode);
+ KeyEvent event = newKeyEvent(di, di.mKeyDownTime, curTime, false,
+ vk.lastKeycode, 0, vk.scancode,
+ KeyEvent.FLAG_CANCELED | KeyEvent.FLAG_VIRTUAL_HARD_KEY);
+ mHapticFeedbackCallback.virtualKeyFeedback(event);
+ addLocked(di, curTimeNano, ev.flags, RawInputEvent.CLASS_KEYBOARD,
+ event);
+ ms.mLastNumPointers = 0;
+ return false;
+ }
+
+ return true;
+ }
+
/**
* Returns a new meta state for the given keys and old state.
*/
@@ -851,8 +956,8 @@
if (ev.event == ev.inputDevice.mRel.currentMove) {
if (false) Log.i(TAG, "Detach rel " + ev.event);
ev.inputDevice.mRel.currentMove = null;
- ev.inputDevice.mRel.mCurData[MotionEvent.SAMPLE_X] = 0;
- ev.inputDevice.mRel.mCurData[MotionEvent.SAMPLE_Y] = 0;
+ ev.inputDevice.mRel.mNextData[MotionEvent.SAMPLE_X] = 0;
+ ev.inputDevice.mRel.mNextData[MotionEvent.SAMPLE_Y] = 0;
}
recycleLocked(ev);
}
@@ -945,7 +1050,12 @@
InputDevice.AbsoluteInfo absY;
InputDevice.AbsoluteInfo absPressure;
InputDevice.AbsoluteInfo absSize;
- if ((classes&RawInputEvent.CLASS_TOUCHSCREEN) != 0) {
+ if ((classes&RawInputEvent.CLASS_TOUCHSCREEN_MT) != 0) {
+ absX = loadAbsoluteInfo(deviceId, RawInputEvent.ABS_MT_POSITION_X, "X");
+ absY = loadAbsoluteInfo(deviceId, RawInputEvent.ABS_MT_POSITION_Y, "Y");
+ absPressure = loadAbsoluteInfo(deviceId, RawInputEvent.ABS_MT_TOUCH_MAJOR, "Pressure");
+ absSize = loadAbsoluteInfo(deviceId, RawInputEvent.ABS_MT_WIDTH_MAJOR, "Size");
+ } else if ((classes&RawInputEvent.CLASS_TOUCHSCREEN) != 0) {
absX = loadAbsoluteInfo(deviceId, RawInputEvent.ABS_X, "X");
absY = loadAbsoluteInfo(deviceId, RawInputEvent.ABS_Y, "Y");
absPressure = loadAbsoluteInfo(deviceId, RawInputEvent.ABS_PRESSURE, "Pressure");
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index edba5b6..ceb9c41 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -541,6 +541,17 @@
mTransitionAnimationScale = Settings.System.getFloat(context.getContentResolver(),
Settings.System.TRANSITION_ANIMATION_SCALE, mTransitionAnimationScale);
+ int max_events_per_sec = 35;
+ try {
+ max_events_per_sec = Integer.parseInt(SystemProperties
+ .get("windowsmgr.max_events_per_sec"));
+ if (max_events_per_sec < 1) {
+ max_events_per_sec = 35;
+ }
+ } catch (NumberFormatException e) {
+ }
+ mMinWaitTimeBetweenTouchEvents = 1000 / max_events_per_sec;
+
mQueue = new KeyQ();
mInputThread = new InputDispatcherThread();
@@ -4010,8 +4021,8 @@
}
} //end if target
- // TODO remove once we settle on a value or make it app specific
- if (action == MotionEvent.ACTION_DOWN) {
+ // Enable this for testing the "right" value
+ if (false && action == MotionEvent.ACTION_DOWN) {
int max_events_per_sec = 35;
try {
max_events_per_sec = Integer.parseInt(SystemProperties