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);
+    }
 }