Merge "Delay sending Plugin Draw event until the surface is ready."
diff --git a/core/java/android/content/ContentProviderNative.java b/core/java/android/content/ContentProviderNative.java
index abeeb74..9a20951 100644
--- a/core/java/android/content/ContentProviderNative.java
+++ b/core/java/android/content/ContentProviderNative.java
@@ -332,60 +332,60 @@
BulkCursorToCursorAdaptor adaptor) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeInterfaceToken(IContentProvider.descriptor);
+ url.writeToParcel(data, 0);
+ int length = 0;
+ if (projection != null) {
+ length = projection.length;
+ }
+ data.writeInt(length);
+ for (int i = 0; i < length; i++) {
+ data.writeString(projection[i]);
+ }
+ data.writeString(selection);
+ if (selectionArgs != null) {
+ length = selectionArgs.length;
+ } else {
+ length = 0;
+ }
+ data.writeInt(length);
+ for (int i = 0; i < length; i++) {
+ data.writeString(selectionArgs[i]);
+ }
+ data.writeString(sortOrder);
+ data.writeStrongBinder(observer.asBinder());
+ window.writeToParcel(data, 0);
- url.writeToParcel(data, 0);
- int length = 0;
- if (projection != null) {
- length = projection.length;
- }
- data.writeInt(length);
- for (int i = 0; i < length; i++) {
- data.writeString(projection[i]);
- }
- data.writeString(selection);
- if (selectionArgs != null) {
- length = selectionArgs.length;
- } else {
- length = 0;
- }
- data.writeInt(length);
- for (int i = 0; i < length; i++) {
- data.writeString(selectionArgs[i]);
- }
- data.writeString(sortOrder);
- data.writeStrongBinder(observer.asBinder());
- window.writeToParcel(data, 0);
+ // Flag for whether or not we want the number of rows in the
+ // cursor and the position of the "_id" column index (or -1 if
+ // non-existent). Only to be returned if binder != null.
+ final boolean wantsCursorMetadata = (adaptor != null);
+ data.writeInt(wantsCursorMetadata ? 1 : 0);
- // Flag for whether or not we want the number of rows in the
- // cursor and the position of the "_id" column index (or -1 if
- // non-existent). Only to be returned if binder != null.
- final boolean wantsCursorMetadata = (adaptor != null);
- data.writeInt(wantsCursorMetadata ? 1 : 0);
+ mRemote.transact(IContentProvider.QUERY_TRANSACTION, data, reply, 0);
- mRemote.transact(IContentProvider.QUERY_TRANSACTION, data, reply, 0);
+ DatabaseUtils.readExceptionFromParcel(reply);
- DatabaseUtils.readExceptionFromParcel(reply);
+ IBulkCursor bulkCursor = null;
+ IBinder bulkCursorBinder = reply.readStrongBinder();
+ if (bulkCursorBinder != null) {
+ bulkCursor = BulkCursorNative.asInterface(bulkCursorBinder);
- IBulkCursor bulkCursor = null;
- IBinder bulkCursorBinder = reply.readStrongBinder();
- if (bulkCursorBinder != null) {
- bulkCursor = BulkCursorNative.asInterface(bulkCursorBinder);
-
- if (wantsCursorMetadata) {
- int rowCount = reply.readInt();
- int idColumnPosition = reply.readInt();
- if (bulkCursor != null) {
- adaptor.set(bulkCursor, rowCount, idColumnPosition);
+ if (wantsCursorMetadata) {
+ int rowCount = reply.readInt();
+ int idColumnPosition = reply.readInt();
+ if (bulkCursor != null) {
+ adaptor.set(bulkCursor, rowCount, idColumnPosition);
+ }
}
}
+ return bulkCursor;
+ } finally {
+ data.recycle();
+ reply.recycle();
}
-
- data.recycle();
- reply.recycle();
-
- return bulkCursor;
}
public IBulkCursor bulkQuery(Uri url, String[] projection,
@@ -416,240 +416,240 @@
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeInterfaceToken(IContentProvider.descriptor);
+ url.writeToParcel(data, 0);
- url.writeToParcel(data, 0);
+ mRemote.transact(IContentProvider.GET_TYPE_TRANSACTION, data, reply, 0);
- mRemote.transact(IContentProvider.GET_TYPE_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
- String out = reply.readString();
-
- data.recycle();
- reply.recycle();
-
- return out;
+ DatabaseUtils.readExceptionFromParcel(reply);
+ String out = reply.readString();
+ return out;
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
public Uri insert(Uri url, ContentValues values) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeInterfaceToken(IContentProvider.descriptor);
+ url.writeToParcel(data, 0);
+ values.writeToParcel(data, 0);
- url.writeToParcel(data, 0);
- values.writeToParcel(data, 0);
+ mRemote.transact(IContentProvider.INSERT_TRANSACTION, data, reply, 0);
- mRemote.transact(IContentProvider.INSERT_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
- Uri out = Uri.CREATOR.createFromParcel(reply);
-
- data.recycle();
- reply.recycle();
-
- return out;
+ DatabaseUtils.readExceptionFromParcel(reply);
+ Uri out = Uri.CREATOR.createFromParcel(reply);
+ return out;
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
public int bulkInsert(Uri url, ContentValues[] values) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeInterfaceToken(IContentProvider.descriptor);
+ url.writeToParcel(data, 0);
+ data.writeTypedArray(values, 0);
- url.writeToParcel(data, 0);
- data.writeTypedArray(values, 0);
+ mRemote.transact(IContentProvider.BULK_INSERT_TRANSACTION, data, reply, 0);
- mRemote.transact(IContentProvider.BULK_INSERT_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
- int count = reply.readInt();
-
- data.recycle();
- reply.recycle();
-
- return count;
+ DatabaseUtils.readExceptionFromParcel(reply);
+ int count = reply.readInt();
+ return count;
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
throws RemoteException, OperationApplicationException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IContentProvider.descriptor);
+ data.writeInt(operations.size());
+ for (ContentProviderOperation operation : operations) {
+ operation.writeToParcel(data, 0);
+ }
+ mRemote.transact(IContentProvider.APPLY_BATCH_TRANSACTION, data, reply, 0);
- data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeInt(operations.size());
- for (ContentProviderOperation operation : operations) {
- operation.writeToParcel(data, 0);
+ DatabaseUtils.readExceptionWithOperationApplicationExceptionFromParcel(reply);
+ final ContentProviderResult[] results =
+ reply.createTypedArray(ContentProviderResult.CREATOR);
+ return results;
+ } finally {
+ data.recycle();
+ reply.recycle();
}
- mRemote.transact(IContentProvider.APPLY_BATCH_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionWithOperationApplicationExceptionFromParcel(reply);
- final ContentProviderResult[] results =
- reply.createTypedArray(ContentProviderResult.CREATOR);
-
- data.recycle();
- reply.recycle();
-
- return results;
}
public int delete(Uri url, String selection, String[] selectionArgs)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeInterfaceToken(IContentProvider.descriptor);
+ url.writeToParcel(data, 0);
+ data.writeString(selection);
+ data.writeStringArray(selectionArgs);
- url.writeToParcel(data, 0);
- data.writeString(selection);
- data.writeStringArray(selectionArgs);
+ mRemote.transact(IContentProvider.DELETE_TRANSACTION, data, reply, 0);
- mRemote.transact(IContentProvider.DELETE_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
- int count = reply.readInt();
-
- data.recycle();
- reply.recycle();
-
- return count;
+ DatabaseUtils.readExceptionFromParcel(reply);
+ int count = reply.readInt();
+ return count;
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
public int update(Uri url, ContentValues values, String selection,
String[] selectionArgs) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeInterfaceToken(IContentProvider.descriptor);
+ url.writeToParcel(data, 0);
+ values.writeToParcel(data, 0);
+ data.writeString(selection);
+ data.writeStringArray(selectionArgs);
- url.writeToParcel(data, 0);
- values.writeToParcel(data, 0);
- data.writeString(selection);
- data.writeStringArray(selectionArgs);
+ mRemote.transact(IContentProvider.UPDATE_TRANSACTION, data, reply, 0);
- mRemote.transact(IContentProvider.UPDATE_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
- int count = reply.readInt();
-
- data.recycle();
- reply.recycle();
-
- return count;
+ DatabaseUtils.readExceptionFromParcel(reply);
+ int count = reply.readInt();
+ return count;
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
public ParcelFileDescriptor openFile(Uri url, String mode)
throws RemoteException, FileNotFoundException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeInterfaceToken(IContentProvider.descriptor);
+ url.writeToParcel(data, 0);
+ data.writeString(mode);
- url.writeToParcel(data, 0);
- data.writeString(mode);
+ mRemote.transact(IContentProvider.OPEN_FILE_TRANSACTION, data, reply, 0);
- mRemote.transact(IContentProvider.OPEN_FILE_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply);
- int has = reply.readInt();
- ParcelFileDescriptor fd = has != 0 ? reply.readFileDescriptor() : null;
-
- data.recycle();
- reply.recycle();
-
- return fd;
+ DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply);
+ int has = reply.readInt();
+ ParcelFileDescriptor fd = has != 0 ? reply.readFileDescriptor() : null;
+ return fd;
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
public AssetFileDescriptor openAssetFile(Uri url, String mode)
throws RemoteException, FileNotFoundException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeInterfaceToken(IContentProvider.descriptor);
+ url.writeToParcel(data, 0);
+ data.writeString(mode);
- url.writeToParcel(data, 0);
- data.writeString(mode);
+ mRemote.transact(IContentProvider.OPEN_ASSET_FILE_TRANSACTION, data, reply, 0);
- mRemote.transact(IContentProvider.OPEN_ASSET_FILE_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply);
- int has = reply.readInt();
- AssetFileDescriptor fd = has != 0
- ? AssetFileDescriptor.CREATOR.createFromParcel(reply) : null;
-
- data.recycle();
- reply.recycle();
-
- return fd;
+ DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply);
+ int has = reply.readInt();
+ AssetFileDescriptor fd = has != 0
+ ? AssetFileDescriptor.CREATOR.createFromParcel(reply) : null;
+ return fd;
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
public Bundle call(String method, String request, Bundle args)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeInterfaceToken(IContentProvider.descriptor);
+ data.writeString(method);
+ data.writeString(request);
+ data.writeBundle(args);
- data.writeString(method);
- data.writeString(request);
- data.writeBundle(args);
+ mRemote.transact(IContentProvider.CALL_TRANSACTION, data, reply, 0);
- mRemote.transact(IContentProvider.CALL_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
- Bundle bundle = reply.readBundle();
-
- data.recycle();
- reply.recycle();
-
- return bundle;
+ DatabaseUtils.readExceptionFromParcel(reply);
+ Bundle bundle = reply.readBundle();
+ return bundle;
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
public String[] getStreamTypes(Uri url, String mimeTypeFilter) throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeInterfaceToken(IContentProvider.descriptor);
+ url.writeToParcel(data, 0);
+ data.writeString(mimeTypeFilter);
- url.writeToParcel(data, 0);
- data.writeString(mimeTypeFilter);
+ mRemote.transact(IContentProvider.GET_STREAM_TYPES_TRANSACTION, data, reply, 0);
- mRemote.transact(IContentProvider.GET_STREAM_TYPES_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
- String[] out = reply.createStringArray();
-
- data.recycle();
- reply.recycle();
-
- return out;
+ DatabaseUtils.readExceptionFromParcel(reply);
+ String[] out = reply.createStringArray();
+ return out;
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
public AssetFileDescriptor openTypedAssetFile(Uri url, String mimeType, Bundle opts)
throws RemoteException, FileNotFoundException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IContentProvider.descriptor);
- data.writeInterfaceToken(IContentProvider.descriptor);
+ url.writeToParcel(data, 0);
+ data.writeString(mimeType);
+ data.writeBundle(opts);
- url.writeToParcel(data, 0);
- data.writeString(mimeType);
- data.writeBundle(opts);
+ mRemote.transact(IContentProvider.OPEN_TYPED_ASSET_FILE_TRANSACTION, data, reply, 0);
- mRemote.transact(IContentProvider.OPEN_TYPED_ASSET_FILE_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply);
- int has = reply.readInt();
- AssetFileDescriptor fd = has != 0
- ? AssetFileDescriptor.CREATOR.createFromParcel(reply) : null;
-
- data.recycle();
- reply.recycle();
-
- return fd;
+ DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(reply);
+ int has = reply.readInt();
+ AssetFileDescriptor fd = has != 0
+ ? AssetFileDescriptor.CREATOR.createFromParcel(reply) : null;
+ return fd;
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
private IBinder mRemote;
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 1e72092..0d25926 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -16,6 +16,8 @@
package android.content;
+import dalvik.system.CloseGuard;
+
import android.accounts.Account;
import android.app.ActivityManagerNative;
import android.app.ActivityThread;
@@ -33,6 +35,7 @@
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.StrictMode;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.EventLog;
@@ -1562,27 +1565,39 @@
private final class CursorWrapperInner extends CursorWrapper {
private final IContentProvider mContentProvider;
public static final String TAG="CursorWrapperInner";
- private boolean mCloseFlag = false;
+
+ private final CloseGuard mCloseGuard = CloseGuard.get();
+ private boolean mProviderReleased;
CursorWrapperInner(Cursor cursor, IContentProvider icp) {
super(cursor);
mContentProvider = icp;
+ mCloseGuard.open("close");
}
@Override
public void close() {
super.close();
ContentResolver.this.releaseProvider(mContentProvider);
- mCloseFlag = true;
+ mProviderReleased = true;
+
+ if (mCloseGuard != null) {
+ mCloseGuard.close();
+ }
}
@Override
protected void finalize() throws Throwable {
- // TODO: integrate CloseGuard support.
try {
- if(!mCloseFlag) {
+ if (mCloseGuard != null) {
+ mCloseGuard.warnIfOpen();
+ }
+
+ if (!mProviderReleased && mContentProvider != null) {
+ // Even though we are using CloseGuard, log this anyway so that
+ // application developers always see the message in the log.
Log.w(TAG, "Cursor finalized without prior close()");
- close();
+ ContentResolver.this.releaseProvider(mContentProvider);
}
} finally {
super.finalize();
diff --git a/core/java/android/database/BulkCursorNative.java b/core/java/android/database/BulkCursorNative.java
index fa62d69..9925a9a 100644
--- a/core/java/android/database/BulkCursorNative.java
+++ b/core/java/android/database/BulkCursorNative.java
@@ -20,12 +20,13 @@
import android.os.Bundle;
import android.os.IBinder;
import android.os.Parcel;
+import android.os.Parcelable;
import android.os.RemoteException;
/**
* Native implementation of the bulk cursor. This is only for use in implementing
* IPC, application code should use the Cursor interface.
- *
+ *
* {@hide}
*/
public abstract class BulkCursorNative extends Binder implements IBulkCursor
@@ -67,7 +68,7 @@
}
reply.writeNoException();
reply.writeInt(1);
- window.writeToParcel(reply, 0);
+ window.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
return true;
}
@@ -184,172 +185,172 @@
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IBulkCursor.descriptor);
+ data.writeInt(startPos);
- data.writeInterfaceToken(IBulkCursor.descriptor);
+ mRemote.transact(GET_CURSOR_WINDOW_TRANSACTION, data, reply, 0);
+ DatabaseUtils.readExceptionFromParcel(reply);
- data.writeInt(startPos);
-
- mRemote.transact(GET_CURSOR_WINDOW_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- CursorWindow window = null;
- if (reply.readInt() == 1) {
- window = CursorWindow.newFromParcel(reply);
+ CursorWindow window = null;
+ if (reply.readInt() == 1) {
+ window = CursorWindow.newFromParcel(reply);
+ }
+ return window;
+ } finally {
+ data.recycle();
+ reply.recycle();
}
-
- data.recycle();
- reply.recycle();
-
- return window;
}
public void onMove(int position) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IBulkCursor.descriptor);
+ data.writeInt(position);
- data.writeInterfaceToken(IBulkCursor.descriptor);
-
- data.writeInt(position);
-
- mRemote.transact(ON_MOVE_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- data.recycle();
- reply.recycle();
+ mRemote.transact(ON_MOVE_TRANSACTION, data, reply, 0);
+ DatabaseUtils.readExceptionFromParcel(reply);
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
public int count() throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IBulkCursor.descriptor);
- data.writeInterfaceToken(IBulkCursor.descriptor);
+ boolean result = mRemote.transact(COUNT_TRANSACTION, data, reply, 0);
+ DatabaseUtils.readExceptionFromParcel(reply);
- boolean result = mRemote.transact(COUNT_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- int count;
- if (result == false) {
- count = -1;
- } else {
- count = reply.readInt();
+ int count;
+ if (result == false) {
+ count = -1;
+ } else {
+ count = reply.readInt();
+ }
+ return count;
+ } finally {
+ data.recycle();
+ reply.recycle();
}
- data.recycle();
- reply.recycle();
- return count;
}
public String[] getColumnNames() throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IBulkCursor.descriptor);
- data.writeInterfaceToken(IBulkCursor.descriptor);
+ mRemote.transact(GET_COLUMN_NAMES_TRANSACTION, data, reply, 0);
+ DatabaseUtils.readExceptionFromParcel(reply);
- mRemote.transact(GET_COLUMN_NAMES_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- String[] columnNames = null;
- int numColumns = reply.readInt();
- columnNames = new String[numColumns];
- for (int i = 0; i < numColumns; i++) {
- columnNames[i] = reply.readString();
+ String[] columnNames = null;
+ int numColumns = reply.readInt();
+ columnNames = new String[numColumns];
+ for (int i = 0; i < numColumns; i++) {
+ columnNames[i] = reply.readString();
+ }
+ return columnNames;
+ } finally {
+ data.recycle();
+ reply.recycle();
}
-
- data.recycle();
- reply.recycle();
- return columnNames;
}
public void deactivate() throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IBulkCursor.descriptor);
- data.writeInterfaceToken(IBulkCursor.descriptor);
-
- mRemote.transact(DEACTIVATE_TRANSACTION, data, reply, 0);
- DatabaseUtils.readExceptionFromParcel(reply);
-
- data.recycle();
- reply.recycle();
+ mRemote.transact(DEACTIVATE_TRANSACTION, data, reply, 0);
+ DatabaseUtils.readExceptionFromParcel(reply);
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
public void close() throws RemoteException
{
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IBulkCursor.descriptor);
- data.writeInterfaceToken(IBulkCursor.descriptor);
-
- mRemote.transact(CLOSE_TRANSACTION, data, reply, 0);
- DatabaseUtils.readExceptionFromParcel(reply);
-
- data.recycle();
- reply.recycle();
+ mRemote.transact(CLOSE_TRANSACTION, data, reply, 0);
+ DatabaseUtils.readExceptionFromParcel(reply);
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
public int requery(IContentObserver observer, CursorWindow window) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IBulkCursor.descriptor);
+ data.writeStrongInterface(observer);
+ window.writeToParcel(data, 0);
- data.writeInterfaceToken(IBulkCursor.descriptor);
+ boolean result = mRemote.transact(REQUERY_TRANSACTION, data, reply, 0);
+ DatabaseUtils.readExceptionFromParcel(reply);
- data.writeStrongInterface(observer);
- window.writeToParcel(data, 0);
-
- boolean result = mRemote.transact(REQUERY_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- int count;
- if (!result) {
- count = -1;
- } else {
- count = reply.readInt();
- mExtras = reply.readBundle();
+ int count;
+ if (!result) {
+ count = -1;
+ } else {
+ count = reply.readInt();
+ mExtras = reply.readBundle();
+ }
+ return count;
+ } finally {
+ data.recycle();
+ reply.recycle();
}
-
- data.recycle();
- reply.recycle();
-
- return count;
}
public boolean getWantsAllOnMoveCalls() throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IBulkCursor.descriptor);
- data.writeInterfaceToken(IBulkCursor.descriptor);
+ mRemote.transact(WANTS_ON_MOVE_TRANSACTION, data, reply, 0);
+ DatabaseUtils.readExceptionFromParcel(reply);
- mRemote.transact(WANTS_ON_MOVE_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- int result = reply.readInt();
- data.recycle();
- reply.recycle();
- return result != 0;
+ int result = reply.readInt();
+ return result != 0;
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
public Bundle getExtras() throws RemoteException {
if (mExtras == null) {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IBulkCursor.descriptor);
- data.writeInterfaceToken(IBulkCursor.descriptor);
+ mRemote.transact(GET_EXTRAS_TRANSACTION, data, reply, 0);
+ DatabaseUtils.readExceptionFromParcel(reply);
- mRemote.transact(GET_EXTRAS_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- mExtras = reply.readBundle();
- data.recycle();
- reply.recycle();
+ mExtras = reply.readBundle();
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
return mExtras;
}
@@ -357,19 +358,19 @@
public Bundle respond(Bundle extras) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
+ try {
+ data.writeInterfaceToken(IBulkCursor.descriptor);
+ data.writeBundle(extras);
- data.writeInterfaceToken(IBulkCursor.descriptor);
+ mRemote.transact(RESPOND_TRANSACTION, data, reply, 0);
+ DatabaseUtils.readExceptionFromParcel(reply);
- data.writeBundle(extras);
-
- mRemote.transact(RESPOND_TRANSACTION, data, reply, 0);
-
- DatabaseUtils.readExceptionFromParcel(reply);
-
- Bundle returnExtras = reply.readBundle();
- data.recycle();
- reply.recycle();
- return returnExtras;
+ Bundle returnExtras = reply.readBundle();
+ return returnExtras;
+ } finally {
+ data.recycle();
+ reply.recycle();
+ }
}
}
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index 68385b4..4d7a9bb 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -908,6 +908,9 @@
if (!IS_USER_BUILD) {
threadPolicyMask |= StrictMode.PENALTY_DROPBOX;
+ if (IS_ENG_BUILD) {
+ threadPolicyMask |= StrictMode.PENALTY_LOG;
+ }
}
if (doFlashes) {
threadPolicyMask |= StrictMode.PENALTY_FLASH;
@@ -918,7 +921,11 @@
if (IS_USER_BUILD) {
setCloseGuardEnabled(false);
} else {
- setVmPolicy(new VmPolicy.Builder().detectAll().penaltyDropBox().build());
+ VmPolicy.Builder policyBuilder = new VmPolicy.Builder().detectAll().penaltyDropBox();
+ if (IS_ENG_BUILD) {
+ policyBuilder.penaltyLog();
+ }
+ setVmPolicy(policyBuilder.build());
setCloseGuardEnabled(vmClosableObjectLeaksEnabled());
}
return true;
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 7a803f9..6d19c23 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -2074,7 +2074,8 @@
* If the value of the encoding parameter is 'base64', then the data must
* be encoded as base64. Otherwise, the data must use ASCII encoding for
* octets inside the range of safe URL characters and use the standard %xx
- * hex encoding of URLs for octets outside that range.
+ * hex encoding of URLs for octets outside that range. For example,
+ * '#', '%', '\', '?' should be replaced by %23, %25, %27, %3f respectively.
* <p>
* The 'data' scheme URL formed by this method uses the default US-ASCII
* charset. If you need need to set a different charset, you should form a
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index fa9417a..1165af5 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -2005,6 +2005,11 @@
mConnectingDataSource->setUID(mUID);
}
+ String8 cacheConfig;
+ bool disconnectAtHighwatermark;
+ NuCachedSource2::RemoveCacheSpecificHeaders(
+ &mUriHeaders, &cacheConfig, &disconnectAtHighwatermark);
+
mLock.unlock();
status_t err = mConnectingDataSource->connect(mUri, &mUriHeaders);
mLock.lock();
@@ -2024,7 +2029,10 @@
new ThrottledSource(
mConnectingDataSource, 50 * 1024 /* bytes/sec */));
#else
- mCachedSource = new NuCachedSource2(mConnectingDataSource);
+ mCachedSource = new NuCachedSource2(
+ mConnectingDataSource,
+ cacheConfig.isEmpty() ? NULL : cacheConfig.string(),
+ disconnectAtHighwatermark);
#endif
dataSource = mCachedSource;
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index 9adb841..4f183f5 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -177,7 +177,10 @@
////////////////////////////////////////////////////////////////////////////////
-NuCachedSource2::NuCachedSource2(const sp<DataSource> &source)
+NuCachedSource2::NuCachedSource2(
+ const sp<DataSource> &source,
+ const char *cacheConfig,
+ bool disconnectAtHighwatermark)
: mSource(source),
mReflector(new AHandlerReflector<NuCachedSource2>(this)),
mLooper(new ALooper),
@@ -190,9 +193,24 @@
mNumRetriesLeft(kMaxNumRetries),
mHighwaterThresholdBytes(kDefaultHighWaterThreshold),
mLowwaterThresholdBytes(kDefaultLowWaterThreshold),
- mKeepAliveIntervalUs(kDefaultKeepAliveIntervalUs) {
+ mKeepAliveIntervalUs(kDefaultKeepAliveIntervalUs),
+ mDisconnectAtHighwatermark(disconnectAtHighwatermark) {
+ // We are NOT going to support disconnect-at-highwatermark indefinitely
+ // and we are not guaranteeing support for client-specified cache
+ // parameters. Both of these are temporary measures to solve a specific
+ // problem that will be solved in a better way going forward.
+
updateCacheParamsFromSystemProperty();
+ if (cacheConfig != NULL) {
+ updateCacheParamsFromString(cacheConfig);
+ }
+
+ if (mDisconnectAtHighwatermark) {
+ // Makes no sense to disconnect and do keep-alives...
+ mKeepAliveIntervalUs = 0;
+ }
+
mLooper->setName("NuCachedSource2");
mLooper->registerHandler(mReflector);
mLooper->start();
@@ -339,6 +357,12 @@
if (mFetching && mCache->totalSize() >= mHighwaterThresholdBytes) {
LOGI("Cache full, done prefetching for now");
mFetching = false;
+
+ if (mDisconnectAtHighwatermark
+ && (mSource->flags() & DataSource::kIsHTTPBasedSource)) {
+ LOGV("Disconnecting at high watermark");
+ static_cast<HTTPBase *>(mSource.get())->disconnect();
+ }
}
} else {
Mutex::Autolock autoLock(mLock);
@@ -637,4 +661,34 @@
mKeepAliveIntervalUs);
}
+// static
+void NuCachedSource2::RemoveCacheSpecificHeaders(
+ KeyedVector<String8, String8> *headers,
+ String8 *cacheConfig,
+ bool *disconnectAtHighwatermark) {
+ *cacheConfig = String8();
+ *disconnectAtHighwatermark = false;
+
+ if (headers == NULL) {
+ return;
+ }
+
+ ssize_t index;
+ if ((index = headers->indexOfKey(String8("x-cache-config"))) >= 0) {
+ *cacheConfig = headers->valueAt(index);
+
+ headers->removeItemsAt(index);
+
+ LOGV("Using special cache config '%s'", cacheConfig->string());
+ }
+
+ if ((index = headers->indexOfKey(
+ String8("x-disconnect-at-highwatermark"))) >= 0) {
+ *disconnectAtHighwatermark = true;
+ headers->removeItemsAt(index);
+
+ LOGV("Client requested disconnection at highwater mark");
+ }
+}
+
} // namespace android
diff --git a/media/libstagefright/include/NuCachedSource2.h b/media/libstagefright/include/NuCachedSource2.h
index f04c566..7a03e7e 100644
--- a/media/libstagefright/include/NuCachedSource2.h
+++ b/media/libstagefright/include/NuCachedSource2.h
@@ -28,7 +28,10 @@
struct PageCache;
struct NuCachedSource2 : public DataSource {
- NuCachedSource2(const sp<DataSource> &source);
+ NuCachedSource2(
+ const sp<DataSource> &source,
+ const char *cacheConfig = NULL,
+ bool disconnectAtHighwatermark = false);
virtual status_t initCheck() const;
@@ -56,6 +59,11 @@
status_t getEstimatedBandwidthKbps(int32_t *kbps);
status_t setCacheStatCollectFreq(int32_t freqMs);
+ static void RemoveCacheSpecificHeaders(
+ KeyedVector<String8, String8> *headers,
+ String8 *cacheConfig,
+ bool *disconnectAtHighwatermark);
+
protected:
virtual ~NuCachedSource2();
@@ -105,6 +113,8 @@
// If the keep-alive interval is 0, keep-alives are disabled.
int64_t mKeepAliveIntervalUs;
+ bool mDisconnectAtHighwatermark;
+
void onMessageReceived(const sp<AMessage> &msg);
void onFetch();
void onRead(const sp<AMessage> &msg);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
index b851ab7..2444829 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsBackupAgent.java
@@ -350,16 +350,21 @@
private byte[] getSystemSettings() {
Cursor cursor = getContentResolver().query(Settings.System.CONTENT_URI, PROJECTION, null,
null, null);
- byte[] result = extractRelevantValues(cursor, Settings.System.SETTINGS_TO_BACKUP);
- cursor.close();
- return result;
+ try {
+ return extractRelevantValues(cursor, Settings.System.SETTINGS_TO_BACKUP);
+ } finally {
+ cursor.close();
+ }
}
private byte[] getSecureSettings() {
Cursor cursor = getContentResolver().query(Settings.Secure.CONTENT_URI, PROJECTION, null,
null, null);
- byte[] result = extractRelevantValues(cursor, Settings.Secure.SETTINGS_TO_BACKUP);
- return result;
+ try {
+ return extractRelevantValues(cursor, Settings.Secure.SETTINGS_TO_BACKUP);
+ } finally {
+ cursor.close();
+ }
}
private void restoreSettings(BackupDataInput data, Uri contentUri) {
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 51eb0a3..dab0705 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -22,6 +22,9 @@
ifeq ($(TARGET_BOARD_PLATFORM), omap3)
LOCAL_CFLAGS += -DNO_RGBX_8888
endif
+ifeq ($(TARGET_BOARD_PLATFORM), omap4)
+ LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY
+endif
ifeq ($(TARGET_BOARD_PLATFORM), s5pc110)
LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY -DNEVER_DEFAULT_TO_ASYNC_MODE
endif