Merge "Change recents UIs to do task switches."
diff --git a/api/current.xml b/api/current.xml
index 9923020..15224ce 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -9425,6 +9425,17 @@
visibility="public"
>
</field>
+<field name="textIsSelectable"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843559"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="textLineHeight"
type="int"
transient="false"
@@ -10360,6 +10371,17 @@
visibility="public"
>
</field>
+<field name="windowEnableSplitTouch"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843560"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="windowEnterAnimation"
type="int"
transient="false"
@@ -219227,6 +219249,19 @@
<parameter name="data" type="android.os.Bundle">
</parameter>
</method>
+<method name="setCurrentInputMethodSubtype"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="subtype" type="android.view.inputmethod.InputMethodSubtype">
+</parameter>
+</method>
<method name="setInputMethod"
return="void"
abstract="false"
@@ -219341,6 +219376,19 @@
<parameter name="iconId" type="int">
</parameter>
</method>
+<method name="switchToLastInputMethod"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="imeToken" type="android.os.IBinder">
+</parameter>
+</method>
<method name="toggleSoftInput"
return="void"
abstract="false"
@@ -243536,6 +243584,17 @@
visibility="public"
>
</method>
+<method name="isTextSelectable"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="length"
return="int"
abstract="false"
@@ -244583,6 +244642,19 @@
<parameter name="colors" type="android.content.res.ColorStateList">
</parameter>
</method>
+<method name="setTextIsSelectable"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="selectable" type="boolean">
+</parameter>
+</method>
<method name="setTextKeepState"
return="void"
abstract="false"
@@ -246446,7 +246518,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="t" type="T">
+<parameter name="arg0" type="T">
</parameter>
</method>
</interface>
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index 01414fa..3a6fd23 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -33,10 +33,7 @@
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
/**
* The download manager is a system service that handles long-running HTTP downloads. Clients may
@@ -281,46 +278,32 @@
*/
public static final String EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS = "extra_click_download_ids";
- // this array must contain all public columns
- private static final String[] COLUMNS = new String[] {
- COLUMN_ID,
- COLUMN_MEDIAPROVIDER_URI,
- Downloads.Impl.COLUMN_DESTINATION,
- COLUMN_TITLE,
- COLUMN_DESCRIPTION,
- COLUMN_URI,
- COLUMN_MEDIA_TYPE,
- COLUMN_TOTAL_SIZE_BYTES,
- COLUMN_LOCAL_URI,
- COLUMN_STATUS,
- COLUMN_REASON,
- COLUMN_BYTES_DOWNLOADED_SO_FAR,
- COLUMN_LAST_MODIFIED_TIMESTAMP,
- COLUMN_LOCAL_FILENAME,
- };
-
- // columns to request from DownloadProvider
- private static final String[] UNDERLYING_COLUMNS = new String[] {
+ /**
+ * columns to request from DownloadProvider.
+ * @hide
+ */
+ public static final String[] UNDERLYING_COLUMNS = new String[] {
Downloads.Impl._ID,
+ Downloads.Impl._DATA,
Downloads.Impl.COLUMN_MEDIAPROVIDER_URI,
Downloads.Impl.COLUMN_DESTINATION,
Downloads.Impl.COLUMN_TITLE,
Downloads.Impl.COLUMN_DESCRIPTION,
Downloads.Impl.COLUMN_URI,
- Downloads.Impl.COLUMN_MIME_TYPE,
- Downloads.Impl.COLUMN_TOTAL_BYTES,
Downloads.Impl.COLUMN_STATUS,
- Downloads.Impl.COLUMN_CURRENT_BYTES,
- Downloads.Impl.COLUMN_LAST_MODIFICATION,
Downloads.Impl.COLUMN_FILE_NAME_HINT,
- Downloads.Impl._DATA,
+ Downloads.Impl.COLUMN_MIME_TYPE + " AS " + COLUMN_MEDIA_TYPE,
+ Downloads.Impl.COLUMN_TOTAL_BYTES + " AS " + COLUMN_TOTAL_SIZE_BYTES,
+ Downloads.Impl.COLUMN_LAST_MODIFICATION + " AS " + COLUMN_LAST_MODIFIED_TIMESTAMP,
+ Downloads.Impl.COLUMN_CURRENT_BYTES + " AS " + COLUMN_BYTES_DOWNLOADED_SO_FAR,
+ /* add the following 'computed' columns to the cursor.
+ * they are not 'returned' by the database, but their inclusion
+ * eliminates need to have lot of methods in CursorTranslator
+ */
+ "'placeholder' AS " + COLUMN_LOCAL_URI,
+ "'placeholder' AS " + COLUMN_REASON
};
- private static final Set<String> LONG_COLUMNS = new HashSet<String>(
- Arrays.asList(COLUMN_ID, COLUMN_TOTAL_SIZE_BYTES, COLUMN_STATUS, COLUMN_REASON,
- COLUMN_BYTES_DOWNLOADED_SO_FAR, COLUMN_LAST_MODIFIED_TIMESTAMP,
- Downloads.Impl.COLUMN_DESTINATION));
-
/**
* This class contains all the information necessary to request a new download. The URI is the
* only required parameter.
@@ -871,11 +854,7 @@
* @return the number of downloads actually removed
*/
public int remove(long... ids) {
- if (ids == null || ids.length == 0) {
- // called with nothing to remove!
- throw new IllegalArgumentException("input param 'ids' can't be null");
- }
- return mResolver.delete(mBaseUri, getWhereClauseForIds(ids), getWhereArgsForIds(ids));
+ return markRowDeleted(ids);
}
/**
@@ -1032,117 +1011,32 @@
}
@Override
- public int getColumnIndex(String columnName) {
- return Arrays.asList(COLUMNS).indexOf(columnName);
- }
-
- @Override
- public int getColumnIndexOrThrow(String columnName) throws IllegalArgumentException {
- int index = getColumnIndex(columnName);
- if (index == -1) {
- throw new IllegalArgumentException("No such column: " + columnName);
- }
- return index;
- }
-
- @Override
- public String getColumnName(int columnIndex) {
- int numColumns = COLUMNS.length;
- if (columnIndex < 0 || columnIndex >= numColumns) {
- throw new IllegalArgumentException("Invalid column index " + columnIndex + ", "
- + numColumns + " columns exist");
- }
- return COLUMNS[columnIndex];
- }
-
- @Override
- public String[] getColumnNames() {
- String[] returnColumns = new String[COLUMNS.length];
- System.arraycopy(COLUMNS, 0, returnColumns, 0, COLUMNS.length);
- return returnColumns;
- }
-
- @Override
- public int getColumnCount() {
- return COLUMNS.length;
- }
-
- @Override
- public byte[] getBlob(int columnIndex) {
- throw new UnsupportedOperationException();
- }
-
- @Override
- public double getDouble(int columnIndex) {
- return getLong(columnIndex);
- }
-
- private boolean isLongColumn(String column) {
- return LONG_COLUMNS.contains(column);
- }
-
- @Override
- public float getFloat(int columnIndex) {
- return (float) getDouble(columnIndex);
- }
-
- @Override
public int getInt(int columnIndex) {
return (int) getLong(columnIndex);
}
@Override
public long getLong(int columnIndex) {
- return translateLong(getColumnName(columnIndex));
- }
-
- @Override
- public short getShort(int columnIndex) {
- return (short) getLong(columnIndex);
+ if (getColumnName(columnIndex).equals(COLUMN_REASON)) {
+ return getReason(super.getInt(getColumnIndex(Downloads.Impl.COLUMN_STATUS)));
+ } else if (getColumnName(columnIndex).equals(COLUMN_STATUS)) {
+ return translateStatus(super.getInt(getColumnIndex(Downloads.Impl.COLUMN_STATUS)));
+ } else {
+ return super.getLong(columnIndex);
+ }
}
@Override
public String getString(int columnIndex) {
- return translateString(getColumnName(columnIndex));
- }
-
- private String translateString(String column) {
- if (isLongColumn(column)) {
- return Long.toString(translateLong(column));
- }
- if (column.equals(COLUMN_TITLE)) {
- return getUnderlyingString(Downloads.Impl.COLUMN_TITLE);
- }
- if (column.equals(COLUMN_DESCRIPTION)) {
- return getUnderlyingString(Downloads.Impl.COLUMN_DESCRIPTION);
- }
- if (column.equals(COLUMN_URI)) {
- return getUnderlyingString(Downloads.Impl.COLUMN_URI);
- }
- if (column.equals(COLUMN_MEDIA_TYPE)) {
- return getUnderlyingString(Downloads.Impl.COLUMN_MIME_TYPE);
- }
- if (column.equals(COLUMN_LOCAL_FILENAME)) {
- return getUnderlyingString(Downloads.Impl._DATA);
- }
- if (column.equals(COLUMN_MEDIAPROVIDER_URI)) {
- return getUnderlyingString(Downloads.Impl.COLUMN_MEDIAPROVIDER_URI);
- }
-
- assert column.equals(COLUMN_LOCAL_URI);
- return getLocalUri();
+ return (getColumnName(columnIndex).equals(COLUMN_LOCAL_URI)) ? getLocalUri() :
+ super.getString(columnIndex);
}
private String getLocalUri() {
- long destinationType = getUnderlyingLong(Downloads.Impl.COLUMN_DESTINATION);
- if (destinationType == Downloads.Impl.DESTINATION_FILE_URI) {
- // return client-provided file URI for external download
- return getUnderlyingString(Downloads.Impl.COLUMN_FILE_NAME_HINT);
- }
-
- if (destinationType == Downloads.Impl.DESTINATION_EXTERNAL) {
- // return stored destination for legacy external download
- String localPath = getUnderlyingString(Downloads.Impl._DATA);
+ long destinationType = getLong(getColumnIndex(Downloads.Impl.COLUMN_DESTINATION));
+ if (destinationType == Downloads.Impl.DESTINATION_FILE_URI ||
+ destinationType == Downloads.Impl.DESTINATION_EXTERNAL) {
+ String localPath = getString(getColumnIndex(Downloads.Impl._DATA));
if (localPath == null) {
return null;
}
@@ -1150,38 +1044,10 @@
}
// return content URI for cache download
- long downloadId = getUnderlyingLong(Downloads.Impl._ID);
+ long downloadId = getLong(getColumnIndex(Downloads.Impl._ID));
return ContentUris.withAppendedId(mBaseUri, downloadId).toString();
}
- private long translateLong(String column) {
- if (!isLongColumn(column)) {
- // mimic behavior of underlying cursor -- most likely, throw NumberFormatException
- return Long.valueOf(translateString(column));
- }
-
- if (column.equals(COLUMN_ID)) {
- return getUnderlyingLong(Downloads.Impl._ID);
- }
- if (column.equals(COLUMN_TOTAL_SIZE_BYTES)) {
- return getUnderlyingLong(Downloads.Impl.COLUMN_TOTAL_BYTES);
- }
- if (column.equals(COLUMN_STATUS)) {
- return translateStatus((int) getUnderlyingLong(Downloads.Impl.COLUMN_STATUS));
- }
- if (column.equals(COLUMN_REASON)) {
- return getReason((int) getUnderlyingLong(Downloads.Impl.COLUMN_STATUS));
- }
- if (column.equals(COLUMN_BYTES_DOWNLOADED_SO_FAR)) {
- return getUnderlyingLong(Downloads.Impl.COLUMN_CURRENT_BYTES);
- }
- if (column.equals(Downloads.Impl.COLUMN_DESTINATION)) {
- return getUnderlyingLong(Downloads.Impl.COLUMN_DESTINATION);
- }
- assert column.equals(COLUMN_LAST_MODIFIED_TIMESTAMP);
- return getUnderlyingLong(Downloads.Impl.COLUMN_LAST_MODIFICATION);
- }
-
private long getReason(int status) {
switch (translateStatus(status)) {
case STATUS_FAILED:
@@ -1249,14 +1115,6 @@
}
}
- private long getUnderlyingLong(String column) {
- return super.getLong(super.getColumnIndex(column));
- }
-
- private String getUnderlyingString(String column) {
- return super.getString(super.getColumnIndex(column));
- }
-
private int translateStatus(int status) {
switch (status) {
case Downloads.Impl.STATUS_PENDING:
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 34bd386..221fe23 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -705,6 +705,14 @@
}
}
+ private void clearBackoffSetting(SyncOperation op) {
+ mSyncStorageEngine.setBackoff(op.account, op.authority,
+ SyncStorageEngine.NOT_IN_BACKOFF_MODE, SyncStorageEngine.NOT_IN_BACKOFF_MODE);
+ synchronized (mSyncQueue) {
+ mSyncQueue.onBackoffChanged(op.account, op.authority, 0);
+ }
+ }
+
private void increaseBackoffSetting(SyncOperation op) {
final long now = SystemClock.elapsedRealtime();
@@ -1854,6 +1862,7 @@
// TODO: set these correctly when the SyncResult is extended to include it
downstreamActivity = 0;
upstreamActivity = 0;
+ clearBackoffSetting(syncOperation);
} else {
Log.d(TAG, "failed sync operation " + syncOperation + ", " + syncResult);
// the operation failed so increase the backoff time
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 41bb364..7efb7fd 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -1081,7 +1081,7 @@
mConnectionPool.close();
}
} finally {
- unlock();
+ unlock();
}
}
@@ -1772,8 +1772,7 @@
*/
public int updateWithOnConflict(String table, ContentValues values,
String whereClause, String[] whereArgs, int conflictAlgorithm) {
- int setValuesSize = values.size();
- if (values == null || setValuesSize == 0) {
+ if (values == null || values.size() == 0) {
throw new IllegalArgumentException("Empty values");
}
@@ -1784,6 +1783,7 @@
sql.append(" SET ");
// move all bind args to one array
+ int setValuesSize = values.size();
int bindArgsSize = (whereArgs == null) ? setValuesSize : (setValuesSize + whereArgs.length);
Object[] bindArgs = new Object[bindArgsSize];
int i = 0;
@@ -2118,7 +2118,7 @@
int maxCacheSz = (mConnectionNum == 0) ? mMaxSqlCacheSize :
mParentConnObj.mMaxSqlCacheSize;
-
+
if (SQLiteDebug.DEBUG_SQL_CACHE) {
boolean printWarning = (mConnectionNum == 0)
? (!mCacheFullWarning && mCompiledQueries.size() == maxCacheSz)
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 033ee7c..5e7a133 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -1432,6 +1432,28 @@
}
}
+ public boolean setCurrentInputMethodSubtype(InputMethodSubtype subtype) {
+ synchronized (mH) {
+ try {
+ return mService.setCurrentInputMethodSubtype(subtype);
+ } catch (RemoteException e) {
+ Log.w(TAG, "IME died: " + mCurId, e);
+ return false;
+ }
+ }
+ }
+
+ public boolean switchToLastInputMethod(IBinder imeToken) {
+ synchronized (mH) {
+ try {
+ return mService.switchToLastInputMethod(imeToken);
+ } catch (RemoteException e) {
+ Log.w(TAG, "IME died: " + mCurId, e);
+ return false;
+ }
+ }
+ }
+
void doDump(FileDescriptor fd, PrintWriter fout, String[] args) {
final Printer p = new PrintWriterPrinter(fout);
p.println("Input method client state for " + this + ":");
diff --git a/core/java/android/webkit/DebugFlags.java b/core/java/android/webkit/DebugFlags.java
index 8e25395..3cb5e24 100644
--- a/core/java/android/webkit/DebugFlags.java
+++ b/core/java/android/webkit/DebugFlags.java
@@ -45,5 +45,9 @@
public static final boolean WEB_TEXT_VIEW = false;
public static final boolean WEB_VIEW = false;
public static final boolean WEB_VIEW_CORE = false;
-
+ /*
+ * Set to true to allow the WebTextView to draw on top of the web page in a
+ * different color so that you can see how the two line up.
+ */
+ public static final boolean DRAW_WEBTEXTVIEW = false;
}
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index a58d648..f477f8f 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -157,7 +157,7 @@
// Set the text color to black, regardless of the theme. This ensures
// that other applications that use embedded WebViews will properly
// display the text in password textfields.
- setTextColor(Color.BLACK);
+ setTextColor(DebugFlags.DRAW_WEBTEXTVIEW ? Color.RED : Color.BLACK);
// This helps to align the text better with the text in the web page.
setIncludeFontPadding(false);
}
@@ -404,8 +404,9 @@
// onDraw should only be called for password fields. If WebTextView is
// still drawing, but is no longer corresponding to a password field,
// remove it.
- if (mWebView == null || !mWebView.nativeFocusCandidateIsPassword()
- || !isSameTextField(mWebView.nativeFocusCandidatePointer())) {
+ if (!DebugFlags.DRAW_WEBTEXTVIEW && (mWebView == null
+ || !mWebView.nativeFocusCandidateIsPassword()
+ || !isSameTextField(mWebView.nativeFocusCandidatePointer()))) {
// Although calling remove() would seem to make more sense here,
// changing it to not be a password field will make it not draw.
// Other code will make sure that it is removed completely, but this
@@ -819,7 +820,9 @@
}
// For password fields, draw the WebTextView. For others, just show
// webkit's drawing.
- setWillNotDraw(!inPassword);
+ if (!DebugFlags.DRAW_WEBTEXTVIEW) {
+ setWillNotDraw(!inPassword);
+ }
setBackgroundDrawable(inPassword ? mBackground : null);
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 4e0c386..14dbfe2 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -7481,7 +7481,7 @@
private native Rect nativeFocusCandidatePaddingRect();
/* package */ native int nativeFocusCandidatePointer();
private native String nativeFocusCandidateText();
- /* package */ native int nativeFocusCandidateTextSize();
+ /* package */ native float nativeFocusCandidateTextSize();
/**
* Returns an integer corresponding to WebView.cpp::type.
* See WebTextView.setType()
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 6e927a6..0fcd26c 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -1803,6 +1803,8 @@
} else {
width = Math.max(w, mViewportWidth);
}
+ } else if (mSettings.getUseFixedViewport()) {
+ width = mWebView.getViewWidth();
} else {
width = textwrapWidth;
}
diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java
index 7d78777..695ea6b 100644
--- a/core/java/android/widget/AdapterViewAnimator.java
+++ b/core/java/android/widget/AdapterViewAnimator.java
@@ -24,7 +24,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.res.TypedArray;
-import android.graphics.Rect;
import android.os.Handler;
import android.os.Looper;
import android.os.Parcel;
diff --git a/core/java/android/widget/MediaController.java b/core/java/android/widget/MediaController.java
index 27a6ad3..690164c 100644
--- a/core/java/android/widget/MediaController.java
+++ b/core/java/android/widget/MediaController.java
@@ -298,7 +298,8 @@
p.y = anchorpos[1] + mAnchor.getHeight() - p.height;
p.format = PixelFormat.TRANSLUCENT;
p.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
- p.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
+ p.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+ | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
p.token = null;
p.windowAnimations = 0; // android.R.style.DropDownAnimationDown;
mWindowManager.addView(mDecor, p);
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 95678c6..0f61cd4 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -25,6 +25,7 @@
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
+import android.os.Build;
import android.os.IBinder;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
@@ -87,7 +88,7 @@
private boolean mTouchable = true;
private boolean mOutsideTouchable = false;
private boolean mClippingEnabled = true;
- private boolean mSplitTouchEnabled;
+ private int mSplitTouchEnabled = -1;
private boolean mLayoutInScreen;
private boolean mClipToScreen;
@@ -602,14 +603,17 @@
* @hide
*/
public boolean isSplitTouchEnabled() {
- return mSplitTouchEnabled;
+ if (mSplitTouchEnabled < 0 && mContext != null) {
+ return mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.HONEYCOMB;
+ }
+ return mSplitTouchEnabled == 1;
}
/**
* <p>Allows the popup window to split touches across other windows that also
- * support split touch. When this flag is not set, the first pointer
+ * support split touch. When this flag is false, the first pointer
* that goes down determines the window to which all subsequent touches
- * go until all pointers go up. When this flag is set, each pointer
+ * go until all pointers go up. When this flag is true, each pointer
* (not necessarily the first) that goes down determines the window
* to which all subsequent touches of that pointer will go until that
* pointer goes up thereby enabling touches with multiple pointers
@@ -620,7 +624,7 @@
* @hide
*/
public void setSplitTouchEnabled(boolean enabled) {
- mSplitTouchEnabled = enabled;
+ mSplitTouchEnabled = enabled ? 1 : 0;
}
/**
@@ -993,7 +997,7 @@
if (!mClippingEnabled) {
curFlags |= WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
}
- if (mSplitTouchEnabled) {
+ if (isSplitTouchEnabled()) {
curFlags |= WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
}
if (mLayoutInScreen) {
diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java
index 01044d9..7c38714 100644
--- a/core/java/android/widget/StackView.java
+++ b/core/java/android/widget/StackView.java
@@ -122,7 +122,7 @@
private boolean mFirstLayoutHappened = false;
private int mStackMode;
private int mFramePadding;
- private final Rect invalidateRect = new Rect();
+ private final Rect stackInvalidateRect = new Rect();
public StackView(Context context) {
super(context);
@@ -243,6 +243,7 @@
@Override
@android.view.RemotableViewMethod
public void showNext() {
+ if (mSwipeGestureType != GESTURE_NONE) return;
if (!mTransitionIsSetup) {
View v = getViewAtRelativeIndex(1);
if (v != null) {
@@ -257,6 +258,7 @@
@Override
@android.view.RemotableViewMethod
public void showPrevious() {
+ if (mSwipeGestureType != GESTURE_NONE) return;
if (!mTransitionIsSetup) {
View v = getViewAtRelativeIndex(0);
if (v != null) {
@@ -301,8 +303,11 @@
// Here we need to make sure that the z-order of the children is correct
for (int i = mCurrentWindowEnd; i >= mCurrentWindowStart; i--) {
int index = modulo(i, getWindowSize());
- View v = mViewsMap.get(index).view;
- if (v != null) v.bringToFront();
+ ViewAndIndex vi = mViewsMap.get(index);
+ if (vi != null) {
+ View v = mViewsMap.get(index).view;
+ if (v != null) v.bringToFront();
+ }
}
mTransitionIsSetup = false;
}
@@ -331,16 +336,15 @@
@Override
protected void dispatchDraw(Canvas canvas) {
- canvas.getClipBounds(invalidateRect);
+ canvas.getClipBounds(stackInvalidateRect);
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
LayoutParams lp = (LayoutParams) getChildAt(i).getLayoutParams();
- invalidateRect.union(lp.getInvalidateRect());
+ stackInvalidateRect.union(lp.getInvalidateRect());
lp.resetInvalidateRect();
}
-
canvas.save(Canvas.CLIP_SAVE_FLAG);
- canvas.clipRect(invalidateRect, Region.Op.UNION);
+ canvas.clipRect(stackInvalidateRect, Region.Op.UNION);
super.dispatchDraw(canvas);
canvas.restore();
}
@@ -553,6 +557,10 @@
if (deltaY > mSwipeThreshold && mSwipeGestureType == GESTURE_SLIDE_DOWN
&& mStackSlider.mMode == StackSlider.NORMAL_MODE) {
+ // We reset the gesture variable, because otherwise we will ignore showPrevious() /
+ // showNext();
+ mSwipeGestureType = GESTURE_NONE;
+
// Swipe threshold exceeded, swipe down
if (mStackMode == ITEMS_SLIDE_UP) {
showPrevious();
@@ -562,6 +570,10 @@
mHighlight.bringToFront();
} else if (deltaY < -mSwipeThreshold && mSwipeGestureType == GESTURE_SLIDE_UP
&& mStackSlider.mMode == StackSlider.NORMAL_MODE) {
+ // We reset the gesture variable, because otherwise we will ignore showPrevious() /
+ // showNext();
+ mSwipeGestureType = GESTURE_NONE;
+
// Swipe threshold exceeded, swipe up
if (mStackMode == ITEMS_SLIDE_UP) {
showNext();
@@ -897,7 +909,6 @@
int horizontalOffset;
int verticalOffset;
View mView;
- int left, top, right, bottom;
private final Rect parentRect = new Rect();
private final Rect invalidateRect = new Rect();
private final RectF invalidateRectf = new RectF();
@@ -952,44 +963,32 @@
}
void resetInvalidateRect() {
- invalidateRect.set(0, 0, 0, 0);
+ invalidateRect.set(0, 0, 0, 0);
}
// This is public so that ObjectAnimator can access it
public void setVerticalOffset(int newVerticalOffset) {
- int offsetDelta = newVerticalOffset - verticalOffset;
+ setOffsets(horizontalOffset, newVerticalOffset);
+ }
+
+ public void setHorizontalOffset(int newHorizontalOffset) {
+ setOffsets(newHorizontalOffset, verticalOffset);
+ }
+
+ public void setOffsets(int newHorizontalOffset, int newVerticalOffset) {
+ int horizontalOffsetDelta = newHorizontalOffset - horizontalOffset;
+ horizontalOffset = newHorizontalOffset;
+ int verticalOffsetDelta = newVerticalOffset - verticalOffset;
verticalOffset = newVerticalOffset;
if (mView != null) {
mView.requestLayout();
- int top = Math.min(mView.getTop() + offsetDelta, mView.getTop());
- int bottom = Math.max(mView.getBottom() + offsetDelta, mView.getBottom());
+ int left = Math.min(mView.getLeft() + horizontalOffsetDelta, mView.getLeft());
+ int right = Math.max(mView.getRight() + horizontalOffsetDelta, mView.getRight());
+ int top = Math.min(mView.getTop() + verticalOffsetDelta, mView.getTop());
+ int bottom = Math.max(mView.getBottom() + verticalOffsetDelta, mView.getBottom());
- invalidateRectf.set(mView.getLeft(), top, mView.getRight(), bottom);
-
- float xoffset = -invalidateRectf.left;
- float yoffset = -invalidateRectf.top;
- invalidateRectf.offset(xoffset, yoffset);
- mView.getMatrix().mapRect(invalidateRectf);
- invalidateRectf.offset(-xoffset, -yoffset);
- invalidateRect.union((int) Math.floor(invalidateRectf.left),
- (int) Math.floor(invalidateRectf.top),
- (int) Math.ceil(invalidateRectf.right),
- (int) Math.ceil(invalidateRectf.bottom));
-
- invalidateGlobalRegion(mView, invalidateRect);
- }
- }
-
- public void setHorizontalOffset(int newHorizontalOffset) {
- int offsetDelta = newHorizontalOffset - horizontalOffset;
- horizontalOffset = newHorizontalOffset;
-
- if (mView != null) {
- mView.requestLayout();
- int left = Math.min(mView.getLeft() + offsetDelta, mView.getLeft());
- int right = Math.max(mView.getRight() + offsetDelta, mView.getRight());
- invalidateRectf.set(left, mView.getTop(), right, mView.getBottom());
+ invalidateRectf.set(left, top, right, bottom);
float xoffset = -invalidateRectf.left;
float yoffset = -invalidateRectf.top;
@@ -997,7 +996,7 @@
mView.getMatrix().mapRect(invalidateRectf);
invalidateRectf.offset(-xoffset, -yoffset);
- invalidateRect.union((int) Math.floor(invalidateRectf.left),
+ invalidateRect.set((int) Math.floor(invalidateRectf.left),
(int) Math.floor(invalidateRectf.top),
(int) Math.ceil(invalidateRectf.right),
(int) Math.ceil(invalidateRectf.bottom));
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index fdd75d5..5320b10 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -66,6 +66,7 @@
import android.text.TextPaint;
import android.text.TextUtils;
import android.text.TextWatcher;
+import android.text.method.ArrowKeyMovementMethod;
import android.text.method.DateKeyListener;
import android.text.method.DateTimeKeyListener;
import android.text.method.DialerKeyListener;
@@ -755,6 +756,11 @@
if (lineHeight != 0) {
setLineHeight(lineHeight);
}
+ break;
+
+ case com.android.internal.R.styleable.TextView_textIsSelectable:
+ mTextIsSelectable = a.getBoolean(attr, false);
+ break;
}
}
a.recycle();
@@ -844,6 +850,14 @@
mInput = TextKeyListener.getInstance(autotext, cap);
mInputType = inputType;
+ } else if (mTextIsSelectable) {
+ // Prevent text changes from keyboard.
+ mInputType = EditorInfo.TYPE_NULL;
+ mInput = null;
+ bufferType = BufferType.SPANNABLE;
+ setFocusableInTouchMode(true);
+ // So that selection can be changed using arrow keys and touch is handled.
+ setMovementMethod(ArrowKeyMovementMethod.getInstance());
} else if (editable) {
mInput = TextKeyListener.getInstance();
mInputType = EditorInfo.TYPE_CLASS_TEXT;
@@ -1098,6 +1112,8 @@
* within the text can cause individual lines to be taller or shorter
* than this height, and the layout may contain additional first-
* or last-line padding.
+ *
+ * @attr ref android.R.styleable#TextView_textLineHeight
*/
public int getLineHeight() {
if (mLineHeight != 0) {
@@ -4028,6 +4044,71 @@
return false;
}
+ /**
+ * When a TextView is used to display a useful piece of information to the user (such as a
+ * contact's address), it should be made selectable, so that the user can select and copy this
+ * content.
+ *
+ * Use {@link #setTextIsSelectable(boolean)} or the
+ * {@link android.R.styleable#TextView_textIsSelectable} XML attribute to make this TextView
+ * selectable (the text is not selectable by default). Note that the content of an EditText is
+ * always selectable.
+ *
+ * @return True if the text displayed in this TextView can be selected by the user.
+ *
+ * @attr ref android.R.styleable#TextView_textIsSelectable
+ */
+ public boolean isTextSelectable() {
+ return mTextIsSelectable;
+ }
+
+ /**
+ * Sets whether or not (default) the content of this view is selectable by the user.
+ *
+ * See {@link #isTextSelectable} for details.
+ *
+ * @param selectable Whether or not the content of this TextView should be selectable.
+ */
+ public void setTextIsSelectable(boolean selectable) {
+ if (mTextIsSelectable == selectable) return;
+
+ mTextIsSelectable = selectable;
+
+ setFocusableInTouchMode(selectable);
+ setFocusable(selectable);
+ setClickable(selectable);
+ setLongClickable(selectable);
+
+ // mInputType is already EditorInfo.TYPE_NULL and mInput is null;
+
+ setMovementMethod(selectable ? ArrowKeyMovementMethod.getInstance() : null);
+ setText(getText(), selectable ? BufferType.SPANNABLE : BufferType.NORMAL);
+
+ // Called by setText above, but safer in case of future code changes
+ prepareCursorControllers();
+ }
+
+ @Override
+ protected int[] onCreateDrawableState(int extraSpace) {
+ final int[] drawableState = super.onCreateDrawableState(extraSpace);
+ if (mTextIsSelectable) {
+ // Disable pressed state, which was introduced when TextView was made clickable.
+ // Prevents text color change.
+ // setClickable(false) would have a similar effect, but it also disables focus changes
+ // and long press actions, which are both needed by text selection.
+ final int length = drawableState.length;
+ for (int i = 0; i < length; i++) {
+ if (drawableState[i] == R.attr.state_pressed) {
+ final int[] nonPressedState = new int[length - 1];
+ System.arraycopy(drawableState, 0, nonPressedState, 0, i);
+ System.arraycopy(drawableState, i + 1, nonPressedState, i, length - i - 1);
+ return nonPressedState;
+ }
+ }
+ }
+ return drawableState;
+ }
+
@Override
protected void onDraw(Canvas canvas) {
if (mCurrentAlpha <= ViewConfiguration.ALPHA_THRESHOLD_INT) return;
@@ -4190,12 +4271,13 @@
selStart = getSelectionStart();
selEnd = getSelectionEnd();
- if (mCursorVisible && selStart >= 0 && isEnabled()) {
+ if ((mCursorVisible || mTextIsSelectable) && selStart >= 0 && isEnabled()) {
if (mHighlightPath == null)
mHighlightPath = new Path();
if (selStart == selEnd) {
- if ((SystemClock.uptimeMillis() - mShowCursor) % (2 * BLINK) < BLINK) {
+ if (!mTextIsSelectable &&
+ (SystemClock.uptimeMillis() - mShowCursor) % (2 * BLINK) < BLINK) {
if (mHighlightPathBogus) {
mHighlightPath.reset();
mLayout.getCursorPath(selStart, mHighlightPath, mText);
@@ -7011,9 +7093,9 @@
mSelectionModifierCursorController.updatePosition();
}
}
- if (action == MotionEvent.ACTION_UP && isFocused() && !mScrolled) {
+ if (action == MotionEvent.ACTION_UP && !mScrolled && isFocused()) {
InputMethodManager imm = (InputMethodManager)
- getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+ getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
CommitSelectionReceiver csr = null;
if (getSelectionStart() != oldSelStart || getSelectionEnd() != oldSelEnd ||
@@ -7047,7 +7129,8 @@
|| windowParams.type > WindowManager.LayoutParams.LAST_SUB_WINDOW;
}
- if (windowSupportsHandles && isTextEditable() && mCursorVisible && mLayout != null) {
+ if (windowSupportsHandles && isTextEditable() && mCursorVisible && mLayout != null &&
+ !mTextIsSelectable) {
if (mInsertionPointCursorController == null) {
mInsertionPointCursorController = new InsertionPointCursorController();
}
@@ -7070,10 +7153,12 @@
}
/**
- * @return True iff this TextView contains a text that can be edited.
+ * @return True iff this TextView contains a text that can be edited, or if this is
+ * a selectable TextView.
*/
private boolean isTextEditable() {
- return mText instanceof Editable && onCheckIsTextEditor() && isEnabled();
+ return (mText instanceof Editable && onCheckIsTextEditor() && isEnabled())
+ || mTextIsSelectable;
}
/**
@@ -7320,9 +7405,7 @@
// prepareCursorController() relies on this method.
// If you change this condition, make sure prepareCursorController is called anywhere
// the value of this condition might be changed.
- return (mText instanceof Spannable &&
- mMovement != null &&
- mMovement.canSelectArbitrarily());
+ return (mText instanceof Spannable && mMovement != null && mMovement.canSelectArbitrarily());
}
private boolean canCut() {
@@ -8883,6 +8966,7 @@
private float mSpacingMult = 1;
private float mSpacingAdd = 0;
private int mLineHeight = 0;
+ private boolean mTextIsSelectable = false;
private static final int LINES = 1;
private static final int EMS = LINES;
diff --git a/core/java/com/android/internal/os/SamplingProfilerIntegration.java b/core/java/com/android/internal/os/SamplingProfilerIntegration.java
index 6d2bcae..c930c57c 100644
--- a/core/java/com/android/internal/os/SamplingProfilerIntegration.java
+++ b/core/java/com/android/internal/os/SamplingProfilerIntegration.java
@@ -53,7 +53,10 @@
static {
samplingProfilerHz = SystemProperties.getInt("persist.sys.profiler_hz", 0);
- if (samplingProfilerHz > 0) {
+ // Disabling this for now, as it crashes when enabled server-side. So adding
+ // a new property ("REALLY") for those wanting to test and fix it.
+ boolean really = SystemProperties.getInt("persist.sys.profiler_hz_REALLY", 0) > 0;
+ if (samplingProfilerHz > 0 && really) {
snapshotWriter = Executors.newSingleThreadExecutor();
enabled = true;
Log.i(TAG, "Profiler is enabled. Sampling Profiler Hz: " + samplingProfilerHz);
diff --git a/core/java/com/android/internal/view/IInputMethodManager.aidl b/core/java/com/android/internal/view/IInputMethodManager.aidl
index ca1cd59..7592e8b 100644
--- a/core/java/com/android/internal/view/IInputMethodManager.aidl
+++ b/core/java/com/android/internal/view/IInputMethodManager.aidl
@@ -57,7 +57,7 @@
void updateStatusIcon(in IBinder token, String packageName, int iconId);
void setIMEButtonVisible(in IBinder token, boolean visible);
InputMethodSubtype getCurrentInputMethodSubtype();
-
+ boolean setCurrentInputMethodSubtype(in InputMethodSubtype subtype);
+ boolean switchToLastInputMethod(in IBinder token);
boolean setInputMethodEnabled(String id, boolean enabled);
}
-
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 7ff75b3..d6684fe 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -345,6 +345,18 @@
because there will be no such interaction coming. -->
<attr name="windowNoDisplay" format="boolean" />
+ <!-- Flag indicating that this window should allow touches to be split
+ across other windows that also support split touch.
+ The default value is true for applications with a targetSdkVersion
+ of Honeycomb or newer; false otherwise.
+ When this flag is false, the first pointer that goes down determines
+ the window to which all subsequent touches go until all pointers go up.
+ When this flag is true, each pointer (not necessarily the first) that
+ goes down determines the window to which all subsequent touches of that
+ pointer will go until that pointers go up thereby enabling touches
+ with multiple pointers to be split across multiple windows. -->
+ <attr name="windowEnableSplitTouch" format="boolean" />
+
<!-- ============ -->
<!-- Alert Dialog styles -->
<!-- ============ -->
@@ -635,6 +647,10 @@
<!-- Height of a line of text. -->
<attr name="textLineHeight" format="dimension" />
+ <!-- Indicates that the content of a non-editable TextView can be selected.
+ Default value is false. EditText content is always selectable. -->
+ <attr name="textIsSelectable" format="boolean" />
+
<!-- Where to ellipsize text. -->
<attr name="ellipsize">
<enum name="none" value="0" />
@@ -1223,6 +1239,7 @@
<attr name="windowActionBar" />
<attr name="windowActionModeOverlay" />
<attr name="windowActionBarOverlay" />
+ <attr name="windowEnableSplitTouch" />
</declare-styleable>
<!-- The set of attributes that describe a AlertDialog's theme. -->
@@ -2477,6 +2494,9 @@
<!-- Height of a line of text. -->
<attr name="textLineHeight" />
+ <!-- Indicates that a non-editable text can be selected. -->
+ <attr name="textIsSelectable" />
+
</declare-styleable>
<!-- An <code>input-extras</code> is a container for extra data to supply to
an input method. Contains
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index bf0ac47..28df995 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1365,12 +1365,13 @@
<public type="attr" name="selectableItemBackground" />
<public type="attr" name="autoAdvanceViewId" />
<public type="attr" name="useIntrinsicSizeAsMinimum" />
-
<public type="attr" name="actionModeCutDrawable" />
<public type="attr" name="actionModeCopyDrawable" />
<public type="attr" name="actionModePasteDrawable" />
<public type="attr" name="textEditPasteWindowLayout" />
<public type="attr" name="textEditNoPasteWindowLayout" />
+ <public type="attr" name="textIsSelectable" />
+ <public type="attr" name="windowEnableSplitTouch" />
<public type="anim" name="animator_fade_in" />
<public type="anim" name="animator_fade_out" />
diff --git a/graphics/java/android/renderscript/BaseObj.java b/graphics/java/android/renderscript/BaseObj.java
index 026f7de..78b5617 100644
--- a/graphics/java/android/renderscript/BaseObj.java
+++ b/graphics/java/android/renderscript/BaseObj.java
@@ -41,6 +41,13 @@
mID = id;
}
+ /**
+ * Lookup the native object ID for this object. Primarily used by the
+ * generated reflected code.
+ *
+ *
+ * @return int
+ */
public int getID() {
if (mDestroyed) {
throw new RSInvalidStateException("using a destroyed object.");
@@ -53,8 +60,15 @@
private String mName;
RenderScript mRS;
- public void setName(String s) {
- if(s.length() < 1) {
+ /**
+ * setName assigns a name to an object. This object can later be looked up
+ * by this name. This name will also be retained if the object is written
+ * to an A3D file.
+ *
+ * @param name The name to assign to the object.
+ */
+ public void setName(String name) {
+ if(name.length() < 1) {
throw new RSIllegalArgumentException("setName does not accept a zero length string.");
}
if(mName != null) {
@@ -62,9 +76,9 @@
}
try {
- byte[] bytes = s.getBytes("UTF-8");
+ byte[] bytes = name.getBytes("UTF-8");
mRS.nAssignName(mID, bytes);
- mName = s;
+ mName = name;
} catch (java.io.UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
@@ -84,6 +98,12 @@
super.finalize();
}
+ /**
+ * destroy disconnects the object from the native object effectivly
+ * rendering this java object dead. The primary use is to force immediate
+ * cleanup of resources when its believed the GC will not respond quickly
+ * enough.
+ */
synchronized public void destroy() {
if(mDestroyed) {
throw new RSInvalidStateException("Object already destroyed.");
@@ -92,8 +112,10 @@
mRS.nObjDestroy(mID);
}
- // If an object came from an a3d file, java fields need to be
- // created with objects from the native layer
+ /**
+ * If an object came from an a3d file, java fields need to be
+ * created with objects from the native layer
+ */
void updateFromNative() {
mRS.validate();
mName = mRS.nGetName(getID());
diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java
index 8907cd2..4b007f2 100644
--- a/graphics/java/android/renderscript/Element.java
+++ b/graphics/java/android/renderscript/Element.java
@@ -22,6 +22,25 @@
/**
* @hide
*
+ * Element is the basic data type of RenderScript. An element can be of 2
+ * forms. Basic elements contain a single component of data. This can be of
+ * any of the legal RS types. Examples of basic element types.
+ * Single float value
+ * 4 element float vector
+ * single RGB-565 color
+ * single unsigned int 16
+ *
+ * Complex elements will contain a list of sub-elements and names. This in
+ * effect represents a structure of data. The fields can be accessed by name
+ * from a script or shader. The memory layout is defined and ordered. Data
+ * alignment is determinied by the most basic primitive type. i.e. a float4
+ * vector will be alligned to sizeof(float) and not sizeof(float4). The
+ * ordering of elements in memory will be the order in which they were added
+ * with each component aligned as necessary. No re-ordering will be done.
+ *
+ * The primary source of elements will be from scripts. A script that exports a
+ * bind point for a data structure will generate a RS element to represent the
+ * data exported by the script.
**/
public class Element extends BaseObj {
int mSize;
@@ -36,6 +55,21 @@
int getSizeBytes() {return mSize;}
+
+ /**
+ * DataType represents the basic type information for a basic element. The
+ * naming convention follows. For numeric types its FLOAT, SIGNED, UNSIGNED
+ * followed by the _BITS where BITS is the size of the data. BOOLEAN is a
+ * true / false (1,0) represented in an 8 bit container. The UNSIGNED
+ * variants with multiple bit definitions are for packed graphical data
+ * formats and represents vectors with per vector member sizes which are
+ * treated as a single unit for packing and alignment purposes.
+ *
+ * MATRIX the three matrix types contain FLOAT_32 elements and are treated
+ * as 32 bits for alignment purposes.
+ *
+ * RS_* objects. 32 bit opaque handles.
+ */
public enum DataType {
//FLOAT_16 (1, 2),
FLOAT_32 (2, 4),
@@ -78,6 +112,12 @@
}
}
+ /**
+ * The special interpretation of the data if required. This is primarly
+ * useful for graphical data. USER indicates no special interpretation is
+ * expected. PIXEL is used in conjunction with the standard data types for
+ * representing texture formats.
+ */
public enum DataKind {
USER (0),
@@ -93,6 +133,12 @@
}
}
+ /**
+ * Return if a element is too complex for use as a data source for a Mesh or
+ * a Program.
+ *
+ * @return boolean
+ */
public boolean isComplex() {
if (mElements == null) {
return false;
@@ -105,6 +151,13 @@
return false;
}
+ /**
+ * Utility function for returning an Element containing a single Boolean.
+ *
+ * @param rs Context to which the element will belong.
+ *
+ * @return Element
+ */
public static Element BOOLEAN(RenderScript rs) {
if(rs.mElement_BOOLEAN == null) {
rs.mElement_BOOLEAN = createUser(rs, DataType.BOOLEAN);
@@ -112,6 +165,13 @@
return rs.mElement_BOOLEAN;
}
+ /**
+ * Utility function for returning an Element containing a single UNSIGNED_8.
+ *
+ * @param rs Context to which the element will belong.
+ *
+ * @return Element
+ */
public static Element U8(RenderScript rs) {
if(rs.mElement_U8 == null) {
rs.mElement_U8 = createUser(rs, DataType.UNSIGNED_8);
@@ -119,6 +179,13 @@
return rs.mElement_U8;
}
+ /**
+ * Utility function for returning an Element containing a single SIGNED_8.
+ *
+ * @param rs Context to which the element will belong.
+ *
+ * @return Element
+ */
public static Element I8(RenderScript rs) {
if(rs.mElement_I8 == null) {
rs.mElement_I8 = createUser(rs, DataType.SIGNED_8);
@@ -414,7 +481,14 @@
super.destroy();
}
- /////////////////////////////////////////
+ /**
+ * Create a custom Element of the specified DataType. The DataKind will be
+ * set to USER and the vector size to 1 indicating non-vector.
+ *
+ * @param rs The context associated with the new Element.
+ * @param dt The DataType for the new element.
+ * @return Element
+ */
public static Element createUser(RenderScript rs, DataType dt) {
DataKind dk = DataKind.USER;
boolean norm = false;
@@ -423,6 +497,17 @@
return new Element(id, rs, dt, dk, norm, vecSize);
}
+ /**
+ * Create a custom vector element of the specified DataType and vector size.
+ * DataKind will be set to USER.
+ *
+ * @param rs The context associated with the new Element.
+ * @param dt The DataType for the new element.
+ * @param size Vector size for the new Element. Range 2-4 inclusive
+ * supported.
+ *
+ * @return Element
+ */
public static Element createVector(RenderScript rs, DataType dt, int size) {
if (size < 2 || size > 4) {
throw new RSIllegalArgumentException("Vector size out of rance 2-4.");
@@ -433,6 +518,18 @@
return new Element(id, rs, dt, dk, norm, size);
}
+ /**
+ * Create a new pixel Element type. A matching DataType and DataKind must
+ * be provided. The DataType and DataKind must contain the same number of
+ * components. Vector size will be set to 1.
+ *
+ * @param rs The context associated with the new Element.
+ * @param dt The DataType for the new element.
+ * @param dk The DataKind to specify the mapping of each component in the
+ * DataType.
+ *
+ * @return Element
+ */
public static Element createPixel(RenderScript rs, DataType dt, DataKind dk) {
if (!(dk == DataKind.PIXEL_L ||
dk == DataKind.PIXEL_A ||
@@ -473,6 +570,12 @@
return new Element(id, rs, dt, dk, norm, size);
}
+ /**
+ * Builder class for producing complex elements with matching field and name
+ * pairs. The builder starts empty. The order in which elements are added
+ * is retained for the layout in memory.
+ *
+ */
public static class Builder {
RenderScript mRS;
Element[] mElements;
@@ -480,6 +583,11 @@
int[] mArraySizes;
int mCount;
+ /**
+ * Create a builder object.
+ *
+ * @param rs
+ */
public Builder(RenderScript rs) {
mRS = rs;
mCount = 0;
@@ -488,6 +596,13 @@
mArraySizes = new int[8];
}
+ /**
+ * Add an array of elements to this element.
+ *
+ * @param element
+ * @param name
+ * @param arraySize
+ */
public void add(Element element, String name, int arraySize) {
if (arraySize < 1) {
throw new RSIllegalArgumentException("Array size cannot be less than 1.");
@@ -509,10 +624,22 @@
mCount++;
}
+ /**
+ * Add a single element to this Element.
+ *
+ * @param element
+ * @param name
+ */
public void add(Element element, String name) {
add(element, name, 1);
}
+ /**
+ * Create the element from this builder.
+ *
+ *
+ * @return Element
+ */
public Element create() {
mRS.validate();
Element[] ein = new Element[mCount];
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 64afb6f..df03e13 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -28,6 +28,13 @@
/**
* @hide
*
+ * RenderScript base master class. An instance of this class creates native
+ * worker threads for processing commands from this object. This base class
+ * does not provide any extended capabilities beyond simple data processing.
+ * For extended capabilities use derived classes such as RenderScriptGL.
+ *
+ *
+ *
**/
public class RenderScript {
static final String LOG_TAG = "RenderScript_jni";
@@ -581,6 +588,14 @@
///////////////////////////////////////////////////////////////////////////////////
//
+ /**
+ * Base class application should derive from for handling RS messages
+ * comming from their scripts. When a script calls sendToClient the data
+ * fields will be filled in and then the run method called by a message
+ * handling thread. This will occur some time after sendToClient completes
+ * in the script.
+ *
+ */
public static class RSMessage implements Runnable {
protected int[] mData;
protected int mID;
@@ -588,16 +603,42 @@
public void run() {
}
}
+ /**
+ * If an application is expecting messages it should set this field to an
+ * instance of RSMessage. This instance will receive all the user messages
+ * sent from sendToClient by scripts from this context.
+ *
+ */
public RSMessage mMessageCallback = null;
+ /**
+ * Runtime error base class. An application should derive from this class
+ * if it wishes to install an error handler. When errors occur at runtime
+ * the fields in this class will be filled and the run method called.
+ *
+ */
public static class RSAsyncError implements Runnable {
protected String mErrorMessage;
protected int mErrorNum;
public void run() {
}
}
+
+ /**
+ * Application Error handler. All runtime errors will be dispatched to the
+ * instance of RSAsyncError set here. If this field is null a
+ * RSRuntimeException will instead be thrown with details about the error.
+ * This will cause program termaination.
+ *
+ */
public RSAsyncError mErrorCallback = null;
+ /**
+ * RenderScript worker threads priority enumeration. The default value is
+ * NORMAL. Applications wishing to do background processing such as
+ * wallpapers should set their priority to LOW to avoid starving forground
+ * processes.
+ */
public enum Priority {
LOW (5), //ANDROID_PRIORITY_BACKGROUND + 5
NORMAL (-4); //ANDROID_PRIORITY_DISPLAY
@@ -614,6 +655,12 @@
}
}
+
+ /**
+ * Change the priority of the worker threads for this context.
+ *
+ * @param p New priority to be set.
+ */
public void contextSetPriority(Priority p) {
validate();
nContextSetPriority(p.mID);
@@ -690,9 +737,15 @@
}
}
- protected RenderScript() {
+ RenderScript() {
}
+ /**
+ * Create a basic RenderScript context.
+ *
+ *
+ * @return RenderScript
+ */
public static RenderScript create() {
RenderScript rs = new RenderScript();
@@ -704,15 +757,32 @@
return rs;
}
+ /**
+ * Print the currently available debugging information about the state of
+ * the RS context to the log.
+ *
+ *
+ * @param bits Currently ignored.
+ */
public void contextDump(int bits) {
validate();
nContextDump(bits);
}
+ /**
+ * Wait for any commands in the fifo between the java bindings and native to
+ * be processed.
+ *
+ */
public void finish() {
nContextFinish();
}
+ /**
+ * Destroy this renderscript context. Once this function is called its no
+ * longer legal to use this or any objects created by this context.
+ *
+ */
public void destroy() {
validate();
nContextDeinitToClient(mContext);
@@ -733,9 +803,6 @@
return mContext != 0;
}
- ///////////////////////////////////////////////////////////////////////////////////
- // Root state
-
protected int safeID(BaseObj o) {
if(o != null) {
return o.getID();
diff --git a/graphics/java/android/renderscript/RenderScriptGL.java b/graphics/java/android/renderscript/RenderScriptGL.java
index cace063..181d4bd 100644
--- a/graphics/java/android/renderscript/RenderScriptGL.java
+++ b/graphics/java/android/renderscript/RenderScriptGL.java
@@ -30,12 +30,22 @@
/**
* @hide
*
+ * The Graphics derivitive of RenderScript. Extends the basic context to add a
+ * root script which is the display window for graphical output. When the
+ * system needs to update the display the currently bound root script will be
+ * called. This script is expected to issue the rendering commands to repaint
+ * the screen.
**/
public class RenderScriptGL extends RenderScript {
private Surface mSurface;
int mWidth;
int mHeight;
+ /**
+ * Class which is used to describe a pixel format for a graphical buffer.
+ * This is used to describe the intended format of the display surface.
+ *
+ */
public static class SurfaceConfig {
int mDepthMin = 0;
int mDepthPref = 0;
diff --git a/graphics/java/android/renderscript/Type.java b/graphics/java/android/renderscript/Type.java
index ad933b8..44aee63 100644
--- a/graphics/java/android/renderscript/Type.java
+++ b/graphics/java/android/renderscript/Type.java
@@ -23,6 +23,20 @@
/**
* @hide
*
+ * Type is an allocation template. It consists of an Element and one or more
+ * dimensions. It describes only the layout of memory but does not allocate and
+ * storage for the data thus described.
+ *
+ * A Type consists of several dimensions. Those are X, Y, Z, LOD (level of
+ * detail), Faces (faces of a cube map). The X,Y,Z dimensions can be assigned
+ * any positive integral value within the constraints of available memory. A
+ * single dimension allocation would have an X dimension of greater than zero
+ * while the Y and Z dimensions would be zero to indicate not present. In this
+ * regard an allocation of x=10, y=1 would be considered 2 dimensionsal while
+ * x=10, y=0 would be considered 1 dimensional.
+ *
+ * The LOD and Faces dimensions are booleans to indicate present or not present.
+ *
**/
public class Type extends BaseObj {
int mDimX;
@@ -33,25 +47,65 @@
int mElementCount;
Element mElement;
+ /**
+ * Return the element associated with this Type.
+ *
+ * @return Element
+ */
public Element getElement() {
return mElement;
}
+ /**
+ * Return the value of the X dimension.
+ *
+ * @return int
+ */
public int getX() {
return mDimX;
}
+
+ /**
+ * Return the value of the Y dimension or 0 for a 1D allocation.
+ *
+ * @return int
+ */
public int getY() {
return mDimY;
}
+
+ /**
+ * Return the value of the Z dimension or 0 for a 1D or 2D allocation.
+ *
+ * @return int
+ */
public int getZ() {
return mDimZ;
}
+
+ /**
+ * Return if the Type has a mipmap chain.
+ *
+ * @return boolean
+ */
public boolean getLOD() {
return mDimLOD;
}
+
+ /**
+ * Return if the Type is a cube map.
+ *
+ * @return boolean
+ */
public boolean getFaces() {
return mDimFaces;
}
+
+ /**
+ * Return the total number of accessable cells in the Type.
+ *
+ * @return int
+ */
public int getElementCount() {
return mElementCount;
}
@@ -122,6 +176,10 @@
calcElementCount();
}
+ /**
+ * Builder class for Type.
+ *
+ */
public static class Builder {
RenderScript mRS;
Dimension[] mDimensions;
@@ -134,6 +192,12 @@
int mValue;
}
+ /**
+ * Create a new builder object.
+ *
+ * @param rs
+ * @param e The element for the type to be created.
+ */
public Builder(RenderScript rs, Element e) {
if(e.getID() == 0) {
throw new RSIllegalArgumentException("Invalid element.");
@@ -145,6 +209,13 @@
mElement = e;
}
+ /**
+ * Add a dimension to the Type.
+ *
+ *
+ * @param d
+ * @param value
+ */
public void add(Dimension d, int value) {
if(value < 1) {
throw new RSIllegalArgumentException("Values of less than 1 for Dimensions are not valid.");
@@ -163,6 +234,11 @@
mEntryCount++;
}
+ /**
+ * Validate structure and create a new type.
+ *
+ * @return Type
+ */
public Type create() {
int dims[] = new int[mEntryCount];
for (int ct=0; ct < mEntryCount; ct++) {
@@ -190,6 +266,26 @@
t.mDimFaces = mDimensionValues[ct] != 0;
}
}
+
+ if (t.mDimZ > 0) {
+ if ((t.mDimX < 1) || (t.mDimY < 1)) {
+ throw new RSInvalidStateException("Both X and Y dimension required when Z is present.");
+ }
+ if (t.mDimFaces) {
+ throw new RSInvalidStateException("Cube maps not supported with 3D types.");
+ }
+ }
+ if (t.mDimY > 0) {
+ if (t.mDimX < 1) {
+ throw new RSInvalidStateException("X dimension required when Y is present.");
+ }
+ }
+ if (t.mDimFaces) {
+ if (t.mDimY < 1) {
+ throw new RSInvalidStateException("Cube maps require 2D Types.");
+ }
+ }
+
t.calcElementCount();
return t;
}
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 1081c35..cce2400 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -472,7 +472,7 @@
AudioParameter(const String8& keyValuePairs);
virtual ~AudioParameter();
- // reserved parameter keys for changeing standard parameters with setParameters() function.
+ // reserved parameter keys for changing standard parameters with setParameters() function.
// Using these keys is mandatory for AudioFlinger to properly monitor audio output/input
// configuration changes and act accordingly.
// keyRouting: to change audio routing, value is an int in AudioSystem::audio_devices
@@ -480,11 +480,14 @@
// keyFormat: to change audio format, value is an int in AudioSystem::audio_format
// keyChannels: to change audio channel configuration, value is an int in AudioSystem::audio_channels
// keyFrameCount: to change audio output frame count, value is an int
+ // keyInputSource: to change audio input source, value is an int in audio_source
+ // (defined in media/mediarecorder.h)
static const char *keyRouting;
static const char *keySamplingRate;
static const char *keyFormat;
static const char *keyChannels;
static const char *keyFrameCount;
+ static const char *keyInputSource;
String8 toString();
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index b4c5d3c..295b127 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -37,7 +37,8 @@
kKeyStride = 'strd', // int32_t
kKeySliceHeight = 'slht', // int32_t
kKeyChannelCount = '#chn', // int32_t
- kKeySampleRate = 'srte', // int32_t (also video frame rate)
+ kKeySampleRate = 'srte', // int32_t (audio sampling rate Hz)
+ kKeyFrameRate = 'frmR', // int32_t (video frame rate fps)
kKeyBitRate = 'brte', // int32_t (bps)
kKeyESDS = 'esds', // raw data
kKeyAVCC = 'avcc', // raw data
diff --git a/include/ui/InputDispatcher.h b/include/ui/InputDispatcher.h
index d09ff41..15a3925 100644
--- a/include/ui/InputDispatcher.h
+++ b/include/ui/InputDispatcher.h
@@ -219,6 +219,8 @@
* motion events to be delivered to them with AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED.
*/
bool isTrustedOverlay() const;
+
+ bool supportsSplitTouch() const;
};
@@ -946,7 +948,7 @@
struct TouchedWindow {
const InputWindow* window;
int32_t targetFlags;
- BitSet32 pointerIds;
+ BitSet32 pointerIds; // zero unless target flag FLAG_SPLIT is set
sp<InputChannel> channel;
};
struct TouchState {
diff --git a/libs/rs/java/Balls/src/com/android/balls/BallsRS.java b/libs/rs/java/Balls/src/com/android/balls/BallsRS.java
index 9c845aa..359f334 100644
--- a/libs/rs/java/Balls/src/com/android/balls/BallsRS.java
+++ b/libs/rs/java/Balls/src/com/android/balls/BallsRS.java
@@ -30,7 +30,8 @@
private RenderScriptGL mRS;
private ScriptC_balls mScript;
private ScriptC_ball_physics mPhysicsScript;
- private ProgramFragment mPF;
+ private ProgramFragment mPFLines;
+ private ProgramFragment mPFPoints;
private ProgramVertex mPV;
private ProgramRaster mPR;
private ProgramStore mPS;
@@ -89,10 +90,13 @@
pfb.setTexture(ProgramFragment.Builder.EnvMode.MODULATE,
ProgramFragment.Builder.Format.RGBA, 0);
pfb.setVaryingColor(true);
- mPF = pfb.create();
- rs.contextBindProgramFragment(mPF);
+ mPFPoints = pfb.create();
- mPF.bindTexture(loadTexture(R.drawable.flares), 0);
+ pfb = new ProgramFragment.Builder(rs);
+ pfb.setVaryingColor(true);
+ mPFLines = pfb.create();
+
+ mPFPoints.bindTexture(loadTexture(R.drawable.flares), 0);
mPoints = new ScriptField_Point(mRS, PART_COUNT);
mArcs = new ScriptField_Point(mRS, PART_COUNT * 2);
@@ -118,7 +122,8 @@
mScript.bind_balls1(new ScriptField_Ball(mRS, PART_COUNT));
mScript.bind_balls2(new ScriptField_Ball(mRS, PART_COUNT));
- mScript.set_gPF(mPF);
+ mScript.set_gPFLines(mPFLines);
+ mScript.set_gPFPoints(mPFPoints);
createProgramVertex();
createProgramRaster();
diff --git a/libs/rs/java/Balls/src/com/android/balls/balls.rs b/libs/rs/java/Balls/src/com/android/balls/balls.rs
index 493633b..bbd03cf 100644
--- a/libs/rs/java/Balls/src/com/android/balls/balls.rs
+++ b/libs/rs/java/Balls/src/com/android/balls/balls.rs
@@ -6,7 +6,8 @@
#pragma stateFragment(parent)
-rs_program_fragment gPF;
+rs_program_fragment gPFPoints;
+rs_program_fragment gPFLines;
rs_program_vertex gPV;
rs_program_raster gPR;
rs_program_store gPS;
@@ -93,11 +94,12 @@
}
frame++;
- rsgBindProgramFragment(gPF);
+ rsgBindProgramFragment(gPFLines);
rsgBindProgramVertex(gPV);
rsgBindProgramRaster(gPR);
rsgBindProgramStore(gPS);
rsgDrawMesh(arcMesh, 0, 0, arcIdx);
+ rsgBindProgramFragment(gPFPoints);
rsgDrawMesh(partMesh);
rsClearObject(&bc.ain);
rsClearObject(&bc.aout);
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
index 7ddb3c7..db7d448 100644
--- a/libs/ui/InputDispatcher.cpp
+++ b/libs/ui/InputDispatcher.cpp
@@ -157,6 +157,10 @@
|| layoutParamsType == TYPE_SECURE_SYSTEM_OVERLAY;
}
+bool InputWindow::supportsSplitTouch() const {
+ return layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH;
+}
+
// --- InputDispatcher ---
@@ -1110,8 +1114,7 @@
}
// Figure out whether splitting will be allowed for this window.
- if (newTouchedWindow
- && (newTouchedWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH)) {
+ if (newTouchedWindow && newTouchedWindow->supportsSplitTouch()) {
// New window supports splitting.
isSplit = true;
} else if (isSplit) {
@@ -2648,13 +2651,8 @@
mTouchState.windows.removeAt(i);
- int32_t newTargetFlags = 0;
- if (oldTargetFlags & InputTarget::FLAG_FOREGROUND) {
- newTargetFlags |= InputTarget::FLAG_FOREGROUND;
- if (toWindow->layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH) {
- newTargetFlags |= InputTarget::FLAG_SPLIT;
- }
- }
+ int32_t newTargetFlags = oldTargetFlags
+ & (InputTarget::FLAG_FOREGROUND | InputTarget::FLAG_SPLIT);
mTouchState.addOrUpdateWindow(toWindow, newTargetFlags, pointerIds);
found = true;
diff --git a/media/java/android/media/videoeditor/MediaImageItem.java b/media/java/android/media/videoeditor/MediaImageItem.java
index a969ac1..a4b0770 100755
--- a/media/java/android/media/videoeditor/MediaImageItem.java
+++ b/media/java/android/media/videoeditor/MediaImageItem.java
@@ -162,62 +162,41 @@
* @param durationMs The duration of the image in the storyboard timeline
*/
public void setDuration(long durationMs) {
- // Invalidate the beginning and end transitions if necessary
- if (mBeginTransition != null) {
- final long transitionDurationMs = mBeginTransition.getDuration();
-
- // The begin transition must be invalidated if it overlaps with
- // an effect. To optimize this code we could invalidate the
- // begin transition only for a Ken Burns effect (color effects
- // should not affect the begin transition) however when new effects
- // will be added this code would have to be modified... so we
- // opted to always invalidate the transition if there is an
- // overlap.
- final List<Effect> effects = getAllEffects();
- for (Effect effect : effects) {
- // Check if the effect overlaps with the begin transition
- if (effect.getStartTime() < transitionDurationMs) {
- mBeginTransition.invalidate();
- break;
- }
- }
+ if (durationMs == mDurationMs) {
+ return;
}
- if (mEndTransition != null) {
- final long transitionDurationMs = mEndTransition.getDuration();
+ // Invalidate the end transitions if necessary.
+ // This invalidation is necessary for the case in which an effect or
+ // an overlay is overlapping with the end transition
+ // (before the duration is changed) and it no longer overlaps with the
+ // transition after the duration is increased.
- // The end transition must be invalidated if it overlaps with
- // an effect
- final List<Effect> effects = getAllEffects();
- for (Effect effect : effects) {
- // Check if the effect overlaps with the end transition
- if (effect.getStartTime() + effect.getDuration() >
- mDurationMs - transitionDurationMs) {
- mEndTransition.invalidate();
- break;
- }
- }
+ // The beginning transition does not need to be invalidated at this time
+ // because an effect or an overlay overlaps with the beginning
+ // transition, the begin transition is unaffected by a media item
+ // duration change.
+ invalidateEndTransition();
- if (mEndTransition.isGenerated()) {
- // The end transition must be invalidated if it overlaps with
- // an overlay
- final List<Overlay> overlays = getAllOverlays();
- for (Overlay overlay : overlays) {
- // Check if the overlay overlaps with the end transition
- if (overlay.getStartTime() + overlay.getDuration() >
- mDurationMs - transitionDurationMs) {
- mEndTransition.invalidate();
- break;
- }
- }
- }
- }
-
+ final long oldDurationMs = mDurationMs;
mDurationMs = durationMs;
adjustTransitions();
adjustOverlays();
adjustEffects();
+
+ // Invalidate the beginning and end transitions after adjustments.
+ // This invalidation is necessary for the case in which an effect or
+ // an overlay was not overlapping with the beginning or end transitions
+ // before the setDuration reduces the duration of the media item and
+ // causes an overlap of the beginning and/or end transition with the
+ // effect.
+ // If the duration is growing, the begin transition does not need to
+ // be invalidated since the effects, overlays are not adjusted.
+ if (mDurationMs < oldDurationMs) {
+ invalidateBeginTransition();
+ }
+ invalidateEndTransition();
}
/*
@@ -278,6 +257,76 @@
}
/**
+ * Invalidate the begin transition if any effects and overlays overlap
+ * with the begin transition.
+ */
+ private void invalidateBeginTransition() {
+ if (mBeginTransition != null && mBeginTransition.isGenerated()) {
+ final long transitionDurationMs = mBeginTransition.getDuration();
+
+ // The begin transition must be invalidated if it overlaps with
+ // an effect.
+ final List<Effect> effects = getAllEffects();
+ for (Effect effect : effects) {
+ // Check if the effect overlaps with the begin transition
+ if (effect.getStartTime() < transitionDurationMs) {
+ mBeginTransition.invalidate();
+ break;
+ }
+ }
+
+ if (mBeginTransition.isGenerated()) {
+ // The end transition must be invalidated if it overlaps with
+ // an overlay.
+ final List<Overlay> overlays = getAllOverlays();
+ for (Overlay overlay : overlays) {
+ // Check if the overlay overlaps with the end transition
+ if (overlay.getStartTime() < transitionDurationMs) {
+ mBeginTransition.invalidate();
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Invalidate the end transition if any effects and overlays overlap
+ * with the end transition.
+ */
+ private void invalidateEndTransition() {
+ if (mEndTransition != null && mEndTransition.isGenerated()) {
+ final long transitionDurationMs = mEndTransition.getDuration();
+
+ // The end transition must be invalidated if it overlaps with
+ // an effect.
+ final List<Effect> effects = getAllEffects();
+ for (Effect effect : effects) {
+ // Check if the effect overlaps with the end transition
+ if (effect.getStartTime() + effect.getDuration() >
+ mDurationMs - transitionDurationMs) {
+ mEndTransition.invalidate();
+ break;
+ }
+ }
+
+ if (mEndTransition.isGenerated()) {
+ // The end transition must be invalidated if it overlaps with
+ // an overlay.
+ final List<Overlay> overlays = getAllOverlays();
+ for (Overlay overlay : overlays) {
+ // Check if the overlay overlaps with the end transition
+ if (overlay.getStartTime() + overlay.getDuration() >
+ mDurationMs - transitionDurationMs) {
+ mEndTransition.invalidate();
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /**
* Adjust the start time and/or duration of effects.
*/
private void adjustEffects() {
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 9c2a8ba..1a3fcd6 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -835,6 +835,7 @@
const char *AudioParameter::keyFormat = "format";
const char *AudioParameter::keyChannels = "channels";
const char *AudioParameter::keyFrameCount = "frame_count";
+const char *AudioParameter::keyInputSource = "input_source";
AudioParameter::AudioParameter(const String8& keyValuePairs)
{
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 5f9b6e6..dadd1db 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -1078,7 +1078,7 @@
if (mFrameRate == -1) {
int32_t frameRate = 0;
CHECK ((*cameraSource)->getFormat()->findInt32(
- kKeySampleRate, &frameRate));
+ kKeyFrameRate, &frameRate));
LOGI("Frame rate is not explicitly set. Use the current frame "
"rate (%d fps)", frameRate);
mFrameRate = frameRate;
@@ -1100,7 +1100,7 @@
sp<MetaData> enc_meta = new MetaData;
enc_meta->setInt32(kKeyBitRate, videoBitRate);
- enc_meta->setInt32(kKeySampleRate, mFrameRate);
+ enc_meta->setInt32(kKeyFrameRate, mFrameRate);
switch (mVideoEncoder) {
case VIDEO_ENCODER_H263:
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index 159d937..b8450fb 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -531,7 +531,7 @@
mMeta->setInt32(kKeyHeight, mVideoSize.height);
mMeta->setInt32(kKeyStride, mVideoSize.width);
mMeta->setInt32(kKeySliceHeight, mVideoSize.height);
- mMeta->setInt32(kKeySampleRate, mVideoFrameRate);
+ mMeta->setInt32(kKeyFrameRate, mVideoFrameRate);
return OK;
}
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 3d490c9..8edcd12 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -935,7 +935,7 @@
int32_t width, height, frameRate, bitRate, stride, sliceHeight;
bool success = meta->findInt32(kKeyWidth, &width);
success = success && meta->findInt32(kKeyHeight, &height);
- success = success && meta->findInt32(kKeySampleRate, &frameRate);
+ success = success && meta->findInt32(kKeyFrameRate, &frameRate);
success = success && meta->findInt32(kKeyBitRate, &bitRate);
success = success && meta->findInt32(kKeyStride, &stride);
success = success && meta->findInt32(kKeySliceHeight, &sliceHeight);
@@ -1155,7 +1155,7 @@
status_t OMXCodec::setupH263EncoderParameters(const sp<MetaData>& meta) {
int32_t iFramesInterval, frameRate, bitRate;
bool success = meta->findInt32(kKeyBitRate, &bitRate);
- success = success && meta->findInt32(kKeySampleRate, &frameRate);
+ success = success && meta->findInt32(kKeyFrameRate, &frameRate);
success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
CHECK(success);
OMX_VIDEO_PARAM_H263TYPE h263type;
@@ -1202,7 +1202,7 @@
status_t OMXCodec::setupMPEG4EncoderParameters(const sp<MetaData>& meta) {
int32_t iFramesInterval, frameRate, bitRate;
bool success = meta->findInt32(kKeyBitRate, &bitRate);
- success = success && meta->findInt32(kKeySampleRate, &frameRate);
+ success = success && meta->findInt32(kKeyFrameRate, &frameRate);
success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
CHECK(success);
OMX_VIDEO_PARAM_MPEG4TYPE mpeg4type;
@@ -1254,7 +1254,7 @@
status_t OMXCodec::setupAVCEncoderParameters(const sp<MetaData>& meta) {
int32_t iFramesInterval, frameRate, bitRate;
bool success = meta->findInt32(kKeyBitRate, &bitRate);
- success = success && meta->findInt32(kKeySampleRate, &frameRate);
+ success = success && meta->findInt32(kKeyFrameRate, &frameRate);
success = success && meta->findInt32(kKeyIFramesInterval, &iFramesInterval);
CHECK(success);
diff --git a/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp b/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp
index a6b179e..e6a0976 100644
--- a/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp
+++ b/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp
@@ -207,7 +207,7 @@
LOGV("initCheck");
CHECK(meta->findInt32(kKeyWidth, &mVideoWidth));
CHECK(meta->findInt32(kKeyHeight, &mVideoHeight));
- CHECK(meta->findInt32(kKeySampleRate, &mVideoFrameRate));
+ CHECK(meta->findInt32(kKeyFrameRate, &mVideoFrameRate));
CHECK(meta->findInt32(kKeyBitRate, &mVideoBitRate));
// XXX: Add more color format support
@@ -322,7 +322,7 @@
mFormat->setInt32(kKeyWidth, mVideoWidth);
mFormat->setInt32(kKeyHeight, mVideoHeight);
mFormat->setInt32(kKeyBitRate, mVideoBitRate);
- mFormat->setInt32(kKeySampleRate, mVideoFrameRate);
+ mFormat->setInt32(kKeyFrameRate, mVideoFrameRate);
mFormat->setInt32(kKeyColorFormat, mVideoColorFormat);
mFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_AVC);
mFormat->setCString(kKeyDecoderComponent, "AVCEncoder");
diff --git a/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp
index 72611cf..c7a475b 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/M4vH263Encoder.cpp
@@ -200,7 +200,7 @@
LOGV("initCheck");
CHECK(meta->findInt32(kKeyWidth, &mVideoWidth));
CHECK(meta->findInt32(kKeyHeight, &mVideoHeight));
- CHECK(meta->findInt32(kKeySampleRate, &mVideoFrameRate));
+ CHECK(meta->findInt32(kKeyFrameRate, &mVideoFrameRate));
CHECK(meta->findInt32(kKeyBitRate, &mVideoBitRate));
// XXX: Add more color format support
@@ -299,7 +299,7 @@
mFormat->setInt32(kKeyWidth, mVideoWidth);
mFormat->setInt32(kKeyHeight, mVideoHeight);
mFormat->setInt32(kKeyBitRate, mVideoBitRate);
- mFormat->setInt32(kKeySampleRate, mVideoFrameRate);
+ mFormat->setInt32(kKeyFrameRate, mVideoFrameRate);
mFormat->setInt32(kKeyColorFormat, mVideoColorFormat);
mFormat->setCString(kKeyMIMEType, mime);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
index b174973..d3d2285 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
@@ -298,7 +298,8 @@
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
+ | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+ | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.TRANSLUCENT);
lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL;
lp.y += height * 1.5; // FIXME
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
index 00b39c5..776b59c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java
@@ -109,7 +109,8 @@
height,
WindowManager.LayoutParams.TYPE_STATUS_BAR,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING,
+ | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING
+ | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.RGBX_8888);
lp.gravity = getStatusBarGravity();
lp.setTitle("StatusBar");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java
index 7ee3c19..09c8cd2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/ShirtPocket.java
@@ -197,7 +197,8 @@
250,
WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
- | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
+ | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+ | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.TRANSLUCENT);
lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
// int pos[] = new int[2];
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
index 29f0fe2..da44f43 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java
@@ -153,7 +153,8 @@
ViewGroup.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
- | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
+ | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+ | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.TRANSLUCENT);
lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
lp.setTitle("NotificationPanel");
@@ -188,7 +189,8 @@
ViewGroup.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
- | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
+ | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+ | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.TRANSLUCENT);
lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
lp.setTitle("NotificationPeekWindow");
@@ -208,7 +210,8 @@
ViewGroup.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
- | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
+ | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+ | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.TRANSLUCENT);
lp.gravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL;
lp.setTitle("SystemPanel");
@@ -232,7 +235,8 @@
ViewGroup.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
- | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
+ | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+ | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
PixelFormat.TRANSLUCENT);
lp.gravity = Gravity.BOTTOM | Gravity.LEFT;
lp.setTitle("RecentsPanel");
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 1bded54..71bf956 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -22,6 +22,7 @@
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY;
+import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
import com.android.internal.view.BaseSurfaceHolder;
import com.android.internal.view.RootViewSurfaceTaker;
@@ -497,7 +498,8 @@
WRAP_CONTENT, WRAP_CONTENT,
st.x, st.y, WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG,
WindowManager.LayoutParams.FLAG_DITHER
- | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
+ | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+ | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH,
st.decorView.mDefaultOpacity);
lp.gravity = st.gravity;
@@ -2164,6 +2166,12 @@
setFlags(FLAG_SHOW_WALLPAPER, FLAG_SHOW_WALLPAPER&(~getForcedWindowFlags()));
}
+ if (a.getBoolean(com.android.internal.R.styleable.Window_windowEnableSplitTouch,
+ getContext().getApplicationInfo().targetSdkVersion
+ >= android.os.Build.VERSION_CODES.HONEYCOMB)) {
+ setFlags(FLAG_SPLIT_TOUCH, FLAG_SPLIT_TOUCH&(~getForcedWindowFlags()));
+ }
+
if (getContext().getApplicationInfo().targetSdkVersion
< android.os.Build.VERSION_CODES.HONEYCOMB) {
addFlags(WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY);
diff --git a/services/audioflinger/AudioPolicyManagerBase.cpp b/services/audioflinger/AudioPolicyManagerBase.cpp
index edea2c5..b17584a 100644
--- a/services/audioflinger/AudioPolicyManagerBase.cpp
+++ b/services/audioflinger/AudioPolicyManagerBase.cpp
@@ -760,10 +760,8 @@
AudioParameter param = AudioParameter();
param.addInt(String8(AudioParameter::keyRouting), (int)inputDesc->mDevice);
- // use Voice Recognition mode or not for this input based on input source
- int vr_enabled = inputDesc->mInputSource == AUDIO_SOURCE_VOICE_RECOGNITION ? 1 : 0;
- param.addInt(String8("vr_mode"), vr_enabled);
- LOGV("AudioPolicyManager::startInput(%d), setting vr_mode to %d", inputDesc->mInputSource, vr_enabled);
+ param.addInt(String8(AudioParameter::keyInputSource), (int)inputDesc->mInputSource);
+ LOGV("AudioPolicyManager::startInput() input source = %d", inputDesc->mInputSource);
mpClientInterface->setParameters(input, param.toString());
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 0d3cfde..4f8862c 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -961,7 +961,12 @@
// enabled.
String id = Settings.Secure.getString(mContext.getContentResolver(),
Settings.Secure.DEFAULT_INPUT_METHOD);
- if (id != null && id.length() > 0) {
+ // There is no input method selected, try to choose new applicable input method.
+ if (TextUtils.isEmpty(id) && chooseNewDefaultIMELocked()) {
+ id = Settings.Secure.getString(mContext.getContentResolver(),
+ Settings.Secure.DEFAULT_INPUT_METHOD);
+ }
+ if (!TextUtils.isEmpty(id)) {
try {
setInputMethodLocked(id, getSelectedInputMethodSubtypeId(id));
} catch (IllegalArgumentException e) {
@@ -983,8 +988,9 @@
}
if (id.equals(mCurMethodId)) {
- if (subtypeId != NOT_A_SUBTYPE_ID) {
- InputMethodSubtype subtype = info.getSubtypes().get(subtypeId);
+ ArrayList<InputMethodSubtype> subtypes = info.getSubtypes();
+ if (subtypeId >= 0 && subtypeId < subtypes.size()) {
+ InputMethodSubtype subtype = subtypes.get(subtypeId);
if (subtype != mCurrentSubtype) {
synchronized (mMethodMap) {
if (mCurMethod != null) {
@@ -1279,6 +1285,21 @@
setInputMethodWithSubtype(token, id, NOT_A_SUBTYPE_ID);
}
+ public boolean switchToLastInputMethod(IBinder token) {
+ synchronized (mMethodMap) {
+ Pair<String, String> lastIme = mSettings.getLastInputMethodAndSubtypeLocked();
+ if (lastIme != null) {
+ InputMethodInfo imi = mMethodMap.get(lastIme.first);
+ if (imi != null) {
+ setInputMethodWithSubtype(token, lastIme.first, getSubtypeIdFromHashCode(
+ imi, Integer.valueOf(lastIme.second)));
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
private void setInputMethodWithSubtype(IBinder token, String id, int subtypeId) {
synchronized (mMethodMap) {
if (token == null) {
@@ -1482,6 +1503,9 @@
}
}
InputMethodInfo imi = enabled.get(i);
+ if (DEBUG) {
+ Slog.d(TAG, "New default IME was selected: " + imi.getId());
+ }
resetSelectedInputMethodAndSubtypeLocked(imi.getId());
return true;
}
@@ -1785,9 +1809,9 @@
// Disabled input method is currently selected, switch to another one.
String selId = Settings.Secure.getString(mContext.getContentResolver(),
Settings.Secure.DEFAULT_INPUT_METHOD);
- if (id.equals(selId)) {
- resetSelectedInputMethodAndSubtypeLocked(enabledInputMethodsList.size() > 0
- ? enabledInputMethodsList.get(0).first : "");
+ if (id.equals(selId) && !chooseNewDefaultIMELocked()) {
+ Slog.i(TAG, "Can't find new IME, unsetting the current input method.");
+ resetSelectedInputMethodAndSubtypeLocked("");
}
// Previous state was enabled.
return true;
@@ -1911,7 +1935,7 @@
// The first subtype applicable to the system locale will be defined as the most applicable
// subtype.
if (DEBUG) {
- Slog.d(TAG, "Applicable InputMethodSubtype was found: " + applicableSubtypeId
+ Slog.d(TAG, "Applicable InputMethodSubtype was found: " + applicableSubtypeId + ","
+ subtypes.get(applicableSubtypeId).getLocale());
}
return applicableSubtypeId;
@@ -1941,6 +1965,20 @@
return mCurrentSubtype;
}
+ public boolean setCurrentInputMethodSubtype(InputMethodSubtype subtype) {
+ synchronized (mMethodMap) {
+ if (subtype != null && mCurMethodId != null) {
+ InputMethodInfo imi = mMethodMap.get(mCurMethodId);
+ int subtypeId = getSubtypeIdFromHashCode(imi, subtype.hashCode());
+ if (subtypeId != NOT_A_SUBTYPE_ID) {
+ setInputMethodLocked(mCurMethodId, subtypeId);
+ return true;
+ }
+ }
+ return false;
+ }
+ }
+
/**
* Utility class for putting and getting settings for InputMethod
* TODO: Move all putters and getters of settings to this class.
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index 374bbb4..a5f3456 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -480,13 +480,9 @@
graphics.setTransform(new AffineTransform());
// set the color
- graphics.setColor(new Color(color));
+ graphics.setColor(new Color(color, true /*alpha*/));
- // set the mode and alpha.
- int alpha = color >>> 24;
- float falpha = alpha / 255.f;
-
- setModeInGraphics(graphics, mode, falpha);
+ setModeInGraphics(graphics, mode);
graphics.fillRect(0, 0, canvasDelegate.mBufferedImage.getWidth(),
canvasDelegate.mBufferedImage.getHeight());
@@ -996,15 +992,8 @@
}
}
- // need to get the alpha to set it in the composite.
- float falpha = 1.f;
-
if (useColorPaint) {
- g.setColor(new Color(paint.getColor()));
-
- // the alpha is taken from the alpha channel of the color
- int alpha = paint.getAlpha();
- falpha = alpha / 255.f;
+ g.setColor(new Color(paint.getColor(), true /*hasAlpha*/));
}
int style = paint.getStyle();
@@ -1036,10 +1025,10 @@
if (xfermodeDelegate instanceof PorterDuffXfermode_Delegate) {
int mode = ((PorterDuffXfermode_Delegate)xfermodeDelegate).getMode();
- setModeInGraphics(g, mode, falpha);
+ setModeInGraphics(g, mode);
} else {
// default mode is src_over
- g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, falpha));
+ g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
// if xfermode wasn't null, then it's something we don't support. log it.
if (mLogger != null && xfermodeDelegate != null) {
@@ -1052,36 +1041,36 @@
return g;
}
- private static void setModeInGraphics(Graphics2D g, int mode, float falpha) {
+ private static void setModeInGraphics(Graphics2D g, int mode) {
for (PorterDuff.Mode m : PorterDuff.Mode.values()) {
if (m.nativeInt == mode) {
- setModeInGraphics(g, m, falpha);
+ setModeInGraphics(g, m);
return;
}
}
}
- private static void setModeInGraphics(Graphics2D g, PorterDuff.Mode mode, float falpha) {
+ private static void setModeInGraphics(Graphics2D g, PorterDuff.Mode mode) {
switch (mode) {
case CLEAR:
- g.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, falpha));
+ g.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 1.0f /*alpha*/));
break;
case DARKEN:
break;
case DST:
- g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST, falpha));
+ g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST, 1.0f /*alpha*/));
break;
case DST_ATOP:
- g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_ATOP, falpha));
+ g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_ATOP, 1.0f /*alpha*/));
break;
case DST_IN:
- g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_IN, falpha));
+ g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_IN, 1.0f /*alpha*/));
break;
case DST_OUT:
- g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_OUT, falpha));
+ g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_OUT, 1.0f /*alpha*/));
break;
case DST_OVER:
- g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_OVER, falpha));
+ g.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_OVER, 1.0f /*alpha*/));
break;
case LIGHTEN:
break;
@@ -1090,22 +1079,22 @@
case SCREEN:
break;
case SRC:
- g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, falpha));
+ g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC, 1.0f /*alpha*/));
break;
case SRC_ATOP:
- g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, falpha));
+ g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1.0f /*alpha*/));
break;
case SRC_IN:
- g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, falpha));
+ g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, 1.0f /*alpha*/));
break;
case SRC_OUT:
- g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OUT, falpha));
+ g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OUT, 1.0f /*alpha*/));
break;
case SRC_OVER:
- g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, falpha));
+ g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f /*alpha*/));
break;
case XOR:
- g.setComposite(AlphaComposite.getInstance(AlphaComposite.XOR, falpha));
+ g.setComposite(AlphaComposite.getInstance(AlphaComposite.XOR, 1.0f /*alpha*/));
break;
}
}
@@ -1156,12 +1145,6 @@
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
}
-
- if (paintDelegate.getAlpha() != 0xFF) {
- c = g.getComposite();
- g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
- paintDelegate.getAlpha()/255.f));
- }
}
g.drawImage(image, dleft, dtop, dright, dbottom,
diff --git a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
index d83a33b..93f757a 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Paint_Delegate.java
@@ -114,10 +114,6 @@
return mColor;
}
- public int getAlpha() {
- return mColor >>> 24;
- }
-
public int getTextAlign() {
return mTextAlign;
}
@@ -260,7 +256,7 @@
return 0;
}
- return delegate.getAlpha();
+ return delegate.mColor >>> 24;
}
/*package*/ static void setAlpha(Paint thisPaint, int a) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java
index 5fcb9ff..8b67166 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeLayoutScene.java
@@ -22,6 +22,7 @@
import com.android.layoutlib.bridge.impl.LayoutSceneImpl;
import java.awt.image.BufferedImage;
+import java.util.Map;
/**
* An implementation of {@link LayoutScene}.
@@ -52,6 +53,11 @@
}
@Override
+ public Map<String, String> getDefaultViewPropertyValues(Object viewObject) {
+ return mScene.getDefaultViewPropertyValues(viewObject);
+ }
+
+ @Override
public SceneResult render() {
synchronized (mBridge) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 79aecff..02db2cf 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -63,6 +63,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
+import java.util.IdentityHashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.Map.Entry;
@@ -82,6 +83,9 @@
private final Map<String, Map<String, IResourceValue>> mFrameworkResources;
private final Map<IStyleResourceValue, IStyleResourceValue> mStyleInheritanceMap;
+ private final Map<Object, Map<String, String>> mDefaultPropMaps =
+ new IdentityHashMap<Object, Map<String,String>>();
+
// maps for dynamically generated id representing style objects (IStyleResourceValue)
private Map<Integer, IStyleResourceValue> mDynamicIdToStyleMap;
private Map<IStyleResourceValue, Integer> mStyleToDynamicIdMap;
@@ -180,6 +184,9 @@
return mLogger;
}
+ public Map<String, String> getDefaultPropMap(Object key) {
+ return mDefaultPropMaps.get(key);
+ }
// ------------- Activity Methods
@@ -285,13 +292,16 @@
return null;
}
- Object key = null;
+ Map<String, String> defaultPropMap = null;
if (parser != null) {
- key = parser.getViewKey();
- }
- if (key != null) {
- String attrs_name = Bridge.resolveResourceValue(attrs);
- System.out.println("KEY: " + key.toString() + "(" + attrs_name + ")");
+ Object key = parser.getViewKey();
+ if (key != null) {
+ defaultPropMap = mDefaultPropMaps.get(key);
+ if (defaultPropMap == null) {
+ defaultPropMap = new HashMap<String, String>();
+ mDefaultPropMaps.put(key, defaultPropMap);
+ }
+ }
}
boolean[] frameworkAttributes = new boolean[1];
@@ -309,9 +319,6 @@
customStyle = parser.getAttributeValue(null /* namespace*/, "style");
}
if (customStyle != null) {
- if (key != null) {
- print("style", customStyle, false);
- }
IResourceValue item = findResValue(customStyle, false /*forceFrameworkOnly*/);
if (item instanceof IStyleResourceValue) {
@@ -323,8 +330,8 @@
// get the name from the int.
String defStyleName = searchAttr(defStyleAttr);
- if (key != null) {
- print("style", defStyleName, true);
+ if (defaultPropMap != null) {
+ defaultPropMap.put("style", defStyleName);
}
// look for the style in the current theme, and its parent:
@@ -385,20 +392,16 @@
// if we found a value, we make sure this doesn't reference another value.
// So we resolve it.
if (resValue != null) {
- if (key != null) {
- print(name, resValue.getValue(), true);
+ // put the first default value, before the resolution.
+ if (defaultPropMap != null) {
+ defaultPropMap.put(name, resValue.getValue());
}
resValue = resolveResValue(resValue);
- } else if (key != null) {
- print(name, "<unknown>", true);
}
ta.bridgeSetValue(index, name, resValue);
} else {
- if (key != null) {
- print(name, value, false);
- }
// there is a value in the XML, but we need to resolve it in case it's
// referencing another resource or a theme value.
ta.bridgeSetValue(index, name, resolveValue(null, name, value));
@@ -411,15 +414,6 @@
return ta;
}
- private void print(String name, String value, boolean isDefault) {
- System.out.print("\t" + name + " : " + value);
- if (isDefault) {
- System.out.println(" (default)");
- } else {
- System.out.println("");
- }
- }
-
@Override
public Looper getMainLooper() {
return Looper.myLooper();
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
index d8a59ce..b0316a3 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/LayoutSceneImpl.java
@@ -665,7 +665,8 @@
ViewInfo result = new ViewInfo(view.getClass().getName(),
context.getViewKey(view),
- view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
+ view.getLeft(), view.getTop(), view.getRight(), view.getBottom(),
+ view, view.getLayoutParams());
if (view instanceof ViewGroup) {
ViewGroup group = ((ViewGroup) view);
@@ -686,4 +687,8 @@
public ViewInfo getViewInfo() {
return mViewInfo;
}
+
+ public Map<String, String> getDefaultViewPropertyValues(Object viewObject) {
+ return mContext.getDefaultPropMap(viewObject);
+ }
}