From 116d12b87f319767618e2c0827544412e7e3fd67 Mon Sep 17 00:00:00 2001 From: The Android Automerger Date: Wed, 2 Nov 2011 04:41:24 -0700 Subject: [PATCH 01/13] Revert "Merge "BatteryService(jni): properly handle read's return value" into ics-mr0" This reverts commit f0ad147fc33cf55cd9427010b2cdb3eb89b9eec3, reversing changes made to bd9b1528051a1b257768fdbc5077a2d4473b02dd. --- services/jni/com_android_server_BatteryService.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/services/jni/com_android_server_BatteryService.cpp b/services/jni/com_android_server_BatteryService.cpp index 2ceb5356e624b..b9f2c1f182d17 100644 --- a/services/jni/com_android_server_BatteryService.cpp +++ b/services/jni/com_android_server_BatteryService.cpp @@ -141,10 +141,10 @@ static int readFromFile(const char* path, char* buf, size_t size) return -1; } - ssize_t count = read(fd, buf, size); + size_t count = read(fd, buf, size); if (count > 0) { - while (count > 0 && buf[count-1] == '\n') - count--; + count = (count < size) ? count : size - 1; + while (count > 0 && buf[count-1] == '\n') count--; buf[count] = '\0'; } else { buf[0] = '\0'; From 5db81e1f1c19ab93c1126a9092213812629c9ece Mon Sep 17 00:00:00 2001 From: The Android Automerger Date: Wed, 2 Nov 2011 10:05:33 -0700 Subject: [PATCH 02/13] Revert "Merge "Improve the slow query instrumentation." into ics-mr0" This reverts commit 2d280f754e32e556407df05d977cfabdfff1c070, reversing changes made to 2cc1c5d067736f221554be593c2ba2c96390f847. --- core/java/android/database/CursorWindow.java | 18 ------------ .../database/sqlite/SQLiteDatabase.java | 28 +++++++++++++++++++ .../android/database/sqlite/SQLiteDebug.java | 24 ---------------- .../android/database/sqlite/SQLiteQuery.java | 20 +------------ core/java/android/os/Build.java | 7 ----- core/jni/android_database_CursorWindow.cpp | 7 ----- libs/binder/CursorWindow.cpp | 2 +- 7 files changed, 30 insertions(+), 76 deletions(-) diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java index a1be121aaf9d2..380236b499487 100644 --- a/core/java/android/database/CursorWindow.java +++ b/core/java/android/database/CursorWindow.java @@ -55,7 +55,6 @@ public class CursorWindow extends SQLiteClosable implements Parcelable { public int mWindowPtr; private int mStartPos; - private final String mName; private final CloseGuard mCloseGuard = CloseGuard.get(); @@ -86,8 +85,6 @@ public class CursorWindow extends SQLiteClosable implements Parcelable { private static native boolean nativePutDouble(int windowPtr, double value, int row, int column); private static native boolean nativePutNull(int windowPtr, int row, int column); - private static native String nativeGetName(int windowPtr); - /** * Creates a new empty cursor window and gives it a name. *

