diff options
48 files changed, 918 insertions, 419 deletions
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 android.util.Pair; 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 class DownloadManager { */ 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 @@ public class DownloadManager { * @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 @@ public class DownloadManager { } @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 @@ public class DownloadManager { } // 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 @@ public class DownloadManager { } } - 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 @@ public class SyncManager implements OnAccountsUpdateListener { } } + 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 @@ public class SyncManager implements OnAccountsUpdateListener { // 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 @@ public class SQLiteDatabase extends SQLiteClosable { mConnectionPool.close(); } } finally { - unlock(); + unlock(); } } @@ -1772,8 +1772,7 @@ public class SQLiteDatabase extends SQLiteClosable { */ 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 @@ public class SQLiteDatabase extends SQLiteClosable { 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 @@ public class SQLiteDatabase extends SQLiteClosable { 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 final class InputMethodManager { } } + 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 @@ class DebugFlags { 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 @@ import junit.framework.Assert; // 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 @@ import junit.framework.Assert; // 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 @@ import junit.framework.Assert; } // 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 @@ public class WebView extends AbsoluteLayout 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 @@ final class WebViewCore { } 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.animation.ObjectAnimator; 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 @@ public class MediaController extends FrameLayout { 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.PixelFormat; 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 @@ public class PopupWindow { 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 @@ public class PopupWindow { * @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 @@ public class PopupWindow { * @hide */ public void setSplitTouchEnabled(boolean enabled) { - mSplitTouchEnabled = enabled; + mSplitTouchEnabled = enabled ? 1 : 0; } /** @@ -993,7 +997,7 @@ public class PopupWindow { 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 @@ public class StackView extends AdapterViewAnimator { 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 @@ public class StackView extends AdapterViewAnimator { @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 @@ public class StackView extends AdapterViewAnimator { @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 @@ public class StackView extends AdapterViewAnimator { // 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 @@ public class StackView extends AdapterViewAnimator { @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 @@ public class StackView extends AdapterViewAnimator { 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 @@ public class StackView extends AdapterViewAnimator { 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 @@ public class StackView extends AdapterViewAnimator { 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 @@ public class StackView extends AdapterViewAnimator { } 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; - 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()); - - 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); - } + setOffsets(horizontalOffset, newVerticalOffset); } public void setHorizontalOffset(int newHorizontalOffset) { - int offsetDelta = newHorizontalOffset - horizontalOffset; + 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 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()); + 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(left, top, right, bottom); float xoffset = -invalidateRectf.left; float yoffset = -invalidateRectf.top; @@ -997,7 +996,7 @@ public class StackView extends AdapterViewAnimator { 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.StaticLayout; 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener * 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener || 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } /** - * @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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener // 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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..c930c57 100644 --- a/core/java/com/android/internal/os/SamplingProfilerIntegration.java +++ b/core/java/com/android/internal/os/SamplingProfilerIntegration.java @@ -53,7 +53,10 @@ public class SamplingProfilerIntegration { 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 @@ interface IInputMethodManager { 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 @@ class BaseObj { 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 @@ class BaseObj { 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 @@ class BaseObj { } 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 @@ class BaseObj { 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 @@ class BaseObj { 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 @@ import android.util.Log; /** * @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 @@ public class Element extends BaseObj { 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 @@ public class Element extends BaseObj { } } + /** + * 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 @@ public class Element extends BaseObj { } } + /** + * 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 @@ public class Element extends BaseObj { 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 @@ public class Element extends BaseObj { 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 @@ public class Element extends BaseObj { 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 @@ public class Element extends BaseObj { 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 @@ public class Element extends BaseObj { 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 @@ public class Element extends BaseObj { 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 @@ public class Element extends BaseObj { 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 @@ public class Element extends BaseObj { int[] mArraySizes; int mCount; + /** + * Create a builder object. + * + * @param rs + */ public Builder(RenderScript rs) { mRS = rs; mCount = 0; @@ -488,6 +596,13 @@ public class Element extends BaseObj { 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 @@ public class Element extends BaseObj { 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 @@ import android.view.Surface; /** * @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 @@ public class RenderScript { /////////////////////////////////////////////////////////////////////////////////// // + /** + * 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 class RenderScript { 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 @@ public class RenderScript { } } + + /** + * 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 @@ public class RenderScript { } } - protected RenderScript() { + RenderScript() { } + /** + * Create a basic RenderScript context. + * + * + * @return RenderScript + */ public static RenderScript create() { RenderScript rs = new RenderScript(); @@ -704,15 +757,32 @@ public class RenderScript { 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 @@ public class RenderScript { 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 @@ import android.view.SurfaceView; /** * @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 @@ import android.util.Log; /** * @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 @@ public class Type extends BaseObj { 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 @@ public class Type extends BaseObj { calcElementCount(); } + /** + * Builder class for Type. + * + */ public static class Builder { RenderScript mRS; Dimension[] mDimensions; @@ -134,6 +192,12 @@ public class Type extends BaseObj { 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 @@ public class Type extends BaseObj { 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 @@ public class Type extends BaseObj { 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 @@ public class Type extends BaseObj { 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 @@ public: 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 @@ public: // 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 @@ enum { 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 @@ struct InputWindow { * motion events to be delivered to them with AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED. */ bool isTrustedOverlay() const; + + bool supportsSplitTouch() const; }; @@ -946,7 +948,7 @@ private: 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 @@ public class BallsRS { 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 @@ public class BallsRS { 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 @@ public class BallsRS { 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 @@ int root() { } 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 @@ bool InputWindow::isTrustedOverlay() const { || layoutParamsType == TYPE_SECURE_SYSTEM_OVERLAY; } +bool InputWindow::supportsSplitTouch() const { + return layoutParamsFlags & InputWindow::FLAG_SPLIT_TOUCH; +} + // --- InputDispatcher --- @@ -1110,8 +1114,7 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, } // 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 @@ bool InputDispatcher::transferTouchFocus(const sp<InputChannel>& fromChannel, 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 @@ public class MediaImageItem extends MediaItem { * @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();
-
- // 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;
- }
- }
+ // 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.
- 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;
- }
- }
- }
- }
+ // 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();
+ 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 @@ public class MediaImageItem extends MediaItem { }
/**
+ * 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::keySamplingRate = "sampling_rate"; 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 @@ status_t StagefrightRecorder::setupCameraSource( 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 @@ status_t StagefrightRecorder::setupVideoEncoder( 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 @@ status_t CameraSource::init( 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 @@ void OMXCodec::setVideoInputFormat( 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::getVideoProfileLevel( 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::setupH263EncoderParameters(const sp<MetaData>& meta) { 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::setupMPEG4EncoderParameters(const sp<MetaData>& meta) { 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 @@ status_t AVCEncoder::initCheck(const sp<MetaData>& meta) { 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 @@ status_t AVCEncoder::initCheck(const sp<MetaData>& meta) { 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 @@ status_t M4vH263Encoder::initCheck(const sp<MetaData>& meta) { 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 @@ status_t M4vH263Encoder::initCheck(const sp<MetaData>& meta) { 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 @@ public class PhoneStatusBarService extends StatusBarService { | 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 @@ public abstract class StatusBarService extends SystemUI implements CommandQueue. 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 @@ public class ShirtPocket extends FrameLayout { 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 @@ public class TabletStatusBarService extends StatusBarService { 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 @@ public class TabletStatusBarService extends StatusBarService { 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 @@ public class TabletStatusBarService extends StatusBarService { 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 @@ public class TabletStatusBarService extends StatusBarService { 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_INSET_DECOR; 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 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { 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 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { 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 @@ status_t AudioPolicyManagerBase::startInput(audio_io_handle_t input) 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 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // 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 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } 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 @@ public class InputMethodManagerService extends IInputMethodManager.Stub 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 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } 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 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // 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 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // 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 @@ public class InputMethodManagerService extends IInputMethodManager.Stub 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 @@ public class Canvas_Delegate { 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 @@ public class Canvas_Delegate { } } - // 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 @@ public class Canvas_Delegate { 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 @@ public class Canvas_Delegate { 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 @@ public class Canvas_Delegate { 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 @@ public class Canvas_Delegate { 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 @@ public class Paint_Delegate { return mColor; } - public int getAlpha() { - return mColor >>> 24; - } - public int getTextAlign() { return mTextAlign; } @@ -260,7 +256,7 @@ public class Paint_Delegate { 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.api.ViewInfo; 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 @@ public class BridgeLayoutScene extends LayoutScene { } @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.FileOutputStream; 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 @@ public final class BridgeContext extends Activity { 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 @@ public final class BridgeContext extends Activity { return mLogger; } + public Map<String, String> getDefaultPropMap(Object key) { + return mDefaultPropMaps.get(key); + } // ------------- Activity Methods @@ -285,13 +292,16 @@ public final class BridgeContext extends Activity { 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 @@ public final class BridgeContext extends Activity { 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 @@ public final class BridgeContext extends Activity { // 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 @@ public final class BridgeContext extends Activity { // 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 @@ public final class BridgeContext extends Activity { 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 @@ public class LayoutSceneImpl { 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 class LayoutSceneImpl { public ViewInfo getViewInfo() { return mViewInfo; } + + public Map<String, String> getDefaultViewPropertyValues(Object viewObject) { + return mContext.getDefaultPropMap(viewObject); + } } |
