Merge "Fix bug 2203203 Route STREAM_VOICE_CALL to A2DP when not in call."
diff --git a/core/java/android/app/SearchableInfo.java b/core/java/android/app/SearchableInfo.java
index 4496354..b8c54dd 100644
--- a/core/java/android/app/SearchableInfo.java
+++ b/core/java/android/app/SearchableInfo.java
@@ -303,7 +303,7 @@
InputType.TYPE_CLASS_TEXT |
InputType.TYPE_TEXT_VARIATION_NORMAL);
mSearchImeOptions = a.getInt(com.android.internal.R.styleable.Searchable_imeOptions,
- EditorInfo.IME_ACTION_SEARCH);
+ EditorInfo.IME_ACTION_GO);
mIncludeInGlobalSearch = a.getBoolean(
com.android.internal.R.styleable.Searchable_includeInGlobalSearch, false);
mQueryAfterZeroResults = a.getBoolean(
@@ -672,7 +672,7 @@
/**
* Return the input method options specified in the searchable attributes.
- * This will default to EditorInfo.ACTION_SEARCH if not specified (which is
+ * This will default to EditorInfo.ACTION_GO if not specified (which is
* appropriate for a search box).
*
* @return the input type
diff --git a/core/java/android/database/sqlite/SQLiteQueryBuilder.java b/core/java/android/database/sqlite/SQLiteQueryBuilder.java
index af54a71..1d154ce 100644
--- a/core/java/android/database/sqlite/SQLiteQueryBuilder.java
+++ b/core/java/android/database/sqlite/SQLiteQueryBuilder.java
@@ -40,7 +40,7 @@
private Map<String, String> mProjectionMap = null;
private String mTables = "";
- private final StringBuilder mWhereClause = new StringBuilder(64);
+ private StringBuilder mWhereClause = null; // lazily created
private boolean mDistinct;
private SQLiteDatabase.CursorFactory mFactory;
@@ -89,6 +89,9 @@
* @param inWhere the chunk of text to append to the WHERE clause.
*/
public void appendWhere(CharSequence inWhere) {
+ if (mWhereClause == null) {
+ mWhereClause = new StringBuilder(inWhere.length() + 16);
+ }
if (mWhereClause.length() == 0) {
mWhereClause.append('(');
}
@@ -106,6 +109,9 @@
* to avoid SQL injection attacks
*/
public void appendWhereEscapeString(String inWhere) {
+ if (mWhereClause == null) {
+ mWhereClause = new StringBuilder(inWhere.length() + 16);
+ }
if (mWhereClause.length() == 0) {
mWhereClause.append('(');
}
@@ -356,15 +362,16 @@
String[] projection = computeProjection(projectionIn);
StringBuilder where = new StringBuilder();
+ boolean hasBaseWhereClause = mWhereClause != null && mWhereClause.length() > 0;
- if (mWhereClause.length() > 0) {
+ if (hasBaseWhereClause) {
where.append(mWhereClause.toString());
where.append(')');
}
// Tack on the user's selection, if present.
if (selection != null && selection.length() > 0) {
- if (mWhereClause.length() > 0) {
+ if (hasBaseWhereClause) {
where.append(" AND ");
}
diff --git a/core/java/android/provider/Browser.java b/core/java/android/provider/Browser.java
index 4377a2b..27092ae 100644
--- a/core/java/android/provider/Browser.java
+++ b/core/java/android/provider/Browser.java
@@ -351,23 +351,27 @@
* @hide pending API council approval
*/
public static final String[] getVisitedHistory(ContentResolver cr) {
+ Cursor c = null;
+ String[] str = null;
try {
String[] projection = new String[] {
"url"
};
- Cursor c = cr.query(BOOKMARKS_URI, projection, "visits > 0", null,
+ c = cr.query(BOOKMARKS_URI, projection, "visits > 0", null,
null);
- String[] str = new String[c.getCount()];
+ str = new String[c.getCount()];
int i = 0;
while (c.moveToNext()) {
str[i] = c.getString(0);
i++;
}
- c.close();
- return str;
} catch (IllegalStateException e) {
- return new String[0];
+ Log.e(LOGTAG, "getVisitedHistory", e);
+ str = new String[0];
+ } finally {
+ if (c != null) c.close();
}
+ return str;
}
/**
@@ -382,9 +386,10 @@
* @param cr The ContentResolver used to access the database.
*/
public static final void truncateHistory(ContentResolver cr) {
+ Cursor c = null;
try {
// Select non-bookmark history, ordered by date
- Cursor c = cr.query(
+ c = cr.query(
BOOKMARKS_URI,
TRUNCATE_HISTORY_PROJECTION,
"bookmark = 0",
@@ -396,16 +401,16 @@
for (int i = 0; i < TRUNCATE_N_OLDEST; i++) {
// Log.v(LOGTAG, "truncate history " +
// c.getInt(TRUNCATE_HISTORY_PROJECTION_ID_INDEX));
- deleteHistoryWhere(
- cr, "_id = " +
- c.getInt(TRUNCATE_HISTORY_PROJECTION_ID_INDEX));
+ cr.delete(BOOKMARKS_URI, "_id = " +
+ c.getInt(TRUNCATE_HISTORY_PROJECTION_ID_INDEX),
+ null);
if (!c.moveToNext()) break;
}
}
- c.close();
} catch (IllegalStateException e) {
Log.e(LOGTAG, "truncateHistory", e);
- return;
+ } finally {
+ if (c != null) c.close();
}
}
@@ -416,8 +421,10 @@
* @return boolean True if the history can be cleared.
*/
public static final boolean canClearHistory(ContentResolver cr) {
+ Cursor c = null;
+ boolean ret = false;
try {
- Cursor c = cr.query(
+ c = cr.query(
BOOKMARKS_URI,
new String [] { BookmarkColumns._ID,
BookmarkColumns.BOOKMARK,
@@ -426,12 +433,13 @@
null,
null
);
- boolean ret = c.moveToFirst();
- c.close();
- return ret;
+ ret = c.moveToFirst();
} catch (IllegalStateException e) {
- return false;
+ Log.e(LOGTAG, "canClearHistory", e);
+ } finally {
+ if (c != null) c.close();
}
+ return ret;
}
/**
@@ -455,57 +463,57 @@
*/
private static final void deleteHistoryWhere(ContentResolver cr,
String whereClause) {
+ Cursor c = null;
try {
- Cursor c = cr.query(BOOKMARKS_URI,
+ c = cr.query(BOOKMARKS_URI,
HISTORY_PROJECTION,
whereClause,
null,
null);
- if (!c.moveToFirst()) {
- c.close();
- return;
- }
-
- final WebIconDatabase iconDb = WebIconDatabase.getInstance();
- /* Delete favicons, and revert bookmarks which have been visited
- * to simply bookmarks.
- */
- StringBuffer sb = new StringBuffer();
- boolean firstTime = true;
- do {
- String url = c.getString(HISTORY_PROJECTION_URL_INDEX);
- boolean isBookmark =
- c.getInt(HISTORY_PROJECTION_BOOKMARK_INDEX) == 1;
- if (isBookmark) {
- if (firstTime) {
- firstTime = false;
+ if (c.moveToFirst()) {
+ final WebIconDatabase iconDb = WebIconDatabase.getInstance();
+ /* Delete favicons, and revert bookmarks which have been visited
+ * to simply bookmarks.
+ */
+ StringBuffer sb = new StringBuffer();
+ boolean firstTime = true;
+ do {
+ String url = c.getString(HISTORY_PROJECTION_URL_INDEX);
+ boolean isBookmark =
+ c.getInt(HISTORY_PROJECTION_BOOKMARK_INDEX) == 1;
+ if (isBookmark) {
+ if (firstTime) {
+ firstTime = false;
+ } else {
+ sb.append(" OR ");
+ }
+ sb.append("( _id = ");
+ sb.append(c.getInt(0));
+ sb.append(" )");
} else {
- sb.append(" OR ");
+ iconDb.releaseIconForPageUrl(url);
}
- sb.append("( _id = ");
- sb.append(c.getInt(0));
- sb.append(" )");
- } else {
- iconDb.releaseIconForPageUrl(url);
+ } while (c.moveToNext());
+
+ if (!firstTime) {
+ ContentValues map = new ContentValues();
+ map.put(BookmarkColumns.VISITS, 0);
+ map.put(BookmarkColumns.DATE, 0);
+ /* FIXME: Should I also remove the title? */
+ cr.update(BOOKMARKS_URI, map, sb.toString(), null);
}
- } while (c.moveToNext());
- c.close();
- if (!firstTime) {
- ContentValues map = new ContentValues();
- map.put(BookmarkColumns.VISITS, 0);
- map.put(BookmarkColumns.DATE, 0);
- /* FIXME: Should I also remove the title? */
- cr.update(BOOKMARKS_URI, map, sb.toString(), null);
+ String deleteWhereClause = BookmarkColumns.BOOKMARK + " = 0";
+ if (whereClause != null) {
+ deleteWhereClause += " AND " + whereClause;
+ }
+ cr.delete(BOOKMARKS_URI, deleteWhereClause, null);
}
-
- String deleteWhereClause = BookmarkColumns.BOOKMARK + " = 0";
- if (whereClause != null) {
- deleteWhereClause += " AND " + whereClause;
- }
- cr.delete(BOOKMARKS_URI, deleteWhereClause, null);
} catch (IllegalStateException e) {
+ Log.e(LOGTAG, "deleteHistoryWhere", e);
return;
+ } finally {
+ if (c != null) c.close();
}
}
@@ -560,8 +568,9 @@
*/
public static final void addSearchUrl(ContentResolver cr, String search) {
long now = new Date().getTime();
+ Cursor c = null;
try {
- Cursor c = cr.query(
+ c = cr.query(
SEARCHES_URI,
SEARCHES_PROJECTION,
SEARCHES_WHERE_CLAUSE,
@@ -576,10 +585,10 @@
} else {
cr.insert(SEARCHES_URI, map);
}
- c.close();
} catch (IllegalStateException e) {
Log.e(LOGTAG, "addSearchUrl", e);
- return;
+ } finally {
+ if (c != null) c.close();
}
}
/**
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 582ef3f..484922d 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -2241,7 +2241,8 @@
* leaving touch mode alone is considered the event).
*/
private boolean checkForLeavingTouchModeAndConsume(KeyEvent event) {
- if (event.getAction() != KeyEvent.ACTION_DOWN) {
+ final int action = event.getAction();
+ if (action != KeyEvent.ACTION_DOWN && action != KeyEvent.ACTION_MULTIPLE) {
return false;
}
if ((event.getFlags()&KeyEvent.FLAG_KEEP_TOUCH_MODE) != 0) {
diff --git a/core/java/android/webkit/PluginFullScreenHolder.java b/core/java/android/webkit/PluginFullScreenHolder.java
index b641803..6d9e108 100644
--- a/core/java/android/webkit/PluginFullScreenHolder.java
+++ b/core/java/android/webkit/PluginFullScreenHolder.java
@@ -25,8 +25,6 @@
package android.webkit;
import android.app.Dialog;
-import android.graphics.Rect;
-import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
@@ -34,15 +32,9 @@
class PluginFullScreenHolder extends Dialog {
- private static final String LOGTAG = "FullScreenHolder";
-
private final WebView mWebView;
private final int mNpp;
private View mContentView;
- private int mX;
- private int mY;
- private int mWidth;
- private int mHeight;
PluginFullScreenHolder(WebView webView, int npp) {
super(webView.getContext(), android.R.style.Theme_NoTitleBar_Fullscreen);
@@ -50,23 +42,15 @@
mNpp = npp;
}
- Rect getBound() {
- return new Rect(mX, mY, mWidth, mHeight);
- }
-
- /*
- * x, y, width, height are in the caller's view coordinate system. (x, y) is
- * relative to the top left corner of the caller's view.
- */
- void updateBound(int x, int y, int width, int height) {
- mX = x;
- mY = y;
- mWidth = width;
- mHeight = height;
- }
-
@Override
public void setContentView(View contentView) {
+ // as we are sharing the View between full screen and
+ // embedded mode, we have to remove the
+ // AbsoluteLayout.LayoutParams set by embedded mode to
+ // ViewGroup.LayoutParams before adding it to the dialog
+ contentView.setLayoutParams(new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT));
super.setContentView(contentView);
mContentView = contentView;
}
@@ -99,15 +83,7 @@
@Override
public boolean onTouchEvent(MotionEvent event) {
- final float x = event.getX();
- final float y = event.getY();
- // TODO: find a way to know when the dialog size changed so that we can
- // cache the ratio
- final View decorView = getWindow().getDecorView();
- event.setLocation(mX + x * mWidth / decorView.getWidth(),
- mY + y * mHeight / decorView.getHeight());
- mWebView.onTouchEvent(event);
- // always return true as we are the handler
+ // always return true as we don't want the event to propagate any further
return true;
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index c5a4e9e..52bc8be1 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1464,7 +1464,9 @@
* Load the given data into the WebView. This will load the data into
* WebView using the data: scheme. Content loaded through this mechanism
* does not have the ability to load content from the network.
- * @param data A String of data in the given encoding.
+ * @param data A String of data in the given encoding. The date must
+ * be URI-escaped -- '#', '%', '\', '?' should be replaced by %23, %25,
+ * %27, %3f respectively.
* @param mimeType The MIMEType of the data. i.e. text/html, image/jpeg
* @param encoding The encoding of the data. i.e. utf-8, base64
*/
@@ -6508,80 +6510,21 @@
break;
case SHOW_FULLSCREEN: {
- WebViewCore.PluginFullScreenData data
- = (WebViewCore.PluginFullScreenData) msg.obj;
- if (data.mNpp != 0 && data.mView != null) {
- if (inFullScreenMode()) {
- Log.w(LOGTAG,
- "Should not have another full screen.");
- mFullScreenHolder.dismiss();
- }
- mFullScreenHolder = new PluginFullScreenHolder(
- WebView.this, data.mNpp);
- // as we are sharing the View between full screen and
- // embedded mode, we have to remove the
- // AbsoluteLayout.LayoutParams set by embedded mode to
- // ViewGroup.LayoutParams before adding it to the dialog
- data.mView.setLayoutParams(new FrameLayout.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT,
- ViewGroup.LayoutParams.FILL_PARENT));
- mFullScreenHolder.setContentView(data.mView);
- mFullScreenHolder.setCancelable(false);
- mFullScreenHolder.setCanceledOnTouchOutside(false);
- mFullScreenHolder.show();
- } else if (!inFullScreenMode()) {
- // this may happen if user dismisses the fullscreen and
- // then the WebCore re-position message finally reached
- // the UI thread.
- break;
- }
- // move the matching embedded view fully into the view so
- // that touch will be valid instead of rejected due to out
- // of the visible bounds
- // TODO: do we need to preserve the original position and
- // scale so that we can revert it when leaving the full
- // screen mode?
- int x = contentToViewX(data.mDocX);
- int y = contentToViewY(data.mDocY);
- int width = contentToViewDimension(data.mDocWidth);
- int height = contentToViewDimension(data.mDocHeight);
- int viewWidth = getViewWidth();
- int viewHeight = getViewHeight();
- int newX = mScrollX;
- int newY = mScrollY;
- if (x < mScrollX) {
- newX = x + (width > viewWidth
- ? (width - viewWidth) / 2 : 0);
- } else if (x + width > mScrollX + viewWidth) {
- newX = x + width - viewWidth - (width > viewWidth
- ? (width - viewWidth) / 2 : 0);
- }
- if (y < mScrollY) {
- newY = y + (height > viewHeight
- ? (height - viewHeight) / 2 : 0);
- } else if (y + height > mScrollY + viewHeight) {
- newY = y + height - viewHeight - (height > viewHeight
- ? (height - viewHeight) / 2 : 0);
- }
- scrollTo(newX, newY);
- if (width > viewWidth || height > viewHeight) {
- mZoomCenterX = viewWidth * .5f;
- mZoomCenterY = viewHeight * .5f;
- // do not change text wrap scale so that there is no
- // reflow
- setNewZoomScale(mActualScale
- / Math.max((float) width / viewWidth,
- (float) height / viewHeight), false,
- false);
- }
- // Now update the bound
- mFullScreenHolder.updateBound(contentToViewX(data.mDocX)
- - mScrollX, contentToViewY(data.mDocY) - mScrollY,
- contentToViewDimension(data.mDocWidth),
- contentToViewDimension(data.mDocHeight));
- }
- break;
+ View view = (View) msg.obj;
+ int npp = msg.arg1;
+ if (mFullScreenHolder != null) {
+ Log.w(LOGTAG, "Should not have another full screen.");
+ mFullScreenHolder.dismiss();
+ }
+ mFullScreenHolder = new PluginFullScreenHolder(WebView.this, npp);
+ mFullScreenHolder.setContentView(view);
+ mFullScreenHolder.setCancelable(false);
+ mFullScreenHolder.setCanceledOnTouchOutside(false);
+ mFullScreenHolder.show();
+
+ break;
+ }
case HIDE_FULLSCREEN:
if (inFullScreenMode()) {
mFullScreenHolder.dismiss();
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index a274378..4073e37 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -716,14 +716,7 @@
boolean mRemember;
}
- static class PluginFullScreenData {
- View mView;
- int mNpp;
- int mDocX;
- int mDocY;
- int mDocWidth;
- int mDocHeight;
- }
+
static final String[] HandlerDebugString = {
"REQUEST_LABEL", // 97
@@ -2351,22 +2344,15 @@
// called by JNI. PluginWidget function to launch a full-screen view using a
// View object provided by the plugin class.
- private void showFullScreenPlugin(ViewManager.ChildView childView,
- final int npp, int x, int y, int width, int height) {
-
+ private void showFullScreenPlugin(ViewManager.ChildView childView, int npp) {
if (mWebView == null) {
return;
}
- PluginFullScreenData data = new PluginFullScreenData();
- data.mView = childView.mView;
- data.mNpp = npp;
- data.mDocX = x;
- data.mDocY = y;
- data.mDocWidth = width;
- data.mDocHeight = height;
- mWebView.mPrivateHandler.obtainMessage(WebView.SHOW_FULLSCREEN, data)
- .sendToTarget();
+ Message message = mWebView.mPrivateHandler.obtainMessage(WebView.SHOW_FULLSCREEN);
+ message.obj = childView.mView;
+ message.arg1 = npp;
+ message.sendToTarget();
}
// called by JNI
@@ -2378,22 +2364,6 @@
.sendToTarget();
}
- // called by JNI
- private void updateFullScreenPlugin(int x, int y, int width, int height) {
- if (mWebView == null) {
- return;
- }
-
- PluginFullScreenData data = new PluginFullScreenData();
- data.mDocX = x;
- data.mDocY = y;
- data.mDocWidth = width;
- data.mDocHeight = height;
- // null mView and mNpp to indicate it is an update
- mWebView.mPrivateHandler.obtainMessage(WebView.SHOW_FULLSCREEN, data)
- .sendToTarget();
- }
-
// called by JNI. PluginWidget functions for creating an embedded View for
// the surface drawing model.
private ViewManager.ChildView addSurface(View pluginView, int x, int y,
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 5bded0b..a07397f 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -1980,11 +1980,11 @@
if (touchMode == TOUCH_MODE_OVERSCROLL || touchMode == TOUCH_MODE_OVERFLING) {
if (mFlingRunnable != null) {
mFlingRunnable.endFling();
-
- if (mScrollY != 0) {
- mScrollY = 0;
- invalidate();
- }
+ }
+
+ if (mScrollY != 0) {
+ mScrollY = 0;
+ invalidate();
}
}
}
diff --git a/core/jni/android_media_AudioRecord.cpp b/core/jni/android_media_AudioRecord.cpp
index d7485ae..17f5daf 100644
--- a/core/jni/android_media_AudioRecord.cpp
+++ b/core/jni/android_media_AudioRecord.cpp
@@ -55,6 +55,8 @@
jobject audioRecord_ref;
};
+Mutex sLock;
+
// ----------------------------------------------------------------------------
#define AUDIORECORD_SUCCESS 0
@@ -255,12 +257,21 @@
// ----------------------------------------------------------------------------
-static void android_media_AudioRecord_finalize(JNIEnv *env, jobject thiz) {
-
- // delete the AudioRecord object
+static void android_media_AudioRecord_release(JNIEnv *env, jobject thiz) {
+
+ // serialize access. Ugly, but functional.
+ Mutex::Autolock lock(&sLock);
AudioRecord *lpRecorder =
(AudioRecord *)env->GetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj);
+ audiorecord_callback_cookie *lpCookie = (audiorecord_callback_cookie *)env->GetIntField(
+ thiz, javaAudioRecordFields.nativeCallbackCookie);
+ // reset the native resources in the Java object so any attempt to access
+ // them after a call to release fails.
+ env->SetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj, 0);
+ env->SetIntField(thiz, javaAudioRecordFields.nativeCallbackCookie, 0);
+
+ // delete the AudioRecord object
if (lpRecorder) {
LOGV("About to delete lpRecorder: %x\n", (int)lpRecorder);
lpRecorder->stop();
@@ -268,27 +279,18 @@
}
// delete the callback information
- audiorecord_callback_cookie *lpCookie = (audiorecord_callback_cookie *)env->GetIntField(
- thiz, javaAudioRecordFields.nativeCallbackCookie);
if (lpCookie) {
LOGV("deleting lpCookie: %x\n", (int)lpCookie);
env->DeleteGlobalRef(lpCookie->audioRecord_class);
env->DeleteGlobalRef(lpCookie->audioRecord_ref);
delete lpCookie;
}
-
}
// ----------------------------------------------------------------------------
-static void android_media_AudioRecord_release(JNIEnv *env, jobject thiz) {
-
- // do everything a call to finalize would
- android_media_AudioRecord_finalize(env, thiz);
- // + reset the native resources in the Java object so any attempt to access
- // them after a call to release fails.
- env->SetIntField(thiz, javaAudioRecordFields.nativeRecorderInJavaObj, 0);
- env->SetIntField(thiz, javaAudioRecordFields.nativeCallbackCookie, 0);
+static void android_media_AudioRecord_finalize(JNIEnv *env, jobject thiz) {
+ android_media_AudioRecord_release(env, thiz);
}
diff --git a/data/fonts/DroidSansFallback.ttf b/data/fonts/DroidSansFallback.ttf
index a935f16..206621f 100644
--- a/data/fonts/DroidSansFallback.ttf
+++ b/data/fonts/DroidSansFallback.ttf
Binary files differ
diff --git a/include/media/MediaMetadataRetrieverInterface.h b/include/media/MediaMetadataRetrieverInterface.h
index e228357..ff57774 100644
--- a/include/media/MediaMetadataRetrieverInterface.h
+++ b/include/media/MediaMetadataRetrieverInterface.h
@@ -43,6 +43,10 @@
class MediaMetadataRetrieverInterface : public MediaMetadataRetrieverBase
{
public:
+ MediaMetadataRetrieverInterface()
+ : mMode(0) {
+ }
+
virtual ~MediaMetadataRetrieverInterface() {}
// @param mode The intended mode of operations:
@@ -57,6 +61,8 @@
mode > METADATA_MODE_FRAME_CAPTURE_AND_METADATA_RETRIEVAL) {
return BAD_VALUE;
}
+
+ mMode = mode;
return NO_ERROR;
}
diff --git a/include/media/mediametadataretriever.h b/include/media/mediametadataretriever.h
index 9b12410..dbbcc49 100644
--- a/include/media/mediametadataretriever.h
+++ b/include/media/mediametadataretriever.h
@@ -67,8 +67,8 @@
// and meta data retrieval.$
enum {
METADATA_MODE_NOOP = 0x00,
- METADATA_MODE_FRAME_CAPTURE_ONLY = 0x01,
- METADATA_MODE_METADATA_RETRIEVAL_ONLY = 0x02,
+ METADATA_MODE_METADATA_RETRIEVAL_ONLY = 0x01,
+ METADATA_MODE_FRAME_CAPTURE_ONLY = 0x02,
METADATA_MODE_FRAME_CAPTURE_AND_METADATA_RETRIEVAL = 0x03
};
diff --git a/media/java/android/media/ThumbnailUtils.java b/media/java/android/media/ThumbnailUtils.java
index 23f850a..5062e87 100644
--- a/media/java/android/media/ThumbnailUtils.java
+++ b/media/java/android/media/ThumbnailUtils.java
@@ -568,7 +568,7 @@
fullThumbWidth = fullOptions.outWidth / fullOptions.inSampleSize;
// Choose the larger thumbnail as the returning sizedThumbBitmap.
- if (exifThumbWidth >= fullThumbWidth) {
+ if (thumbData != null && exifThumbWidth >= fullThumbWidth) {
int width = exifOptions.outWidth;
int height = exifOptions.outHeight;
exifOptions.inJustDecodeBounds = false;
diff --git a/media/jni/soundpool/SoundPool.cpp b/media/jni/soundpool/SoundPool.cpp
index 2012b3d..fef880b 100644
--- a/media/jni/soundpool/SoundPool.cpp
+++ b/media/jni/soundpool/SoundPool.cpp
@@ -144,7 +144,7 @@
bool SoundPool::startThreads()
{
- createThreadEtc(beginThread, this, "SoundPoolThread");
+ createThreadEtc(beginThread, this, "SoundPool");
if (mDecodeThread == NULL)
mDecodeThread = new SoundPoolThread(this);
return mDecodeThread != NULL;
@@ -827,4 +827,3 @@
}
} // end namespace android
-
diff --git a/media/jni/soundpool/SoundPoolThread.cpp b/media/jni/soundpool/SoundPoolThread.cpp
index e32c794..275c519 100644
--- a/media/jni/soundpool/SoundPoolThread.cpp
+++ b/media/jni/soundpool/SoundPoolThread.cpp
@@ -62,7 +62,7 @@
mSoundPool(soundPool)
{
mMsgQueue.setCapacity(maxMessages);
- if (createThread(beginThread, this)) {
+ if (createThreadEtc(beginThread, this, "SoundPoolThread")) {
mRunning = true;
}
}
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index f1c3f0f..f50451d 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -501,7 +501,10 @@
}
}
+ bool isTrack = false;
if (chunk_type == FOURCC('t', 'r', 'a', 'k')) {
+ isTrack = true;
+
Track *track = new Track;
track->next = NULL;
if (mLastTrack) {
@@ -513,6 +516,7 @@
track->meta = new MetaData;
track->includes_expensive_metadata = false;
+ track->skipTrack = false;
track->timescale = 0;
track->sampleTable = new SampleTable(mDataSource);
track->meta->setCString(kKeyMIMEType, "application/octet-stream");
@@ -531,7 +535,25 @@
return ERROR_MALFORMED;
}
- if (chunk_type == FOURCC('t', 'r', 'a', 'k')) {
+ if (isTrack) {
+ if (mLastTrack->skipTrack) {
+ Track *cur = mFirstTrack;
+
+ if (cur == mLastTrack) {
+ delete cur;
+ mFirstTrack = mLastTrack = NULL;
+ } else {
+ while (cur && cur->next != mLastTrack) {
+ cur = cur->next;
+ }
+ cur->next = NULL;
+ delete mLastTrack;
+ mLastTrack = cur;
+ }
+
+ return OK;
+ }
+
status_t err = verifyTrack(mLastTrack);
if (err != OK) {
@@ -655,32 +677,6 @@
break;
}
- case FOURCC('h', 'd', 'l', 'r'):
- {
- if (chunk_data_size < 25) {
- return ERROR_MALFORMED;
- }
-
- uint8_t buffer[24];
- if (mDataSource->readAt(data_offset, buffer, 24) < 24) {
- return ERROR_IO;
- }
-
- if (U32_AT(buffer) != 0) {
- // Should be version 0, flags 0.
- return ERROR_MALFORMED;
- }
-
- if (U32_AT(&buffer[4]) != 0) {
- // pre_defined should be 0.
- return ERROR_MALFORMED;
- }
-
- mHandlerType = U32_AT(&buffer[8]);
- *offset += chunk_size;
- break;
- }
-
case FOURCC('s', 't', 's', 'd'):
{
if (chunk_data_size < 8) {
@@ -706,7 +702,10 @@
if (entry_count > 1) {
// For now we only support a single type of media per track.
- return ERROR_UNSUPPORTED;
+
+ mLastTrack->skipTrack = true;
+ *offset += chunk_size;
+ break;
}
off_t stop_offset = *offset + chunk_size;
@@ -728,10 +727,6 @@
case FOURCC('s', 'a', 'm', 'r'):
case FOURCC('s', 'a', 'w', 'b'):
{
- if (mHandlerType != FOURCC('s', 'o', 'u', 'n')) {
- return ERROR_MALFORMED;
- }
-
uint8_t buffer[8 + 20];
if (chunk_data_size < (ssize_t)sizeof(buffer)) {
// Basic AudioSampleEntry size.
@@ -785,10 +780,6 @@
{
mHasVideo = true;
- if (mHandlerType != FOURCC('v', 'i', 'd', 'e')) {
- return ERROR_MALFORMED;
- }
-
uint8_t buffer[78];
if (chunk_data_size < (ssize_t)sizeof(buffer)) {
// Basic VideoSampleEntry size.
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index 4679207..2968917 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -206,6 +206,12 @@
VideoFrame *StagefrightMetadataRetriever::captureFrame() {
LOGV("captureFrame");
+ if (0 == (mMode & METADATA_MODE_FRAME_CAPTURE_ONLY)) {
+ LOGV("captureFrame disabled by mode (0x%08x)", mMode);
+
+ return NULL;
+ }
+
if (mExtractor.get() == NULL) {
LOGV("no extractor.");
return NULL;
@@ -256,6 +262,12 @@
MediaAlbumArt *StagefrightMetadataRetriever::extractAlbumArt() {
LOGV("extractAlbumArt (extractor: %s)", mExtractor.get() != NULL ? "YES" : "NO");
+ if (0 == (mMode & METADATA_MODE_METADATA_RETRIEVAL_ONLY)) {
+ LOGV("extractAlbumArt/metadata retrieval disabled by mode");
+
+ return NULL;
+ }
+
if (mExtractor == NULL) {
return NULL;
}
@@ -274,6 +286,12 @@
}
const char *StagefrightMetadataRetriever::extractMetadata(int keyCode) {
+ if (0 == (mMode & METADATA_MODE_METADATA_RETRIEVAL_ONLY)) {
+ LOGV("extractAlbumArt/metadata retrieval disabled by mode");
+
+ return NULL;
+ }
+
if (mExtractor == NULL) {
return NULL;
}
diff --git a/media/libstagefright/id3/Android.mk b/media/libstagefright/id3/Android.mk
index add8f3c..93fac1c 100644
--- a/media/libstagefright/id3/Android.mk
+++ b/media/libstagefright/id3/Android.mk
@@ -23,6 +23,8 @@
LOCAL_STATIC_LIBRARIES := \
libstagefright_id3
+LOCAL_MODULE_TAGS := debug
+
LOCAL_MODULE := testid3
include $(BUILD_EXECUTABLE)
diff --git a/media/libstagefright/include/MPEG4Extractor.h b/media/libstagefright/include/MPEG4Extractor.h
index 9d35e0c..c8663d5 100644
--- a/media/libstagefright/include/MPEG4Extractor.h
+++ b/media/libstagefright/include/MPEG4Extractor.h
@@ -48,6 +48,7 @@
uint32_t timescale;
sp<SampleTable> sampleTable;
bool includes_expensive_metadata;
+ bool skipTrack;
};
sp<DataSource> mDataSource;
@@ -58,7 +59,6 @@
sp<MetaData> mFileMetaData;
- uint32_t mHandlerType;
Vector<uint32_t> mPath;
status_t readMetaData();
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 13cb460..132e31b 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -19,7 +19,8 @@
#include <utils/Log.h>
#include <dlfcn.h>
-#include <linux/prctl.h>
+
+#include <sys/prctl.h>
#include <sys/resource.h>
#include "../include/OMX.h"
diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java
index 84790ca..37a3cdf 100644
--- a/services/java/com/android/server/UiModeManagerService.java
+++ b/services/java/com/android/server/UiModeManagerService.java
@@ -423,6 +423,7 @@
String action = null;
String oldAction = null;
if (mLastBroadcastState == Intent.EXTRA_DOCK_STATE_CAR) {
+ adjustStatusBarCarModeLocked();
oldAction = UiModeManager.ACTION_EXIT_CAR_MODE;
} else if (mLastBroadcastState == Intent.EXTRA_DOCK_STATE_DESK) {
oldAction = UiModeManager.ACTION_EXIT_DESK_MODE;
@@ -447,10 +448,6 @@
action = UiModeManager.ACTION_ENTER_DESK_MODE;
}
} else {
- if (mLastBroadcastState == Intent.EXTRA_DOCK_STATE_CAR) {
- adjustStatusBarCarModeLocked();
- }
-
mLastBroadcastState = Intent.EXTRA_DOCK_STATE_UNDOCKED;
action = oldAction;
}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
index e3486a0..297b963 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
@@ -72,10 +72,10 @@
};
static final String[] ignoreTestList = {
+ "editing/selection/move-left-right.html", // Causes DumpRenderTree to hang
"fast/js/regexp-charclass-crash.html", // RegExp is too large, causing OOM
"fast/regex/test1.html", // Causes DumpRenderTree to hang with V8
- "fast/regex/slow.html", // Causes DumpRenderTree to hang with V8
- "editing/selection/move-left-right.html" // Causes DumpRenderTree to hang
+ "fast/regex/slow.html" // Causes DumpRenderTree to hang with V8
};
static void fillIgnoreResultList() {
@@ -98,6 +98,7 @@
ignoreResultList.add("storage/database-lock-after-reload.html"); // failure
// Will always fail
+ ignoreResultList.add("dom/svg/level3/xpath"); // XPath not supported
ignoreResultList.add("fast/workers/shared-worker-constructor.html"); // shared workers not supported
ignoreResultList.add("fast/workers/shared-worker-context-gc.html"); // shared workers not supported
ignoreResultList.add("fast/workers/shared-worker-event-listener.html"); // shared workers not supported
@@ -114,6 +115,7 @@
ignoreResultList.add("fast/workers/shared-worker-script-error.html"); // shared workers not supported
ignoreResultList.add("fast/workers/shared-worker-shared.html"); // shared workers not supported
ignoreResultList.add("fast/workers/shared-worker-simple.html"); // shared workers not supported
+ ignoreResultList.add("fast/xpath"); // XPath not supported
// TODO: These need to be triaged
ignoreResultList.add("fast/css/case-transform.html"); // will not fix #619707