@@ -103,7 +100,6 @@ public class CursorWindow extends SQLiteClosable implements Parcelable { */ public CursorWindow(String name, boolean localWindow) { mStartPos = 0; - mName = name; mWindowPtr = nativeCreate(name, sCursorWindowSize, localWindow); if (mWindowPtr == 0) { throw new CursorWindowAllocationException("Cursor window allocation of " + @@ -134,7 +130,6 @@ public class CursorWindow extends SQLiteClosable implements Parcelable { throw new CursorWindowAllocationException("Cursor window could not be " + "created from binder."); } - mName = nativeGetName(mWindowPtr); mCloseGuard.open("close"); } @@ -161,14 +156,6 @@ public class CursorWindow extends SQLiteClosable implements Parcelable { } } - /** - * Gets the name of this cursor window. - * @hide - */ - public String getName() { - return mName; - } - /** * Closes the cursor window and frees its underlying resources when all other * remaining references have been released. @@ -791,9 +778,4 @@ public class CursorWindow extends SQLiteClosable implements Parcelable { String s = (buff.length() > 980) ? buff.substring(0, 980) : buff.toString(); return "# Open Cursors=" + total + s; } - - @Override - public String toString() { - return getName() + " {" + Integer.toHexString(mWindowPtr) + "}"; - } } diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java index f990be60809da..00d7ce80a6fa8 100644 --- a/core/java/android/database/sqlite/SQLiteDatabase.java +++ b/core/java/android/database/sqlite/SQLiteDatabase.java @@ -306,6 +306,10 @@ public class SQLiteDatabase extends SQLiteClosable { /** Used to find out where this object was created in case it never got closed. */ private final Throwable mStackTrace; + // System property that enables logging of slow queries. Specify the threshold in ms. + private static final String LOG_SLOW_QUERIES_PROPERTY = "db.log.slow_query_threshold"; + private final int mSlowQueryThreshold; + /** stores the list of statement ids that need to be finalized by sqlite */ private final ArrayList mClosedStatementIds = new ArrayList(); @@ -1555,6 +1559,11 @@ public class SQLiteDatabase extends SQLiteClosable { String editTable) { verifyDbIsOpen(); BlockGuard.getThreadPolicy().onReadFromDisk(); + long timeStart = 0; + + if (false || mSlowQueryThreshold != -1) { + timeStart = System.currentTimeMillis(); + } SQLiteDatabase db = getDbConnection(sql); SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(db, sql, editTable); @@ -1565,6 +1574,24 @@ public class SQLiteDatabase extends SQLiteClosable { cursorFactory != null ? cursorFactory : mFactory, selectionArgs); } finally { + if (false || mSlowQueryThreshold != -1) { + + // Force query execution + int count = -1; + if (cursor != null) { + count = cursor.getCount(); + } + + long duration = System.currentTimeMillis() - timeStart; + + if (false || duration >= mSlowQueryThreshold) { + Log.v(SQLiteCursor.TAG, + "query (" + duration + " ms): " + driver.toString() + ", args are " + + (selectionArgs != null + ? TextUtils.join(",", selectionArgs) + : "") + ", count is " + count); + } + } releaseDbConnection(db); } return cursor; @@ -1940,6 +1967,7 @@ public class SQLiteDatabase extends SQLiteClosable { setMaxSqlCacheSize(DEFAULT_SQL_CACHE_SIZE); mFlags = flags; mPath = path; + mSlowQueryThreshold = SystemProperties.getInt(LOG_SLOW_QUERIES_PROPERTY, -1); mStackTrace = new DatabaseObjectNotClosedException().fillInStackTrace(); mFactory = factory; mPrograms = new WeakHashMap(); diff --git a/core/java/android/database/sqlite/SQLiteDebug.java b/core/java/android/database/sqlite/SQLiteDebug.java index cc057e016fe3d..9496079178e61 100644 --- a/core/java/android/database/sqlite/SQLiteDebug.java +++ b/core/java/android/database/sqlite/SQLiteDebug.java @@ -18,8 +18,6 @@ package android.database.sqlite; import java.util.ArrayList; -import android.os.Build; -import android.os.SystemProperties; import android.util.Log; /** @@ -66,28 +64,6 @@ public final class SQLiteDebug { public static final boolean DEBUG_LOCK_TIME_TRACKING_STACK_TRACE = Log.isLoggable("SQLiteLockStackTrace", Log.VERBOSE); - /** - * True to enable database performance testing instrumentation. - * @hide - */ - public static final boolean DEBUG_LOG_SLOW_QUERIES = Build.IS_DEBUGGABLE; - - /** - * Determines whether a query should be logged. - * - * Reads the "db.log.slow_query_threshold" system property, which can be changed - * by the user at any time. If the value is zero, then all queries will - * be considered slow. If the value does not exist, then no queries will - * be considered slow. - * - * This value can be changed dynamically while the system is running. - * @hide - */ - public static final boolean shouldLogSlowQuery(long elapsedTimeMillis) { - int slowQueryMillis = SystemProperties.getInt("db.log.slow_query_threshold", -1); - return slowQueryMillis >= 0 && elapsedTimeMillis > slowQueryMillis; - } - /** * Contains statistics about the active pagers in the current process. * diff --git a/core/java/android/database/sqlite/SQLiteQuery.java b/core/java/android/database/sqlite/SQLiteQuery.java index faf6cba106799..7db0914140b2f 100644 --- a/core/java/android/database/sqlite/SQLiteQuery.java +++ b/core/java/android/database/sqlite/SQLiteQuery.java @@ -18,7 +18,6 @@ package android.database.sqlite; import android.database.CursorWindow; import android.os.SystemClock; -import android.text.TextUtils; import android.util.Log; /** @@ -33,7 +32,6 @@ public class SQLiteQuery extends SQLiteProgram { private static native int nativeFillWindow(int databasePtr, int statementPtr, int windowPtr, int startPos, int offsetParam); - private static native int nativeColumnCount(int statementPtr); private static native String nativeColumnName(int statementPtr, int columnIndex); @@ -82,24 +80,8 @@ public class SQLiteQuery extends SQLiteProgram { acquireReference(); try { window.acquireReference(); - int startPos = window.getStartPosition(); int numRows = nativeFillWindow(nHandle, nStatement, window.mWindowPtr, - startPos, mOffsetIndex); - if (SQLiteDebug.DEBUG_LOG_SLOW_QUERIES) { - long elapsed = SystemClock.uptimeMillis() - timeStart; - if (SQLiteDebug.shouldLogSlowQuery(elapsed)) { - Log.d(TAG, "fillWindow took " + elapsed - + " ms: window=\"" + window - + "\", startPos=" + startPos - + ", offset=" + mOffsetIndex - + ", filledRows=" + window.getNumRows() - + ", countedRows=" + numRows - + ", query=\"" + mSql + "\"" - + ", args=[" + (mBindArgs != null ? - TextUtils.join(", ", mBindArgs.values()) : "") - + "]"); - } - } + window.getStartPosition(), mOffsetIndex); mDatabase.logTimeStat(mSql, timeStart); return numRows; } catch (IllegalStateException e){ diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index 17a882de1a8c1..5faab36039866 100644 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -325,13 +325,6 @@ public class Build { public static final String USER = getString("ro.build.user"); public static final String HOST = getString("ro.build.host"); - /** - * Returns true if we are running a debug build such as "user-debug" or "eng". - * @hide - */ - public static final boolean IS_DEBUGGABLE = - SystemProperties.getInt("ro.debuggable", 0) == 1; - /** * Returns the version string for the radio firmware. May return * null (if, for instance, the radio is not currently on). diff --git a/core/jni/android_database_CursorWindow.cpp b/core/jni/android_database_CursorWindow.cpp index 9725c9ff6768e..722aeea682966 100644 --- a/core/jni/android_database_CursorWindow.cpp +++ b/core/jni/android_database_CursorWindow.cpp @@ -104,11 +104,6 @@ static void nativeDispose(JNIEnv* env, jclass clazz, jint windowPtr) { } } -static jstring nativeGetName(JNIEnv* env, jclass clazz, jint windowPtr) { - CursorWindow* window = reinterpret_cast(windowPtr); - return env->NewStringUTF(window->name().string()); -} - static void nativeWriteToParcel(JNIEnv * env, jclass clazz, jint windowPtr, jobject parcelObj) { CursorWindow* window = reinterpret_cast(windowPtr); @@ -490,8 +485,6 @@ static JNINativeMethod sMethods[] = (void*)nativeDispose }, { "nativeWriteToParcel", "(ILandroid/os/Parcel;)V", (void*)nativeWriteToParcel }, - { "nativeGetName", "(I)Ljava/lang/String;", - (void*)nativeGetName }, { "nativeClear", "(I)V", (void*)nativeClear }, { "nativeGetNumRows", "(I)I", diff --git a/libs/binder/CursorWindow.cpp b/libs/binder/CursorWindow.cpp index 60681c420715c..1b85a71ca8ffc 100644 --- a/libs/binder/CursorWindow.cpp +++ b/libs/binder/CursorWindow.cpp @@ -211,7 +211,7 @@ uint32_t CursorWindow::alloc(size_t size, bool aligned) { uint32_t offset = mHeader->freeOffset + padding; uint32_t nextFreeOffset = offset + size; if (nextFreeOffset > mSize) { - LOGW("Window is full: requested allocation %d bytes, " + LOGE("Window is full: requested allocation %d bytes, " "free space %d bytes, window size %d bytes", size, freeSpace(), mSize); return 0; From 5070dd097caa6f935803a933117fe6b3000bda47 Mon Sep 17 00:00:00 2001 From: The Android Automerger Date: Wed, 2 Nov 2011 10:07:57 -0700 Subject: [PATCH 03/13] Revert "Merge "Fix potential segfault in RS watchdog." into ics-mr0" This reverts commit af675222f6340a8a9edbe9e8635014a18521e5e0, reversing changes made to 6e91e5b689a3eb8e6a6f3c038322b8044a9d6670. --- libs/rs/rsContext.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp index 5291a1f73f2e3..948ecf90a732e 100644 --- a/libs/rs/rsContext.cpp +++ b/libs/rs/rsContext.cpp @@ -359,7 +359,6 @@ Context::Context() { mTargetSdkVersion = 14; mDPI = 96; mIsContextLite = false; - memset(&watchdog, 0, sizeof(watchdog)); } Context * Context::createContext(Device *dev, const RsSurfaceConfig *sc) { From 8e31988d264785f05b97606a09d2d65de0d59904 Mon Sep 17 00:00:00 2001 From: The Android Automerger Date: Wed, 2 Nov 2011 10:14:18 -0700 Subject: [PATCH 04/13] Revert "Merge "Update camera continuous autofocus javadoc." into ics-mr0" This reverts commit 4b6353ea0265bfed52d0637abd1b17596ce25ff0, reversing changes made to af675222f6340a8a9edbe9e8635014a18521e5e0. --- core/java/android/hardware/Camera.java | 21 +++++++++------------ include/camera/CameraParameters.h | 20 +++++++++----------- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java index 68f0247600b16..caad6fde9436e 100644 --- a/core/java/android/hardware/Camera.java +++ b/core/java/android/hardware/Camera.java @@ -1687,18 +1687,15 @@ public class Camera { * aggressive than {@link #FOCUS_MODE_CONTINUOUS_VIDEO}. Auto focus * starts when the parameter is set. * - *

Applications can call {@link #autoFocus(AutoFocusCallback)} in - * this mode. If the autofocus is in the middle of scanning, the focus - * callback will return when it completes. If the autofocus is not - * scanning, the focus callback will immediately return with a boolean - * that indicates whether the focus is sharp or not. The apps can then - * decide if they want to take a picture immediately or to change the - * focus mode to auto, and run a full autofocus cycle. The focus - * position is locked after autoFocus call. If applications want to - * resume the continuous focus, cancelAutoFocus must be called. - * Restarting the preview will not resume the continuous autofocus. To - * stop continuous focus, applications should change the focus mode to - * other modes. + *

If applications call {@link #autoFocus(AutoFocusCallback)} in this + * mode, the focus callback will immediately return with a boolean that + * indicates whether the focus is sharp or not. The apps can then decide + * if they want to take a picture immediately or to change the focus + * mode to auto, and run a full autofocus cycle. The focus position is + * locked after autoFocus call. If applications want to resume the + * continuous focus, cancelAutoFocus must be called. Restarting the + * preview will not resume the continuous autofocus. To stop continuous + * focus, applications should change the focus mode to other modes. * * @see #FOCUS_MODE_CONTINUOUS_VIDEO */ diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h index 7edf6b4562ff3..ef4cf5c705fce 100644 --- a/include/camera/CameraParameters.h +++ b/include/camera/CameraParameters.h @@ -644,17 +644,15 @@ public: // than FOCUS_MODE_CONTINUOUS_VIDEO. Auto focus starts when the parameter is // set. // - // Applications can call CameraHardwareInterface.autoFocus in this mode. If - // the autofocus is in the middle of scanning, the focus callback will - // return when it completes. If the autofocus is not scanning, focus - // callback will immediately return with a boolean that indicates whether - // the focus is sharp or not. The apps can then decide if they want to take - // a picture immediately or to change the focus mode to auto, and run a full - // autofocus cycle. The focus position is locked after autoFocus call. If - // applications want to resume the continuous focus, cancelAutoFocus must be - // called. Restarting the preview will not resume the continuous autofocus. - // To stop continuous focus, applications should change the focus mode to - // other modes. + // If applications call CameraHardwareInterface.autoFocus in this mode, the + // focus callback will immediately return with a boolean that indicates + // whether the focus is sharp or not. The apps can then decide if they want + // to take a picture immediately or to change the focus mode to auto, and + // run a full autofocus cycle. The focus position is locked after autoFocus + // call. If applications want to resume the continuous focus, + // cancelAutoFocus must be called. Restarting the preview will not resume + // the continuous autofocus. To stop continuous focus, applications should + // change the focus mode to other modes. static const char FOCUS_MODE_CONTINUOUS_PICTURE[]; private: From beb470af433368bb423c0efd57de77c0a933e7bd Mon Sep 17 00:00:00 2001 From: The Android Automerger Date: Wed, 2 Nov 2011 10:18:09 -0700 Subject: [PATCH 05/13] Revert "Merge "BatteryService(jni): properly handle read's return value" into ics-mr0" This reverts commit f0ad147fc33cf55cd9427010b2cdb3eb89b9eec3, reversing changes made to bd9b1528051a1b257768fdbc5077a2d4473b02dd. --- services/jni/com_android_server_BatteryService.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/services/jni/com_android_server_BatteryService.cpp b/services/jni/com_android_server_BatteryService.cpp index 2ceb5356e624b..b9f2c1f182d17 100644 --- a/services/jni/com_android_server_BatteryService.cpp +++ b/services/jni/com_android_server_BatteryService.cpp @@ -141,10 +141,10 @@ static int readFromFile(const char* path, char* buf, size_t size) return -1; } - ssize_t count = read(fd, buf, size); + size_t count = read(fd, buf, size); if (count > 0) { - while (count > 0 && buf[count-1] == '\n') - count--; + count = (count < size) ? count : size - 1; + while (count > 0 && buf[count-1] == '\n') count--; buf[count] = '\0'; } else { buf[0] = '\0'; From 50b193c82d0458a1c225f3042f84618fe3408482 Mon Sep 17 00:00:00 2001 From: The Android Automerger Date: Wed, 2 Nov 2011 20:58:00 -0700 Subject: [PATCH 06/13] Revert "Merge "Improve the slow query instrumentation." into ics-mr0" This reverts commit 2d280f754e32e556407df05d977cfabdfff1c070, reversing changes made to 2cc1c5d067736f221554be593c2ba2c96390f847. --- core/java/android/database/CursorWindow.java | 18 ------------ .../database/sqlite/SQLiteDatabase.java | 28 +++++++++++++++++++ .../android/database/sqlite/SQLiteDebug.java | 24 ---------------- .../android/database/sqlite/SQLiteQuery.java | 20 +------------ core/java/android/os/Build.java | 7 ----- core/jni/android_database_CursorWindow.cpp | 7 ----- libs/binder/CursorWindow.cpp | 2 +- 7 files changed, 30 insertions(+), 76 deletions(-) diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java index a1be121aaf9d2..380236b499487 100644 --- a/core/java/android/database/CursorWindow.java +++ b/core/java/android/database/CursorWindow.java @@ -55,7 +55,6 @@ public class CursorWindow extends SQLiteClosable implements Parcelable { public int mWindowPtr; private int mStartPos; - private final String mName; private final CloseGuard mCloseGuard = CloseGuard.get(); @@ -86,8 +85,6 @@ public class CursorWindow extends SQLiteClosable implements Parcelable { private static native boolean nativePutDouble(int windowPtr, double value, int row, int column); private static native boolean nativePutNull(int windowPtr, int row, int column); - private static native String nativeGetName(int windowPtr); - /** * Creates a new empty cursor window and gives it a name. *

@@ -103,7 +100,6 @@ public class CursorWindow extends SQLiteClosable implements Parcelable { */ public CursorWindow(String name, boolean localWindow) { mStartPos = 0; - mName = name; mWindowPtr = nativeCreate(name, sCursorWindowSize, localWindow); if (mWindowPtr == 0) { throw new CursorWindowAllocationException("Cursor window allocation of " + @@ -134,7 +130,6 @@ public class CursorWindow extends SQLiteClosable implements Parcelable { throw new CursorWindowAllocationException("Cursor window could not be " + "created from binder."); } - mName = nativeGetName(mWindowPtr); mCloseGuard.open("close"); } @@ -161,14 +156,6 @@ public class CursorWindow extends SQLiteClosable implements Parcelable { } } - /** - * Gets the name of this cursor window. - * @hide - */ - public String getName() { - return mName; - } - /** * Closes the cursor window and frees its underlying resources when all other * remaining references have been released. @@ -791,9 +778,4 @@ public class CursorWindow extends SQLiteClosable implements Parcelable { String s = (buff.length() > 980) ? buff.substring(0, 980) : buff.toString(); return "# Open Cursors=" + total + s; } - - @Override - public String toString() { - return getName() + " {" + Integer.toHexString(mWindowPtr) + "}"; - } } diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java index f990be60809da..00d7ce80a6fa8 100644 --- a/core/java/android/database/sqlite/SQLiteDatabase.java +++ b/core/java/android/database/sqlite/SQLiteDatabase.java @@ -306,6 +306,10 @@ public class SQLiteDatabase extends SQLiteClosable { /** Used to find out where this object was created in case it never got closed. */ private final Throwable mStackTrace; + // System property that enables logging of slow queries. Specify the threshold in ms. + private static final String LOG_SLOW_QUERIES_PROPERTY = "db.log.slow_query_threshold"; + private final int mSlowQueryThreshold; + /** stores the list of statement ids that need to be finalized by sqlite */ private final ArrayList mClosedStatementIds = new ArrayList(); @@ -1555,6 +1559,11 @@ public class SQLiteDatabase extends SQLiteClosable { String editTable) { verifyDbIsOpen(); BlockGuard.getThreadPolicy().onReadFromDisk(); + long timeStart = 0; + + if (false || mSlowQueryThreshold != -1) { + timeStart = System.currentTimeMillis(); + } SQLiteDatabase db = getDbConnection(sql); SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(db, sql, editTable); @@ -1565,6 +1574,24 @@ public class SQLiteDatabase extends SQLiteClosable { cursorFactory != null ? cursorFactory : mFactory, selectionArgs); } finally { + if (false || mSlowQueryThreshold != -1) { + + // Force query execution + int count = -1; + if (cursor != null) { + count = cursor.getCount(); + } + + long duration = System.currentTimeMillis() - timeStart; + + if (false || duration >= mSlowQueryThreshold) { + Log.v(SQLiteCursor.TAG, + "query (" + duration + " ms): " + driver.toString() + ", args are " + + (selectionArgs != null + ? TextUtils.join(",", selectionArgs) + : "") + ", count is " + count); + } + } releaseDbConnection(db); } return cursor; @@ -1940,6 +1967,7 @@ public class SQLiteDatabase extends SQLiteClosable { setMaxSqlCacheSize(DEFAULT_SQL_CACHE_SIZE); mFlags = flags; mPath = path; + mSlowQueryThreshold = SystemProperties.getInt(LOG_SLOW_QUERIES_PROPERTY, -1); mStackTrace = new DatabaseObjectNotClosedException().fillInStackTrace(); mFactory = factory; mPrograms = new WeakHashMap(); diff --git a/core/java/android/database/sqlite/SQLiteDebug.java b/core/java/android/database/sqlite/SQLiteDebug.java index cc057e016fe3d..9496079178e61 100644 --- a/core/java/android/database/sqlite/SQLiteDebug.java +++ b/core/java/android/database/sqlite/SQLiteDebug.java @@ -18,8 +18,6 @@ package android.database.sqlite; import java.util.ArrayList; -import android.os.Build; -import android.os.SystemProperties; import android.util.Log; /** @@ -66,28 +64,6 @@ public final class SQLiteDebug { public static final boolean DEBUG_LOCK_TIME_TRACKING_STACK_TRACE = Log.isLoggable("SQLiteLockStackTrace", Log.VERBOSE); - /** - * True to enable database performance testing instrumentation. - * @hide - */ - public static final boolean DEBUG_LOG_SLOW_QUERIES = Build.IS_DEBUGGABLE; - - /** - * Determines whether a query should be logged. - * - * Reads the "db.log.slow_query_threshold" system property, which can be changed - * by the user at any time. If the value is zero, then all queries will - * be considered slow. If the value does not exist, then no queries will - * be considered slow. - * - * This value can be changed dynamically while the system is running. - * @hide - */ - public static final boolean shouldLogSlowQuery(long elapsedTimeMillis) { - int slowQueryMillis = SystemProperties.getInt("db.log.slow_query_threshold", -1); - return slowQueryMillis >= 0 && elapsedTimeMillis > slowQueryMillis; - } - /** * Contains statistics about the active pagers in the current process. * diff --git a/core/java/android/database/sqlite/SQLiteQuery.java b/core/java/android/database/sqlite/SQLiteQuery.java index faf6cba106799..7db0914140b2f 100644 --- a/core/java/android/database/sqlite/SQLiteQuery.java +++ b/core/java/android/database/sqlite/SQLiteQuery.java @@ -18,7 +18,6 @@ package android.database.sqlite; import android.database.CursorWindow; import android.os.SystemClock; -import android.text.TextUtils; import android.util.Log; /** @@ -33,7 +32,6 @@ public class SQLiteQuery extends SQLiteProgram { private static native int nativeFillWindow(int databasePtr, int statementPtr, int windowPtr, int startPos, int offsetParam); - private static native int nativeColumnCount(int statementPtr); private static native String nativeColumnName(int statementPtr, int columnIndex); @@ -82,24 +80,8 @@ public class SQLiteQuery extends SQLiteProgram { acquireReference(); try { window.acquireReference(); - int startPos = window.getStartPosition(); int numRows = nativeFillWindow(nHandle, nStatement, window.mWindowPtr, - startPos, mOffsetIndex); - if (SQLiteDebug.DEBUG_LOG_SLOW_QUERIES) { - long elapsed = SystemClock.uptimeMillis() - timeStart; - if (SQLiteDebug.shouldLogSlowQuery(elapsed)) { - Log.d(TAG, "fillWindow took " + elapsed - + " ms: window=\"" + window - + "\", startPos=" + startPos - + ", offset=" + mOffsetIndex - + ", filledRows=" + window.getNumRows() - + ", countedRows=" + numRows - + ", query=\"" + mSql + "\"" - + ", args=[" + (mBindArgs != null ? - TextUtils.join(", ", mBindArgs.values()) : "") - + "]"); - } - } + window.getStartPosition(), mOffsetIndex); mDatabase.logTimeStat(mSql, timeStart); return numRows; } catch (IllegalStateException e){ diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java index 17a882de1a8c1..5faab36039866 100644 --- a/core/java/android/os/Build.java +++ b/core/java/android/os/Build.java @@ -325,13 +325,6 @@ public class Build { public static final String USER = getString("ro.build.user"); public static final String HOST = getString("ro.build.host"); - /** - * Returns true if we are running a debug build such as "user-debug" or "eng". - * @hide - */ - public static final boolean IS_DEBUGGABLE = - SystemProperties.getInt("ro.debuggable", 0) == 1; - /** * Returns the version string for the radio firmware. May return * null (if, for instance, the radio is not currently on). diff --git a/core/jni/android_database_CursorWindow.cpp b/core/jni/android_database_CursorWindow.cpp index 9725c9ff6768e..722aeea682966 100644 --- a/core/jni/android_database_CursorWindow.cpp +++ b/core/jni/android_database_CursorWindow.cpp @@ -104,11 +104,6 @@ static void nativeDispose(JNIEnv* env, jclass clazz, jint windowPtr) { } } -static jstring nativeGetName(JNIEnv* env, jclass clazz, jint windowPtr) { - CursorWindow* window = reinterpret_cast(windowPtr); - return env->NewStringUTF(window->name().string()); -} - static void nativeWriteToParcel(JNIEnv * env, jclass clazz, jint windowPtr, jobject parcelObj) { CursorWindow* window = reinterpret_cast(windowPtr); @@ -490,8 +485,6 @@ static JNINativeMethod sMethods[] = (void*)nativeDispose }, { "nativeWriteToParcel", "(ILandroid/os/Parcel;)V", (void*)nativeWriteToParcel }, - { "nativeGetName", "(I)Ljava/lang/String;", - (void*)nativeGetName }, { "nativeClear", "(I)V", (void*)nativeClear }, { "nativeGetNumRows", "(I)I", diff --git a/libs/binder/CursorWindow.cpp b/libs/binder/CursorWindow.cpp index 60681c420715c..1b85a71ca8ffc 100644 --- a/libs/binder/CursorWindow.cpp +++ b/libs/binder/CursorWindow.cpp @@ -211,7 +211,7 @@ uint32_t CursorWindow::alloc(size_t size, bool aligned) { uint32_t offset = mHeader->freeOffset + padding; uint32_t nextFreeOffset = offset + size; if (nextFreeOffset > mSize) { - LOGW("Window is full: requested allocation %d bytes, " + LOGE("Window is full: requested allocation %d bytes, " "free space %d bytes, window size %d bytes", size, freeSpace(), mSize); return 0; From 54b212c75e17ffb963b1266c31f1908a1a70ca71 Mon Sep 17 00:00:00 2001 From: The Android Automerger Date: Wed, 2 Nov 2011 20:58:26 -0700 Subject: [PATCH 07/13] Revert "Merge "Fix potential segfault in RS watchdog." into ics-mr0" This reverts commit af675222f6340a8a9edbe9e8635014a18521e5e0, reversing changes made to 6e91e5b689a3eb8e6a6f3c038322b8044a9d6670. --- libs/rs/rsContext.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp index 5291a1f73f2e3..948ecf90a732e 100644 --- a/libs/rs/rsContext.cpp +++ b/libs/rs/rsContext.cpp @@ -359,7 +359,6 @@ Context::Context() { mTargetSdkVersion = 14; mDPI = 96; mIsContextLite = false; - memset(&watchdog, 0, sizeof(watchdog)); } Context * Context::createContext(Device *dev, const RsSurfaceConfig *sc) { From f17756f8e60ba192d1c222d9d180b41fdbdbec32 Mon Sep 17 00:00:00 2001 From: The Android Automerger Date: Wed, 2 Nov 2011 20:59:04 -0700 Subject: [PATCH 08/13] Revert "Merge "Update camera continuous autofocus javadoc." into ics-mr0" This reverts commit 4b6353ea0265bfed52d0637abd1b17596ce25ff0, reversing changes made to af675222f6340a8a9edbe9e8635014a18521e5e0. --- core/java/android/hardware/Camera.java | 21 +++++++++------------ include/camera/CameraParameters.h | 20 +++++++++----------- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java index 68f0247600b16..caad6fde9436e 100644 --- a/core/java/android/hardware/Camera.java +++ b/core/java/android/hardware/Camera.java @@ -1687,18 +1687,15 @@ public class Camera { * aggressive than {@link #FOCUS_MODE_CONTINUOUS_VIDEO}. Auto focus * starts when the parameter is set. * - *

Applications can call {@link #autoFocus(AutoFocusCallback)} in - * this mode. If the autofocus is in the middle of scanning, the focus - * callback will return when it completes. If the autofocus is not - * scanning, the focus callback will immediately return with a boolean - * that indicates whether the focus is sharp or not. The apps can then - * decide if they want to take a picture immediately or to change the - * focus mode to auto, and run a full autofocus cycle. The focus - * position is locked after autoFocus call. If applications want to - * resume the continuous focus, cancelAutoFocus must be called. - * Restarting the preview will not resume the continuous autofocus. To - * stop continuous focus, applications should change the focus mode to - * other modes. + *

If applications call {@link #autoFocus(AutoFocusCallback)} in this + * mode, the focus callback will immediately return with a boolean that + * indicates whether the focus is sharp or not. The apps can then decide + * if they want to take a picture immediately or to change the focus + * mode to auto, and run a full autofocus cycle. The focus position is + * locked after autoFocus call. If applications want to resume the + * continuous focus, cancelAutoFocus must be called. Restarting the + * preview will not resume the continuous autofocus. To stop continuous + * focus, applications should change the focus mode to other modes. * * @see #FOCUS_MODE_CONTINUOUS_VIDEO */ diff --git a/include/camera/CameraParameters.h b/include/camera/CameraParameters.h index 7edf6b4562ff3..ef4cf5c705fce 100644 --- a/include/camera/CameraParameters.h +++ b/include/camera/CameraParameters.h @@ -644,17 +644,15 @@ public: // than FOCUS_MODE_CONTINUOUS_VIDEO. Auto focus starts when the parameter is // set. // - // Applications can call CameraHardwareInterface.autoFocus in this mode. If - // the autofocus is in the middle of scanning, the focus callback will - // return when it completes. If the autofocus is not scanning, focus - // callback will immediately return with a boolean that indicates whether - // the focus is sharp or not. The apps can then decide if they want to take - // a picture immediately or to change the focus mode to auto, and run a full - // autofocus cycle. The focus position is locked after autoFocus call. If - // applications want to resume the continuous focus, cancelAutoFocus must be - // called. Restarting the preview will not resume the continuous autofocus. - // To stop continuous focus, applications should change the focus mode to - // other modes. + // If applications call CameraHardwareInterface.autoFocus in this mode, the + // focus callback will immediately return with a boolean that indicates + // whether the focus is sharp or not. The apps can then decide if they want + // to take a picture immediately or to change the focus mode to auto, and + // run a full autofocus cycle. The focus position is locked after autoFocus + // call. If applications want to resume the continuous focus, + // cancelAutoFocus must be called. Restarting the preview will not resume + // the continuous autofocus. To stop continuous focus, applications should + // change the focus mode to other modes. static const char FOCUS_MODE_CONTINUOUS_PICTURE[]; private: From b6b117624b460fec104be94977ed64d190473182 Mon Sep 17 00:00:00 2001 From: The Android Automerger Date: Wed, 2 Nov 2011 21:04:32 -0700 Subject: [PATCH 09/13] Revert "Merge "BatteryService(jni): properly handle read's return value" into ics-mr0" This reverts commit f0ad147fc33cf55cd9427010b2cdb3eb89b9eec3, reversing changes made to bd9b1528051a1b257768fdbc5077a2d4473b02dd. --- services/jni/com_android_server_BatteryService.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/services/jni/com_android_server_BatteryService.cpp b/services/jni/com_android_server_BatteryService.cpp index 2ceb5356e624b..b9f2c1f182d17 100644 --- a/services/jni/com_android_server_BatteryService.cpp +++ b/services/jni/com_android_server_BatteryService.cpp @@ -141,10 +141,10 @@ static int readFromFile(const char* path, char* buf, size_t size) return -1; } - ssize_t count = read(fd, buf, size); + size_t count = read(fd, buf, size); if (count > 0) { - while (count > 0 && buf[count-1] == '\n') - count--; + count = (count < size) ? count : size - 1; + while (count > 0 && buf[count-1] == '\n') count--; buf[count] = '\0'; } else { buf[0] = '\0'; From 287c1e66feaf6cee7c0789d7f82940d3856eafc2 Mon Sep 17 00:00:00 2001 From: The Android Automerger Date: Wed, 2 Nov 2011 21:08:38 -0700 Subject: [PATCH 10/13] Revert "Merge "Avoid duplicate dialogs leading to NPE" into ics-mr0" This reverts commit 7f00c22b7fa7b38b644585c0a3c6faadc5def94c, reversing changes made to 451fa13e82ea1226895b41282fdb33bf9fea5d19. --- .../android/net/wifi/p2p/WifiP2pService.java | 115 +++--------------- 1 file changed, 14 insertions(+), 101 deletions(-) diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java index 6bb22a4cde93d..1b027741864c6 100644 --- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java +++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java @@ -81,7 +81,7 @@ import java.util.Collection; */ public class WifiP2pService extends IWifiP2pManager.Stub { private static final String TAG = "WifiP2pService"; - private static final boolean DBG = false; + private static final boolean DBG = true; private static final String NETWORKTYPE = "WIFI_P2P"; private Context mContext; @@ -131,22 +131,12 @@ public class WifiP2pService extends IWifiP2pManager.Stub { /* User rejected to disable Wi-Fi in order to enable p2p */ private static final int WIFI_DISABLE_USER_REJECT = BASE + 5; - /* User accepted a group negotiation request */ - private static final int GROUP_NEGOTIATION_USER_ACCEPT = BASE + 6; - /* User rejected a group negotiation request */ - private static final int GROUP_NEGOTIATION_USER_REJECT = BASE + 7; - - /* User accepted a group invitation request */ - private static final int GROUP_INVITATION_USER_ACCEPT = BASE + 8; - /* User rejected a group invitation request */ - private static final int GROUP_INVITATION_USER_REJECT = BASE + 9; - /* Airplane mode changed */ - private static final int AIRPLANE_MODE_CHANGED = BASE + 10; + private static final int AIRPLANE_MODE_CHANGED = BASE + 6; /* Emergency callback mode */ - private static final int EMERGENCY_CALLBACK_MODE = BASE + 11; - private static final int WPS_PBC = BASE + 12; - private static final int WPS_PIN = BASE + 13; + private static final int EMERGENCY_CALLBACK_MODE = BASE + 7; + private static final int WPS_PBC = BASE + 8; + private static final int WPS_PIN = BASE + 9; private final boolean mP2pSupported; @@ -270,10 +260,6 @@ public class WifiP2pService extends IWifiP2pManager.Stub { private P2pEnabledState mP2pEnabledState = new P2pEnabledState(); // Inactive is when p2p is enabled with no connectivity private InactiveState mInactiveState = new InactiveState(); - private UserAuthorizingGroupNegotiationState mUserAuthorizingGroupNegotiationState - = new UserAuthorizingGroupNegotiationState(); - private UserAuthorizingGroupInvitationState mUserAuthorizingGroupInvitationState - = new UserAuthorizingGroupInvitationState(); private GroupNegotiationState mGroupNegotiationState = new GroupNegotiationState(); private GroupCreatedState mGroupCreatedState = new GroupCreatedState(); @@ -304,8 +290,6 @@ public class WifiP2pService extends IWifiP2pManager.Stub { addState(mP2pEnablingState, mDefaultState); addState(mP2pEnabledState, mDefaultState); addState(mInactiveState, mP2pEnabledState); - addState(mUserAuthorizingGroupNegotiationState, mInactiveState); - addState(mUserAuthorizingGroupInvitationState, mInactiveState); addState(mGroupNegotiationState, mP2pEnabledState); addState(mGroupCreatedState, mP2pEnabledState); @@ -395,10 +379,6 @@ public class WifiP2pService extends IWifiP2pManager.Stub { // Ignore case WIFI_DISABLE_USER_ACCEPT: case WIFI_DISABLE_USER_REJECT: - case GROUP_NEGOTIATION_USER_ACCEPT: - case GROUP_NEGOTIATION_USER_REJECT: - case GROUP_INVITATION_USER_ACCEPT: - case GROUP_INVITATION_USER_REJECT: case GROUP_NEGOTIATION_TIMED_OUT: break; default: @@ -767,7 +747,6 @@ public class WifiP2pService extends IWifiP2pManager.Stub { case WifiMonitor.P2P_GO_NEGOTIATION_REQUEST_EVENT: mSavedGoNegotiationConfig = (WifiP2pConfig) message.obj; notifyP2pGoNegotationRequest(mSavedGoNegotiationConfig); - transitionTo(mUserAuthorizingGroupNegotiationState); break; case WifiP2pManager.CREATE_GROUP: mPersistGroup = true; @@ -782,7 +761,6 @@ public class WifiP2pService extends IWifiP2pManager.Stub { case WifiMonitor.P2P_INVITATION_RECEIVED_EVENT: WifiP2pGroup group = (WifiP2pGroup) message.obj; notifyP2pInvitationReceived(group); - transitionTo(mUserAuthorizingGroupInvitationState); break; default: return NOT_HANDLED; @@ -791,70 +769,6 @@ public class WifiP2pService extends IWifiP2pManager.Stub { } } - class UserAuthorizingGroupNegotiationState extends State { - @Override - public void enter() { - if (DBG) logd(getName()); - } - - @Override - public boolean processMessage(Message message) { - if (DBG) logd(getName() + message.toString()); - switch (message.what) { - case WifiMonitor.P2P_GO_NEGOTIATION_REQUEST_EVENT: - case WifiMonitor.P2P_INVITATION_RECEIVED_EVENT: - //Ignore additional connection requests - break; - case GROUP_NEGOTIATION_USER_ACCEPT: - sendMessage(WifiP2pManager.CONNECT, mSavedGoNegotiationConfig); - mSavedGoNegotiationConfig = null; - break; - case GROUP_NEGOTIATION_USER_REJECT: - if (DBG) logd("User rejected incoming negotiation request"); - mSavedGoNegotiationConfig = null; - transitionTo(mInactiveState); - break; - default: - return NOT_HANDLED; - } - return HANDLED; - } - } - - class UserAuthorizingGroupInvitationState extends State { - @Override - public void enter() { - if (DBG) logd(getName()); - } - - @Override - public boolean processMessage(Message message) { - if (DBG) logd(getName() + message.toString()); - switch (message.what) { - case WifiMonitor.P2P_GO_NEGOTIATION_REQUEST_EVENT: - case WifiMonitor.P2P_INVITATION_RECEIVED_EVENT: - //Ignore additional connection requests - break; - case GROUP_INVITATION_USER_ACCEPT: - if (DBG) logd(getName() + " connect to invited group"); - WifiP2pConfig config = new WifiP2pConfig(); - config.deviceAddress = mSavedP2pGroup.getOwner().deviceAddress; - sendMessage(WifiP2pManager.CONNECT, config); - mSavedP2pGroup = null; - break; - case GROUP_INVITATION_USER_REJECT: - if (DBG) logd("User rejected incoming invitation request"); - mSavedP2pGroup = null; - transitionTo(mInactiveState); - break; - default: - return NOT_HANDLED; - } - return HANDLED; - } - } - - class GroupNegotiationState extends State { @Override public void enter() { @@ -1177,14 +1091,15 @@ public class WifiP2pService extends IWifiP2pManager.Stub { mSavedGoNegotiationConfig.wps.setup = WpsInfo.KEYPAD; mSavedGoNegotiationConfig.wps.pin = pin.getText().toString(); } - sendMessage(GROUP_NEGOTIATION_USER_ACCEPT); + sendMessage(WifiP2pManager.CONNECT, mSavedGoNegotiationConfig); + mSavedGoNegotiationConfig = null; } }) .setNegativeButton(r.getString(R.string.cancel), new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (DBG) logd(getName() + " ignore connect"); - sendMessage(GROUP_NEGOTIATION_USER_REJECT); + mSavedGoNegotiationConfig = null; } }) .create(); @@ -1265,16 +1180,14 @@ public class WifiP2pService extends IWifiP2pManager.Stub { .setView(textEntryView) .setPositiveButton(r.getString(R.string.ok), new OnClickListener() { public void onClick(DialogInterface dialog, int which) { - sendMessage(GROUP_INVITATION_USER_ACCEPT); - } - }) - .setNegativeButton(r.getString(R.string.cancel), new OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - if (DBG) logd(getName() + " ignore invite"); - sendMessage(GROUP_INVITATION_USER_REJECT); + WifiP2pConfig config = new WifiP2pConfig(); + config.deviceAddress = mSavedP2pGroup.getOwner().deviceAddress; + if (DBG) logd(getName() + " connect to invited group"); + sendMessage(WifiP2pManager.CONNECT, config); + mSavedP2pGroup = null; } }) + .setNegativeButton(r.getString(R.string.cancel), null) .create(); pin.setVisibility(View.GONE); From 6d25e3400cee4ca6965a9fd22222a8389c08380c Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Thu, 3 Nov 2011 11:00:21 -0700 Subject: [PATCH 11/13] DO NOT MERGE Poll input data with a small timeout and don't consume a full core. Change-Id: I3c288698920fe6ead0df24a52330483609821a41 related-to-bug: 5549263 --- media/libmediaplayerservice/nuplayer/NuPlayer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp index 6b40528a160f4..6c541301eaf2d 100644 --- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp +++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp @@ -274,7 +274,7 @@ void NuPlayer::onMessageReceived(const sp &msg) { if (err == -EWOULDBLOCK) { if (mSource->feedMoreTSData() == OK) { - msg->post(); + msg->post(10000ll); } } } else if (what == ACodec::kWhatEOS) { From 829a6f208cbdcc9eecaa59d086b27b413e3227ee Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Fri, 4 Nov 2011 19:01:44 -0700 Subject: [PATCH 12/13] Fix a leak in Parcel::writeBlob. Was mistakenly assuming that Parcel::writeFileDescriptor took ownership of the fd that was passed in. It does not! Added some comments and a default parameter to allow the caller to specify whether it wishes the Parcel to take ownership. Bug: 5563374 Change-Id: I5a12f51d582bf246ce90133cce7690bb9bca93f6 --- include/binder/Parcel.h | 3 ++- libs/binder/Parcel.cpp | 13 ++++--------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h index 3fa2acbdaaaf0..33b2f005061eb 100644 --- a/include/binder/Parcel.h +++ b/include/binder/Parcel.h @@ -110,7 +110,8 @@ public: // Place a file descriptor into the parcel. The given fd must remain // valid for the lifetime of the parcel. - status_t writeFileDescriptor(int fd); + // The Parcel does not take ownership of the given fd unless you ask it to. + status_t writeFileDescriptor(int fd, bool takeOwnership = false); // Place a file descriptor into the parcel. A dup of the fd is made, which // will be closed once the parcel is destroyed. diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index c7180cee03cd3..6b4c1a61e4c93 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -710,24 +710,19 @@ status_t Parcel::writeNativeHandle(const native_handle* handle) return err; } -status_t Parcel::writeFileDescriptor(int fd) +status_t Parcel::writeFileDescriptor(int fd, bool takeOwnership) { flat_binder_object obj; obj.type = BINDER_TYPE_FD; obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS; obj.handle = fd; - obj.cookie = (void*)0; + obj.cookie = (void*) (takeOwnership ? 1 : 0); return writeObject(obj, true); } status_t Parcel::writeDupFileDescriptor(int fd) { - flat_binder_object obj; - obj.type = BINDER_TYPE_FD; - obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS; - obj.handle = dup(fd); - obj.cookie = (void*)1; - return writeObject(obj, true); + return writeFileDescriptor(dup(fd), true /*takeOwnership*/); } status_t Parcel::writeBlob(size_t len, WritableBlob* outBlob) @@ -764,7 +759,7 @@ status_t Parcel::writeBlob(size_t len, WritableBlob* outBlob) } else { status = writeInt32(1); if (!status) { - status = writeFileDescriptor(fd); + status = writeFileDescriptor(fd, true /*takeOwnership*/); if (!status) { outBlob->init(true /*mapped*/, ptr, len); return NO_ERROR; From fd1d05a01a704db47f6e60425c0ac3e1bd4cffbf Mon Sep 17 00:00:00 2001 From: Jeff Brown Date: Fri, 11 Nov 2011 15:03:05 -0800 Subject: [PATCH 13/13] Fix bug in TextLayoutCacheKey handling embedded nulls. We were not passing the length of the UTF-16 string to String16::setTo. As a result, it was copying the contents of the text up to the first null it found. First problem, these strings are not typically null terminated! Second problem, if the string contained a null character, then we might truncate it. However, we only truncated the string when the copy constructor was invoked (say, when we called get() on the cache) but not in internalTextCopy() (before adding the key to the cache). As a result of the second problem, we would first search the cache for a key that matched a partially copied truncated string (potentially reading uninitialized memory that followed it). Finding none, we would add the entry to the cache using the correct key. If the cache already had a value associated with the correct key, then the put would fail, returning false. Charging ever onwards, we would add the size of the entry to the cache size. Proceeding in this manner, it was possible for the cache to believe it had less remaining space than it really did. At that point, it was possible for the cache to evict all entries and yet still not think it had room to add a new one, so it would continue trying to make space indefinitely. Bug: 5576812 Change-Id: I05251594f6b2da0a5dc09f7200f04fe9100ec766 --- core/jni/android/graphics/TextLayoutCache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/jni/android/graphics/TextLayoutCache.cpp b/core/jni/android/graphics/TextLayoutCache.cpp index 7db8abd39d689..f67b8b18aa58a 100644 --- a/core/jni/android/graphics/TextLayoutCache.cpp +++ b/core/jni/android/graphics/TextLayoutCache.cpp @@ -249,7 +249,7 @@ TextLayoutCacheKey::TextLayoutCacheKey(const TextLayoutCacheKey& other) : flags(other.flags), hinting(other.hinting) { if (other.text) { - textCopy.setTo(other.text); + textCopy.setTo(other.text, other.contextCount); } }