Merge "Second of three sets of minor edits for SD card storage text."
diff --git a/core/java/android/database/sqlite/SQLiteCompiledSql.java b/core/java/android/database/sqlite/SQLiteCompiledSql.java
index 18cc1d5..816f8a8 100644
--- a/core/java/android/database/sqlite/SQLiteCompiledSql.java
+++ b/core/java/android/database/sqlite/SQLiteCompiledSql.java
@@ -93,6 +93,9 @@
// Note that native_finalize() checks to make sure that nStatement is
// non-null before destroying it.
if (nStatement != 0) {
+ if (SQLiteDebug.DEBUG_ACTIVE_CURSOR_FINALIZATION) {
+ Log.v(TAG, "closed and deallocated DbObj (id#" + nStatement +")");
+ }
try {
mDatabase.lock();
native_finalize();
@@ -112,10 +115,16 @@
return false;
}
mInUse = true;
+ if (SQLiteDebug.DEBUG_ACTIVE_CURSOR_FINALIZATION) {
+ Log.v(TAG, "Acquired DbObj (id#" + nStatement + ") from DB cache");
+ }
return true;
}
/* package */ synchronized void release() {
+ if (SQLiteDebug.DEBUG_ACTIVE_CURSOR_FINALIZATION) {
+ Log.v(TAG, "Released DbObj (id#" + nStatement + ") back to DB cache");
+ }
mInUse = false;
}
@@ -127,6 +136,9 @@
try {
if (nStatement == 0) return;
// finalizer should NEVER get called
+ if (SQLiteDebug.DEBUG_ACTIVE_CURSOR_FINALIZATION) {
+ Log.v(TAG, "** warning ** Finalized DbObj (id#" + nStatement + ")");
+ }
Log.w(TAG, "finalizer should never be called on sql: " + mSqlStmt, mStackTrace);
releaseSqlStatement();
} finally {
diff --git a/core/java/android/database/sqlite/SQLiteProgram.java b/core/java/android/database/sqlite/SQLiteProgram.java
index 5b4516d..66ce3b0 100644
--- a/core/java/android/database/sqlite/SQLiteProgram.java
+++ b/core/java/android/database/sqlite/SQLiteProgram.java
@@ -16,11 +16,15 @@
package android.database.sqlite;
+import android.util.Log;
+
/**
* A base class for compiled SQLite programs.
*/
public abstract class SQLiteProgram extends SQLiteClosable {
+ private static final String TAG = "SQLiteProgram";
+
/** The database this program is compiled against.
* @deprecated do not use this
*/
@@ -80,16 +84,26 @@
// make sure it is acquired by me.
mCompiledSql.acquire();
db.addToCompiledQueries(sql, mCompiledSql);
+ if (SQLiteDebug.DEBUG_ACTIVE_CURSOR_FINALIZATION) {
+ Log.v(TAG, "Created DbObj (id#" + mCompiledSql.nStatement +
+ ") for sql: " + sql);
+ }
} else {
// it is already in compiled-sql cache.
// try to acquire the object.
if (!mCompiledSql.acquire()) {
+ int last = mCompiledSql.nStatement;
// the SQLiteCompiledSql in cache is in use by some other SQLiteProgram object.
// we can't have two different SQLiteProgam objects can't share the same
// CompiledSql object. create a new one.
// finalize it when I am done with it in "this" object.
mCompiledSql = new SQLiteCompiledSql(db, sql);
-
+ if (SQLiteDebug.DEBUG_ACTIVE_CURSOR_FINALIZATION) {
+ Log.v(TAG, "** possible bug ** Created NEW DbObj (id#" +
+ mCompiledSql.nStatement +
+ ") because the previously created DbObj (id#" + last +
+ ") was not released for sql:" + sql);
+ }
// since it is not in the cache, no need to acquire() it.
}
}
@@ -124,7 +138,7 @@
// it is in compiled-sql cache. reset its CompiledSql#mInUse flag
mCompiledSql.release();
}
- }
+ }
}
/**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 4995cac..873e1a6f 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1034,6 +1034,24 @@
public static final String END_BUTTON_BEHAVIOR = "end_button_behavior";
/**
+ * END_BUTTON_BEHAVIOR value for "go home".
+ * @hide
+ */
+ public static final int END_BUTTON_BEHAVIOR_HOME = 0x1;
+
+ /**
+ * END_BUTTON_BEHAVIOR value for "go to sleep".
+ * @hide
+ */
+ public static final int END_BUTTON_BEHAVIOR_SLEEP = 0x2;
+
+ /**
+ * END_BUTTON_BEHAVIOR default value.
+ * @hide
+ */
+ public static final int END_BUTTON_BEHAVIOR_DEFAULT = END_BUTTON_BEHAVIOR_SLEEP;
+
+ /**
* Whether Airplane Mode is on.
*/
public static final String AIRPLANE_MODE_ON = "airplane_mode_on";
@@ -3191,6 +3209,36 @@
public static final String VOICE_RECOGNITION_SERVICE = "voice_recognition_service";
/**
+ * What happens when the user presses the Power button while in-call
+ * and the screen is on.<br/>
+ * <b>Values:</b><br/>
+ * 1 - The Power button turns off the screen and locks the device. (Default behavior)<br/>
+ * 2 - The Power button hangs up the current call.<br/>
+ *
+ * @hide
+ */
+ public static final String INCALL_POWER_BUTTON_BEHAVIOR = "incall_power_button_behavior";
+
+ /**
+ * INCALL_POWER_BUTTON_BEHAVIOR value for "turn off screen".
+ * @hide
+ */
+ public static final int INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF = 0x1;
+
+ /**
+ * INCALL_POWER_BUTTON_BEHAVIOR value for "hang up".
+ * @hide
+ */
+ public static final int INCALL_POWER_BUTTON_BEHAVIOR_HANGUP = 0x2;
+
+ /**
+ * INCALL_POWER_BUTTON_BEHAVIOR default value.
+ * @hide
+ */
+ public static final int INCALL_POWER_BUTTON_BEHAVIOR_DEFAULT =
+ INCALL_POWER_BUTTON_BEHAVIOR_SCREEN_OFF;
+
+ /**
* @hide
*/
public static final String[] SETTINGS_TO_BACKUP = {
diff --git a/core/java/android/provider/Telephony.java b/core/java/android/provider/Telephony.java
index 0de1868..bf9e854 100644
--- a/core/java/android/provider/Telephony.java
+++ b/core/java/android/provider/Telephony.java
@@ -164,6 +164,12 @@
* <P>Type: INTEGER</P>
*/
public static final String ERROR_CODE = "error_code";
+
+ /**
+ * Meta data used externally.
+ * <P>Type: TEXT</P>
+ */
+ public static final String META_DATA = "meta_data";
}
/**
@@ -1064,6 +1070,12 @@
* <P>Type: INTEGER (boolean)</P>
*/
public static final String LOCKED = "locked";
+
+ /**
+ * Meta data used externally.
+ * <P>Type: TEXT</P>
+ */
+ public static final String META_DATA = "meta_data";
}
/**
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 7a0c445..54c805f 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -2078,8 +2078,14 @@
mHandler = getContext().getClass().getMethod(handlerName,
View.class);
} catch (NoSuchMethodException e) {
+ int id = getId();
+ String idText = id == NO_ID ? "" : " with id '"
+ + getContext().getResources().getResourceEntryName(
+ id) + "'";
throw new IllegalStateException("Could not find a method " +
- handlerName + "(View) in the activity", e);
+ handlerName + "(View) in the activity "
+ + getContext().getClass() + " for onClick handler"
+ + " on view " + View.this.getClass() + idText, e);
}
}
@@ -4350,6 +4356,7 @@
mPendingCheckForTap = new CheckForTap();
}
mPrivateFlags |= PREPRESSED;
+ mHasPerformedLongPress = false;
postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
break;
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index a1c3fa2..ce236c0 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -381,12 +381,12 @@
/**
* Maximum distance to overscroll by
*/
- private int mOverscrollMax;
+ int mOverscrollMax;
/**
* Content height divided by this is the overscroll limit.
*/
- private static final int OVERSCROLL_LIMIT_DIVISOR = 3;
+ static final int OVERSCROLL_LIMIT_DIVISOR = 3;
/**
* Used to request a layout when we changed touch mode
@@ -2390,7 +2390,7 @@
awakenScrollBars();
}
- private int getOverscrollMax() {
+ int getOverscrollMax() {
final int childCount = getChildCount();
if (childCount > 0) {
return Math.min(mOverscrollMax,
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 0594844..27700fd 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -1250,10 +1250,19 @@
int findMotionRow(int y) {
int childCount = getChildCount();
if (childCount > 0) {
- for (int i = 0; i < childCount; i++) {
- View v = getChildAt(i);
- if (y <= v.getBottom()) {
- return mFirstPosition + i;
+ if (!mStackFromBottom) {
+ for (int i = 0; i < childCount; i++) {
+ View v = getChildAt(i);
+ if (y <= v.getBottom()) {
+ return mFirstPosition + i;
+ }
+ }
+ } else {
+ for (int i = childCount - 1; i >= 0; i--) {
+ View v = getChildAt(i);
+ if (y >= v.getTop()) {
+ return mFirstPosition + i;
+ }
}
}
}
@@ -3682,6 +3691,20 @@
mCheckedIdStates.clear();
}
}
+
+ @Override
+ int getOverscrollMax() {
+ if (mStackFromBottom) {
+ final int childCount = getChildCount();
+ if (childCount > 0) {
+ return Math.min(mOverscrollMax,
+ (getHeight() - getChildAt(0).getTop()) / OVERSCROLL_LIMIT_DIVISOR);
+ } else {
+ return mOverscrollMax;
+ }
+ }
+ return super.getOverscrollMax();
+ }
static class SavedState extends BaseSavedState {
SparseBooleanArray checkState;
diff --git a/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java b/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java
index 251ecbc..e961116 100644
--- a/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java
+++ b/core/java/com/android/internal/service/wallpaper/ImageWallpaper.java
@@ -16,12 +16,15 @@
package com.android.internal.service.wallpaper;
+import com.android.internal.view.WindowManagerPolicyThread;
+
import android.app.WallpaperManager;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.Region.Op;
import android.graphics.drawable.Drawable;
import android.os.HandlerThread;
+import android.os.Looper;
import android.os.Process;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
@@ -43,9 +46,14 @@
public void onCreate() {
super.onCreate();
mWallpaperManager = (WallpaperManager) getSystemService(WALLPAPER_SERVICE);
- mThread = new HandlerThread("Wallpaper", Process.THREAD_PRIORITY_FOREGROUND);
- mThread.start();
- setCallbackLooper(mThread.getLooper());
+ Looper looper = WindowManagerPolicyThread.getLooper();
+ if (looper != null) {
+ setCallbackLooper(looper);
+ } else {
+ mThread = new HandlerThread("Wallpaper", Process.THREAD_PRIORITY_FOREGROUND);
+ mThread.start();
+ setCallbackLooper(mThread.getLooper());
+ }
}
public Engine onCreateEngine() {
@@ -55,7 +63,9 @@
@Override
public void onDestroy() {
super.onDestroy();
- mThread.quit();
+ if (mThread != null) {
+ mThread.quit();
+ }
}
class DrawableEngine extends Engine {
diff --git a/core/java/com/android/internal/util/HierarchicalStateMachine.java b/core/java/com/android/internal/util/HierarchicalStateMachine.java
index 1289d36..bebf051 100644
--- a/core/java/com/android/internal/util/HierarchicalStateMachine.java
+++ b/core/java/com/android/internal/util/HierarchicalStateMachine.java
@@ -550,7 +550,8 @@
private class QuittingState extends HierarchicalState {
@Override
public boolean processMessage(Message msg) {
- throw new RuntimeException("QuitingState: processMessage called should not happen");
+ // Ignore
+ return false;
}
}
@@ -960,7 +961,7 @@
* @param looper for this state machine
* @param name of the state machine
*/
- private void initStateMachine(Looper looper, String name) {
+ private void initStateMachine(String name, Looper looper) {
mName = name;
mHsmHandler = new HsmHandler(looper, this);
}
@@ -975,7 +976,7 @@
mHsmThread.start();
Looper looper = mHsmThread.getLooper();
- initStateMachine(looper, name);
+ initStateMachine(name, looper);
}
/**
@@ -983,8 +984,8 @@
*
* @param name of the state machine
*/
- protected HierarchicalStateMachine(Looper looper, String name) {
- initStateMachine(looper, name);
+ protected HierarchicalStateMachine(String name, Looper looper) {
+ initStateMachine(name, looper);
}
/**
diff --git a/core/java/com/android/internal/view/WindowManagerPolicyThread.java b/core/java/com/android/internal/view/WindowManagerPolicyThread.java
new file mode 100644
index 0000000..6078683
--- /dev/null
+++ b/core/java/com/android/internal/view/WindowManagerPolicyThread.java
@@ -0,0 +1,25 @@
+package com.android.internal.view;
+
+import android.os.Looper;
+
+/**
+ * Static storage of the thread running the window manager policy, to
+ * share with others.
+ */
+public class WindowManagerPolicyThread {
+ static Thread mThread;
+ static Looper mLooper;
+
+ public static void set(Thread thread, Looper looper) {
+ mThread = thread;
+ mLooper = looper;
+ }
+
+ public static Thread getThread() {
+ return mThread;
+ }
+
+ public static Looper getLooper() {
+ return mLooper;
+ }
+}
diff --git a/core/tests/coretests/src/android/os/HierarchicalStateMachineTest.java b/core/tests/coretests/src/android/os/HierarchicalStateMachineTest.java
index 3f4bc04..20c55c2 100644
--- a/core/tests/coretests/src/android/os/HierarchicalStateMachineTest.java
+++ b/core/tests/coretests/src/android/os/HierarchicalStateMachineTest.java
@@ -1204,8 +1204,8 @@
* complete.
*/
class StateMachineSharedThread extends HierarchicalStateMachine {
- StateMachineSharedThread(Looper looper, String name, int maxCount) {
- super(looper, name);
+ StateMachineSharedThread(String name, Looper looper, int maxCount) {
+ super(name, looper);
mMaxCount = maxCount;
setDbg(DBG);
@@ -1254,7 +1254,7 @@
// Create the state machines
StateMachineSharedThread sms[] = new StateMachineSharedThread[10];
for (int i = 0; i < sms.length; i++) {
- sms[i] = new StateMachineSharedThread(smThread.getLooper(), "sm", sms.length);
+ sms[i] = new StateMachineSharedThread("sm", smThread.getLooper(), sms.length);
sms[i].start();
}
diff --git a/include/surfaceflinger/Surface.h b/include/surfaceflinger/Surface.h
index 9808832..0279d84 100644
--- a/include/surfaceflinger/Surface.h
+++ b/include/surfaceflinger/Surface.h
@@ -210,9 +210,16 @@
status_t dequeueBuffer(sp<GraphicBuffer>* buffer);
+ void dispatch_setUsage(va_list args);
+ int dispatch_connect(va_list args);
+ int dispatch_disconnect(va_list args);
void setUsage(uint32_t reqUsage);
+ int connect(int api);
+ int disconnect(int api);
+
uint32_t getUsage() const;
+ int getConnectedApi() const;
// constants
sp<SurfaceComposerClient> mClient;
@@ -227,6 +234,7 @@
// protected by mSurfaceLock
Rect mSwapRectangle;
uint32_t mUsage;
+ int mConnected;
// protected by mSurfaceLock. These are also used from lock/unlock
// but in that case, they must be called form the same thread.
diff --git a/include/ui/egl/android_natives.h b/include/ui/egl/android_natives.h
index 3740db5..773fd93 100644
--- a/include/ui/egl/android_natives.h
+++ b/include/ui/egl/android_natives.h
@@ -69,7 +69,14 @@
/* valid operations for the (*perform)() hook */
enum {
- NATIVE_WINDOW_SET_USAGE = 0
+ NATIVE_WINDOW_SET_USAGE = 0,
+ NATIVE_WINDOW_CONNECT = 1,
+ NATIVE_WINDOW_DISCONNECT = 2
+};
+
+/* parameter for NATIVE_WINDOW_[DIS]CONNECT */
+enum {
+ NATIVE_WINDOW_API_EGL = 1
};
typedef struct android_native_window_t
@@ -157,8 +164,13 @@
* This hook should not be called directly, instead use the helper functions
* defined below.
*
+ * (*perform)() returns -ENOENT if the 'what' parameter is not supported
+ * by the surface's implementation.
+ *
* The valid operations are:
* NATIVE_WINDOW_SET_USAGE
+ * NATIVE_WINDOW_CONNECT
+ * NATIVE_WINDOW_DISCONNECT
*
*/
@@ -185,6 +197,30 @@
return window->perform(window, NATIVE_WINDOW_SET_USAGE, usage);
}
+/*
+ * native_window_connect(..., NATIVE_WINDOW_API_EGL) must be called
+ * by EGL when the window is made current.
+ * Returns -EINVAL if for some reason the window cannot be connected, which
+ * can happen if it's connected to some other API.
+ */
+static inline int native_window_connect(
+ android_native_window_t* window, int api)
+{
+ return window->perform(window, NATIVE_WINDOW_CONNECT, api);
+}
+
+/*
+ * native_window_disconnect(..., NATIVE_WINDOW_API_EGL) must be called
+ * by EGL when the window is made not current.
+ * An error is returned if for instance the window wasn't connected in the
+ * first place.
+ */
+static inline int native_window_disconnect(
+ android_native_window_t* window, int api)
+{
+ return window->perform(window, NATIVE_WINDOW_DISCONNECT, api);
+}
+
// ---------------------------------------------------------------------------
diff --git a/libs/surfaceflinger_client/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
index eb3457b..5dd75c3 100644
--- a/libs/surfaceflinger_client/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -353,6 +353,7 @@
const_cast<uint32_t&>(android_native_window_t::flags) = 0;
// be default we request a hardware surface
mUsage = GRALLOC_USAGE_HW_RENDER;
+ mConnected = 0;
mNeedFullUpdate = false;
}
@@ -579,28 +580,93 @@
{
int res = NO_ERROR;
switch (operation) {
- case NATIVE_WINDOW_SET_USAGE:
- setUsage( va_arg(args, int) );
- break;
- default:
- res = NAME_NOT_FOUND;
- break;
+ case NATIVE_WINDOW_SET_USAGE:
+ dispatch_setUsage( args );
+ break;
+ case NATIVE_WINDOW_CONNECT:
+ res = dispatch_connect( args );
+ break;
+ case NATIVE_WINDOW_DISCONNECT:
+ res = dispatch_disconnect( args );
+ break;
+ default:
+ res = NAME_NOT_FOUND;
+ break;
}
return res;
}
+void Surface::dispatch_setUsage(va_list args) {
+ int usage = va_arg(args, int);
+ setUsage( usage );
+}
+int Surface::dispatch_connect(va_list args) {
+ int api = va_arg(args, int);
+ return connect( api );
+}
+int Surface::dispatch_disconnect(va_list args) {
+ int api = va_arg(args, int);
+ return disconnect( api );
+}
+
+
void Surface::setUsage(uint32_t reqUsage)
{
Mutex::Autolock _l(mSurfaceLock);
mUsage = reqUsage;
}
+int Surface::connect(int api)
+{
+ Mutex::Autolock _l(mSurfaceLock);
+ int err = NO_ERROR;
+ switch (api) {
+ case NATIVE_WINDOW_API_EGL:
+ if (mConnected) {
+ err = -EINVAL;
+ } else {
+ mConnected = api;
+ }
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+ return err;
+}
+
+int Surface::disconnect(int api)
+{
+ Mutex::Autolock _l(mSurfaceLock);
+ int err = NO_ERROR;
+ switch (api) {
+ case NATIVE_WINDOW_API_EGL:
+ if (mConnected == api) {
+ mConnected = 0;
+ } else {
+ err = -EINVAL;
+ }
+ break;
+ default:
+ err = -EINVAL;
+ break;
+ }
+ return err;
+}
+
uint32_t Surface::getUsage() const
{
Mutex::Autolock _l(mSurfaceLock);
return mUsage;
}
+int Surface::getConnectedApi() const
+{
+ Mutex::Autolock _l(mSurfaceLock);
+ return mConnected;
+}
+
+
// ----------------------------------------------------------------------------
status_t Surface::lock(SurfaceInfo* info, bool blocking) {
@@ -609,11 +675,20 @@
status_t Surface::lock(SurfaceInfo* other, Region* dirtyIn, bool blocking)
{
+ if (getConnectedApi()) {
+ LOGE("Surface::lock(%p) failed. Already connected to another API",
+ (android_native_window_t*)this);
+ CallStack stack;
+ stack.update();
+ stack.dump("");
+ return INVALID_OPERATION;
+ }
+
if (mApiLock.tryLock() != NO_ERROR) {
LOGE("calling Surface::lock from different threads!");
CallStack stack;
stack.update();
- stack.dump("Surface::lock called from different threads");
+ stack.dump("");
return WOULD_BLOCK;
}
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index 1fa2c68..52380a0 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -250,6 +250,8 @@
{
switch (operation) {
case NATIVE_WINDOW_SET_USAGE:
+ case NATIVE_WINDOW_CONNECT:
+ case NATIVE_WINDOW_DISCONNECT:
break;
default:
return NAME_NOT_FOUND;
diff --git a/media/libmedia/MediaScannerClient.cpp b/media/libmedia/MediaScannerClient.cpp
index bb3717f..bd3596e 100644
--- a/media/libmedia/MediaScannerClient.cpp
+++ b/media/libmedia/MediaScannerClient.cpp
@@ -64,26 +64,28 @@
bool MediaScannerClient::addStringTag(const char* name, const char* value)
{
- // don't bother caching strings that are all ASCII.
- // call handleStringTag directly instead.
- // check to see if value (which should be utf8) has any non-ASCII characters
- bool nonAscii = false;
- const char* chp = value;
- char ch;
- while ((ch = *chp++)) {
- if (ch & 0x80) {
- nonAscii = true;
- break;
+ if (mLocaleEncoding != kEncodingNone) {
+ // don't bother caching strings that are all ASCII.
+ // call handleStringTag directly instead.
+ // check to see if value (which should be utf8) has any non-ASCII characters
+ bool nonAscii = false;
+ const char* chp = value;
+ char ch;
+ while ((ch = *chp++)) {
+ if (ch & 0x80) {
+ nonAscii = true;
+ break;
+ }
}
- }
- if (nonAscii) {
- // save the strings for later so they can be used for native encoding detection
- mNames->push_back(name);
- mValues->push_back(value);
- return true;
+ if (nonAscii) {
+ // save the strings for later so they can be used for native encoding detection
+ mNames->push_back(name);
+ mValues->push_back(value);
+ return true;
+ }
+ // else fall through
}
- // else fall through
// autodetection is not necessary, so no need to cache the values
// pass directly to the client instead
@@ -196,29 +198,23 @@
void MediaScannerClient::endFile()
{
- int size = mNames->size();
- uint32_t encoding = kEncodingAll;
+ if (mLocaleEncoding != kEncodingNone) {
+ int size = mNames->size();
+ uint32_t encoding = kEncodingAll;
- // compute a bit mask containing all possible encodings
- for (int i = 0; i < mNames->size(); i++)
- encoding &= possibleEncodings(mValues->getEntry(i));
+ // compute a bit mask containing all possible encodings
+ for (int i = 0; i < mNames->size(); i++)
+ encoding &= possibleEncodings(mValues->getEntry(i));
- // If one of the possible encodings matches the locale encoding, use that.
- // Otherwise, if there is only one possible encoding, use that.
- if (encoding & mLocaleEncoding)
- convertValues(mLocaleEncoding);
- else if ((encoding & (encoding - 1)) == 0)
- convertValues(encoding);
- else {
- // TODO: try harder to disambiguate the encoding, perhaps by looking at
- // other files by same artist, or even the user's entire collection.
- // For now, fall through and insert the strings as they are.
- }
+ // if the locale encoding matches, then assume we have a native encoding.
+ if (encoding & mLocaleEncoding)
+ convertValues(mLocaleEncoding);
- // finally, push all name/value pairs to the client
- for (int i = 0; i < mNames->size(); i++) {
- if (!handleStringTag(mNames->getEntry(i), mValues->getEntry(i)))
- break;
+ // finally, push all name/value pairs to the client
+ for (int i = 0; i < mNames->size(); i++) {
+ if (!handleStringTag(mNames->getEntry(i), mValues->getEntry(i)))
+ break;
+ }
}
// else addStringTag() has done all the work so we have nothing to do
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index ba66dc5..fb39ac0 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -902,6 +902,7 @@
vibrate = AudioService.getValueForVibrateSetting(vibrate,
AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_OFF);
loadSetting(stmt, Settings.System.VIBRATE_ON, vibrate);
+ stmt.close();
}
private void loadSettings(SQLiteDatabase db) {
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index 5de68f9..7350213 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -935,6 +935,16 @@
// as before?
String pkg = parser.getAttributeValue(null, "pkg");
String cl = parser.getAttributeValue(null, "cl");
+
+ final PackageManager packageManager = mContext.getPackageManager();
+ try {
+ packageManager.getReceiverInfo(new ComponentName(pkg, cl), 0);
+ } catch (PackageManager.NameNotFoundException e) {
+ String[] pkgs = packageManager.currentToCanonicalPackageNames(
+ new String[] { pkg });
+ pkg = pkgs[0];
+ }
+
Provider p = lookupProviderLocked(new ComponentName(pkg, cl));
if (p == null && mSafeMode) {
// if we're in safe mode, make a temporary one
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index fa06244..fc20d96 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -320,7 +320,7 @@
}
}
- mTethering = new Tethering(mContext);
+ mTethering = new Tethering(mContext, mHandler.getLooper());
mTetheringConfigValid = (((mNetTrackers[ConnectivityManager.TYPE_MOBILE_DUN] != null) ||
!mTethering.isDunRequired()) &&
(mTethering.getTetherableUsbRegexs().length != 0 ||
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 63afabc..ed8e22b 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -7707,7 +7707,11 @@
resourcePath, vc, pkgFlags);
if (DEBUG_UPGRADE) Log.v(TAG, "Package " + name
+ " is adopting original package " + origPackage.name);
+ // Note that we will retain the new package's signature so
+ // that we can keep its data.
+ PackageSignatures s = p.signatures;
p.copyFrom(origPackage);
+ p.signatures = s;
p.sharedUser = origPackage.sharedUser;
p.userId = origPackage.userId;
p.origPackage = origPackage;
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 989fe2a..b27736a 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -47,6 +47,7 @@
import com.android.internal.view.IInputContext;
import com.android.internal.view.IInputMethodClient;
import com.android.internal.view.IInputMethodManager;
+import com.android.internal.view.WindowManagerPolicyThread;
import com.android.server.KeyInputQueue.QueuedEvent;
import com.android.server.am.BatteryStatsService;
@@ -135,6 +136,7 @@
static final boolean DEBUG_FOCUS = false;
static final boolean DEBUG_ANIM = false;
static final boolean DEBUG_LAYOUT = false;
+ static final boolean DEBUG_RESIZE = false;
static final boolean DEBUG_LAYERS = false;
static final boolean DEBUG_INPUT = false;
static final boolean DEBUG_INPUT_METHOD = false;
@@ -558,6 +560,8 @@
public void run() {
Looper.prepare();
+ WindowManagerPolicyThread.set(this, Looper.myLooper());
+
//Looper.myLooper().setMessageLogging(new LogPrinter(
// Log.VERBOSE, "WindowManagerPolicy", Log.LOG_ID_SYSTEM));
android.os.Process.setThreadPriority(
@@ -6911,6 +6915,12 @@
final Rect mLastShownFrame = new Rect();
/**
+ * Set when we have changed the size of the surface, to know that
+ * we must tell them application to resize (and thus redraw itself).
+ */
+ boolean mSurfaceResized;
+
+ /**
* Insets that determine the actually visible area
*/
final Rect mVisibleInsets = new Rect();
@@ -10066,6 +10076,20 @@
final int attrFlags = attrs.flags;
if (w.mSurface != null) {
+ // XXX NOTE: The logic here could be improved. We have
+ // the decision about whether to resize a window separated
+ // from whether to hide the surface. This can cause us to
+ // resize a surface even if we are going to hide it. You
+ // can see this by (1) holding device in landscape mode on
+ // home screen; (2) tapping browser icon (device will rotate
+ // to landscape; (3) tap home. The wallpaper will be resized
+ // in step 2 but then immediately hidden, causing us to
+ // have to resize and then redraw it again in step 3. It
+ // would be nice to figure out how to avoid this, but it is
+ // difficult because we do need to resize surfaces in some
+ // cases while they are hidden such as when first showing a
+ // window.
+
w.computeShownFrameLocked();
if (localLOGV) Slog.v(
TAG, "Placing surface #" + i + " " + w.mSurface
@@ -10112,6 +10136,7 @@
+ w.mShownFrame.top + " SIZE "
+ w.mShownFrame.width() + "x"
+ w.mShownFrame.height(), null);
+ w.mSurfaceResized = true;
w.mSurface.setSize(width, height);
w.mSurface.setPosition(w.mShownFrame.left,
w.mShownFrame.top);
@@ -10144,6 +10169,7 @@
if (!w.mLastFrame.equals(w.mFrame)
|| w.mContentInsetsChanged
|| w.mVisibleInsetsChanged
+ || w.mSurfaceResized
|| configChanged) {
w.mLastFrame.set(w.mFrame);
w.mLastContentInsets.set(w.mContentInsets);
@@ -10180,7 +10206,7 @@
w.mAppToken.allDrawn = false;
}
}
- if (DEBUG_ORIENTATION) Slog.v(TAG,
+ if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
"Resizing window " + w + " to " + w.mFrame);
mResizingWindows.add(w);
} else if (w.mOrientationChanging) {
@@ -10479,14 +10505,14 @@
i--;
WindowState win = mResizingWindows.get(i);
try {
- if (DEBUG_ORIENTATION) Slog.v(TAG, "Reporting new frame to "
- + win + ": " + win.mFrame);
+ if (DEBUG_RESIZE || DEBUG_ORIENTATION) Slog.v(TAG,
+ "Reporting new frame to " + win + ": " + win.mFrame);
boolean configChanged =
win.mConfiguration != mCurConfiguration
&& (win.mConfiguration == null
|| mCurConfiguration.diff(win.mConfiguration) != 0);
win.mConfiguration = mCurConfiguration;
- if (DEBUG_ORIENTATION && configChanged) {
+ if ((DEBUG_RESIZE || DEBUG_ORIENTATION) && configChanged) {
Slog.i(TAG, "Sending new config to window " + win + ": "
+ win.mFrame.width() + "x" + win.mFrame.height()
+ " / " + win.mConfiguration);
@@ -10497,6 +10523,7 @@
configChanged ? win.mConfiguration : null);
win.mContentInsetsChanged = false;
win.mVisibleInsetsChanged = false;
+ win.mSurfaceResized = false;
} catch (RemoteException e) {
win.mOrientationChanging = false;
}
diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java
index ebd3314..25f123c 100644
--- a/services/java/com/android/server/connectivity/Tethering.java
+++ b/services/java/com/android/server/connectivity/Tethering.java
@@ -36,6 +36,7 @@
import android.os.Environment;
import android.os.IBinder;
import android.os.INetworkManagementService;
+import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -73,6 +74,8 @@
private String[] mTetherableWifiRegexs;
private String[] mUpstreamIfaceRegexs;
+ private Looper mLooper; // given to us at construction time..
+
private HashMap<String, TetherInterfaceSM> mIfaces; // all tethered/tetherable ifaces
private BroadcastReceiver mStateReceiver;
@@ -101,9 +104,10 @@
private boolean mUsbMassStorageOff; // track the status of USB Mass Storage
private boolean mUsbConnected; // track the status of USB connection
- public Tethering(Context context) {
+ public Tethering(Context context, Looper looper) {
Log.d(TAG, "Tethering starting");
mContext = context;
+ mLooper = looper;
// register for notifications from NetworkManagement Service
IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
@@ -116,7 +120,7 @@
mIfaces = new HashMap<String, TetherInterfaceSM>();
- mTetherMasterSM = new TetherMasterSM("TetherMaster");
+ mTetherMasterSM = new TetherMasterSM("TetherMaster", mLooper);
mTetherMasterSM.start();
// TODO - remove this hack after real USB connections are detected.
@@ -175,7 +179,7 @@
TetherInterfaceSM sm = mIfaces.get(iface);
if (link) {
if (sm == null) {
- sm = new TetherInterfaceSM(iface, usb);
+ sm = new TetherInterfaceSM(iface, mLooper, usb);
mIfaces.put(iface, sm);
sm.start();
}
@@ -225,7 +229,7 @@
Log.e(TAG, "active iface (" + iface + ") reported as added, ignoring");
return;
}
- sm = new TetherInterfaceSM(iface, usb);
+ sm = new TetherInterfaceSM(iface, mLooper, usb);
mIfaces.put(iface, sm);
sm.start();
}
@@ -639,8 +643,8 @@
String mIfaceName;
boolean mUsb;
- TetherInterfaceSM(String name, boolean usb) {
- super(name);
+ TetherInterfaceSM(String name, Looper looper, boolean usb) {
+ super(name, looper);
mIfaceName = name;
mUsb = usb;
setLastError(ConnectivityManager.TETHER_ERROR_NO_ERROR);
@@ -1023,8 +1027,8 @@
private static final int CELL_DISABLE_DUN_TIMEOUT_MS = 3000;
private static final int CELL_DUN_RENEW_MS = 40000;
- TetherMasterSM(String name) {
- super(name);
+ TetherMasterSM(String name, Looper looper) {
+ super(name, looper);
//Add states
mInitialState = new InitialState();
diff --git a/telephony/java/android/telephony/CellLocation.java b/telephony/java/android/telephony/CellLocation.java
index f763d3f..2edfc23 100644
--- a/telephony/java/android/telephony/CellLocation.java
+++ b/telephony/java/android/telephony/CellLocation.java
@@ -79,6 +79,11 @@
public abstract void fillInNotifierBundle(Bundle bundle);
/**
+ * @hide
+ */
+ public abstract boolean isEmpty();
+
+ /**
* Return a new CellLocation object representing an unknown
* location, or null for unknown/none phone radio types.
*
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 6685c18..a6b1d93 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -203,7 +203,10 @@
public CellLocation getCellLocation() {
try {
Bundle bundle = getITelephony().getCellLocation();
- return CellLocation.newFromBundle(bundle);
+ CellLocation cl = CellLocation.newFromBundle(bundle);
+ if (cl.isEmpty())
+ return null;
+ return cl;
} catch (RemoteException ex) {
return null;
} catch (NullPointerException ex) {
diff --git a/telephony/java/android/telephony/cdma/CdmaCellLocation.java b/telephony/java/android/telephony/cdma/CdmaCellLocation.java
index 2a0f8cd..84db830 100644
--- a/telephony/java/android/telephony/cdma/CdmaCellLocation.java
+++ b/telephony/java/android/telephony/cdma/CdmaCellLocation.java
@@ -204,6 +204,18 @@
bundleToFill.putInt("networkId", this.mNetworkId);
}
+ /**
+ * @hide
+ */
+ public boolean isEmpty() {
+ return (this.mBaseStationId == -1 &&
+ this.mBaseStationLatitude == INVALID_LAT_LONG &&
+ this.mBaseStationLongitude == INVALID_LAT_LONG &&
+ this.mSystemId == -1 &&
+ this.mNetworkId == -1);
+ }
+
+
}
diff --git a/telephony/java/android/telephony/gsm/GsmCellLocation.java b/telephony/java/android/telephony/gsm/GsmCellLocation.java
index 0d4e0be..fa1f985 100644
--- a/telephony/java/android/telephony/gsm/GsmCellLocation.java
+++ b/telephony/java/android/telephony/gsm/GsmCellLocation.java
@@ -119,4 +119,11 @@
m.putInt("lac", mLac);
m.putInt("cid", mCid);
}
+
+ /**
+ * @hide
+ */
+ public boolean isEmpty() {
+ return (mLac == -1 && mCid == -1);
+ }
}