diff options
104 files changed, 700 insertions, 746 deletions
diff --git a/api/current.xml b/api/current.xml index 357daae..ebfa842 100644 --- a/api/current.xml +++ b/api/current.xml @@ -19596,6 +19596,17 @@ synchronized="false" static="false" final="false" + deprecated="deprecated" + visibility="public" +> +</method> +<method name="getCustomView" + return="android.view.View" + abstract="true" + native="false" + synchronized="false" + static="false" + final="false" deprecated="not deprecated" visibility="public" > @@ -26471,6 +26482,19 @@ <parameter name="request" type="android.app.DownloadManager.Request"> </parameter> </method> +<method name="getMimeTypeForDownloadedFile" + return="java.lang.String" + abstract="false" + native="false" + synchronized="false" + static="false" + final="false" + deprecated="not deprecated" + visibility="public" +> +<parameter name="id" type="long"> +</parameter> +</method> <method name="getUriForDownloadedFile" return="android.net.Uri" abstract="false" diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java index e6b1c08..8471df9 100644 --- a/core/java/android/accounts/AccountManagerService.java +++ b/core/java/android/accounts/AccountManagerService.java @@ -520,6 +520,18 @@ public class AccountManagerService if (account == null) throw new IllegalArgumentException("account is null"); checkManageAccountsPermission(); long identityToken = clearCallingIdentity(); + + cancelNotification(getSigninRequiredNotificationId(account)); + synchronized(mCredentialsPermissionNotificationIds) { + for (Pair<Pair<Account, String>, Integer> pair: + mCredentialsPermissionNotificationIds.keySet()) { + if (account.equals(pair.first.first)) { + int id = mCredentialsPermissionNotificationIds.get(pair); + cancelNotification(id); + } + } + } + try { new RemoveAccountSession(response, account).bind(); } finally { diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java index a57b54a..246d661 100644 --- a/core/java/android/app/ActionBar.java +++ b/core/java/android/app/ActionBar.java @@ -138,14 +138,19 @@ public abstract class ActionBar { * Set the action bar into custom navigation mode, supplying a view * for custom navigation. * - * Custom navigation views appear between the application icon and + * <p>Custom navigation views appear between the application icon and * any action buttons and may use any space available there. Common * use cases for custom navigation views might include an auto-suggesting * address bar for a browser or other navigation mechanisms that do not - * translate well to provided navigation modes. + * translate well to provided navigation modes.</p> + * + * <p>The display option {@link #DISPLAY_SHOW_CUSTOM} must be set for + * the custom view to be displayed.</p> * * @param view Custom navigation view to place in the ActionBar. * @param layoutParams How this custom view should layout in the bar. + * + * @see #setDisplayOptions(int, int) */ public abstract void setCustomView(View view, LayoutParams layoutParams); @@ -248,39 +253,47 @@ public abstract class ActionBar { public abstract void setStandardNavigationMode(); /** - * Set the action bar's title. This will only be displayed in standard navigation mode. + * Set the action bar's title. This will only be displayed if + * {@link #DISPLAY_SHOW_TITLE} is set. * * @param title Title to set * * @see #setTitle(int) + * @see #setDisplayOptions(int, int) */ public abstract void setTitle(CharSequence title); /** - * Set the action bar's title. This will only be displayed in standard navigation mode. + * Set the action bar's title. This will only be displayed if + * {@link #DISPLAY_SHOW_TITLE} is set. * * @param resId Resource ID of title string to set * * @see #setTitle(CharSequence) + * @see #setDisplayOptions(int, int) */ public abstract void setTitle(int resId); /** - * Set the action bar's subtitle. This will only be displayed in standard navigation mode. - * Set to null to disable the subtitle entirely. + * Set the action bar's subtitle. This will only be displayed if + * {@link #DISPLAY_SHOW_TITLE} is set. Set to null to disable the + * subtitle entirely. * * @param subtitle Subtitle to set * * @see #setSubtitle(int) + * @see #setDisplayOptions(int, int) */ public abstract void setSubtitle(CharSequence subtitle); /** - * Set the action bar's subtitle. This will only be displayed in standard navigation mode. + * Set the action bar's subtitle. This will only be displayed if + * {@link #DISPLAY_SHOW_TITLE} is set. * * @param resId Resource ID of subtitle string to set * * @see #setSubtitle(CharSequence) + * @see #setDisplayOptions(int, int) */ public abstract void setSubtitle(int resId); @@ -317,9 +330,16 @@ public abstract class ActionBar { /** * @return The current custom navigation view. + * @deprecated Method has been renamed. Use {@link #getCustomView()}. */ + @Deprecated public abstract View getCustomNavigationView(); - + + /** + * @return The current custom view. + */ + public abstract View getCustomView(); + /** * Returns the current ActionBar title in standard mode. * Returns null if {@link #getNavigationMode()} would not return diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java index 6e18533..09a21f8 100644 --- a/core/java/android/app/DownloadManager.java +++ b/core/java/android/app/DownloadManager.java @@ -886,8 +886,8 @@ public class DownloadManager { * downloaded successfully. otherwise, null is returned. *<p> * If the specified downloaded file is in external storage (for example, /sdcard dir), - * then it is assumed to be safe for anyone to read and the returned {@link Uri} can be used - * by any app to access the downloaded file. + * then it is assumed to be safe for anyone to read and the returned {@link Uri} corresponds + * to the filepath on sdcard. * * @param id the id of the downloaded file. * @return the {@link Uri} for the given downloaded file id, if download was successful. null @@ -903,8 +903,7 @@ public class DownloadManager { return null; } while (cursor.moveToFirst()) { - int status = cursor.getInt(cursor.getColumnIndexOrThrow( - DownloadManager.COLUMN_STATUS)); + int status = cursor.getInt(cursor.getColumnIndexOrThrow(COLUMN_STATUS)); if (DownloadManager.STATUS_SUCCESSFUL == status) { int indx = cursor.getColumnIndexOrThrow( Downloads.Impl.COLUMN_DESTINATION); @@ -919,8 +918,9 @@ public class DownloadManager { return ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, id); } else { // return public uri - return ContentUris.withAppendedId( - Downloads.Impl.PUBLICLY_ACCESSIBLE_DOWNLOADS_URI, id); + String path = cursor.getString( + cursor.getColumnIndexOrThrow(COLUMN_LOCAL_FILENAME)); + return Uri.fromFile(new File(path)); } } } @@ -934,6 +934,38 @@ public class DownloadManager { } /** + * Returns {@link Uri} for the given downloaded file id, if the file is + * downloaded successfully. otherwise, null is returned. + *<p> + * If the specified downloaded file is in external storage (for example, /sdcard dir), + * then it is assumed to be safe for anyone to read and the returned {@link Uri} corresponds + * to the filepath on sdcard. + * + * @param id the id of the downloaded file. + * @return the {@link Uri} for the given downloaded file id, if download was successful. null + * otherwise. + */ + public String getMimeTypeForDownloadedFile(long id) { + Query query = new Query().setFilterById(id); + Cursor cursor = null; + try { + cursor = query(query); + if (cursor == null) { + return null; + } + while (cursor.moveToFirst()) { + return cursor.getString(cursor.getColumnIndexOrThrow(COLUMN_MEDIA_TYPE)); + } + } finally { + if (cursor != null) { + cursor.close(); + } + } + // downloaded file not found or its status is not 'successfully completed' + return null; + } + + /** * Restart the given downloads, which must have already completed (successfully or not). This * method will only work when called from within the download manager's process. * @param ids the IDs of the downloads diff --git a/core/java/android/content/ContentQueryMap.java b/core/java/android/content/ContentQueryMap.java index c955094..8aeaa8f 100644 --- a/core/java/android/content/ContentQueryMap.java +++ b/core/java/android/content/ContentQueryMap.java @@ -33,7 +33,7 @@ import java.util.Observable; * The cursor data is accessed by row key and column name via getValue(). */ public class ContentQueryMap extends Observable { - private Cursor mCursor; + private volatile Cursor mCursor; private String[] mColumnNames; private int mKeyColumn; @@ -71,7 +71,7 @@ public class ContentQueryMap extends Observable { // ContentProvider then read it once into the cache. Otherwise the cache will be filled // automatically. if (!keepUpdated) { - readCursorIntoCache(); + readCursorIntoCache(cursor); } } @@ -128,27 +128,35 @@ public class ContentQueryMap extends Observable { /** Requeries the cursor and reads the contents into the cache */ public void requery() { + final Cursor cursor = mCursor; + if (cursor == null) { + // If mCursor is null then it means there was a requery() in flight + // while another thread called close(), which nulls out mCursor. + // If this happens ignore the requery() since we are closed anyways. + return; + } mDirty = false; - if (!mCursor.requery()) { - throw new IllegalStateException("trying to requery an already closed cursor"); + if (!cursor.requery()) { + // again, don't do anything if the cursor is already closed + return; } - readCursorIntoCache(); + readCursorIntoCache(cursor); setChanged(); notifyObservers(); } - private synchronized void readCursorIntoCache() { + private synchronized void readCursorIntoCache(Cursor cursor) { // Make a new map so old values returned by getRows() are undisturbed. int capacity = mValues != null ? mValues.size() : 0; mValues = new HashMap<String, ContentValues>(capacity); - while (mCursor.moveToNext()) { + while (cursor.moveToNext()) { ContentValues values = new ContentValues(); for (int i = 0; i < mColumnNames.length; i++) { if (i != mKeyColumn) { - values.put(mColumnNames[i], mCursor.getString(i)); + values.put(mColumnNames[i], cursor.getString(i)); } } - mValues.put(mCursor.getString(mKeyColumn), values); + mValues.put(cursor.getString(mKeyColumn), values); } } diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java index 8762512..1fa5af2 100644 --- a/core/java/android/os/StrictMode.java +++ b/core/java/android/os/StrictMode.java @@ -106,6 +106,8 @@ public final class StrictMode { private static final String TAG = "StrictMode"; private static final boolean LOG_V = false; + private static final boolean IS_USER_BUILD = "user".equals(Build.TYPE); + // Only log a duplicate stack trace to the logs every second. private static final long MIN_LOG_INTERVAL_MS = 1000; @@ -693,7 +695,7 @@ public final class StrictMode { public static boolean conditionallyEnableDebugLogging() { // For debug builds, log event loop stalls to dropbox for analysis. // Similar logic also appears in ActivityThread.java for system apps. - if ("user".equals(Build.TYPE)) { + if (IS_USER_BUILD) { setCloseGuardEnabled(false); return false; } @@ -1240,6 +1242,11 @@ public final class StrictMode { mContainerState = threadState; } + // Empty constructor for the NO_OP_SPAN + protected Span() { + mContainerState = null; + } + /** * To be called when the critical span is complete (i.e. the * animation is done animating). This can be called on any @@ -1269,11 +1276,14 @@ public final class StrictMode { state.mActiveHead = mNext; } + state.mActiveSize--; + + if (LOG_V) Log.d(TAG, "Span finished=" + mName + "; size=" + state.mActiveSize); + this.mCreateMillis = -1; this.mName = null; this.mPrev = null; this.mNext = null; - state.mActiveSize--; // Add ourselves to the freeList, if it's not already // too big. @@ -1286,6 +1296,13 @@ public final class StrictMode { } } + // The no-op span that's used in user builds. + private static final Span NO_OP_SPAN = new Span() { + public void finish() { + // Do nothing. + } + }; + /** * Linked lists of active spans and a freelist. * @@ -1327,6 +1344,9 @@ public final class StrictMode { * @hide */ public static Span enterCriticalSpan(String name) { + if (IS_USER_BUILD) { + return NO_OP_SPAN; + } if (name == null || name.isEmpty()) { throw new IllegalArgumentException("name must be non-null and non-empty"); } @@ -1350,6 +1370,7 @@ public final class StrictMode { if (span.mNext != null) { span.mNext.mPrev = span; } + if (LOG_V) Log.d(TAG, "Span enter=" + name + "; size=" + state.mActiveSize); } return span; } diff --git a/core/java/android/text/Layout.java b/core/java/android/text/Layout.java index dd25eaa..3fe4f4c 100644 --- a/core/java/android/text/Layout.java +++ b/core/java/android/text/Layout.java @@ -26,12 +26,11 @@ import android.graphics.Rect; import android.text.method.TextKeyListener; import android.text.style.AlignmentSpan; import android.text.style.LeadingMarginSpan; +import android.text.style.LeadingMarginSpan.LeadingMarginSpan2; import android.text.style.LineBackgroundSpan; import android.text.style.ParagraphStyle; import android.text.style.ReplacementSpan; import android.text.style.TabStopSpan; -import android.text.style.LeadingMarginSpan.LeadingMarginSpan2; -import android.view.KeyEvent; import java.util.Arrays; @@ -1056,23 +1055,30 @@ public abstract class Layout { int lineEnd = getLineEnd(line); int lineDir = getParagraphDirection(line); + boolean lineChanged = false; boolean advance = toLeft == (lineDir == DIR_RIGHT_TO_LEFT); - if (caret == (advance ? lineEnd : lineStart)) { - // walking off line, so look at the line we're headed to + // if walking off line, look at the line we're headed to + if (advance) { + if (caret == lineEnd) { + if (line < getLineCount() - 1) { + lineChanged = true; + ++line; + } else { + return caret; // at very end, don't move + } + } + } else { if (caret == lineStart) { if (line > 0) { + lineChanged = true; --line; } else { return caret; // at very start, don't move } - } else { - if (line < getLineCount() - 1) { - ++line; - } else { - return caret; // at very end, don't move - } } + } + if (lineChanged) { lineStart = getLineStart(line); lineEnd = getLineEnd(line); int newDir = getParagraphDirection(line); @@ -1672,6 +1678,7 @@ public abstract class Layout { return new String(s); } + @Override public String toString() { char[] s = new char[length()]; getChars(0, length(), s, 0); @@ -1709,6 +1716,7 @@ public abstract class Layout { return mSpanned.nextSpanTransition(start, limit, type); } + @Override public CharSequence subSequence(int start, int end) { char[] s = new char[end - start]; getChars(start, end, s, 0); diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 06800d5..f987a49 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -4185,9 +4185,8 @@ public class WebView extends AbsoluteLayout if (keyCode == KeyEvent.KEYCODE_SHIFT_LEFT || keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT) { - if (pageShouldHandleShiftAndArrows()) { - mShiftIsPressed = true; - } else if (!nativeCursorWantsKeyEvents() && !mSelectingText) { + if (!pageShouldHandleShiftAndArrows() && !nativeCursorWantsKeyEvents() + && !mSelectingText) { setUpSelect(); } } @@ -4206,7 +4205,7 @@ public class WebView extends AbsoluteLayout && keyCode <= KeyEvent.KEYCODE_DPAD_RIGHT) { switchOutDrawHistory(); if (pageShouldHandleShiftAndArrows()) { - letPageHandleNavKey(keyCode, event.getEventTime(), true); + letPageHandleNavKey(keyCode, event.getEventTime(), true, event.getMetaState()); return true; } if (mSelectingText) { @@ -4248,7 +4247,6 @@ public class WebView extends AbsoluteLayout && keyCode != KeyEvent.KEYCODE_SHIFT_RIGHT) { // turn off copy select if a shift-key combo is pressed selectionDone(); - mShiftIsPressed = false; } if (getSettings().getNavDump()) { @@ -4339,9 +4337,7 @@ public class WebView extends AbsoluteLayout if (keyCode == KeyEvent.KEYCODE_SHIFT_LEFT || keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT) { - if (pageShouldHandleShiftAndArrows()) { - mShiftIsPressed = false; - } else if (copySelection()) { + if (!pageShouldHandleShiftAndArrows() && copySelection()) { selectionDone(); return true; } @@ -4350,7 +4346,7 @@ public class WebView extends AbsoluteLayout if (keyCode >= KeyEvent.KEYCODE_DPAD_UP && keyCode <= KeyEvent.KEYCODE_DPAD_RIGHT) { if (pageShouldHandleShiftAndArrows()) { - letPageHandleNavKey(keyCode, event.getEventTime(), false); + letPageHandleNavKey(keyCode, event.getEventTime(), false, event.getMetaState()); return true; } // always handle the navigation keys in the UI thread @@ -4592,7 +4588,6 @@ public class WebView extends AbsoluteLayout mDrawCursorRing = false; } mGotKeyDown = false; - mShiftIsPressed = false; mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS); mTouchMode = TOUCH_DONE_MODE; if (mNativeClass != 0) { @@ -5529,7 +5524,6 @@ public class WebView extends AbsoluteLayout private int mSelectX = 0; private int mSelectY = 0; private boolean mFocusSizeChanged = false; - private boolean mShiftIsPressed = false; private boolean mTrackballDown = false; private long mTrackballUpTime = 0; private long mLastCursorTime = 0; @@ -5600,7 +5594,7 @@ public class WebView extends AbsoluteLayout } return false; // let common code in onKeyUp at it } - if ((mMapTrackballToArrowKeys && mShiftIsPressed == false) || + if ((mMapTrackballToArrowKeys && (ev.getMetaState() & KeyEvent.META_SHIFT_ON) == 0) || (mAccessibilityInjector != null || mAccessibilityScriptInjected)) { if (DebugFlags.WEB_VIEW) Log.v(LOGTAG, "onTrackballEvent gmail quit"); return false; @@ -5629,7 +5623,7 @@ public class WebView extends AbsoluteLayout } mTrackballRemainsX += ev.getX(); mTrackballRemainsY += ev.getY(); - doTrackball(time); + doTrackball(time, ev.getMetaState()); return true; } @@ -5713,7 +5707,7 @@ public class WebView extends AbsoluteLayout "KEYCODE_DPAD_LEFT}."); } - private void doTrackball(long time) { + private void doTrackball(long time, int metaState) { int elapsed = (int) (mTrackballLastTime - mTrackballFirstTime); if (elapsed == 0) { elapsed = TRACKBALL_TIMEOUT; @@ -5771,9 +5765,9 @@ public class WebView extends AbsoluteLayout } if (mNativeClass != 0 && nativePageShouldHandleShiftAndArrows()) { for (int i = 0; i < count; i++) { - letPageHandleNavKey(selectKeyCode, time, true); + letPageHandleNavKey(selectKeyCode, time, true, metaState); } - letPageHandleNavKey(selectKeyCode, time, false); + letPageHandleNavKey(selectKeyCode, time, false, metaState); } else if (navHandledKey(selectKeyCode, count, false, time)) { playSoundEffect(keyCodeToSoundsEffect(selectKeyCode)); } @@ -7282,7 +7276,7 @@ public class WebView extends AbsoluteLayout * Pass the key directly to the page. This assumes that * nativePageShouldHandleShiftAndArrows() returned true. */ - private void letPageHandleNavKey(int keyCode, long time, boolean down) { + private void letPageHandleNavKey(int keyCode, long time, boolean down, int metaState) { int keyEventAction; int eventHubAction; if (down) { @@ -7293,10 +7287,11 @@ public class WebView extends AbsoluteLayout keyEventAction = KeyEvent.ACTION_UP; eventHubAction = EventHub.KEY_UP; } + KeyEvent event = new KeyEvent(time, time, keyEventAction, keyCode, - 1, (mShiftIsPressed ? KeyEvent.META_SHIFT_ON : 0) - | (false ? KeyEvent.META_ALT_ON : 0) // FIXME - | (false ? KeyEvent.META_SYM_ON : 0) // FIXME + 1, (metaState & KeyEvent.META_SHIFT_ON) + | (metaState & KeyEvent.META_ALT_ON) + | (metaState & KeyEvent.META_SYM_ON) , 0, 0, 0); mWebViewCore.sendMessage(eventHubAction, event); } diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java index ab5ff3d..466e541 100644 --- a/core/java/android/widget/AbsListView.java +++ b/core/java/android/widget/AbsListView.java @@ -29,6 +29,7 @@ import android.os.Debug; import android.os.Handler; import android.os.Parcel; import android.os.Parcelable; +import android.os.StrictMode; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; @@ -460,6 +461,15 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te private boolean mFlingProfilingStarted = false; /** + * The StrictMode "critical time span" objects to catch animation + * stutters. Non-null when a time-sensitive animation is + * in-flight. Must call finish() on them when done animating. + * These are no-ops on user builds. + */ + private StrictMode.Span mScrollStrictSpan = null; + private StrictMode.Span mFlingStrictSpan = null; + + /** * The last CheckForLongPress runnable we posted, if any */ private CheckForLongPress mPendingCheckForLongPress; @@ -2089,6 +2099,16 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mAdapter.unregisterDataSetObserver(mDataSetObserver); mDataSetObserver = null; } + + if (mScrollStrictSpan != null) { + mScrollStrictSpan.finish(); + mScrollStrictSpan = null; + } + + if (mFlingStrictSpan != null) { + mFlingStrictSpan.finish(); + mFlingStrictSpan = null; + } } @Override @@ -2559,6 +2579,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te } } + if (mScrollStrictSpan == null) { + // If it's non-null, we're already in a scroll. + mScrollStrictSpan = StrictMode.enterCriticalSpan("AbsListView-scroll"); + } + if (y != mLastY) { // We may be here after stopping a fling and continuing to scroll. // If so, we haven't disallowed intercepting touch events yet. @@ -2722,6 +2747,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mScrollProfilingStarted = false; } } + + if (mScrollStrictSpan != null) { + mScrollStrictSpan.finish(); + mScrollStrictSpan = null; + } break; } @@ -2893,8 +2923,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te void reportScrollStateChange(int newState) { if (newState != mLastScrollState) { if (mOnScrollListener != null) { - mOnScrollListener.onScrollStateChanged(this, newState); mLastScrollState = newState; + mOnScrollListener.onScrollStateChanged(this, newState); } } } @@ -2934,6 +2964,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mFlingProfilingStarted = true; } } + + if (mFlingStrictSpan == null) { + mFlingStrictSpan = StrictMode.enterCriticalSpan("AbsListView-fling"); + } } void startScroll(int distance, int duration) { @@ -3012,6 +3046,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te mFlingProfilingStarted = false; } } + + if (mFlingStrictSpan != null) { + mFlingStrictSpan.finish(); + mFlingStrictSpan = null; + } } break; } @@ -3431,12 +3470,13 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te public void smoothScrollBy(int distance, int duration) { if (mFlingRunnable == null) { mFlingRunnable = new FlingRunnable(); - } else { - mFlingRunnable.endFling(); } // No sense starting to scroll if we're not going anywhere if (distance != 0) { + reportScrollStateChange(OnScrollListener.SCROLL_STATE_FLING); mFlingRunnable.startScroll(distance, duration); + } else { + mFlingRunnable.endFling(); } } diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java index 432dd4a..e2d78c0 100644 --- a/core/java/android/widget/StackView.java +++ b/core/java/android/widget/StackView.java @@ -100,6 +100,8 @@ public class StackView extends AdapterViewAnimator { private static final int FRAME_PADDING = 4; + private final Rect mTouchRect = new Rect(); + /** * These variables are all related to the current state of touch interaction * with the stack @@ -531,7 +533,6 @@ public class StackView extends AdapterViewAnimator { return true; } - private final Rect touchRect = new Rect(); private void onSecondaryPointerUp(MotionEvent ev) { final int activePointerIndex = ev.getActionIndex(); final int pointerId = ev.getPointerId(activePointerIndex); @@ -552,8 +553,8 @@ public class StackView extends AdapterViewAnimator { float x = ev.getX(index); float y = ev.getY(index); - touchRect.set(v.getLeft(), v.getTop(), v.getRight(), v.getBottom()); - if (touchRect.contains(Math.round(x), Math.round(y))) { + mTouchRect.set(v.getLeft(), v.getTop(), v.getRight(), v.getBottom()); + if (mTouchRect.contains(Math.round(x), Math.round(y))) { float oldX = ev.getX(activePointerIndex); float oldY = ev.getY(activePointerIndex); @@ -1049,18 +1050,23 @@ public class StackView extends AdapterViewAnimator { private static final int RES_OUT = 0; private static final int CLICK_FEEDBACK = 1; private float mDensity; + private BlurMaskFilter mSmallBlurMaskFilter; + private BlurMaskFilter mLargeBlurMaskFilter; + private final Canvas mCanvas = new Canvas(); + private final Canvas mMaskCanvas = new Canvas(); + private final int[] mTmpXY = new int[2]; + private final Matrix mIdentityMatrix = new Matrix(); HolographicHelper(Context context) { - initializePaints(context); - } - - void initializePaints(Context context) { mDensity = context.getResources().getDisplayMetrics().density; mHolographicPaint.setFilterBitmap(true); mHolographicPaint.setMaskFilter(TableMaskFilter.CreateClipTable(0, 30)); mErasePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); mErasePaint.setFilterBitmap(true); + + mSmallBlurMaskFilter = new BlurMaskFilter(2 * mDensity, BlurMaskFilter.Blur.NORMAL); + mLargeBlurMaskFilter = new BlurMaskFilter(4 * mDensity, BlurMaskFilter.Blur.NORMAL); } Bitmap createOutline(View v) { @@ -1070,10 +1076,10 @@ public class StackView extends AdapterViewAnimator { Bitmap createOutline(View v, int type) { if (type == RES_OUT) { mHolographicPaint.setColor(0xff6699ff); - mBlurPaint.setMaskFilter(new BlurMaskFilter(2*mDensity, BlurMaskFilter.Blur.NORMAL)); + mBlurPaint.setMaskFilter(mSmallBlurMaskFilter); } else if (type == CLICK_FEEDBACK) { mHolographicPaint.setColor(0x886699ff); - mBlurPaint.setMaskFilter(new BlurMaskFilter(4*mDensity, BlurMaskFilter.Blur.NORMAL)); + mBlurPaint.setMaskFilter(mLargeBlurMaskFilter); } if (v.getMeasuredWidth() == 0 || v.getMeasuredHeight() == 0) { @@ -1082,7 +1088,7 @@ public class StackView extends AdapterViewAnimator { Bitmap bitmap = Bitmap.createBitmap(v.getMeasuredWidth(), v.getMeasuredHeight(), Bitmap.Config.ARGB_8888); - Canvas canvas = new Canvas(bitmap); + mCanvas.setBitmap(bitmap); float rotationX = v.getRotationX(); float rotation = v.getRotation(); @@ -1090,23 +1096,22 @@ public class StackView extends AdapterViewAnimator { v.setRotationX(0); v.setRotation(0); v.setTranslationY(0); - v.draw(canvas); + v.draw(mCanvas); v.setRotationX(rotationX); v.setRotation(rotation); v.setTranslationY(translationY); - drawOutline(canvas, bitmap); + drawOutline(mCanvas, bitmap); return bitmap; } - final Matrix id = new Matrix(); void drawOutline(Canvas dest, Bitmap src) { - int[] xy = new int[2]; + final int[] xy = mTmpXY; Bitmap mask = src.extractAlpha(mBlurPaint, xy); - Canvas maskCanvas = new Canvas(mask); - maskCanvas.drawBitmap(src, -xy[0], -xy[1], mErasePaint); + mMaskCanvas.setBitmap(mask); + mMaskCanvas.drawBitmap(src, -xy[0], -xy[1], mErasePaint); dest.drawColor(0, PorterDuff.Mode.CLEAR); - dest.setMatrix(id); + dest.setMatrix(mIdentityMatrix); dest.drawBitmap(mask, xy[0], xy[1], mHolographicPaint); mask.recycle(); } diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java index b143325..f32ae92 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -305,6 +305,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener int mTextSelectHandleRes; int mTextEditPasteWindowLayout; int mTextEditNoPasteWindowLayout; + Drawable mEditTextMultilineBackground; + Drawable mEditTextSingleLineBackground; Drawable mSelectHandleLeft; Drawable mSelectHandleRight; @@ -751,6 +753,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener mTextEditNoPasteWindowLayout = a.getResourceId(attr, 0); break; + case com.android.internal.R.styleable.TextView_multilineBackground: + mEditTextMultilineBackground = a.getDrawable(attr); + break; + case com.android.internal.R.styleable.TextView_textLineHeight: int lineHeight = a.getDimensionPixelSize(attr, 0); if (lineHeight != 0) { @@ -765,6 +771,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } a.recycle(); + mEditTextSingleLineBackground = getBackground(); BufferType bufferType = BufferType.EDITABLE; final int variation = @@ -6192,12 +6199,17 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener if (applyTransformation) { setTransformationMethod(SingleLineTransformationMethod.getInstance()); } + setBackgroundDrawable(mEditTextSingleLineBackground); } else { setMaxLines(Integer.MAX_VALUE); setHorizontallyScrolling(false); if (applyTransformation) { setTransformationMethod(null); } + // mEditTextMultilineBackground is defined and used only in EditText + if (mEditTextMultilineBackground != null) { + setBackgroundDrawable(mEditTextMultilineBackground); + } } } @@ -6711,7 +6723,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener + " before=" + before + " after=" + after + ": " + buffer); if (AccessibilityManager.getInstance(mContext).isEnabled() - && !isPasswordInputType(mInputType)) { + && !isPasswordInputType(mInputType) + && !hasPasswordTransformationMethod()) { mBeforeText = buffer.toString(); } @@ -7590,7 +7603,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return false; } - final boolean isPassword = isPasswordInputType(mInputType); + final boolean isPassword = hasPasswordTransformationMethod(); if (!isPassword) { CharSequence text = getText(); diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java index cd1cae6..86523ac 100644 --- a/core/java/com/android/internal/app/ActionBarImpl.java +++ b/core/java/com/android/internal/app/ActionBarImpl.java @@ -212,6 +212,10 @@ public class ActionBarImpl extends ActionBar { } public View getCustomNavigationView() { + return getCustomView(); + } + + public View getCustomView() { return mActionView.getCustomNavigationView(); } diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 1018ddb..e50233e 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -1194,6 +1194,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_text_AndroidBidi), REG_JNI(register_android_text_KeyCharacterMap), REG_JNI(register_android_os_Process), + REG_JNI(register_android_os_SystemProperties), REG_JNI(register_android_os_Binder), REG_JNI(register_android_view_Display), REG_JNI(register_android_nio_utils), @@ -1251,7 +1252,6 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_os_ParcelFileDescriptor), REG_JNI(register_android_os_Power), REG_JNI(register_android_os_StatFs), - REG_JNI(register_android_os_SystemProperties), REG_JNI(register_android_os_UEventObserver), REG_JNI(register_android_net_LocalSocketImpl), REG_JNI(register_android_net_NetworkUtils), diff --git a/core/res/res/drawable-hdpi/textfield_active_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_active_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..a38c03a --- /dev/null +++ b/core/res/res/drawable-hdpi/textfield_active_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/textfield_active_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_active_holo_light.9.png Binary files differnew file mode 100644 index 0000000..6a88a69 --- /dev/null +++ b/core/res/res/drawable-hdpi/textfield_active_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/textfield_default_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_default_holo_dark.9.png Binary files differindex 7ec2192..87d9c21 100644 --- a/core/res/res/drawable-hdpi/textfield_default_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/textfield_default_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/textfield_default_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_default_holo_light.9.png Binary files differindex c03e4f6..720ee78 100644 --- a/core/res/res/drawable-hdpi/textfield_default_holo_light.9.png +++ b/core/res/res/drawable-hdpi/textfield_default_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..4275da0 --- /dev/null +++ b/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_light.9.png Binary files differnew file mode 100644 index 0000000..3ec9c1f --- /dev/null +++ b/core/res/res/drawable-hdpi/textfield_disabled_focused_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/textfield_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_disabled_holo_dark.9.png Binary files differindex 6642717..227bde2 100644 --- a/core/res/res/drawable-hdpi/textfield_disabled_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/textfield_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/textfield_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_disabled_holo_light.9.png Binary files differindex 9572752..6ddfab0 100644 --- a/core/res/res/drawable-hdpi/textfield_disabled_holo_light.9.png +++ b/core/res/res/drawable-hdpi/textfield_disabled_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/textfield_disabled_selected_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_disabled_selected_holo_dark.9.png Binary files differdeleted file mode 100644 index 0ad248c..0000000 --- a/core/res/res/drawable-hdpi/textfield_disabled_selected_holo_dark.9.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/textfield_disabled_selected_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_disabled_selected_holo_light.9.png Binary files differdeleted file mode 100644 index b7a07c4..0000000 --- a/core/res/res/drawable-hdpi/textfield_disabled_selected_holo_light.9.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/textfield_multiline_active_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_multiline_active_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..7528479 --- /dev/null +++ b/core/res/res/drawable-hdpi/textfield_multiline_active_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/textfield_multiline_active_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_multiline_active_holo_light.9.png Binary files differnew file mode 100644 index 0000000..4c7d9e7 --- /dev/null +++ b/core/res/res/drawable-hdpi/textfield_multiline_active_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/textfield_multiline_default_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_multiline_default_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..09ca253 --- /dev/null +++ b/core/res/res/drawable-hdpi/textfield_multiline_default_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/textfield_multiline_default_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_multiline_default_holo_light.9.png Binary files differnew file mode 100644 index 0000000..0a7d3a1 --- /dev/null +++ b/core/res/res/drawable-hdpi/textfield_multiline_default_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..54a1519 --- /dev/null +++ b/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_light.9.png Binary files differnew file mode 100644 index 0000000..06ca0d4 --- /dev/null +++ b/core/res/res/drawable-hdpi/textfield_multiline_disabled_focused_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..9015299 --- /dev/null +++ b/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_light.9.png Binary files differnew file mode 100644 index 0000000..b355cb3 --- /dev/null +++ b/core/res/res/drawable-hdpi/textfield_multiline_disabled_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/textfield_pressed.9.png b/core/res/res/drawable-hdpi/textfield_pressed.9.png Binary files differdeleted file mode 100644 index a42d87f..0000000 --- a/core/res/res/drawable-hdpi/textfield_pressed.9.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/textfield_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_pressed_holo_dark.9.png Binary files differdeleted file mode 100644 index a271ac9..0000000 --- a/core/res/res/drawable-hdpi/textfield_pressed_holo_dark.9.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/textfield_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_pressed_holo_light.9.png Binary files differdeleted file mode 100644 index 521722d..0000000 --- a/core/res/res/drawable-hdpi/textfield_pressed_holo_light.9.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/textfield_selected_holo_dark.9.png b/core/res/res/drawable-hdpi/textfield_selected_holo_dark.9.png Binary files differdeleted file mode 100644 index a271ac9..0000000 --- a/core/res/res/drawable-hdpi/textfield_selected_holo_dark.9.png +++ /dev/null diff --git a/core/res/res/drawable-hdpi/textfield_selected_holo_light.9.png b/core/res/res/drawable-hdpi/textfield_selected_holo_light.9.png Binary files differdeleted file mode 100644 index 521722d..0000000 --- a/core/res/res/drawable-hdpi/textfield_selected_holo_light.9.png +++ /dev/null diff --git a/core/res/res/drawable-ldpi/textfield_pressed.9.png b/core/res/res/drawable-ldpi/textfield_pressed.9.png Binary files differdeleted file mode 100644 index 1433365..0000000 --- a/core/res/res/drawable-ldpi/textfield_pressed.9.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/textfield_active_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_active_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..d37c8b2 --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_active_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/textfield_active_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_active_holo_light.9.png Binary files differnew file mode 100644 index 0000000..16f2197 --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_active_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/textfield_default_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_default_holo_dark.9.png Binary files differindex 3a5f36d..c98c951 100644 --- a/core/res/res/drawable-mdpi/textfield_default_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/textfield_default_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/textfield_default_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_default_holo_light.9.png Binary files differindex b8cc76f..7691f81 100644 --- a/core/res/res/drawable-mdpi/textfield_default_holo_light.9.png +++ b/core/res/res/drawable-mdpi/textfield_default_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/textfield_disabled_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_disabled_focused_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..500ede3 --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_disabled_focused_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/textfield_disabled_focused_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_disabled_focused_holo_light.9.png Binary files differnew file mode 100644 index 0000000..99f7f38 --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_disabled_focused_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/textfield_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_disabled_holo_dark.9.png Binary files differindex a1f0c71..fab86ac 100644 --- a/core/res/res/drawable-mdpi/textfield_disabled_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/textfield_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/textfield_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_disabled_holo_light.9.png Binary files differindex 71e3103..876eb794 100644 --- a/core/res/res/drawable-mdpi/textfield_disabled_holo_light.9.png +++ b/core/res/res/drawable-mdpi/textfield_disabled_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/textfield_disabled_selected_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_disabled_selected_holo_dark.9.png Binary files differdeleted file mode 100644 index ac6d406..0000000 --- a/core/res/res/drawable-mdpi/textfield_disabled_selected_holo_dark.9.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/textfield_disabled_selected_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_disabled_selected_holo_light.9.png Binary files differdeleted file mode 100644 index bb6e953..0000000 --- a/core/res/res/drawable-mdpi/textfield_disabled_selected_holo_light.9.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/textfield_multiline_active_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_multiline_active_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..2646899 --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_multiline_active_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/textfield_multiline_active_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_multiline_active_holo_light.9.png Binary files differnew file mode 100644 index 0000000..374d457 --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_multiline_active_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/textfield_multiline_default_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_multiline_default_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..65c87ba --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_multiline_default_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/textfield_multiline_default_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_multiline_default_holo_light.9.png Binary files differnew file mode 100644 index 0000000..724b3fd --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_multiline_default_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/textfield_multiline_disabled_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_multiline_disabled_focused_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..5f0ad56 --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_multiline_disabled_focused_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/textfield_multiline_disabled_focused_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_multiline_disabled_focused_holo_light.9.png Binary files differnew file mode 100644 index 0000000..df03a15 --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_multiline_disabled_focused_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..2cc7f62 --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_light.9.png Binary files differnew file mode 100644 index 0000000..a2d9d8a --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_multiline_disabled_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/textfield_pressed.9.png b/core/res/res/drawable-mdpi/textfield_pressed.9.png Binary files differdeleted file mode 100644 index c909ad2..0000000 --- a/core/res/res/drawable-mdpi/textfield_pressed.9.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/textfield_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_pressed_holo_dark.9.png Binary files differdeleted file mode 100644 index 7667d95..0000000 --- a/core/res/res/drawable-mdpi/textfield_pressed_holo_dark.9.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/textfield_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_pressed_holo_light.9.png Binary files differdeleted file mode 100644 index 269affd..0000000 --- a/core/res/res/drawable-mdpi/textfield_pressed_holo_light.9.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/textfield_selected_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_selected_holo_dark.9.png Binary files differdeleted file mode 100644 index 7667d95..0000000 --- a/core/res/res/drawable-mdpi/textfield_selected_holo_dark.9.png +++ /dev/null diff --git a/core/res/res/drawable-mdpi/textfield_selected_holo_light.9.png b/core/res/res/drawable-mdpi/textfield_selected_holo_light.9.png Binary files differdeleted file mode 100644 index 269affd..0000000 --- a/core/res/res/drawable-mdpi/textfield_selected_holo_light.9.png +++ /dev/null diff --git a/core/res/res/drawable/edit_text.xml b/core/res/res/drawable/edit_text.xml index 315278d..e9ba84b 100644 --- a/core/res/res/drawable/edit_text.xml +++ b/core/res/res/drawable/edit_text.xml @@ -15,11 +15,8 @@ --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:state_window_focused="false" android:state_enabled="true" - android:drawable="@drawable/textfield_default" /> - <item android:state_window_focused="false" android:state_enabled="false" - android:drawable="@drawable/textfield_disabled" /> - <item android:state_pressed="true" android:drawable="@drawable/textfield_pressed" /> + <item android:state_window_focused="false" android:state_enabled="true" android:drawable="@drawable/textfield_default" /> + <item android:state_window_focused="false" android:state_enabled="false" android:drawable="@drawable/textfield_disabled" /> <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_selected" /> <item android:state_enabled="true" android:drawable="@drawable/textfield_default" /> <item android:state_focused="true" android:drawable="@drawable/textfield_disabled_selected" /> diff --git a/core/res/res/drawable/edit_text_holo_dark.xml b/core/res/res/drawable/edit_text_holo_dark.xml index b7d24ff..63ccd1d 100644 --- a/core/res/res/drawable/edit_text_holo_dark.xml +++ b/core/res/res/drawable/edit_text_holo_dark.xml @@ -15,14 +15,11 @@ --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:state_window_focused="false" android:state_enabled="true" - android:drawable="@drawable/textfield_default_holo_dark" /> - <item android:state_window_focused="false" android:state_enabled="false" - android:drawable="@drawable/textfield_disabled_holo_dark" /> - <item android:state_pressed="true" android:drawable="@drawable/textfield_pressed_holo_dark" /> - <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_selected_holo_dark" /> + <item android:state_window_focused="false" android:state_enabled="true" android:drawable="@drawable/textfield_default_holo_dark" /> + <item android:state_window_focused="false" android:state_enabled="false" android:drawable="@drawable/textfield_disabled_holo_dark" /> + <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_active_holo_dark" /> <item android:state_enabled="true" android:drawable="@drawable/textfield_default_holo_dark" /> - <item android:state_focused="true" android:drawable="@drawable/textfield_disabled_selected_holo_dark" /> + <item android:state_focused="true" android:drawable="@drawable/textfield_disabled_focused_holo_dark" /> <item android:drawable="@drawable/textfield_disabled_holo_dark" /> </selector> diff --git a/core/res/res/drawable/edit_text_holo_light.xml b/core/res/res/drawable/edit_text_holo_light.xml index dae39e3..324acda 100644 --- a/core/res/res/drawable/edit_text_holo_light.xml +++ b/core/res/res/drawable/edit_text_holo_light.xml @@ -15,14 +15,11 @@ --> <selector xmlns:android="http://schemas.android.com/apk/res/android"> - <item android:state_window_focused="false" android:state_enabled="true" - android:drawable="@drawable/textfield_default_holo_light" /> - <item android:state_window_focused="false" android:state_enabled="false" - android:drawable="@drawable/textfield_disabled_holo_light" /> - <item android:state_pressed="true" android:drawable="@drawable/textfield_pressed_holo_light" /> - <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_selected_holo_light" /> + <item android:state_window_focused="false" android:state_enabled="true" android:drawable="@drawable/textfield_default_holo_light" /> + <item android:state_window_focused="false" android:state_enabled="false" android:drawable="@drawable/textfield_disabled_holo_light" /> + <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_active_holo_light" /> <item android:state_enabled="true" android:drawable="@drawable/textfield_default_holo_light" /> - <item android:state_focused="true" android:drawable="@drawable/textfield_disabled_selected_holo_light" /> + <item android:state_focused="true" android:drawable="@drawable/textfield_disabled_focused_holo_light" /> <item android:drawable="@drawable/textfield_disabled_holo_light" /> </selector> diff --git a/core/res/res/drawable/edit_text_multiline_holo_dark.xml b/core/res/res/drawable/edit_text_multiline_holo_dark.xml new file mode 100644 index 0000000..67d2748 --- /dev/null +++ b/core/res/res/drawable/edit_text_multiline_holo_dark.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_window_focused="false" android:state_enabled="true" android:drawable="@drawable/textfield_multiline_default_holo_dark" /> + <item android:state_window_focused="false" android:state_enabled="false" android:drawable="@drawable/textfield_multiline_disabled_holo_dark" /> + <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_multiline_active_holo_dark" /> + <item android:state_enabled="true" android:drawable="@drawable/textfield_multiline_default_holo_dark" /> + <item android:state_focused="true" android:drawable="@drawable/textfield_multiline_disabled_focused_holo_dark" /> + <item android:drawable="@drawable/textfield_multiline_disabled_holo_dark" /> +</selector> diff --git a/core/res/res/drawable/edit_text_multiline_holo_light.xml b/core/res/res/drawable/edit_text_multiline_holo_light.xml new file mode 100644 index 0000000..08b3ec6 --- /dev/null +++ b/core/res/res/drawable/edit_text_multiline_holo_light.xml @@ -0,0 +1,24 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_window_focused="false" android:state_enabled="true" android:drawable="@drawable/textfield_multiline_default_holo_light" /> + <item android:state_window_focused="false" android:state_enabled="false" android:drawable="@drawable/textfield_multiline_disabled_holo_light" /> + <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_multiline_active_holo_light" /> + <item android:state_enabled="true" android:drawable="@drawable/textfield_multiline_default_holo_light" /> + <item android:state_focused="true" android:drawable="@drawable/textfield_multiline_disabled_focused_holo_light" /> + <item android:drawable="@drawable/textfield_multiline_disabled_holo_light" /> +</selector> diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 0b61202..55b3258 100755 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -142,6 +142,8 @@ <attr name="editTextColor" format="reference|color" /> <!-- EditText background drawable. --> <attr name="editTextBackground" format="reference" /> + <!-- EditText background drawable for multiline EditText. --> + <attr name="editTextMultilineBackground" format="reference" /> <!-- A styled string, specifying the style to be used for showing inline candidate text when composing with an input method. The @@ -2508,7 +2510,8 @@ <attr name="textLineHeight" /> <!-- Indicates that a non-editable text can be selected. --> <attr name="textIsSelectable" /> - + <!-- A specific background drawable used by multi-line EditText only. --> + <attr name="multilineBackground" format="reference"/> </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/styles.xml b/core/res/res/values/styles.xml index b2db9b4..dc67f45 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -422,6 +422,7 @@ <item name="android:focusableInTouchMode">true</item> <item name="android:clickable">true</item> <item name="android:background">?android:attr/editTextBackground</item> + <item name="android:multilineBackground">?android:attr/editTextMultilineBackground</item> <item name="android:textAppearance">?android:attr/textAppearanceMediumInverse</item> <item name="android:textColor">?android:attr/editTextColor</item> <item name="android:gravity">center_vertical</item> diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml index 88e755f..dd7c8e48 100644 --- a/core/res/res/values/themes.xml +++ b/core/res/res/values/themes.xml @@ -72,6 +72,7 @@ <item name="editTextColor">?android:attr/textColorPrimaryInverse</item> <item name="editTextBackground">@android:drawable/edit_text</item> + <item name="editTextMultilineBackground">@android:drawable/edit_text</item> <item name="candidatesTextStyleSpans">@android:string/candidates_style</item> @@ -685,6 +686,7 @@ <item name="editTextColor">?android:attr/textColorPrimary</item> <item name="editTextBackground">@android:drawable/edit_text_holo_dark</item> + <item name="editTextMultilineBackground">@android:drawable/edit_text_multiline_holo_dark</item> <item name="candidatesTextStyleSpans">@android:string/candidates_style</item> @@ -917,10 +919,11 @@ <item name="textAppearanceSearchResultSubtitle">@android:style/TextAppearance.Holo.Light.SearchResult.Subtitle</item> <item name="textAppearanceButton">@android:style/TextAppearance.Holo.Light.Widget.Button</item> - + <item name="editTextColor">?android:attr/textColorPrimary</item> <item name="editTextBackground">@android:drawable/edit_text_holo_light</item> - + <item name="editTextMultilineBackground">@android:drawable/edit_text_multiline_holo_light</item> + <item name="candidatesTextStyleSpans">@android:string/candidates_style</item> <item name="textCheckMark">@android:drawable/indicator_check_mark_light</item> diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java index 9dc291b..0de53f2 100644 --- a/graphics/java/android/renderscript/Allocation.java +++ b/graphics/java/android/renderscript/Allocation.java @@ -352,7 +352,7 @@ public class Allocation extends BaseObj { if (bc == Bitmap.Config.RGB_565) { return Element.RGB_565(rs); } - throw new RSInvalidStateException("Bad bitmap type."); + throw new RSInvalidStateException("Bad bitmap type: " + bc); } static private Type typeFromBitmap(RenderScript rs, Bitmap b) { diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h index 3d77278..bba7ed7 100644 --- a/include/media/IMediaPlayer.h +++ b/include/media/IMediaPlayer.h @@ -34,7 +34,6 @@ public: virtual void disconnect() = 0; - virtual status_t setVideoISurface(const sp<ISurface>& surface) = 0; virtual status_t setVideoSurface(const sp<Surface>& surface) = 0; virtual status_t prepareAsync() = 0; virtual status_t start() = 0; diff --git a/include/media/IOMX.h b/include/media/IOMX.h index fa775e7..cb36bbb 100644 --- a/include/media/IOMX.h +++ b/include/media/IOMX.h @@ -120,30 +120,6 @@ public: node_id node, const char *parameter_name, OMX_INDEXTYPE *index) = 0; - - virtual sp<IOMXRenderer> createRenderer( - const sp<ISurface> &surface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t encodedWidth, size_t encodedHeight, - size_t displayWidth, size_t displayHeight) = 0; - - // Note: These methods are _not_ virtual, it exists as a wrapper around - // the virtual "createRenderer" method above facilitating extraction - // of the ISurface from a regular Surface or a java Surface object. - sp<IOMXRenderer> createRenderer( - const sp<Surface> &surface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t encodedWidth, size_t encodedHeight, - size_t displayWidth, size_t displayHeight); - - sp<IOMXRenderer> createRendererFromJavaSurface( - JNIEnv *env, jobject javaSurface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t encodedWidth, size_t encodedHeight, - size_t displayWidth, size_t displayHeight); }; struct omx_message { @@ -190,13 +166,6 @@ public: virtual void onMessage(const omx_message &msg) = 0; }; -class IOMXRenderer : public IInterface { -public: - DECLARE_META_INTERFACE(OMXRenderer); - - virtual void render(IOMX::buffer_id buffer) = 0; -}; - //////////////////////////////////////////////////////////////////////////////// class BnOMX : public BnInterface<IOMX> { @@ -213,13 +182,6 @@ public: uint32_t flags = 0); }; -class BnOMXRenderer : public BnInterface<IOMXRenderer> { -public: - virtual status_t onTransact( - uint32_t code, const Parcel &data, Parcel *reply, - uint32_t flags = 0); -}; - } // namespace android #endif // ANDROID_IOMX_H_ diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h index 2d55a55..672931e 100644 --- a/include/media/MediaPlayerInterface.h +++ b/include/media/MediaPlayerInterface.h @@ -106,7 +106,6 @@ public: const KeyedVector<String8, String8> *headers = NULL) = 0; virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0; - virtual status_t setVideoISurface(const sp<ISurface>& surface) = 0; virtual status_t setVideoSurface(const sp<Surface>& surface) = 0; virtual status_t prepare() = 0; virtual status_t prepareAsync() = 0; diff --git a/include/media/stagefright/HardwareAPI.h b/include/media/stagefright/HardwareAPI.h index 4fd281b..17908b4 100644 --- a/include/media/stagefright/HardwareAPI.h +++ b/include/media/stagefright/HardwareAPI.h @@ -19,8 +19,6 @@ #define HARDWARE_API_H_ #include <media/stagefright/OMXPluginBase.h> -#include <media/stagefright/VideoRenderer.h> -#include <surfaceflinger/ISurface.h> #include <ui/android_native_buffer.h> #include <utils/RefBase.h> @@ -91,13 +89,6 @@ struct UseAndroidNativeBufferParams { } // namespace android -extern android::VideoRenderer *createRenderer( - const android::sp<android::ISurface> &surface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t displayWidth, size_t displayHeight, - size_t decodedWidth, size_t decodedHeight); - extern android::OMXPluginBase *createOMXPlugin(); #endif // HARDWARE_API_H_ diff --git a/include/media/stagefright/VideoRenderer.h b/include/media/stagefright/VideoRenderer.h deleted file mode 100644 index f80b277..0000000 --- a/include/media/stagefright/VideoRenderer.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef VIDEO_RENDERER_H_ - -#define VIDEO_RENDERER_H_ - -#include <sys/types.h> - -namespace android { - -class VideoRenderer { -public: - virtual ~VideoRenderer() {} - - virtual void render( - const void *data, size_t size, void *platformPrivate) = 0; - -protected: - VideoRenderer() {} - - VideoRenderer(const VideoRenderer &); - VideoRenderer &operator=(const VideoRenderer &); -}; - -} // namespace android - -#endif // VIDEO_RENDERER_H_ diff --git a/media/java/android/media/videoeditor/Effect.java b/media/java/android/media/videoeditor/Effect.java index ef0aeb1..8fd0d27 100755 --- a/media/java/android/media/videoeditor/Effect.java +++ b/media/java/android/media/videoeditor/Effect.java @@ -76,7 +76,7 @@ public abstract class Effect { /**
* Set the duration of the effect. If a preview or export is in progress,
- * then this change is effective for next preview or export session. s
+ * then this change is effective for next preview or export session.
*
* @param durationMs of the effect in milliseconds
*/
@@ -85,9 +85,10 @@ public abstract class Effect { throw new IllegalArgumentException("Duration is too large");
}
+ final long oldDurationMs = mDurationMs;
mDurationMs = durationMs;
- mMediaItem.invalidateTransitions(mStartTimeMs, mDurationMs);
+ mMediaItem.invalidateTransitions(mStartTimeMs, oldDurationMs, mStartTimeMs, mDurationMs);
}
/**
@@ -111,9 +112,10 @@ public abstract class Effect { throw new IllegalArgumentException("Start time is too large");
}
+ final long oldStartTimeMs = mStartTimeMs;
mStartTimeMs = startTimeMs;
- mMediaItem.invalidateTransitions(mStartTimeMs, mDurationMs);
+ mMediaItem.invalidateTransitions(oldStartTimeMs, mDurationMs, mStartTimeMs, mDurationMs);
}
/**
@@ -134,10 +136,13 @@ public abstract class Effect { throw new IllegalArgumentException("Invalid start time or duration");
}
+ final long oldStartTimeMs = mStartTimeMs;
+ final long oldDurationMs = mDurationMs;
+
mStartTimeMs = startTimeMs;
mDurationMs = durationMs;
- mMediaItem.invalidateTransitions(mStartTimeMs, mDurationMs);
+ mMediaItem.invalidateTransitions(oldStartTimeMs, oldDurationMs, mStartTimeMs, mDurationMs);
}
/**
diff --git a/media/java/android/media/videoeditor/MediaImageItem.java b/media/java/android/media/videoeditor/MediaImageItem.java index a4b0770..fa8d61b 100755 --- a/media/java/android/media/videoeditor/MediaImageItem.java +++ b/media/java/android/media/videoeditor/MediaImageItem.java @@ -242,15 +242,49 @@ public class MediaImageItem extends MediaItem { */
@Override
void invalidateTransitions(long startTimeMs, long durationMs) {
- // Check if the effect overlaps with the beginning and end transitions
+ // Check if the item overlaps with the beginning and end transitions
if (mBeginTransition != null) {
- if (startTimeMs < mBeginTransition.getDuration()) {
+ if (isOverlapping(startTimeMs, durationMs, 0, mBeginTransition.getDuration())) {
mBeginTransition.invalidate();
}
}
if (mEndTransition != null) {
- if (startTimeMs + durationMs > mDurationMs - mEndTransition.getDuration()) {
+ final long transitionDurationMs = mEndTransition.getDuration();
+ if (isOverlapping(startTimeMs, durationMs,
+ getDuration() - transitionDurationMs, transitionDurationMs)) {
+ mEndTransition.invalidate();
+ }
+ }
+ }
+
+ /*
+ * {@inheritDoc}
+ */
+ @Override
+ void invalidateTransitions(long oldStartTimeMs, long oldDurationMs, long newStartTimeMs,
+ long newDurationMs) {
+ // Check if the item overlaps with the beginning and end transitions
+ if (mBeginTransition != null) {
+ final long transitionDurationMs = mBeginTransition.getDuration();
+ // If the start time has changed and if the old or the new item
+ // overlaps with the begin transition, invalidate the transition.
+ if (oldStartTimeMs != newStartTimeMs &&
+ (isOverlapping(oldStartTimeMs, oldDurationMs, 0, transitionDurationMs) ||
+ isOverlapping(newStartTimeMs, newDurationMs, 0, transitionDurationMs))) {
+ mBeginTransition.invalidate();
+ }
+ }
+
+ if (mEndTransition != null) {
+ final long transitionDurationMs = mEndTransition.getDuration();
+ // If the start time + duration has changed and if the old or the new
+ // item overlaps the end transition, invalidate the transition/
+ if (oldStartTimeMs + oldDurationMs != newStartTimeMs + newDurationMs &&
+ (isOverlapping(oldStartTimeMs, oldDurationMs,
+ mDurationMs - transitionDurationMs, transitionDurationMs) ||
+ isOverlapping(newStartTimeMs, newDurationMs,
+ mDurationMs - transitionDurationMs, transitionDurationMs))) {
mEndTransition.invalidate();
}
}
diff --git a/media/java/android/media/videoeditor/MediaItem.java b/media/java/android/media/videoeditor/MediaItem.java index 12f6084..20fd6c9 100755 --- a/media/java/android/media/videoeditor/MediaItem.java +++ b/media/java/android/media/videoeditor/MediaItem.java @@ -455,6 +455,40 @@ public abstract class MediaItem { abstract void invalidateTransitions(long startTimeMs, long durationMs);
/**
+ * Invalidate the start and end transitions if necessary. This method is
+ * typically called when the start time and/or duration of an overlay or
+ * effect is changing.
+ *
+ * @param oldStartTimeMs The old start time of the effect or overlay
+ * @param oldDurationMs The old duration of the effect or overlay
+ * @param newStartTimeMs The new start time of the effect or overlay
+ * @param newDurationMs The new duration of the effect or overlay
+ */
+ abstract void invalidateTransitions(long oldStartTimeMs, long oldDurationMs,
+ long newStartTimeMs, long newDurationMs);
+
+ /**
+ * Check if two items overlap in time
+ *
+ * @param startTimeMs1 Item 1 start time
+ * @param durationMs1 Item 1 duration
+ * @param startTimeMs2 Item 2 start time
+ * @param durationMs2 Item 2 end time
+ *
+ * @return true if the two items overlap
+ */
+ protected boolean isOverlapping(long startTimeMs1, long durationMs1,
+ long startTimeMs2, long durationMs2) {
+ if (startTimeMs1 + durationMs1 <= startTimeMs2) {
+ return false;
+ } else if (startTimeMs1 >= startTimeMs2 + durationMs2) {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
* Adjust the duration transitions.
*/
protected void adjustTransitions() {
diff --git a/media/java/android/media/videoeditor/MediaVideoItem.java b/media/java/android/media/videoeditor/MediaVideoItem.java index 745b00a..cb835b5 100755 --- a/media/java/android/media/videoeditor/MediaVideoItem.java +++ b/media/java/android/media/videoeditor/MediaVideoItem.java @@ -218,15 +218,52 @@ public class MediaVideoItem extends MediaItem { */
@Override
void invalidateTransitions(long startTimeMs, long durationMs) {
- // Check if the effect overlaps with the beginning and end transitions
+ // Check if the item overlaps with the beginning and end transitions
if (mBeginTransition != null) {
- if (startTimeMs < mBeginTransition.getDuration()) {
+ if (isOverlapping(startTimeMs, durationMs,
+ mBeginBoundaryTimeMs, mBeginTransition.getDuration())) {
mBeginTransition.invalidate();
}
}
if (mEndTransition != null) {
- if (startTimeMs + durationMs > mEndBoundaryTimeMs - mEndTransition.getDuration()) {
+ final long transitionDurationMs = mEndTransition.getDuration();
+ if (isOverlapping(startTimeMs, durationMs,
+ mEndBoundaryTimeMs - transitionDurationMs, transitionDurationMs)) {
+ mEndTransition.invalidate();
+ }
+ }
+ }
+
+ /*
+ * {@inheritDoc}
+ */
+ @Override
+ void invalidateTransitions(long oldStartTimeMs, long oldDurationMs, long newStartTimeMs,
+ long newDurationMs) {
+ // Check if the item overlaps with the beginning and end transitions
+ if (mBeginTransition != null) {
+ final long transitionDurationMs = mBeginTransition.getDuration();
+ // If the start time has changed and if the old or the new item
+ // overlaps with the begin transition, invalidate the transition.
+ if (oldStartTimeMs != newStartTimeMs &&
+ (isOverlapping(oldStartTimeMs, oldDurationMs,
+ mBeginBoundaryTimeMs, transitionDurationMs) ||
+ isOverlapping(newStartTimeMs, newDurationMs,
+ mBeginBoundaryTimeMs, transitionDurationMs))) {
+ mBeginTransition.invalidate();
+ }
+ }
+
+ if (mEndTransition != null) {
+ final long transitionDurationMs = mEndTransition.getDuration();
+ // If the start time + duration has changed and if the old or the new
+ // item overlaps the end transition, invalidate the transition/
+ if (oldStartTimeMs + oldDurationMs != newStartTimeMs + newDurationMs &&
+ (isOverlapping(oldStartTimeMs, oldDurationMs,
+ mEndBoundaryTimeMs - transitionDurationMs, transitionDurationMs) ||
+ isOverlapping(newStartTimeMs, newDurationMs,
+ mEndBoundaryTimeMs - transitionDurationMs, transitionDurationMs))) {
mEndTransition.invalidate();
}
}
diff --git a/media/java/android/media/videoeditor/Overlay.java b/media/java/android/media/videoeditor/Overlay.java index e43f229..0174ba8 100755 --- a/media/java/android/media/videoeditor/Overlay.java +++ b/media/java/android/media/videoeditor/Overlay.java @@ -96,9 +96,10 @@ public abstract class Overlay { throw new IllegalArgumentException("Duration is too large");
}
+ final long oldDurationMs = mDurationMs;
mDurationMs = durationMs;
- mMediaItem.invalidateTransitions(mStartTimeMs, mDurationMs);
+ mMediaItem.invalidateTransitions(mStartTimeMs, oldDurationMs, mStartTimeMs, mDurationMs);
}
/**
@@ -120,9 +121,10 @@ public abstract class Overlay { throw new IllegalArgumentException("Start time is too large");
}
+ final long oldStartTimeMs = mStartTimeMs;
mStartTimeMs = startTimeMs;
- mMediaItem.invalidateTransitions(mStartTimeMs, mDurationMs);
+ mMediaItem.invalidateTransitions(oldStartTimeMs, mDurationMs, mStartTimeMs, mDurationMs);
}
/**
@@ -136,10 +138,13 @@ public abstract class Overlay { throw new IllegalArgumentException("Invalid start time or duration");
}
+ final long oldStartTimeMs = mStartTimeMs;
+ final long oldDurationMs = mDurationMs;
+
mStartTimeMs = startTimeMs;
mDurationMs = durationMs;
- mMediaItem.invalidateTransitions(mStartTimeMs, mDurationMs);
+ mMediaItem.invalidateTransitions(oldStartTimeMs, oldDurationMs, mStartTimeMs, mDurationMs);
}
/**
diff --git a/media/java/android/media/videoeditor/WaveformData.java b/media/java/android/media/videoeditor/WaveformData.java index b53bd7d..5791046 100644 --- a/media/java/android/media/videoeditor/WaveformData.java +++ b/media/java/android/media/videoeditor/WaveformData.java @@ -16,6 +16,8 @@ package android.media.videoeditor; +import java.io.IOException; + /** * Class which describes the waveform data of an audio track. The gain values * represent the average gain for an audio frame. For audio codecs which do @@ -33,7 +35,7 @@ public class WaveformData { * This constructor shall not be used */ @SuppressWarnings("unused") - private WaveformData() { + private WaveformData() throws IOException { mFrameDurationMs = 0; mFramesCount = 0; mGains = null; diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp index 1a46715..c287c0a 100644 --- a/media/libmedia/IMediaPlayer.cpp +++ b/media/libmedia/IMediaPlayer.cpp @@ -29,7 +29,6 @@ namespace android { enum { DISCONNECT = IBinder::FIRST_CALL_TRANSACTION, SET_VIDEO_SURFACE, - SET_VIDEO_ISURFACE, PREPARE_ASYNC, START, STOP, @@ -65,15 +64,6 @@ public: remote()->transact(DISCONNECT, data, &reply); } - status_t setVideoISurface(const sp<ISurface>& surface) - { - Parcel data, reply; - data.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor()); - data.writeStrongBinder(surface->asBinder()); - remote()->transact(SET_VIDEO_ISURFACE, data, &reply); - return reply.readInt32(); - } - status_t setVideoSurface(const sp<Surface>& surface) { Parcel data, reply; @@ -245,12 +235,6 @@ status_t BnMediaPlayer::onTransact( disconnect(); return NO_ERROR; } break; - case SET_VIDEO_ISURFACE: { - CHECK_INTERFACE(IMediaPlayer, data, reply); - sp<ISurface> surface = interface_cast<ISurface>(data.readStrongBinder()); - reply->writeInt32(setVideoISurface(surface)); - return NO_ERROR; - } break; case SET_VIDEO_SURFACE: { CHECK_INTERFACE(IMediaPlayer, data, reply); sp<Surface> surface = Surface::readFromParcel(data); diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp index f975217..9ce6738 100644 --- a/media/libmedia/IOMX.cpp +++ b/media/libmedia/IOMX.cpp @@ -31,48 +31,9 @@ enum { FILL_BUFFER, EMPTY_BUFFER, GET_EXTENSION_INDEX, - CREATE_RENDERER, OBSERVER_ON_MSG, - RENDERER_RENDER, }; -sp<IOMXRenderer> IOMX::createRenderer( - const sp<Surface> &surface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t encodedWidth, size_t encodedHeight, - size_t displayWidth, size_t displayHeight) { - return createRenderer( - surface->getISurface(), - componentName, colorFormat, encodedWidth, encodedHeight, - displayWidth, displayHeight); -} - -sp<IOMXRenderer> IOMX::createRendererFromJavaSurface( - JNIEnv *env, jobject javaSurface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t encodedWidth, size_t encodedHeight, - size_t displayWidth, size_t displayHeight) { - jclass surfaceClass = env->FindClass("android/view/Surface"); - if (surfaceClass == NULL) { - LOGE("Can't find android/view/Surface"); - return NULL; - } - - jfieldID surfaceID = env->GetFieldID(surfaceClass, ANDROID_VIEW_SURFACE_JNI_ID, "I"); - if (surfaceID == NULL) { - LOGE("Can't find Surface.mSurface"); - return NULL; - } - - sp<Surface> surface = (Surface *)env->GetIntField(javaSurface, surfaceID); - - return createRenderer( - surface, componentName, colorFormat, encodedWidth, - encodedHeight, displayWidth, displayHeight); -} - class BpOMX : public BpInterface<IOMX> { public: BpOMX(const sp<IBinder> &impl) @@ -395,28 +356,6 @@ public: return err; } - - virtual sp<IOMXRenderer> createRenderer( - const sp<ISurface> &surface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t encodedWidth, size_t encodedHeight, - size_t displayWidth, size_t displayHeight) { - Parcel data, reply; - data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); - - data.writeStrongBinder(surface->asBinder()); - data.writeCString(componentName); - data.writeInt32(colorFormat); - data.writeInt32(encodedWidth); - data.writeInt32(encodedHeight); - data.writeInt32(displayWidth); - data.writeInt32(displayHeight); - - remote()->transact(CREATE_RENDERER, data, &reply); - - return interface_cast<IOMXRenderer>(reply.readStrongBinder()); - } }; IMPLEMENT_META_INTERFACE(OMX, "android.hardware.IOMX"); @@ -767,33 +706,6 @@ status_t BnOMX::onTransact( return OK; } - case CREATE_RENDERER: - { - CHECK_INTERFACE(IOMX, data, reply); - - sp<ISurface> isurface = - interface_cast<ISurface>(data.readStrongBinder()); - - const char *componentName = data.readCString(); - - OMX_COLOR_FORMATTYPE colorFormat = - static_cast<OMX_COLOR_FORMATTYPE>(data.readInt32()); - - size_t encodedWidth = (size_t)data.readInt32(); - size_t encodedHeight = (size_t)data.readInt32(); - size_t displayWidth = (size_t)data.readInt32(); - size_t displayHeight = (size_t)data.readInt32(); - - sp<IOMXRenderer> renderer = - createRenderer(isurface, componentName, colorFormat, - encodedWidth, encodedHeight, - displayWidth, displayHeight); - - reply->writeStrongBinder(renderer->asBinder()); - - return OK; - } - default: return BBinder::onTransact(code, data, reply, flags); } @@ -839,44 +751,4 @@ status_t BnOMXObserver::onTransact( } } -//////////////////////////////////////////////////////////////////////////////// - -class BpOMXRenderer : public BpInterface<IOMXRenderer> { -public: - BpOMXRenderer(const sp<IBinder> &impl) - : BpInterface<IOMXRenderer>(impl) { - } - - virtual void render(IOMX::buffer_id buffer) { - Parcel data, reply; - data.writeInterfaceToken(IOMXRenderer::getInterfaceDescriptor()); - data.writeIntPtr((intptr_t)buffer); - - // NOTE: Do NOT make this a ONE_WAY call, it must be synchronous - // so that the caller knows when to recycle the buffer. - remote()->transact(RENDERER_RENDER, data, &reply); - } -}; - -IMPLEMENT_META_INTERFACE(OMXRenderer, "android.hardware.IOMXRenderer"); - -status_t BnOMXRenderer::onTransact( - uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) { - switch (code) { - case RENDERER_RENDER: - { - CHECK_INTERFACE(IOMXRenderer, data, reply); - - IOMX::buffer_id buffer = (void*)data.readIntPtr(); - - render(buffer); - - return NO_ERROR; - } - - default: - return BBinder::onTransact(code, data, reply, flags); - } -} - } // namespace android diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp index 34e41a1..54b292c 100644 --- a/media/libmedia/mediaplayer.cpp +++ b/media/libmedia/mediaplayer.cpp @@ -198,13 +198,6 @@ status_t MediaPlayer::setVideoSurface(const sp<Surface>& surface) Mutex::Autolock _l(mLock); if (mPlayer == 0) return NO_INIT; - status_t err = mPlayer->setVideoISurface( - surface == NULL ? NULL : surface->getISurface()); - - if (err != OK) { - return err; - } - return mPlayer->setVideoSurface(surface); } diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp index e84c2dc..00e510b 100644 --- a/media/libmediaplayerservice/MediaPlayerService.cpp +++ b/media/libmediaplayerservice/MediaPlayerService.cpp @@ -864,14 +864,6 @@ status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64 return mStatus; } -status_t MediaPlayerService::Client::setVideoISurface(const sp<ISurface>& surface) -{ - LOGV("[%d] setVideoISurface(%p)", mConnId, surface.get()); - sp<MediaPlayerBase> p = getPlayer(); - if (p == 0) return UNKNOWN_ERROR; - return p->setVideoISurface(surface); -} - status_t MediaPlayerService::Client::setVideoSurface(const sp<Surface>& surface) { LOGV("[%d] setVideoSurface(%p)", mConnId, surface.get()); diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h index e197cde..184324c 100644 --- a/media/libmediaplayerservice/MediaPlayerService.h +++ b/media/libmediaplayerservice/MediaPlayerService.h @@ -206,7 +206,6 @@ private: // IMediaPlayer interface virtual void disconnect(); - virtual status_t setVideoISurface(const sp<ISurface>& surface); virtual status_t setVideoSurface(const sp<Surface>& surface); virtual status_t prepareAsync(); virtual status_t start(); diff --git a/media/libmediaplayerservice/MidiFile.h b/media/libmediaplayerservice/MidiFile.h index 06e4b70..aa8f3f0 100644 --- a/media/libmediaplayerservice/MidiFile.h +++ b/media/libmediaplayerservice/MidiFile.h @@ -35,7 +35,6 @@ public: const char* path, const KeyedVector<String8, String8> *headers); virtual status_t setDataSource(int fd, int64_t offset, int64_t length); - virtual status_t setVideoISurface(const sp<ISurface>& surface) { return UNKNOWN_ERROR; } virtual status_t setVideoSurface(const sp<Surface>& surface) { return UNKNOWN_ERROR; } virtual status_t prepare(); virtual status_t prepareAsync(); diff --git a/media/libmediaplayerservice/StagefrightPlayer.cpp b/media/libmediaplayerservice/StagefrightPlayer.cpp index e0957f6..58ef99b 100644 --- a/media/libmediaplayerservice/StagefrightPlayer.cpp +++ b/media/libmediaplayerservice/StagefrightPlayer.cpp @@ -44,13 +44,6 @@ status_t StagefrightPlayer::setDataSource(int fd, int64_t offset, int64_t length return mPlayer->setDataSource(dup(fd), offset, length); } -status_t StagefrightPlayer::setVideoISurface(const sp<ISurface> &surface) { - LOGV("setVideoISurface"); - - mPlayer->setISurface(surface); - return OK; -} - status_t StagefrightPlayer::setVideoSurface(const sp<Surface> &surface) { LOGV("setVideoSurface"); diff --git a/media/libmediaplayerservice/StagefrightPlayer.h b/media/libmediaplayerservice/StagefrightPlayer.h index 3899447..c4a2588 100644 --- a/media/libmediaplayerservice/StagefrightPlayer.h +++ b/media/libmediaplayerservice/StagefrightPlayer.h @@ -35,7 +35,6 @@ public: const char *url, const KeyedVector<String8, String8> *headers); virtual status_t setDataSource(int fd, int64_t offset, int64_t length); - virtual status_t setVideoISurface(const sp<ISurface> &surface); virtual status_t setVideoSurface(const sp<Surface> &surface); virtual status_t prepare(); virtual status_t prepareAsync(); diff --git a/media/libmediaplayerservice/TestPlayerStub.h b/media/libmediaplayerservice/TestPlayerStub.h index 5eaf592..6abd8e3 100644 --- a/media/libmediaplayerservice/TestPlayerStub.h +++ b/media/libmediaplayerservice/TestPlayerStub.h @@ -75,9 +75,6 @@ class TestPlayerStub : public MediaPlayerInterface { // All the methods below wrap the mPlayer instance. - virtual status_t setVideoISurface(const android::sp<android::ISurface>& s) { - return mPlayer->setVideoISurface(s); - } virtual status_t setVideoSurface(const android::sp<android::Surface>& s) { return mPlayer->setVideoSurface(s); } diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index 41f5f30..538e7bf 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -79,39 +79,18 @@ private: AwesomeEvent &operator=(const AwesomeEvent &); }; -struct AwesomeRemoteRenderer : public AwesomeRenderer { - AwesomeRemoteRenderer(const sp<IOMXRenderer> &target) - : mTarget(target) { - } - - virtual void render(MediaBuffer *buffer) { - void *id; - if (buffer->meta_data()->findPointer(kKeyBufferID, &id)) { - mTarget->render((IOMX::buffer_id)id); - } - } - -private: - sp<IOMXRenderer> mTarget; - - AwesomeRemoteRenderer(const AwesomeRemoteRenderer &); - AwesomeRemoteRenderer &operator=(const AwesomeRemoteRenderer &); -}; - struct AwesomeLocalRenderer : public AwesomeRenderer { AwesomeLocalRenderer( - bool previewOnly, - const char *componentName, OMX_COLOR_FORMATTYPE colorFormat, - const sp<ISurface> &isurface, const sp<Surface> &surface, size_t displayWidth, size_t displayHeight, - size_t decodedWidth, size_t decodedHeight) - : mTarget(NULL), - mLibHandle(NULL) { - init(previewOnly, componentName, - colorFormat, isurface, surface, displayWidth, - displayHeight, decodedWidth, decodedHeight); + size_t decodedWidth, size_t decodedHeight, + int32_t rotationDegrees) + : mTarget(NULL) { + init(colorFormat, surface, + displayWidth, displayHeight, + decodedWidth, decodedHeight, + rotationDegrees); } virtual void render(MediaBuffer *buffer) { @@ -127,78 +106,39 @@ protected: virtual ~AwesomeLocalRenderer() { delete mTarget; mTarget = NULL; - - if (mLibHandle) { - dlclose(mLibHandle); - mLibHandle = NULL; - } } private: - VideoRenderer *mTarget; - void *mLibHandle; + SoftwareRenderer *mTarget; void init( - bool previewOnly, - const char *componentName, OMX_COLOR_FORMATTYPE colorFormat, - const sp<ISurface> &isurface, const sp<Surface> &surface, size_t displayWidth, size_t displayHeight, - size_t decodedWidth, size_t decodedHeight); + size_t decodedWidth, size_t decodedHeight, + int32_t rotationDegrees); AwesomeLocalRenderer(const AwesomeLocalRenderer &); AwesomeLocalRenderer &operator=(const AwesomeLocalRenderer &);; }; void AwesomeLocalRenderer::init( - bool previewOnly, - const char *componentName, OMX_COLOR_FORMATTYPE colorFormat, - const sp<ISurface> &isurface, const sp<Surface> &surface, size_t displayWidth, size_t displayHeight, - size_t decodedWidth, size_t decodedHeight) { - if (!previewOnly) { - // We will stick to the vanilla software-color-converting renderer - // for "previewOnly" mode, to avoid unneccessarily switching overlays - // more often than necessary. - - mLibHandle = dlopen("libstagefrighthw.so", RTLD_NOW); - - if (mLibHandle) { - typedef VideoRenderer *(*CreateRendererFunc)( - const sp<ISurface> &surface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t displayWidth, size_t displayHeight, - size_t decodedWidth, size_t decodedHeight); - - CreateRendererFunc func = - (CreateRendererFunc)dlsym( - mLibHandle, - "_Z14createRendererRKN7android2spINS_8ISurfaceEEEPKc20" - "OMX_COLOR_FORMATTYPEjjjj"); - - if (func) { - mTarget = - (*func)(isurface, componentName, colorFormat, - displayWidth, displayHeight, - decodedWidth, decodedHeight); - } - } - } - - if (mTarget == NULL) { - mTarget = new SoftwareRenderer( - colorFormat, surface, displayWidth, displayHeight, - decodedWidth, decodedHeight); - } + size_t decodedWidth, size_t decodedHeight, + int32_t rotationDegrees) { + mTarget = new SoftwareRenderer( + colorFormat, surface, displayWidth, displayHeight, + decodedWidth, decodedHeight, rotationDegrees); } struct AwesomeNativeWindowRenderer : public AwesomeRenderer { - AwesomeNativeWindowRenderer(const sp<ANativeWindow> &nativeWindow) + AwesomeNativeWindowRenderer( + const sp<ANativeWindow> &nativeWindow, + int32_t rotationDegrees) : mNativeWindow(nativeWindow) { + applyRotation(rotationDegrees); } virtual void render(MediaBuffer *buffer) { @@ -220,6 +160,22 @@ protected: private: sp<ANativeWindow> mNativeWindow; + void applyRotation(int32_t rotationDegrees) { + uint32_t transform; + switch (rotationDegrees) { + case 0: transform = 0; break; + case 90: transform = HAL_TRANSFORM_ROT_90; break; + case 180: transform = HAL_TRANSFORM_ROT_180; break; + case 270: transform = HAL_TRANSFORM_ROT_270; break; + default: transform = 0; break; + } + + if (transform) { + CHECK_EQ(0, native_window_set_buffers_transform( + mNativeWindow.get(), transform)); + } + } + AwesomeNativeWindowRenderer(const AwesomeNativeWindowRenderer &); AwesomeNativeWindowRenderer &operator=( const AwesomeNativeWindowRenderer &); @@ -863,58 +819,65 @@ void AwesomePlayer::notifyVideoSize_l() { CHECK(meta->findInt32(kKeyWidth, &decodedWidth)); CHECK(meta->findInt32(kKeyHeight, &decodedHeight)); - notifyListener_l(MEDIA_SET_VIDEO_SIZE, decodedWidth, decodedHeight); + int32_t rotationDegrees; + if (!mVideoTrack->getFormat()->findInt32( + kKeyRotation, &rotationDegrees)) { + rotationDegrees = 0; + } + + if (rotationDegrees == 90 || rotationDegrees == 270) { + notifyListener_l( + MEDIA_SET_VIDEO_SIZE, decodedHeight, decodedWidth); + } else { + notifyListener_l( + MEDIA_SET_VIDEO_SIZE, decodedWidth, decodedHeight); + } } void AwesomePlayer::initRenderer_l() { - if (mSurface != NULL || mISurface != NULL) { - sp<MetaData> meta = mVideoSource->getFormat(); + if (mSurface == NULL) { + return; + } - int32_t format; - const char *component; - int32_t decodedWidth, decodedHeight; - CHECK(meta->findInt32(kKeyColorFormat, &format)); - CHECK(meta->findCString(kKeyDecoderComponent, &component)); - CHECK(meta->findInt32(kKeyWidth, &decodedWidth)); - CHECK(meta->findInt32(kKeyHeight, &decodedHeight)); + sp<MetaData> meta = mVideoSource->getFormat(); - mVideoRenderer.clear(); + int32_t format; + const char *component; + int32_t decodedWidth, decodedHeight; + CHECK(meta->findInt32(kKeyColorFormat, &format)); + CHECK(meta->findCString(kKeyDecoderComponent, &component)); + CHECK(meta->findInt32(kKeyWidth, &decodedWidth)); + CHECK(meta->findInt32(kKeyHeight, &decodedHeight)); - // Must ensure that mVideoRenderer's destructor is actually executed - // before creating a new one. - IPCThreadState::self()->flushCommands(); + int32_t rotationDegrees; + if (!mVideoTrack->getFormat()->findInt32( + kKeyRotation, &rotationDegrees)) { + rotationDegrees = 0; + } - if (mSurface != NULL) { - if (USE_SURFACE_ALLOC && strncmp(component, "OMX.", 4) == 0) { - // Hardware decoders avoid the CPU color conversion by decoding - // directly to ANativeBuffers, so we must use a renderer that - // just pushes those buffers to the ANativeWindow. - mVideoRenderer = new AwesomeNativeWindowRenderer(mSurface); - } else { - // Other decoders are instantiated locally and as a consequence - // allocate their buffers in local address space. This renderer - // then performs a color conversion and copy to get the data - // into the ANativeBuffer. - mVideoRenderer = new AwesomeLocalRenderer( - false, // previewOnly - component, - (OMX_COLOR_FORMATTYPE)format, - mISurface, - mSurface, - mVideoWidth, mVideoHeight, - decodedWidth, decodedHeight); - } - } else { - // Our OMX codecs allocate buffers on the media_server side - // therefore they require a remote IOMXRenderer that knows how - // to display them. - mVideoRenderer = new AwesomeRemoteRenderer( - mClient.interface()->createRenderer( - mISurface, component, - (OMX_COLOR_FORMATTYPE)format, - decodedWidth, decodedHeight, - mVideoWidth, mVideoHeight)); - } + mVideoRenderer.clear(); + + // Must ensure that mVideoRenderer's destructor is actually executed + // before creating a new one. + IPCThreadState::self()->flushCommands(); + + if (USE_SURFACE_ALLOC && strncmp(component, "OMX.", 4) == 0) { + // Hardware decoders avoid the CPU color conversion by decoding + // directly to ANativeBuffers, so we must use a renderer that + // just pushes those buffers to the ANativeWindow. + mVideoRenderer = + new AwesomeNativeWindowRenderer(mSurface, rotationDegrees); + } else { + // Other decoders are instantiated locally and as a consequence + // allocate their buffers in local address space. This renderer + // then performs a color conversion and copy to get the data + // into the ANativeBuffer. + mVideoRenderer = new AwesomeLocalRenderer( + (OMX_COLOR_FORMATTYPE)format, + mSurface, + mVideoWidth, mVideoHeight, + decodedWidth, decodedHeight, + rotationDegrees); } } @@ -958,12 +921,6 @@ bool AwesomePlayer::isPlaying() const { return (mFlags & PLAYING) || (mFlags & CACHE_UNDERRUN); } -void AwesomePlayer::setISurface(const sp<ISurface> &isurface) { - Mutex::Autolock autoLock(mLock); - - mISurface = isurface; -} - void AwesomePlayer::setSurface(const sp<Surface> &surface) { Mutex::Autolock autoLock(mLock); @@ -1897,18 +1854,16 @@ status_t AwesomePlayer::resume() { mFlags = state->mFlags & (AUTO_LOOPING | LOOPING | AT_EOS); - if (state->mLastVideoFrame && (mSurface != NULL || mISurface != NULL)) { + if (state->mLastVideoFrame && mSurface != NULL) { mVideoRenderer = new AwesomeLocalRenderer( - true, // previewOnly - "", (OMX_COLOR_FORMATTYPE)state->mColorFormat, - mISurface, mSurface, state->mVideoWidth, state->mVideoHeight, state->mDecodedWidth, - state->mDecodedHeight); + state->mDecodedHeight, + 0); mVideoRendererIsPreview = true; diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp index 2e94a12..bb929fd 100644 --- a/media/libstagefright/MPEG4Extractor.cpp +++ b/media/libstagefright/MPEG4Extractor.cpp @@ -27,11 +27,11 @@ #include <stdlib.h> #include <string.h> +#include <media/stagefright/foundation/ADebug.h> #include <media/stagefright/DataSource.h> #include "include/ESDS.h" #include <media/stagefright/MediaBuffer.h> #include <media/stagefright/MediaBufferGroup.h> -#include <media/stagefright/MediaDebug.h> #include <media/stagefright/MediaDefs.h> #include <media/stagefright/MediaSource.h> #include <media/stagefright/MetaData.h> @@ -766,55 +766,11 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { case FOURCC('t', 'k', 'h', 'd'): { - if (chunk_data_size < 4) { - return ERROR_MALFORMED; - } - - uint8_t version; - if (mDataSource->readAt(data_offset, &version, 1) < 1) { - return ERROR_IO; - } - - uint64_t ctime, mtime, duration; - int32_t id; - uint32_t width, height; - - if (version == 1) { - if (chunk_data_size != 36 + 60) { - return ERROR_MALFORMED; - } - - uint8_t buffer[36 + 60]; - if (mDataSource->readAt( - data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { - return ERROR_IO; - } - - ctime = U64_AT(&buffer[4]); - mtime = U64_AT(&buffer[12]); - id = U32_AT(&buffer[20]); - duration = U64_AT(&buffer[28]); - width = U32_AT(&buffer[88]); - height = U32_AT(&buffer[92]); - } else if (version == 0) { - if (chunk_data_size != 24 + 60) { - return ERROR_MALFORMED; - } - - uint8_t buffer[24 + 60]; - if (mDataSource->readAt( - data_offset, buffer, sizeof(buffer)) < (ssize_t)sizeof(buffer)) { - return ERROR_IO; - } - ctime = U32_AT(&buffer[4]); - mtime = U32_AT(&buffer[8]); - id = U32_AT(&buffer[12]); - duration = U32_AT(&buffer[20]); - width = U32_AT(&buffer[76]); - height = U32_AT(&buffer[80]); + status_t err; + if ((err = parseTrackHeader(data_offset, chunk_data_size)) != OK) { + return err; } - mLastTrack->meta->setInt32(kKeyTrackID, id); *offset += chunk_size; break; } @@ -1275,6 +1231,93 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) { return OK; } +status_t MPEG4Extractor::parseTrackHeader( + off_t data_offset, off_t data_size) { + if (data_size < 4) { + return ERROR_MALFORMED; + } + + uint8_t version; + if (mDataSource->readAt(data_offset, &version, 1) < 1) { + return ERROR_IO; + } + + size_t dynSize = (version == 1) ? 36 : 24; + + uint8_t buffer[36 + 60]; + + if (data_size != (off_t)dynSize + 60) { + return ERROR_MALFORMED; + } + + if (mDataSource->readAt( + data_offset, buffer, data_size) < (ssize_t)data_size) { + return ERROR_IO; + } + + uint64_t ctime, mtime, duration; + int32_t id; + + if (version == 1) { + ctime = U64_AT(&buffer[4]); + mtime = U64_AT(&buffer[12]); + id = U32_AT(&buffer[20]); + duration = U64_AT(&buffer[28]); + } else { + CHECK_EQ((unsigned)version, 0u); + + ctime = U32_AT(&buffer[4]); + mtime = U32_AT(&buffer[8]); + id = U32_AT(&buffer[12]); + duration = U32_AT(&buffer[20]); + } + + mLastTrack->meta->setInt32(kKeyTrackID, id); + + size_t matrixOffset = dynSize + 16; + int32_t a00 = U32_AT(&buffer[matrixOffset]); + int32_t a01 = U32_AT(&buffer[matrixOffset + 4]); + int32_t dx = U32_AT(&buffer[matrixOffset + 8]); + int32_t a10 = U32_AT(&buffer[matrixOffset + 12]); + int32_t a11 = U32_AT(&buffer[matrixOffset + 16]); + int32_t dy = U32_AT(&buffer[matrixOffset + 20]); + +#if 0 + LOGI("x' = %.2f * x + %.2f * y + %.2f", + a00 / 65536.0f, a01 / 65536.0f, dx / 65536.0f); + LOGI("y' = %.2f * x + %.2f * y + %.2f", + a10 / 65536.0f, a11 / 65536.0f, dy / 65536.0f); +#endif + + uint32_t rotationDegrees; + + static const int32_t kFixedOne = 0x10000; + if (a00 == kFixedOne && a01 == 0 && a10 == 0 && a11 == kFixedOne) { + // Identity, no rotation + rotationDegrees = 0; + } else if (a00 == 0 && a01 == kFixedOne && a10 == -kFixedOne && a11 == 0) { + rotationDegrees = 90; + } else if (a00 == 0 && a01 == -kFixedOne && a10 == kFixedOne && a11 == 0) { + rotationDegrees = 270; + } else if (a00 == -kFixedOne && a01 == 0 && a10 == 0 && a11 == -kFixedOne) { + rotationDegrees = 180; + } else { + LOGW("We only support 0,90,180,270 degree rotation matrices"); + rotationDegrees = 0; + } + + if (rotationDegrees != 0) { + mLastTrack->meta->setInt32(kKeyRotation, rotationDegrees); + } + +#if 0 + uint32_t width = U32_AT(&buffer[dynSize + 52]); + uint32_t height = U32_AT(&buffer[dynSize + 56]); +#endif + + return OK; +} + status_t MPEG4Extractor::parseMetaData(off_t offset, size_t size) { if (size < 4) { return ERROR_MALFORMED; @@ -1588,7 +1631,7 @@ MPEG4Source::MPEG4Source( const uint8_t *ptr = (const uint8_t *)data; CHECK(size >= 7); - CHECK_EQ(ptr[0], 1); // configurationVersion == 1 + CHECK_EQ((unsigned)ptr[0], 1u); // configurationVersion == 1 // The number of bytes used to encode the length of a NAL unit. mNALLengthSize = 1 + (ptr[4] & 3); @@ -1736,7 +1779,7 @@ status_t MPEG4Source::read( } uint32_t sampleTime; - CHECK_EQ(OK, mSampleTable->getMetaDataForSample( + CHECK_EQ((status_t)OK, mSampleTable->getMetaDataForSample( sampleIndex, NULL, NULL, &sampleTime)); if (mode == ReadOptions::SEEK_CLOSEST) { @@ -1783,7 +1826,7 @@ status_t MPEG4Source::read( err = mGroup->acquire_buffer(&mBuffer); if (err != OK) { - CHECK_EQ(mBuffer, NULL); + CHECK(mBuffer == NULL); return err; } } diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp index 662a84a..3d507ca 100644 --- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp +++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp @@ -35,7 +35,8 @@ SoftwareRenderer::SoftwareRenderer( OMX_COLOR_FORMATTYPE colorFormat, const sp<Surface> &surface, size_t displayWidth, size_t displayHeight, - size_t decodedWidth, size_t decodedHeight) + size_t decodedWidth, size_t decodedHeight, + int32_t rotationDegrees) : mColorFormat(colorFormat), mConverter(NULL), mYUVMode(None), @@ -95,6 +96,20 @@ SoftwareRenderer::SoftwareRenderer( CHECK_EQ(0, native_window_set_buffers_geometry( mSurface.get(), mDecodedWidth, mDecodedHeight, halFormat)); + + uint32_t transform; + switch (rotationDegrees) { + case 0: transform = 0; break; + case 90: transform = HAL_TRANSFORM_ROT_90; break; + case 180: transform = HAL_TRANSFORM_ROT_180; break; + case 270: transform = HAL_TRANSFORM_ROT_270; break; + default: transform = 0; break; + } + + if (transform) { + CHECK_EQ(0, native_window_set_buffers_transform( + mSurface.get(), transform)); + } } SoftwareRenderer::~SoftwareRenderer() { diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h index 302a1ba..4e63b7a 100644 --- a/media/libstagefright/include/AwesomePlayer.h +++ b/media/libstagefright/include/AwesomePlayer.h @@ -79,7 +79,6 @@ struct AwesomePlayer { bool isPlaying() const; - void setISurface(const sp<ISurface> &isurface); void setSurface(const sp<Surface> &surface); void setAudioSink(const sp<MediaPlayerBase::AudioSink> &audioSink); status_t setLooping(bool shouldLoop); @@ -130,7 +129,6 @@ private: bool mQueueStarted; wp<MediaPlayerBase> mListener; - sp<ISurface> mISurface; sp<Surface> mSurface; sp<MediaPlayerBase::AudioSink> mAudioSink; diff --git a/media/libstagefright/include/MPEG4Extractor.h b/media/libstagefright/include/MPEG4Extractor.h index 4e31059..bc2e4dc 100644 --- a/media/libstagefright/include/MPEG4Extractor.h +++ b/media/libstagefright/include/MPEG4Extractor.h @@ -88,6 +88,8 @@ private: bool mIsDrm; status_t parseDrmSINF(off_t *offset, off_t data_offset); + status_t parseTrackHeader(off_t data_offset, off_t data_size); + MPEG4Extractor(const MPEG4Extractor &); MPEG4Extractor &operator=(const MPEG4Extractor &); }; diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h index 5a6c96f9..5fed98a 100644 --- a/media/libstagefright/include/OMX.h +++ b/media/libstagefright/include/OMX.h @@ -97,13 +97,6 @@ public: const char *parameter_name, OMX_INDEXTYPE *index); - virtual sp<IOMXRenderer> createRenderer( - const sp<ISurface> &surface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t encodedWidth, size_t encodedHeight, - size_t displayWidth, size_t displayHeight); - virtual void binderDied(const wp<IBinder> &the_late_who); OMX_ERRORTYPE OnEvent( diff --git a/media/libstagefright/include/SoftwareRenderer.h b/media/libstagefright/include/SoftwareRenderer.h index 8d58056..9cafc68 100644 --- a/media/libstagefright/include/SoftwareRenderer.h +++ b/media/libstagefright/include/SoftwareRenderer.h @@ -19,25 +19,24 @@ #define SOFTWARE_RENDERER_H_ #include <media/stagefright/ColorConverter.h> -#include <media/stagefright/VideoRenderer.h> #include <utils/RefBase.h> namespace android { class Surface; -class MemoryHeapBase; -class SoftwareRenderer : public VideoRenderer { +class SoftwareRenderer { public: SoftwareRenderer( OMX_COLOR_FORMATTYPE colorFormat, const sp<Surface> &surface, size_t displayWidth, size_t displayHeight, - size_t decodedWidth, size_t decodedHeight); + size_t decodedWidth, size_t decodedHeight, + int32_t rotationDegrees); - virtual ~SoftwareRenderer(); + ~SoftwareRenderer(); - virtual void render( + void render( const void *data, size_t size, void *platformPrivate); private: diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp index f9f638f..4e9920b 100644 --- a/media/libstagefright/omx/OMX.cpp +++ b/media/libstagefright/omx/OMX.cpp @@ -24,14 +24,11 @@ #include <sys/resource.h> #include "../include/OMX.h" -#include "OMXRenderer.h" #include "../include/OMXNodeInstance.h" -#include "../include/SoftwareRenderer.h" #include <binder/IMemory.h> #include <media/stagefright/MediaDebug.h> -#include <media/stagefright/VideoRenderer.h> #include <utils/threads.h> #include "OMXMaster.h" @@ -442,110 +439,4 @@ void OMX::invalidateNodeID_l(node_id node) { mNodeIDToInstance.removeItem(node); } -//////////////////////////////////////////////////////////////////////////////// - -struct SharedVideoRenderer : public VideoRenderer { - SharedVideoRenderer(void *libHandle, VideoRenderer *obj) - : mLibHandle(libHandle), - mObj(obj) { - } - - virtual ~SharedVideoRenderer() { - delete mObj; - mObj = NULL; - - dlclose(mLibHandle); - mLibHandle = NULL; - } - - virtual void render( - const void *data, size_t size, void *platformPrivate) { - return mObj->render(data, size, platformPrivate); - } - -private: - void *mLibHandle; - VideoRenderer *mObj; - - SharedVideoRenderer(const SharedVideoRenderer &); - SharedVideoRenderer &operator=(const SharedVideoRenderer &); -}; - -sp<IOMXRenderer> OMX::createRenderer( - const sp<ISurface> &surface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t encodedWidth, size_t encodedHeight, - size_t displayWidth, size_t displayHeight) { - Mutex::Autolock autoLock(mLock); - - VideoRenderer *impl = NULL; - - void *libHandle = dlopen("libstagefrighthw.so", RTLD_NOW); - - if (libHandle) { - typedef VideoRenderer *(*CreateRendererFunc)( - const sp<ISurface> &surface, - const char *componentName, - OMX_COLOR_FORMATTYPE colorFormat, - size_t displayWidth, size_t displayHeight, - size_t decodedWidth, size_t decodedHeight); - - CreateRendererFunc func = - (CreateRendererFunc)dlsym( - libHandle, - "_Z14createRendererRKN7android2spINS_8ISurfaceEEEPKc20" - "OMX_COLOR_FORMATTYPEjjjj"); - - if (func) { - impl = (*func)(surface, componentName, colorFormat, - displayWidth, displayHeight, encodedWidth, encodedHeight); - - if (impl) { - impl = new SharedVideoRenderer(libHandle, impl); - libHandle = NULL; - } - } - - if (libHandle) { - dlclose(libHandle); - libHandle = NULL; - } - } - - if (!impl) { -#if 0 - LOGW("Using software renderer."); - impl = new SoftwareRenderer( - colorFormat, - surface, - displayWidth, displayHeight, - encodedWidth, encodedHeight); -#else - CHECK(!"Should not be here."); - return NULL; -#endif - } - - return new OMXRenderer(impl); -} - -OMXRenderer::OMXRenderer(VideoRenderer *impl) - : mImpl(impl) { -} - -OMXRenderer::~OMXRenderer() { - delete mImpl; - mImpl = NULL; -} - -void OMXRenderer::render(IOMX::buffer_id buffer) { - OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer; - - mImpl->render( - header->pBuffer + header->nOffset, - header->nFilledLen, - header->pPlatformPrivate); -} - } // namespace android diff --git a/media/libstagefright/omx/OMXRenderer.h b/media/libstagefright/omx/OMXRenderer.h deleted file mode 100644 index 4d194ce..0000000 --- a/media/libstagefright/omx/OMXRenderer.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef OMX_RENDERER_H_ - -#define OMX_RENDERER_H_ - -#include <media/IOMX.h> - -namespace android { - -class VideoRenderer; - -class OMXRenderer : public BnOMXRenderer { -public: - // Assumes ownership of "impl". - OMXRenderer(VideoRenderer *impl); - virtual ~OMXRenderer(); - - virtual void render(IOMX::buffer_id buffer); - -private: - VideoRenderer *mImpl; - - OMXRenderer(const OMXRenderer &); - OMXRenderer &operator=(const OMXRenderer &); -}; - -} // namespace android - -#endif // OMX_RENDERER_H_ diff --git a/media/tests/players/invoke_mock_media_player.cpp b/media/tests/players/invoke_mock_media_player.cpp index 53308be..1e3731e 100644 --- a/media/tests/players/invoke_mock_media_player.cpp +++ b/media/tests/players/invoke_mock_media_player.cpp @@ -68,7 +68,6 @@ class Player: public MediaPlayerBase } virtual status_t setDataSource(int fd, int64_t offset, int64_t length) {return OK;} - virtual status_t setVideoISurface(const sp<ISurface>& surface) {return OK;} virtual status_t setVideoSurface(const sp<Surface>& surface) {return OK;} virtual status_t prepare() {return OK;} virtual status_t prepareAsync() {return OK;} diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java index cd58284..a0a1974 100644 --- a/services/java/com/android/server/PackageManagerService.java +++ b/services/java/com/android/server/PackageManagerService.java @@ -7327,16 +7327,22 @@ class PackageManagerService extends IPackageManager.Stub { pw.println(" "); pw.println("Package warning messages:"); File fname = getSettingsProblemFile(); - FileInputStream in; + FileInputStream in = null; try { in = new FileInputStream(fname); int avail = in.available(); byte[] data = new byte[avail]; in.read(data); pw.print(new String(data)); - in.close(); } catch (FileNotFoundException e) { } catch (IOException e) { + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + } + } } } } diff --git a/services/java/com/android/server/ProcessStats.java b/services/java/com/android/server/ProcessStats.java index 43dbcc0..1a12a84 100644 --- a/services/java/com/android/server/ProcessStats.java +++ b/services/java/com/android/server/ProcessStats.java @@ -799,8 +799,9 @@ public class ProcessStats { } private String readFile(String file, char endChar) { + FileInputStream is = null; try { - FileInputStream is = new FileInputStream(file); + is = new FileInputStream(file); int len = is.read(mBuffer); is.close(); @@ -815,6 +816,13 @@ public class ProcessStats { } } catch (java.io.FileNotFoundException e) { } catch (java.io.IOException e) { + } finally { + if (is != null) { + try { + is.close(); + } catch (java.io.IOException e) { + } + } } return null; } @@ -841,4 +849,3 @@ public class ProcessStats { } } } - diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java index 35a2c19..290f2c1 100644 --- a/telephony/java/android/telephony/ServiceState.java +++ b/telephony/java/android/telephony/ServiceState.java @@ -438,9 +438,9 @@ public class ServiceState implements Parcelable { + " " + (mCssIndicator ? "CSS supported" : "CSS not supported") + " " + mNetworkId + " " + mSystemId - + "RoamInd: " + mCdmaRoamingIndicator - + "DefRoamInd: " + mCdmaDefaultRoamingIndicator - + "EmergOnly: " + mIsEmergencyOnly); + + " RoamInd=" + mCdmaRoamingIndicator + + " DefRoamInd=" + mCdmaDefaultRoamingIndicator + + " EmergOnly=" + mIsEmergencyOnly); } public void setStateOutOfService() { diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java index 7c652c5..d7ff0c5 100644 --- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java @@ -240,8 +240,8 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { mCdmaPhone.mRuimRecords.getRecordsLoaded())) { reason += " - radioState= " + mPhone.mCM.getRadioState() + " - RUIM not loaded"; } - if (mPhone.getState() != Phone.State.IDLE && - mCdmaPhone.mSST.isConcurrentVoiceAndData()) { + if (!(mCdmaPhone.mSST.isConcurrentVoiceAndData() || + mPhone.getState() == Phone.State.IDLE)) { reason += " - concurrentVoiceAndData not allowed and state= " + mPhone.getState(); } if (roaming) reason += " - Roaming"; diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java index 2aca9ad..effb743 100644 --- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java +++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java @@ -328,8 +328,8 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { reason += " - PhoneState= " + mPhone.getState(); } if (!mMasterDataEnabled) reason += " - mMasterDataEnabled= false"; - if (mPhone.getServiceState().getRoaming() && getDataOnRoamingEnabled()) { - reason += " - Roaming"; + if (mPhone.getServiceState().getRoaming() && !getDataOnRoamingEnabled()) { + reason += " - Roaming and data roaming not enabled"; } if (mIsPsRestricted) reason += " - mIsPsRestricted= true"; if (!desiredPowerState) reason += " - desiredPowerState= false"; @@ -1037,8 +1037,15 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { } else { GsmDataConnection.FailCause cause; cause = (GsmDataConnection.FailCause) (ar.result); - if(DBG) log("PDP setup failed " + cause); - // Log this failure to the Event Logs. + if (DBG) { + String apnString; + try { + apnString = mWaitingApns.get(0).apn; + } catch (Exception e) { + apnString = "<unknown>"; + } + log(String.format("onDataSetupComplete: error apn=%s cause=%s", apnString, cause)); + } if (cause.isEventLoggable()) { GsmCellLocation loc = ((GsmCellLocation)mPhone.getCellLocation()); EventLog.writeEvent(EventLogTags.PDP_SETUP_FAIL, |
