Merge "rollback AFTER commit causes warning message from sqlite bug:2486731"
diff --git a/CleanSpec.mk b/CleanSpec.mk
new file mode 100644
index 0000000..b6b8640
--- /dev/null
+++ b/CleanSpec.mk
@@ -0,0 +1,6 @@
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/com/android/internal/os/IDropBoxService.java)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/backup)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/com/android/internal/backup)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/backup)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/com/android/internal/backup)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/app)
diff --git a/api/current.xml b/api/current.xml
index 0484b77..4146859 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -204064,6 +204064,17 @@
  synchronized="false"
  static="false"
  final="false"
+ deprecated="deprecated"
+ visibility="public"
+>
+</method>
+<method name="getCheckedItemIds"
+ return="long[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
  deprecated="not deprecated"
  visibility="public"
 >
diff --git a/cleanspec.mk b/cleanspec.mk
deleted file mode 100644
index 9d9aa7e..0000000
--- a/cleanspec.mk
+++ /dev/null
@@ -1,3 +0,0 @@
-$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/com/android/internal/os/IDropBoxService.java)
-$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/backup)
-$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/com/android/internal/backup)
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index adec5a4..eaa34c8 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -110,6 +110,9 @@
     dump_file("KERNEL WAKELOCKS", "/proc/wakelocks");
     dump_file("KERNEL CPUFREQ", "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state");
 
+    run_command("SECURE CONTAINERS", 10, "vdc", "asec", "list", NULL);
+    run_command("MOUNTED FILESYSTEMS", 10, "df", NULL);
+
     run_command("PROCESSES", 10, "ps", "-P", NULL);
     run_command("PROCESSES AND THREADS", 10, "ps", "-t", "-p", "-P", NULL);
     run_command("LIBRANK", 10, "librank", NULL);
@@ -208,7 +211,7 @@
     }
 
     /* switch to non-root user and group */
-    gid_t groups[] = { AID_LOG, AID_SDCARD_RW };
+    gid_t groups[] = { AID_LOG, AID_SDCARD_RW, AID_MOUNT };
     setgroups(sizeof(groups)/sizeof(groups[0]), groups);
     setuid(AID_SHELL);
 
diff --git a/cmds/keystore/keystore_get.h b/cmds/keystore/keystore_get.h
index 0e7e1ae..8330f8e 100644
--- a/cmds/keystore/keystore_get.h
+++ b/cmds/keystore/keystore_get.h
@@ -19,7 +19,6 @@
 
 #include <stdio.h>
 #include <stdint.h>
-#include <string.h>
 #include <unistd.h>
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -28,18 +27,21 @@
 
 #define KEYSTORE_MESSAGE_SIZE 65535
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* This function is provided for native components to get values from keystore.
  * Users are required to link against libcutils. The lengths of keys and values
  * are limited to KEYSTORE_MESSAGE_SIZE. This function returns the length of
  * the requested value or -1 if something goes wrong. */
-static int keystore_get(const char *key, char *value)
+static int keystore_get(const char *key, int length, char *value)
 {
-    int length = strlen(key);
     uint8_t bytes[2] = {length >> 8, length};
     uint8_t code = 'g';
     int sock;
 
-    if (length > KEYSTORE_MESSAGE_SIZE) {
+    if (length < 0 || length > KEYSTORE_MESSAGE_SIZE) {
         return -1;
     }
     sock = socket_local_client("keystore", ANDROID_SOCKET_NAMESPACE_RESERVED,
@@ -66,4 +68,8 @@
     return length;
 }
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index c951ce9..3e426f5 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -668,7 +668,7 @@
                 // The user changed the query, remember it.
                 mUserQuery = s == null ? "" : s.toString();
             }
-            updateVoiceButton(TextUtils.isEmpty(s));
+            updateVoiceButton(mSearchAutoComplete.isEmpty());
         }
 
         public void afterTextChanged(Editable s) {
@@ -691,13 +691,30 @@
     };
 
     /**
-     * Enable/Disable the cancel button based on edit text state (any text?)
+     * Enable/Disable the go button based on edit text state (any text?)
      */
     private void updateWidgetState() {
         // enable the button if we have one or more non-space characters
         boolean enabled = !mSearchAutoComplete.isEmpty();
-        mGoButton.setEnabled(enabled);
-        mGoButton.setFocusable(enabled);
+        if (isBrowserSearch()) {
+            // In the browser, we hide the search button when there is no text
+            if (enabled) {
+                mSearchAutoComplete.setBackgroundResource(
+                        com.android.internal.R.drawable.textfield_search);
+                mGoButton.setVisibility(View.VISIBLE);
+                // Just to be sure
+                mGoButton.setEnabled(true);
+                mGoButton.setFocusable(true);
+            } else {
+                mSearchAutoComplete.setBackgroundResource(
+                        com.android.internal.R.drawable.textfield_search_empty);
+                mGoButton.setVisibility(View.GONE);
+            }
+        } else {
+            // Elsewhere we just disable the button
+            mGoButton.setEnabled(enabled);
+            mGoButton.setFocusable(enabled);
+        }
     }
 
     /**
diff --git a/core/java/android/app/backup/package.html b/core/java/android/app/backup/package.html
index 13c0eb8..8d58e0c 100644
--- a/core/java/android/app/backup/package.html
+++ b/core/java/android/app/backup/package.html
@@ -2,12 +2,12 @@
 <BODY>
 <p>Package containing the backup and restore functionality available to
 applications. All backup management is controlled through
-{@link android.backup.BackupManager}.  Individual backup functionality is
-implemented through a subclass {@link android.app.BackupAgent} and a
+{@link android.app.backup.BackupManager}.  Individual backup functionality is
+implemented through a subclass {@link android.app.backup.BackupAgent} and a
 simple and easy-to-use implementation is provided in
-{@link android.backup.BackupHelperAgent}.</p>
+{@link android.app.backup.BackupHelperAgent}.</p>
 
-<p>STOPSHIP: add more documenation and remove Dev Guide link if not written!</p>
+<p>STOPSHIP: add more documentation and remove Dev Guide link if not written!</p>
 
 <p>The backup APIs let applications:</p>
 <ul>
diff --git a/core/java/android/net/WebAddress.java b/core/java/android/net/WebAddress.java
index a572f60..e5bc6e3 100644
--- a/core/java/android/net/WebAddress.java
+++ b/core/java/android/net/WebAddress.java
@@ -57,7 +57,7 @@
             /* scheme    */ "(?:(http|HTTP|https|HTTPS|file|FILE)\\:\\/\\/)?" +
             /* authority */ "(?:([-A-Za-z0-9$_.+!*'(),;?&=]+(?:\\:[-A-Za-z0-9$_.+!*'(),;?&=]+)?)@)?" +
             /* host      */ "([-" + GOOD_IRI_CHAR + "%_]+(?:\\.[-" + GOOD_IRI_CHAR + "%_]+)*|\\[[0-9a-fA-F:\\.]+\\])?" +
-            /* port      */ "(?:\\:([0-9]+))?" +
+            /* port      */ "(?:\\:([0-9]*))?" +
             /* path      */ "(\\/?[^#]*)?" +
             /* anchor    */ ".*");
 
@@ -85,7 +85,8 @@
             t = m.group(MATCH_GROUP_HOST);
             if (t != null) mHost = t;
             t = m.group(MATCH_GROUP_PORT);
-            if (t != null) {
+            if (t != null && t.length() > 0) {
+                // The ':' character is not returned by the regex.
                 try {
                     mPort = Integer.parseInt(t);
                 } catch (NumberFormatException ex) {
diff --git a/core/java/android/speech/RecognizerResultsIntent.java b/core/java/android/speech/RecognizerResultsIntent.java
index 228258e..4997d50 100644
--- a/core/java/android/speech/RecognizerResultsIntent.java
+++ b/core/java/android/speech/RecognizerResultsIntent.java
@@ -16,6 +16,8 @@
 
 package android.speech;
 
+import android.os.Bundle;
+
 import java.util.ArrayList;
 
 /**
@@ -119,7 +121,22 @@
      */
     public static final String EXTRA_VOICE_SEARCH_RESULT_HTML_BASE_URLS =
             "android.speech.extras.VOICE_SEARCH_RESULT_HTML_BASE_URLS";
-    
+
+    /**
+     * The key to an extra {@link ArrayList} of {@link Bundle}s that contains key/value pairs.
+     * All the values and the keys are {@link String}s. Each key/value pair represents an extra HTTP
+     * header. The keys can't be the standard HTTP headers as they are set by the WebView.
+     *
+     * A list of size 1 may be provided to apply the same HTTP headers to all html results. A list 
+     * of the same size as {@link #EXTRA_VOICE_SEARCH_RESULT_STRINGS} may be provided to apply 
+     * different HTTP headers to each different html result in the 
+     * {@link #EXTRA_VOICE_SEARCH_RESULT_HTML} list.
+     *
+     * @hide not to be exposed immediately as the implementation details may change
+     */
+    public static final String EXTRA_VOICE_SEARCH_RESULT_HTTP_HEADERS =
+            "android.speech.extras.EXTRA_VOICE_SEARCH_RESULT_HTTP_HEADERS";
+
     /**
      * The scheme used currently for html content in {@link #EXTRA_VOICE_SEARCH_RESULT_HTML}.
      * 
diff --git a/core/java/android/util/LongSparseArray.java b/core/java/android/util/LongSparseArray.java
index d90045f..1ec8be6 100644
--- a/core/java/android/util/LongSparseArray.java
+++ b/core/java/android/util/LongSparseArray.java
@@ -48,6 +48,28 @@
         mValues = new Object[initialCapacity];
         mSize = 0;
     }
+    
+    /**
+     * @return A copy of all keys contained in the sparse array.
+     */
+    public long[] getKeys() {
+        int length = mKeys.length;
+        long[] result = new long[length];
+        System.arraycopy(mKeys, 0, result, 0, length);
+        return result;
+    }
+    
+    /**
+     * Sets all supplied keys to the given unique value.
+     * @param keys Keys to set
+     * @param uniqueValue Value to set all supplied keys to
+     */
+    public void setValues(long[] keys, E uniqueValue) {
+        int length = keys.length;
+        for (int i = 0; i < length; i++) {
+            put(keys[i], uniqueValue);
+        }
+    }
 
     /**
      * Gets the Object mapped from the specified key, or <code>null</code>
diff --git a/core/java/android/webkit/CookieManager.java b/core/java/android/webkit/CookieManager.java
index 1d28731..427ce76 100644
--- a/core/java/android/webkit/CookieManager.java
+++ b/core/java/android/webkit/CookieManager.java
@@ -216,19 +216,23 @@
             diff = cookie2.domain.length() - cookie1.domain.length();
             if (diff != 0) return diff;
 
-            diff = cookie2.name.hashCode() - cookie1.name.hashCode();
-            if (diff != 0) return diff;
-
             // If cookie2 has a null value, it should come later in
             // the list.
             if (cookie2.value == null) {
-                return -1;
+                // If both cookies have null values, fall back to using the name
+                // difference.
+                if (cookie1.value != null) {
+                    return -1;
+                }
             } else if (cookie1.value == null) {
                 // Now we know that cookie2 does not have a null value, if
                 // cookie1 has a null value, place it later in the list.
                 return 1;
             }
 
+            diff = cookie2.name.hashCode() - cookie1.name.hashCode();
+            if (diff != 0) return diff;
+
             // cookie1 and cookie2 both have non-null values so we emit a
             // warning and treat them as the same.
             Log.w(LOGTAG, "Found two cookies with the same value."
@@ -804,9 +808,13 @@
             cookie = new Cookie(host, path);
 
             // Cookies like "testcookie; path=/;" are valid and used
-            // (lovefilm.se). Check for equal as in the string "testcookie"
-            // Check for equalIndex == -1 as in the string "testcookie;"
-            if (semicolonIndex <= equalIndex || equalIndex == -1) {
+            // (lovefilm.se).
+            // Look for 2 cases:
+            // 1. "foo" or "foo;" where equalIndex is -1
+            // 2. "foo; path=..." where the first semicolon is before an equal
+            //    and a semicolon exists.
+            if ((semicolonIndex != -1 && (semicolonIndex < equalIndex)) ||
+                    equalIndex == -1) {
                 // Fix up the index in case we have a string like "testcookie"
                 if (semicolonIndex == -1) {
                     semicolonIndex = length;
@@ -815,7 +823,10 @@
                 cookie.value = null;
             } else {
                 cookie.name = cookieString.substring(index, equalIndex);
-                if (cookieString.charAt(equalIndex + 1) == QUOTATION) {
+                // Make sure we do not throw an exception if the cookie is like
+                // "foo="
+                if ((equalIndex < length - 1) &&
+                        (cookieString.charAt(equalIndex + 1) == QUOTATION)) {
                     index = cookieString.indexOf(QUOTATION, equalIndex + 2);
                     if (index == -1) {
                         // bad format, force return
@@ -834,7 +845,7 @@
                             equalIndex + 1 + MAX_COOKIE_LENGTH);
                 } else if (equalIndex + 1 == semicolonIndex
                         || semicolonIndex < equalIndex) {
-                    // this is an unusual case like foo=;
+                    // this is an unusual case like "foo=;" or "foo="
                     cookie.value = "";
                 } else {
                     cookie.value = cookieString.substring(equalIndex + 1,
diff --git a/core/java/android/webkit/FrameLoader.java b/core/java/android/webkit/FrameLoader.java
index dacb33f..303e417 100644
--- a/core/java/android/webkit/FrameLoader.java
+++ b/core/java/android/webkit/FrameLoader.java
@@ -111,11 +111,10 @@
             }
             mNetwork = Network.getInstance(mListener.getContext());
             if (mListener.isSynchronous()) {
-                handleHTTPLoad();
-            } else {
-                WebViewWorker.getHandler().obtainMessage(
-                        WebViewWorker.MSG_ADD_HTTPLOADER, this).sendToTarget();
+                return handleHTTPLoad();
             }
+            WebViewWorker.getHandler().obtainMessage(
+                    WebViewWorker.MSG_ADD_HTTPLOADER, this).sendToTarget();
             return true;
         } else if (handleLocalFile(url, mListener, mSettings)) {
             return true;
@@ -147,34 +146,53 @@
             return true;
         }
         if (URLUtil.isAssetUrl(url)) {
-            // load asset in a separate thread as it involves IO
-            WebViewWorker.getHandler().obtainMessage(
-                    WebViewWorker.MSG_ADD_STREAMLOADER,
-                    new FileLoader(url, loadListener, FileLoader.TYPE_ASSET,
-                            true)).sendToTarget();
+            if (loadListener.isSynchronous()) {
+                new FileLoader(url, loadListener, FileLoader.TYPE_ASSET,
+                        true).load();
+            } else {
+                // load asset in a separate thread as it involves IO
+                WebViewWorker.getHandler().obtainMessage(
+                        WebViewWorker.MSG_ADD_STREAMLOADER,
+                        new FileLoader(url, loadListener, FileLoader.TYPE_ASSET,
+                                true)).sendToTarget();
+            }
             return true;
         } else if (URLUtil.isResourceUrl(url)) {
-            // load resource in a separate thread as it involves IO
-            WebViewWorker.getHandler().obtainMessage(
-                    WebViewWorker.MSG_ADD_STREAMLOADER,
-                    new FileLoader(url, loadListener, FileLoader.TYPE_RES,
-                            true)).sendToTarget();
+            if (loadListener.isSynchronous()) {
+                new FileLoader(url, loadListener, FileLoader.TYPE_RES,
+                        true).load();
+            } else {
+                // load resource in a separate thread as it involves IO
+                WebViewWorker.getHandler().obtainMessage(
+                        WebViewWorker.MSG_ADD_STREAMLOADER,
+                        new FileLoader(url, loadListener, FileLoader.TYPE_RES,
+                                true)).sendToTarget();
+            }
             return true;
         } else if (URLUtil.isFileUrl(url)) {
-            // load file in a separate thread as it involves IO
-            WebViewWorker.getHandler().obtainMessage(
-                    WebViewWorker.MSG_ADD_STREAMLOADER,
-                    new FileLoader(url, loadListener, FileLoader.TYPE_FILE,
-                            settings.getAllowFileAccess())).sendToTarget();
+            if (loadListener.isSynchronous()) {
+                new FileLoader(url, loadListener, FileLoader.TYPE_FILE,
+                        settings.getAllowFileAccess()).load();
+            } else {
+                // load file in a separate thread as it involves IO
+                WebViewWorker.getHandler().obtainMessage(
+                        WebViewWorker.MSG_ADD_STREAMLOADER,
+                        new FileLoader(url, loadListener, FileLoader.TYPE_FILE,
+                                settings.getAllowFileAccess())).sendToTarget();
+            }
             return true;
         } else if (URLUtil.isContentUrl(url)) {
             // Send the raw url to the ContentLoader because it will do a
             // permission check and the url has to match.
-            // load content in a separate thread as it involves IO
-            WebViewWorker.getHandler().obtainMessage(
-                    WebViewWorker.MSG_ADD_STREAMLOADER,
-                    new ContentLoader(loadListener.url(), loadListener))
-                    .sendToTarget();
+            if (loadListener.isSynchronous()) {
+                new ContentLoader(loadListener.url(), loadListener).load();
+            } else {
+                // load content in a separate thread as it involves IO
+                WebViewWorker.getHandler().obtainMessage(
+                        WebViewWorker.MSG_ADD_STREAMLOADER,
+                        new ContentLoader(loadListener.url(), loadListener))
+                        .sendToTarget();
+            }
             return true;
         } else if (URLUtil.isDataUrl(url)) {
             // load data in the current thread to reduce the latency
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index b8d71b9..a889476 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -16,6 +16,7 @@
 
 package android.webkit;
 
+import android.annotation.Widget;
 import android.app.AlertDialog;
 import android.content.Context;
 import android.content.DialogInterface;
@@ -207,6 +208,7 @@
  * changes, and then just leave the WebView alone. It'll automatically
  * re-orient itself as appropriate.</p>
  */
+@Widget
 public class WebView extends AbsoluteLayout
         implements ViewTreeObserver.OnGlobalFocusChangeListener,
         ViewGroup.OnHierarchyChangeListener {
@@ -3211,27 +3213,6 @@
         }
     }
 
-    private static class Metrics {
-        int mScrollX;
-        int mScrollY;
-        int mWidth;
-        int mHeight;
-        float mInvScale;
-    }
-
-    private Metrics getViewMetrics() {
-        Metrics metrics = new Metrics();
-        metrics.mScrollX = mScrollX;
-        metrics.mScrollY = computeVerticalScrollOffset();
-        metrics.mWidth = getWidth();
-        metrics.mHeight = getHeight() - getVisibleTitleHeight();
-        if (mFindIsUp) {
-            metrics.mHeight -= mFindHeight;
-        }
-        metrics.mInvScale = mInvActualScale;
-        return metrics;
-    }
-
     private void drawExtras(Canvas canvas, int extras) {
         // If mNativeClass is 0, we should not reach here, so we do not
         // need to check it again.
@@ -3338,7 +3319,7 @@
             if (!animateScroll) {
                 extras = DRAW_EXTRAS_FIND;
             }
-        } else if (mShiftIsPressed) {
+        } else if (mShiftIsPressed && !nativeFocusIsPlugin()) {
             if (!animateZoom && !mPreviewZoomOnly) {
                 extras = DRAW_EXTRAS_SELECTION;
                 nativeSetSelectionRegion(mTouchSelection || mExtendSelection);
@@ -3693,6 +3674,7 @@
         }
 
         if (mShiftIsPressed == false && nativeCursorWantsKeyEvents() == false
+                && !nativeFocusIsPlugin()
                 && (keyCode == KeyEvent.KEYCODE_SHIFT_LEFT
                 || keyCode == KeyEvent.KEYCODE_SHIFT_RIGHT)) {
             setUpSelectXY();
@@ -3700,8 +3682,11 @@
 
         if (keyCode >= KeyEvent.KEYCODE_DPAD_UP
                 && keyCode <= KeyEvent.KEYCODE_DPAD_RIGHT) {
-            // always handle the navigation keys in the UI thread
             switchOutDrawHistory();
+            if (nativeFocusIsPlugin()) {
+                letPluginHandleNavKey(keyCode, event.getEventTime(), true);
+                return true;
+            }
             if (mShiftIsPressed) {
                 int xRate = keyCode == KeyEvent.KEYCODE_DPAD_LEFT
                     ? -1 : keyCode == KeyEvent.KEYCODE_DPAD_RIGHT ? 1 : 0;
@@ -3711,7 +3696,7 @@
                 moveSelection(xRate * multiplier, yRate * multiplier);
                 return true;
             }
-            if (navHandledKey(keyCode, 1, false, event.getEventTime(), false)) {
+            if (navHandledKey(keyCode, 1, false, event.getEventTime())) {
                 playSoundEffect(keyCodeToSoundsEffect(keyCode));
                 return true;
             }
@@ -3722,7 +3707,7 @@
         if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
             switchOutDrawHistory();
             if (event.getRepeatCount() == 0) {
-                if (mShiftIsPressed) {
+                if (mShiftIsPressed && !nativeFocusIsPlugin()) {
                     return true; // discard press if copy in progress
                 }
                 mGotCenterDown = true;
@@ -3838,6 +3823,10 @@
 
         if (keyCode >= KeyEvent.KEYCODE_DPAD_UP
                 && keyCode <= KeyEvent.KEYCODE_DPAD_RIGHT) {
+            if (nativeFocusIsPlugin()) {
+                letPluginHandleNavKey(keyCode, event.getEventTime(), false);
+                return true;
+            }
             // always handle the navigation keys in the UI thread
             // Bubble up the key event as WebView doesn't handle it
             return false;
@@ -3848,7 +3837,7 @@
             mPrivateHandler.removeMessages(LONG_PRESS_CENTER);
             mGotCenterDown = false;
 
-            if (mShiftIsPressed) {
+            if (mShiftIsPressed && !nativeFocusIsPlugin()) {
                 if (mExtendSelection) {
                     commitCopy();
                 } else {
@@ -5033,7 +5022,7 @@
             return true;
         }
         if (ev.getAction() == MotionEvent.ACTION_DOWN) {
-            if (mShiftIsPressed) {
+            if (mShiftIsPressed && !nativeFocusIsPlugin()) {
                 return true; // discard press if copy in progress
             }
             mTrackballDown = true;
@@ -5058,7 +5047,7 @@
             mPrivateHandler.removeMessages(LONG_PRESS_CENTER);
             mTrackballDown = false;
             mTrackballUpTime = time;
-            if (mShiftIsPressed) {
+            if (mShiftIsPressed && !nativeFocusIsPlugin()) {
                 if (mExtendSelection) {
                     commitCopy();
                 } else {
@@ -5196,7 +5185,7 @@
         float yRate = mTrackballRemainsY * 1000 / elapsed;
         int viewWidth = getViewWidth();
         int viewHeight = getViewHeight();
-        if (mShiftIsPressed) {
+        if (mShiftIsPressed && !nativeFocusIsPlugin()) {
             moveSelection(scaleTrackballX(xRate, viewWidth),
                     scaleTrackballY(yRate, viewHeight));
             mTrackballRemainsX = mTrackballRemainsY = 0;
@@ -5234,7 +5223,12 @@
                         + " mTrackballRemainsX=" + mTrackballRemainsX
                         + " mTrackballRemainsY=" + mTrackballRemainsY);
             }
-            if (navHandledKey(selectKeyCode, count, false, time, false)) {
+            if (nativeFocusIsPlugin()) {
+                for (int i = 0; i < count; i++) {
+                    letPluginHandleNavKey(selectKeyCode, time, true);
+                    letPluginHandleNavKey(selectKeyCode, time, false);
+                }
+            } else if (navHandledKey(selectKeyCode, count, false, time)) {
                 playSoundEffect(keyCodeToSoundsEffect(selectKeyCode));
             }
             mTrackballRemainsX = mTrackballRemainsY = 0;
@@ -5711,7 +5705,7 @@
                         return result;
                 }
                 if (mNativeClass != 0 && !nativeHasCursorNode()) {
-                    navHandledKey(fakeKeyDirection, 1, true, 0, true);
+                    navHandledKey(fakeKeyDirection, 1, true, 0);
                 }
             }
         }
@@ -6137,7 +6131,7 @@
                     }
                     break;
                 case MOVE_OUT_OF_PLUGIN:
-                    navHandledKey(msg.arg1, 1, false, 0, true);
+                    navHandledKey(msg.arg1, 1, false, 0);
                     break;
                 case UPDATE_TEXT_ENTRY_MSG_ID:
                     // this is sent after finishing resize in WebViewCore. Make
@@ -6804,21 +6798,34 @@
         invalidate();
     }
 
-    // return true if the key was handled
-    private boolean navHandledKey(int keyCode, int count, boolean noScroll,
-            long time, boolean ignorePlugin) {
-        if (mNativeClass == 0) {
-            return false;
+    /**
+     * Pass the key to the plugin.  This assumes that nativeFocusIsPlugin()
+     * returned true.
+     */
+    private void letPluginHandleNavKey(int keyCode, long time, boolean down) {
+        int keyEventAction;
+        int eventHubAction;
+        if (down) {
+            keyEventAction = KeyEvent.ACTION_DOWN;
+            eventHubAction = EventHub.KEY_DOWN;
+            playSoundEffect(keyCodeToSoundsEffect(keyCode));
+        } else {
+            keyEventAction = KeyEvent.ACTION_UP;
+            eventHubAction = EventHub.KEY_UP;
         }
-        if (ignorePlugin == false && nativeFocusIsPlugin()) {
-            KeyEvent event = new KeyEvent(time, time, KeyEvent.ACTION_DOWN
-                , keyCode, count, (mShiftIsPressed ? KeyEvent.META_SHIFT_ON : 0)
+        KeyEvent event = new KeyEvent(time, time, keyEventAction, keyCode,
+                1, (mShiftIsPressed ? KeyEvent.META_SHIFT_ON : 0)
                 | (false ? KeyEvent.META_ALT_ON : 0) // FIXME
                 | (false ? KeyEvent.META_SYM_ON : 0) // FIXME
                 , 0, 0, 0);
-            mWebViewCore.sendMessage(EventHub.KEY_DOWN, event);
-            mWebViewCore.sendMessage(EventHub.KEY_UP, event);
-            return true;
+        mWebViewCore.sendMessage(eventHubAction, event);
+    }
+
+    // return true if the key was handled
+    private boolean navHandledKey(int keyCode, int count, boolean noScroll,
+            long time) {
+        if (mNativeClass == 0) {
+            return false;
         }
         mLastCursorTime = time;
         mLastCursorBounds = nativeGetCursorRingBounds();
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index e3eb6db..1a9c0df5 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -30,6 +30,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.AttributeSet;
+import android.util.LongSparseArray;
 import android.util.SparseBooleanArray;
 import android.view.FocusFinder;
 import android.view.KeyEvent;
@@ -131,6 +132,7 @@
     private int mChoiceMode = CHOICE_MODE_NONE;
 
     private SparseBooleanArray mCheckStates;
+    private LongSparseArray<Boolean> mCheckedIdStates;
 
     // used for temporary calculations.
     private final Rect mTempRect = new Rect();
@@ -453,6 +455,12 @@
                 checkSelectionChanged();
             }
 
+            if (mChoiceMode != CHOICE_MODE_NONE &&
+                    mAdapter.hasStableIds() &&
+                    mCheckedIdStates == null) {
+                mCheckedIdStates = new LongSparseArray<Boolean>();
+            }
+
         } else {
             mAreAllItemsSelectable = true;
             checkFocus();
@@ -463,6 +471,10 @@
         if (mCheckStates != null) {
             mCheckStates.clear();
         }
+        
+        if (mCheckedIdStates != null) {
+            mCheckedIdStates.clear();
+        }
 
         requestLayout();
     }
@@ -3310,8 +3322,13 @@
      */
     public void setChoiceMode(int choiceMode) {
         mChoiceMode = choiceMode;
-        if (mChoiceMode != CHOICE_MODE_NONE && mCheckStates == null) {
-            mCheckStates = new SparseBooleanArray();
+        if (mChoiceMode != CHOICE_MODE_NONE) {
+            if (mCheckStates == null) {
+                mCheckStates = new SparseBooleanArray();
+            }
+            if (mCheckedIdStates == null && mAdapter != null && mAdapter.hasStableIds()) {
+                mCheckedIdStates = new LongSparseArray<Boolean>();
+            }
         }
     }
 
@@ -3323,14 +3340,25 @@
             handled = true;
 
             if (mChoiceMode == CHOICE_MODE_MULTIPLE) {
-                boolean oldValue = mCheckStates.get(position, false);
-                mCheckStates.put(position, !oldValue);
+                boolean newValue = !mCheckStates.get(position, false);
+                mCheckStates.put(position, newValue);
+                if (mCheckedIdStates != null && mAdapter.hasStableIds()) {
+                    if (newValue) {
+                        mCheckedIdStates.put(mAdapter.getItemId(position), Boolean.TRUE);
+                    } else {
+                        mCheckedIdStates.delete(mAdapter.getItemId(position));
+                    }
+                }
             } else {
-                boolean oldValue = mCheckStates.get(position, false);
-                if (!oldValue) {
+                boolean newValue = !mCheckStates.get(position, false);
+                if (newValue) {
                     mCheckStates.clear();
                     mCheckStates.put(position, true);
-                }
+                    if (mCheckedIdStates != null && mAdapter.hasStableIds()) {
+                        mCheckedIdStates.clear();
+                        mCheckedIdStates.put(mAdapter.getItemId(position), Boolean.TRUE);
+                    }
+                } 
             }
 
             mDataChanged = true;
@@ -3358,16 +3386,30 @@
 
         if (mChoiceMode == CHOICE_MODE_MULTIPLE) {
             mCheckStates.put(position, value);
+            if (mCheckedIdStates != null && mAdapter.hasStableIds()) {
+                if (value) {
+                    mCheckedIdStates.put(mAdapter.getItemId(position), Boolean.TRUE);
+                } else {
+                    mCheckedIdStates.delete(mAdapter.getItemId(position));
+                }
+            }
         } else {
+            boolean updateIds = mCheckedIdStates != null && mAdapter.hasStableIds();
             // Clear all values if we're checking something, or unchecking the currently
             // selected item
             if (value || isItemChecked(position)) {
                 mCheckStates.clear();
+                if (updateIds) {
+                    mCheckedIdStates.clear();
+                }
             }
             // this may end up selecting the value we just cleared but this way
             // we ensure length of mCheckStates is 1, a fact getCheckedItemPosition relies on
             if (value) {
                 mCheckStates.put(position, true);
+                if (updateIds) {
+                    mCheckedIdStates.put(mAdapter.getItemId(position), Boolean.TRUE);
+                }
             }
         }
 
@@ -3433,38 +3475,39 @@
 
     /**
      * Returns the set of checked items ids. The result is only valid if the
-     * choice mode has not been set to {@link #CHOICE_MODE_SINGLE}.
+     * choice mode has not been set to {@link #CHOICE_MODE_NONE}.
+     * 
+     * @return A new array which contains the id of each checked item in the
+     *         list.
+     *         
+     * @deprecated Use {@link #getCheckedItemIds()} instead. 
+     */
+    public long[] getCheckItemIds() {
+        return getCheckedItemIds();
+    }
+    
+    /**
+     * Returns the set of checked items ids. The result is only valid if the
+     * choice mode has not been set to {@link #CHOICE_MODE_NONE} and the adapter
+     * has stable IDs. ({@link ListAdapter#hasStableIds()} == {@code true})
      * 
      * @return A new array which contains the id of each checked item in the
      *         list.
      */
-    public long[] getCheckItemIds() {
-        if (mChoiceMode != CHOICE_MODE_NONE && mCheckStates != null && mAdapter != null) {
-            final SparseBooleanArray states = mCheckStates;
-            final int count = states.size();
-            final long[] ids = new long[count];
-            final ListAdapter adapter = mAdapter;
-
-            int checkedCount = 0;
-            for (int i = 0; i < count; i++) {
-                if (states.valueAt(i)) {
-                    ids[checkedCount++] = adapter.getItemId(states.keyAt(i));
-                }
-            }
-
-            // Trim array if needed. mCheckStates may contain false values
-            // resulting in checkedCount being smaller than count.
-            if (checkedCount == count) {
-                return ids;
-            } else {
-                final long[] result = new long[checkedCount];
-                System.arraycopy(ids, 0, result, 0, checkedCount);
-
-                return result;
-            }
+    public long[] getCheckedItemIds() {
+        if (mChoiceMode == CHOICE_MODE_NONE || mCheckedIdStates == null || mAdapter == null) {
+            return new long[0];
         }
-
-        return new long[0];
+        
+        final LongSparseArray<Boolean> idStates = mCheckedIdStates;
+        final int count = idStates.size();
+        final long[] ids = new long[count];
+        
+        for (int i = 0; i < count; i++) {
+            ids[i] = idStates.keyAt(i);
+        }
+        
+        return ids;
     }
 
     /**
@@ -3474,17 +3517,23 @@
         if (mCheckStates != null) {
             mCheckStates.clear();
         }
+        if (mCheckedIdStates != null) {
+            mCheckedIdStates.clear();
+        }
     }
 
     static class SavedState extends BaseSavedState {
         SparseBooleanArray checkState;
+        LongSparseArray<Boolean> checkIdState;
 
         /**
          * Constructor called from {@link ListView#onSaveInstanceState()}
          */
-        SavedState(Parcelable superState, SparseBooleanArray checkState) {
+        SavedState(Parcelable superState, SparseBooleanArray checkState,
+                LongSparseArray<Boolean> checkIdState) {
             super(superState);
             this.checkState = checkState;
+            this.checkIdState = checkIdState;
         }
 
         /**
@@ -3493,12 +3542,19 @@
         private SavedState(Parcel in) {
             super(in);
             checkState = in.readSparseBooleanArray();
+            long[] idState = in.createLongArray();
+
+            if (idState.length > 0) {
+                checkIdState = new LongSparseArray<Boolean>();
+                checkIdState.setValues(idState, Boolean.TRUE);
+            }
         }
 
         @Override
         public void writeToParcel(Parcel out, int flags) {
             super.writeToParcel(out, flags);
             out.writeSparseBooleanArray(checkState);
+            out.writeLongArray(checkIdState != null ? checkIdState.getKeys() : new long[0]);
         }
 
         @Override
@@ -3523,7 +3579,7 @@
     @Override
     public Parcelable onSaveInstanceState() {
         Parcelable superState = super.onSaveInstanceState();
-        return new SavedState(superState, mCheckStates);
+        return new SavedState(superState, mCheckStates, mCheckedIdStates);
     }
 
     @Override
@@ -3536,5 +3592,8 @@
            mCheckStates = ss.checkState;
         }
 
+        if (ss.checkIdState != null) {
+            mCheckedIdStates = ss.checkIdState;
+        }
     }
 }
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index fd18db4..582d9e4 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -473,10 +473,13 @@
 
     private int getSelectedPos(String str) {
         if (mDisplayedValues == null) {
-            return Integer.parseInt(str);
+            try {
+                return Integer.parseInt(str);
+            } catch (NumberFormatException e) {
+                /* Ignore as if it's not a number we don't care */
+            }
         } else {
             for (int i = 0; i < mDisplayedValues.length; i++) {
-
                 /* Don't force the user to type in jan when ja will do */
                 str = str.toLowerCase();
                 if (mDisplayedValues[i].toLowerCase().startsWith(str)) {
diff --git a/core/jni/android/graphics/Bitmap.cpp b/core/jni/android/graphics/Bitmap.cpp
index 0f1b845..88bbafd 100644
--- a/core/jni/android/graphics/Bitmap.cpp
+++ b/core/jni/android/graphics/Bitmap.cpp
@@ -527,6 +527,53 @@
     }

 }

 

+static bool Bitmap_sameAs(JNIEnv* env, jobject, const SkBitmap* bm0,

+                             const SkBitmap* bm1) {

+    if (bm0->width() != bm1->width() ||

+        bm0->height() != bm1->height() ||

+        bm0->config() != bm1->config()) {

+        return false;

+    }

+

+    SkAutoLockPixels alp0(*bm0);

+    SkAutoLockPixels alp1(*bm1);

+

+    // if we can't load the pixels, return false

+    if (NULL == bm0->getPixels() || NULL == bm1->getPixels()) {

+        return false;

+    }

+

+    if (bm0->config() == SkBitmap::kIndex8_Config) {

+        SkColorTable* ct0 = bm0->getColorTable();

+        SkColorTable* ct1 = bm1->getColorTable();

+        if (NULL == ct0 || NULL == ct1) {

+            return false;

+        }

+        if (ct0->count() != ct1->count()) {

+            return false;

+        }

+

+        SkAutoLockColors alc0(ct0);

+        SkAutoLockColors alc1(ct1);

+        const size_t size = ct0->count() * sizeof(SkPMColor);

+        if (memcmp(alc0.colors(), alc1.colors(), size) != 0) {

+            return false;

+        }

+    }

+

+    // now compare each scanline. We can't do the entire buffer at once,

+    // since we don't care about the pixel values that might extend beyond

+    // the width (since the scanline might be larger than the logical width)

+    const int h = bm0->height();

+    const size_t size = bm0->width() * bm0->bytesPerPixel();

+    for (int y = 0; y < h; y++) {

+        if (memcmp(bm0->getAddr(0, y), bm1->getAddr(0, y), size) != 0) {

+            return false;

+        }

+    }

+    return true;

+}

+

 static void Bitmap_prepareToDraw(JNIEnv* env, jobject, SkBitmap* bitmap) {

     bitmap->lockPixels();

     bitmap->unlockPixels();

@@ -567,7 +614,8 @@
                                             (void*)Bitmap_copyPixelsToBuffer },

     {   "nativeCopyPixelsFromBuffer", "(ILjava/nio/Buffer;)V",

                                             (void*)Bitmap_copyPixelsFromBuffer },

-    {   "nativePrepareToDraw",      "(I)V", (void*)Bitmap_prepareToDraw }

+    {   "nativeSameAs",             "(II)Z", (void*)Bitmap_sameAs },

+    {   "nativePrepareToDraw",      "(I)V", (void*)Bitmap_prepareToDraw },

 };

 

 #define kClassPathName  "android/graphics/Bitmap"

diff --git a/core/jni/android_backup_BackupDataOutput.cpp b/core/jni/android_backup_BackupDataOutput.cpp
index ce30aaa8..b895d11 100644
--- a/core/jni/android_backup_BackupDataOutput.cpp
+++ b/core/jni/android_backup_BackupDataOutput.cpp
@@ -121,7 +121,7 @@
     LOG_FATAL_IF(s_descriptorField == NULL,
             "Unable to find descriptor field in java.io.FileDescriptor");
 
-    return AndroidRuntime::registerNativeMethods(env, "android/backup/BackupDataOutput",
+    return AndroidRuntime::registerNativeMethods(env, "android/app/backup/BackupDataOutput",
             g_methods, NELEM(g_methods));
 }
 
diff --git a/core/jni/android_backup_FileBackupHelperBase.cpp b/core/jni/android_backup_FileBackupHelperBase.cpp
index 8225a36..0137a06 100644
--- a/core/jni/android_backup_FileBackupHelperBase.cpp
+++ b/core/jni/android_backup_FileBackupHelperBase.cpp
@@ -129,7 +129,7 @@
     LOG_FATAL_IF(s_descriptorField == NULL,
             "Unable to find descriptor field in java.io.FileDescriptor");
     
-    return AndroidRuntime::registerNativeMethods(env, "android/backup/FileBackupHelperBase",
+    return AndroidRuntime::registerNativeMethods(env, "android/app/backup/FileBackupHelperBase",
             g_methods, NELEM(g_methods));
 }
 
diff --git a/core/jni/android_location_GpsLocationProvider.cpp b/core/jni/android_location_GpsLocationProvider.cpp
index f845878..a3be309 100755
--- a/core/jni/android_location_GpsLocationProvider.cpp
+++ b/core/jni/android_location_GpsLocationProvider.cpp
@@ -42,6 +42,7 @@
 static const GpsXtraInterface* sGpsXtraInterface = NULL;
 static const AGpsInterface* sAGpsInterface = NULL;
 static const GpsNiInterface* sGpsNiInterface = NULL;
+static const GpsDebugInterface* sGpsDebugInterface = NULL;
 
 // data written to by GPS callbacks
 static GpsLocation  sGpsLocation;
@@ -57,7 +58,7 @@
     GpsUtcTime  timestamp;
     char        nmea[NMEA_SENTENCE_LENGTH];
 };
-static NmeaSentence sNmeaBuffer[NMEA_SENTENCE_LENGTH];
+static NmeaSentence sNmeaBuffer[NMEA_SENTENCE_COUNT];
 static int mNmeaSentenceCount = 0;
 
 // a copy of the data shared by android_location_GpsLocationProvider_wait_for_event
@@ -66,7 +67,7 @@
 static GpsStatus    sGpsStatusCopy;
 static GpsSvStatus  sGpsSvStatusCopy;
 static AGpsStatus   sAGpsStatusCopy;
-static NmeaSentence sNmeaBufferCopy[NMEA_SENTENCE_LENGTH];
+static NmeaSentence sNmeaBufferCopy[NMEA_SENTENCE_COUNT];
 static GpsNiNotification  sGpsNiNotificationCopy;
 
 enum CallbackType {
@@ -226,6 +227,9 @@
     if (sGpsNiInterface)
        sGpsNiInterface->init(&sGpsNiCallbacks);
 
+    if (!sGpsDebugInterface)
+       sGpsDebugInterface = (const GpsDebugInterface*)sGpsInterface->get_extension(GPS_DEBUG_INTERFACE);
+
     return true;
 }
 
@@ -472,11 +476,26 @@
 static void android_location_GpsLocationProvider_send_ni_response(JNIEnv* env, jobject obj,
       jint notifId, jint response)
 {
-   if (!sGpsNiInterface)
-      sGpsNiInterface = (const GpsNiInterface*)sGpsInterface->get_extension(GPS_NI_INTERFACE);
-   if (sGpsNiInterface) {
-      sGpsNiInterface->respond(notifId, response);
-   }
+    if (!sGpsNiInterface) {
+        sGpsNiInterface = (const GpsNiInterface*)sGpsInterface->get_extension(GPS_NI_INTERFACE);
+    }
+    if (sGpsNiInterface) {
+        sGpsNiInterface->respond(notifId, response);
+    }
+}
+
+static jstring android_location_GpsLocationProvider_get_internal_state(JNIEnv* env, jobject obj)
+{
+    jstring result = NULL;
+    if (sGpsDebugInterface) {
+        const size_t maxLength = 2047;
+        char buffer[maxLength+1];
+        size_t length = sGpsDebugInterface->get_internal_state(buffer, maxLength);
+        if (length > maxLength) length = maxLength;
+        buffer[length] = 0;
+        result = env->NewStringUTF(buffer);
+    }
+    return result;
 }
 
 static JNINativeMethod sMethods[] = {
@@ -501,6 +520,7 @@
     {"native_agps_data_conn_failed", "()V", (void*)android_location_GpsLocationProvider_agps_data_conn_failed},
     {"native_set_agps_server", "(ILjava/lang/String;I)V", (void*)android_location_GpsLocationProvider_set_agps_server},
     {"native_send_ni_response", "(II)V", (void*)android_location_GpsLocationProvider_send_ni_response},
+    {"native_get_internal_state", "()Ljava/lang/String;", (void*)android_location_GpsLocationProvider_get_internal_state},
 };
 
 int register_android_location_GpsLocationProvider(JNIEnv* env)
diff --git a/core/res/res/drawable-hdpi/btn_keyboard_key_normal.9.png b/core/res/res/drawable-hdpi/btn_keyboard_key_normal.9.png
index 5697369..42c7c146 100644
--- a/core/res/res/drawable-hdpi/btn_keyboard_key_normal.9.png
+++ b/core/res/res/drawable-hdpi/btn_keyboard_key_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_keyboard_key_normal_off.9.png b/core/res/res/drawable-hdpi/btn_keyboard_key_normal_off.9.png
index 9940245..01e2506 100644
--- a/core/res/res/drawable-hdpi/btn_keyboard_key_normal_off.9.png
+++ b/core/res/res/drawable-hdpi/btn_keyboard_key_normal_off.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_keyboard_key_normal_on.9.png b/core/res/res/drawable-hdpi/btn_keyboard_key_normal_on.9.png
index 5a26d83..83c6eb3 100644
--- a/core/res/res/drawable-hdpi/btn_keyboard_key_normal_on.9.png
+++ b/core/res/res/drawable-hdpi/btn_keyboard_key_normal_on.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_keyboard_key_pressed.9.png b/core/res/res/drawable-hdpi/btn_keyboard_key_pressed.9.png
index 089dbf3..e047eaf 100644
--- a/core/res/res/drawable-hdpi/btn_keyboard_key_pressed.9.png
+++ b/core/res/res/drawable-hdpi/btn_keyboard_key_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_keyboard_key_pressed_off.9.png b/core/res/res/drawable-hdpi/btn_keyboard_key_pressed_off.9.png
index c10a3db..218a2d2 100644
--- a/core/res/res/drawable-hdpi/btn_keyboard_key_pressed_off.9.png
+++ b/core/res/res/drawable-hdpi/btn_keyboard_key_pressed_off.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_keyboard_key_pressed_on.9.png b/core/res/res/drawable-hdpi/btn_keyboard_key_pressed_on.9.png
index 9e83ace..afe4951 100644
--- a/core/res/res/drawable-hdpi/btn_keyboard_key_pressed_on.9.png
+++ b/core/res/res/drawable-hdpi/btn_keyboard_key_pressed_on.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_search_dialog_voice_default.9.png b/core/res/res/drawable-hdpi/btn_search_dialog_voice_default.9.png
index 44668b3..eda6e16 100644
--- a/core/res/res/drawable-hdpi/btn_search_dialog_voice_default.9.png
+++ b/core/res/res/drawable-hdpi/btn_search_dialog_voice_default.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_search_dialog_voice_pressed.9.png b/core/res/res/drawable-hdpi/btn_search_dialog_voice_pressed.9.png
index 3a4571e..4158ac4 100644
--- a/core/res/res/drawable-hdpi/btn_search_dialog_voice_pressed.9.png
+++ b/core/res/res/drawable-hdpi/btn_search_dialog_voice_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_search_dialog_voice_selected.9.png b/core/res/res/drawable-hdpi/btn_search_dialog_voice_selected.9.png
index 60dc632..6f68f25 100644
--- a/core/res/res/drawable-hdpi/btn_search_dialog_voice_selected.9.png
+++ b/core/res/res/drawable-hdpi/btn_search_dialog_voice_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_empty_default.9.png b/core/res/res/drawable-hdpi/textfield_search_empty_default.9.png
new file mode 100644
index 0000000..c0b84da
--- /dev/null
+++ b/core/res/res/drawable-hdpi/textfield_search_empty_default.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_empty_pressed.9.png b/core/res/res/drawable-hdpi/textfield_search_empty_pressed.9.png
new file mode 100644
index 0000000..0a0fc6b
--- /dev/null
+++ b/core/res/res/drawable-hdpi/textfield_search_empty_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/textfield_search_empty_selected.9.png b/core/res/res/drawable-hdpi/textfield_search_empty_selected.9.png
new file mode 100644
index 0000000..04813c2
--- /dev/null
+++ b/core/res/res/drawable-hdpi/textfield_search_empty_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_empty_default.9.png b/core/res/res/drawable-mdpi/textfield_search_empty_default.9.png
new file mode 100644
index 0000000..515117f
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_search_empty_default.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_empty_pressed.9.png b/core/res/res/drawable-mdpi/textfield_search_empty_pressed.9.png
new file mode 100644
index 0000000..a01f763
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_search_empty_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_search_empty_selected.9.png b/core/res/res/drawable-mdpi/textfield_search_empty_selected.9.png
new file mode 100644
index 0000000..611276f
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_search_empty_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable/textfield_search_empty.xml b/core/res/res/drawable/textfield_search_empty.xml
new file mode 100644
index 0000000..55eec83
--- /dev/null
+++ b/core/res/res/drawable/textfield_search_empty.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+
+    <item android:state_window_focused="false" android:state_enabled="true"
+        android:drawable="@drawable/textfield_search_empty_default" />
+
+    <item android:state_pressed="true"
+        android:drawable="@drawable/textfield_search_empty_pressed" />
+
+    <item android:state_enabled="true" android:state_focused="true"
+        android:drawable="@drawable/textfield_search_empty_selected" />
+
+    <item android:state_enabled="true"
+        android:drawable="@drawable/textfield_search_empty_default" />
+
+</selector>
diff --git a/core/tests/coretests/src/android/provider/SettingsProviderTest.java b/core/tests/coretests/src/android/provider/SettingsProviderTest.java
index f82d79a..370ae78 100644
--- a/core/tests/coretests/src/android/provider/SettingsProviderTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsProviderTest.java
@@ -59,7 +59,7 @@
 
         assertEquals("content://settings/system/test_setting",
                 Settings.System.getUriFor("test_setting").toString());
-        assertEquals("content://settings/gservices/test_service",
+        assertEquals("content://settings/secure/test_service",
                 Settings.Secure.getUriFor("test_service").toString());
 
         // These tables use the row name (not ID) as their content URI.
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 5aa88b0..7ca3741 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -972,6 +972,19 @@
     }
 
     /**
+     *  Given another bitmap, return true if it has the same dimensions, config,
+     *  and pixel data as this bitmap. If any of those differ, return false.
+     *  If other is null, return false.
+     *
+     * @hide (just needed internally right now)
+     */
+    public boolean sameAs(Bitmap other) {
+        return this == other ||
+              (other != null &&
+               nativeSameAs(mNativeBitmap, other.mNativeBitmap));
+    }
+
+    /**
      * Rebuilds any caches associated with the bitmap that are used for
      * drawing it. In the case of purgeable bitmaps, this call will attempt to
      * ensure that the pixels have been decoded.
@@ -1042,6 +1055,7 @@
 
     private static native void nativePrepareToDraw(int nativeBitmap);
     private static native void nativeSetHasAlpha(int nBitmap, boolean hasAlpha);
+    private static native boolean nativeSameAs(int nb0, int nb1);
 
     /* package */ final int ni() {
         return mNativeBitmap;
diff --git a/libs/audioflinger/AudioPolicyManagerBase.cpp b/libs/audioflinger/AudioPolicyManagerBase.cpp
index 7b866c7..cfcc3ea 100644
--- a/libs/audioflinger/AudioPolicyManagerBase.cpp
+++ b/libs/audioflinger/AudioPolicyManagerBase.cpp
@@ -1290,7 +1290,7 @@
                 a2dpOutputDesc->changeRefCount((AudioSystem::stream_type)i,-refCount);
             }
         }
-        // do not change newDevice is it was already set before this call by a previous call to
+        // do not change newDevice if it was already set before this call by a previous call to
         // getNewDevice() or checkOutputForStrategy() for a strategy with higher priority
         if (newDevice == 0 && hwOutputDesc->isUsedByStrategy(strategy)) {
             newDevice = getDeviceForStrategy(strategy, false);
@@ -1466,6 +1466,12 @@
 
     case STRATEGY_MEDIA: {
         uint32_t device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_AUX_DIGITAL;
+        if (device2 == 0) {
+            device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
+        }
+        if (device2 == 0) {
+            device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
+        }
 #ifdef WITH_A2DP
         if (mA2dpOutput != 0) {
             if (strategy == STRATEGY_SONIFICATION && !a2dpUsedForSonification()) {
@@ -1483,12 +1489,6 @@
         }
 #endif
         if (device2 == 0) {
-            device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE;
-        }
-        if (device2 == 0) {
-            device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET;
-        }
-        if (device2 == 0) {
             device2 = mAvailableOutputDevices & AudioSystem::DEVICE_OUT_SPEAKER;
         }
 
diff --git a/location/java/android/location/ILocationProvider.aidl b/location/java/android/location/ILocationProvider.aidl
index 5529b11..97b283c 100644
--- a/location/java/android/location/ILocationProvider.aidl
+++ b/location/java/android/location/ILocationProvider.aidl
@@ -39,6 +39,7 @@
     void disable();
     int getStatus(out Bundle extras);
     long getStatusUpdateTime();
+    String getInternalState();
     void enableLocationTracking(boolean enable);
     void setMinTime(long minTime);
     void updateNetworkState(int state, in NetworkInfo info);
diff --git a/location/java/android/location/LocationProviderInterface.java b/location/java/android/location/LocationProviderInterface.java
index 98beffe..5ffe15c 100644
--- a/location/java/android/location/LocationProviderInterface.java
+++ b/location/java/android/location/LocationProviderInterface.java
@@ -42,6 +42,7 @@
     int getStatus(Bundle extras);
     long getStatusUpdateTime();
     void enableLocationTracking(boolean enable);
+    String getInternalState();
     void setMinTime(long minTime);
     void updateNetworkState(int state, NetworkInfo info);
     void updateLocation(Location location);
diff --git a/location/java/android/location/provider/LocationProvider.java b/location/java/android/location/provider/LocationProvider.java
index 4163def..56cfb33 100644
--- a/location/java/android/location/provider/LocationProvider.java
+++ b/location/java/android/location/provider/LocationProvider.java
@@ -95,6 +95,10 @@
             return LocationProvider.this.onGetStatusUpdateTime();
         }
 
+        public String getInternalState() {
+            return LocationProvider.this.onGetInternalState();
+        }
+
         public void enableLocationTracking(boolean enable) {
             LocationProvider.this.onEnableLocationTracking(enable);
         }
@@ -267,6 +271,13 @@
     public abstract long onGetStatusUpdateTime();
 
     /**
+     * Returns debugging information about the location provider.
+     *
+     * @return string describing the internal state of the location provider, or null.
+     */
+    public abstract String onGetInternalState();
+
+    /**
      * Notifies the location provider that clients are listening for locations.
      * Called with enable set to true when the first client is added and
      * called with enable set to false when the last client is removed.
diff --git a/location/java/com/android/internal/location/GpsLocationProvider.java b/location/java/com/android/internal/location/GpsLocationProvider.java
index 90b50cc..44a5a6b 100755
--- a/location/java/com/android/internal/location/GpsLocationProvider.java
+++ b/location/java/com/android/internal/location/GpsLocationProvider.java
@@ -633,6 +633,10 @@
         }
     }
 
+    public String getInternalState() {
+        return native_get_internal_state();
+    }
+
     private final class Listener implements IBinder.DeathRecipient {
         final IGpsStatusListener mListener;
         
@@ -1391,12 +1395,15 @@
     private native int native_read_nmea(int index, byte[] buffer, int bufferSize);
     private native void native_inject_location(double latitude, double longitude, float accuracy);
 
-    // XTRA Support    
+    // XTRA Support
     private native void native_inject_time(long time, long timeReference, int uncertainty);
     private native boolean native_supports_xtra();
     private native void native_inject_xtra_data(byte[] data, int length);
 
-    // AGPS Support    
+    // DEBUG Support
+    private native String native_get_internal_state();
+
+    // AGPS Support
     private native void native_agps_data_conn_open(String apn);
     private native void native_agps_data_conn_closed();
     private native void native_agps_data_conn_failed();
diff --git a/location/java/com/android/internal/location/LocationProviderProxy.java b/location/java/com/android/internal/location/LocationProviderProxy.java
index abb90b7..31ec09a 100644
--- a/location/java/com/android/internal/location/LocationProviderProxy.java
+++ b/location/java/com/android/internal/location/LocationProviderProxy.java
@@ -266,6 +266,15 @@
         return 0;
      }
 
+    public String getInternalState() {
+        try {
+            return mProvider.getInternalState();
+        } catch (RemoteException e) {
+            Log.e(TAG, "getInternalState failed", e);
+            return null;
+        }
+    }
+
     public boolean isLocationTracking() {
         return mLocationTracking;
     }
diff --git a/location/java/com/android/internal/location/MockProvider.java b/location/java/com/android/internal/location/MockProvider.java
index bc1893e..d912740 100644
--- a/location/java/com/android/internal/location/MockProvider.java
+++ b/location/java/com/android/internal/location/MockProvider.java
@@ -168,6 +168,10 @@
         mStatusUpdateTime = 0;
     }
 
+    public String getInternalState() {
+        return null;
+    }
+
     public void enableLocationTracking(boolean enable) {
     }
 
diff --git a/location/java/com/android/internal/location/PassiveProvider.java b/location/java/com/android/internal/location/PassiveProvider.java
index 7eb711d..ab90937 100644
--- a/location/java/com/android/internal/location/PassiveProvider.java
+++ b/location/java/com/android/internal/location/PassiveProvider.java
@@ -106,6 +106,10 @@
         return -1;
     }
 
+    public String getInternalState() {
+        return null;
+    }
+
     public void enableLocationTracking(boolean enable) {
         mTracking = enable;
     }
diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java
index a186e58..882cbc5 100644
--- a/opengl/java/android/opengl/GLSurfaceView.java
+++ b/opengl/java/android/opengl/GLSurfaceView.java
@@ -30,6 +30,7 @@
 
 import android.content.Context;
 import android.content.pm.ConfigurationInfo;
+import android.graphics.PixelFormat;
 import android.os.SystemProperties;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -75,15 +76,23 @@
  * <li>{@link #setGLWrapper(GLWrapper)}
  * </ul>
  * <p>
- * <h4>Choosing an EGL Configuration</h4>
- * A given Android device may support multiple possible types of drawing surfaces.
- * The available surfaces may differ in how may channels of data are present, as
- * well as how many bits are allocated to each channel. Therefore, the first thing
- * GLSurfaceView has to do when starting to render is choose what type of surface to use.
+ * <h4>Specifying the android.view.Surface</h4>
+ * By default GLSurfaceView will create a PixelFormat.RGB_565 format surface. If a translucent
+ * surface is required, call getHolder().setFormat(PixelFormat.TRANSLUCENT).
+ * The exact format of a TRANSLUCENT surface is device dependent, but it will be
+ * a 32-bit-per-pixel surface with 8 bits per component.
  * <p>
- * By default GLSurfaceView chooses an available surface that's closest to a 16-bit R5G6B5 surface
- * with a 16-bit depth buffer and no stencil. If you would prefer a different surface (for example,
- * if you do not need a depth buffer) you can override the default behavior by calling one of the
+ * <h4>Choosing an EGL Configuration</h4>
+ * A given Android device may support multiple EGLConfig rendering configurations.
+ * The available configurations may differ in how may channels of data are present, as
+ * well as how many bits are allocated to each channel. Therefore, the first thing
+ * GLSurfaceView has to do when starting to render is choose what EGLConfig to use.
+ * <p>
+ * By default GLSurfaceView chooses a EGLConfig that has an RGB_656 pixel format,
+ * with at least a 16-bit depth buffer and no stencil.
+ * <p>
+ * If you would prefer a different EGLConfig
+ * you can override the default behavior by calling one of the
  * setEGLConfigChooser methods.
  * <p>
  * <h4>Debug Behavior</h4>
@@ -149,6 +158,7 @@
     private final static boolean LOG_THREADS = false;
     private final static boolean LOG_SURFACE = false;
     private final static boolean LOG_RENDERER = false;
+    private final static boolean LOG_RENDERER_DRAW_FRAME = false;
     // Work-around for bug 2263168
     private final static boolean DRAW_TWICE_AFTER_SIZE_CHANGED = true;
     /**
@@ -210,6 +220,7 @@
         // underlying surface is created and destroyed
         SurfaceHolder holder = getHolder();
         holder.addCallback(this);
+        holder.setFormat(PixelFormat.RGB_565);
         // setType is not needed for SDK 2.0 or newer. Uncomment this
         // statement if back-porting this code to older SDKs.
         // holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
@@ -330,8 +341,9 @@
      * is called.
      * <p>
      * If no setEGLConfigChooser method is called, then by default the
-     * view will choose a config as close to 16-bit RGB as possible, with
-     * a depth buffer as close to 16 bits as possible.
+     * view will choose an EGLConfig that is compatible with the current
+     * android.view.Surface, with a depth buffer depth of
+     * at least 16 bits.
      * @param configChooser
      */
     public void setEGLConfigChooser(EGLConfigChooser configChooser) {
@@ -347,9 +359,9 @@
      * called, it must be called before {@link #setRenderer(Renderer)}
      * is called.
      * <p>
-      * If no setEGLConfigChooser method is called, then by default the
-     * view will choose a config as close to 16-bit RGB as possible, with
-     * a depth buffer as close to 16 bits as possible.
+     * If no setEGLConfigChooser method is called, then by default the
+     * view will choose an RGB_565 surface with a depth buffer depth of
+     * at least 16 bits.
      *
      * @param needDepth
      */
@@ -359,15 +371,15 @@
 
     /**
      * Install a config chooser which will choose a config
-     * with at least the specified component sizes, and as close
-     * to the specified component sizes as possible.
+     * with at least the specified depthSize and stencilSize,
+     * and exactly the specified redSize, greenSize, blueSize and alphaSize.
      * <p>If this method is
      * called, it must be called before {@link #setRenderer(Renderer)}
      * is called.
      * <p>
      * If no setEGLConfigChooser method is called, then by default the
-     * view will choose a config as close to 16-bit RGB as possible, with
-     * a depth buffer as close to 16 bits as possible.
+     * view will choose an RGB_565 surface with a depth buffer depth of
+     * at least 16 bits.
      *
      */
     public void setEGLConfigChooser(int redSize, int greenSize, int blueSize,
@@ -774,6 +786,10 @@
         }
     }
 
+    /**
+     * Choose a configuration with exactly the specified r,g,b,a sizes,
+     * and at least the specified depth and stencil sizes.
+     */
     private class ComponentSizeChooser extends BaseConfigChooser {
         public ComponentSizeChooser(int redSize, int greenSize, int blueSize,
                 int alphaSize, int depthSize, int stencilSize) {
@@ -797,14 +813,12 @@
         @Override
         public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display,
                 EGLConfig[] configs) {
-            EGLConfig closestConfig = null;
-            int closestDistance = 1000;
-            for(EGLConfig config : configs) {
+            for (EGLConfig config : configs) {
                 int d = findConfigAttrib(egl, display, config,
                         EGL10.EGL_DEPTH_SIZE, 0);
                 int s = findConfigAttrib(egl, display, config,
                         EGL10.EGL_STENCIL_SIZE, 0);
-                if (d >= mDepthSize && s>= mStencilSize) {
+                if ((d >= mDepthSize) && (s >= mStencilSize)) {
                     int r = findConfigAttrib(egl, display, config,
                             EGL10.EGL_RED_SIZE, 0);
                     int g = findConfigAttrib(egl, display, config,
@@ -813,17 +827,13 @@
                               EGL10.EGL_BLUE_SIZE, 0);
                     int a = findConfigAttrib(egl, display, config,
                             EGL10.EGL_ALPHA_SIZE, 0);
-                    int distance = Math.abs(r - mRedSize)
-                                + Math.abs(g - mGreenSize)
-                                + Math.abs(b - mBlueSize)
-                                + Math.abs(a - mAlphaSize);
-                    if (distance < closestDistance) {
-                        closestDistance = distance;
-                        closestConfig = config;
+                    if ((r == mRedSize) && (g == mGreenSize)
+                            && (b == mBlueSize) && (a == mAlphaSize)) {
+                        return config;
                     }
                 }
             }
-            return closestConfig;
+            return null;
         }
 
         private int findConfigAttrib(EGL10 egl, EGLDisplay display,
@@ -846,18 +856,13 @@
         }
 
     /**
-     * This class will choose a supported surface as close to
-     * RGB565 as possible, with or without a depth buffer.
+     * This class will choose a RGB_565 surface with
+     * or without a depth buffer.
      *
      */
     private class SimpleEGLConfigChooser extends ComponentSizeChooser {
         public SimpleEGLConfigChooser(boolean withDepthBuffer) {
-            super(4, 4, 4, 0, withDepthBuffer ? 16 : 0, 0);
-            // Adjust target values. This way we'll accept a 4444 or
-            // 555 buffer if there's no 565 buffer available.
-            mRedSize = 5;
-            mGreenSize = 6;
-            mBlueSize = 5;
+            super(5, 6, 5, 0, withDepthBuffer ? 16 : 0, 0);
         }
     }
 
@@ -1209,15 +1214,18 @@
                     }
 
                     if (createEglSurface) {
+                        if (LOG_SURFACE) {
+                            Log.w("GLThread", "egl createSurface");
+                        }
                         gl = (GL10) mEglHelper.createSurface(getHolder());
                         sGLThreadManager.checkGLDriver(gl);
-                        if (LOG_RENDERER) {
-                            Log.w("GLThread", "onSurfaceCreated");
-                        }
                         createEglSurface = false;
                     }
 
                     if (createEglContext) {
+                        if (LOG_RENDERER) {
+                            Log.w("GLThread", "onSurfaceCreated");
+                        }
                         mRenderer.onSurfaceCreated(gl, mEglHelper.mEglConfig);
                         createEglContext = false;
                     }
@@ -1230,7 +1238,7 @@
                         sizeChanged = false;
                     }
 
-                    if (LOG_RENDERER) {
+                    if (LOG_RENDERER_DRAW_FRAME) {
                         Log.w("GLThread", "onDrawFrame");
                     }
                     mRenderer.onDrawFrame(gl);
@@ -1438,6 +1446,7 @@
     }
 
     private static class GLThreadManager {
+        private static String TAG = "GLThreadManager";
 
         public synchronized void threadExiting(GLThread thread) {
             if (LOG_THREADS) {
@@ -1483,7 +1492,7 @@
 
         public synchronized boolean shouldReleaseEGLContextWhenPausing() {
             checkGLESVersion();
-            return mMultipleGLESContextsAllowed;
+            return !mMultipleGLESContextsAllowed;
         }
 
         public synchronized void checkGLDriver(GL10 gl) {
@@ -1493,6 +1502,10 @@
                     String renderer = gl.glGetString(GL10.GL_RENDERER);
                     mMultipleGLESContextsAllowed =
                         ! renderer.startsWith(kMSM7K_RENDERER_PREFIX);
+                    if (LOG_SURFACE) {
+                        Log.w(TAG, "checkGLDriver renderer = \"" + renderer + "\" multipleContextsAllowed = "
+                            + mMultipleGLESContextsAllowed);
+                    }
                     notifyAll();
                 }
                 mGLESDriverCheckComplete = true;
@@ -1507,6 +1520,10 @@
                 if (mGLESVersion >= kGLES_20) {
                     mMultipleGLESContextsAllowed = true;
                 }
+                if (LOG_SURFACE) {
+                    Log.w(TAG, "checkGLESVersion mGLESVersion =" +
+                            " " + mGLESVersion + " mMultipleGLESContextsAllowed = " + mMultipleGLESContextsAllowed);
+                }
                 mGLESVersionCheckComplete = true;
             }
         }
diff --git a/packages/TtsService/src/android/tts/SynthProxy.java b/packages/TtsService/src/android/tts/SynthProxy.java
index 6255275..cd46c05 100755
--- a/packages/TtsService/src/android/tts/SynthProxy.java
+++ b/packages/TtsService/src/android/tts/SynthProxy.java
@@ -36,9 +36,9 @@
     // Such a huge filter gain is justified by how much energy in the low frequencies is "wasted" at
     // the output of the synthesis. The low shelving filter removes it, leaving room for
     // amplification.
-    private final static float PICO_FILTER_GAIN = 5.5f; // linear gain
-    private final static float PICO_FILTER_LOWSHELF_ATTENUATION = -18.0f; // in dB
-    private final static float PICO_FILTER_TRANSITION_FREQ = 1100.0f;     // in Hz
+    private final static float PICO_FILTER_GAIN = 4.0f; // linear gain
+    private final static float PICO_FILTER_LOWSHELF_ATTENUATION = -16.0f; // in dB
+    private final static float PICO_FILTER_TRANSITION_FREQ = 1000.0f;     // in Hz
     private final static float PICO_FILTER_SHELF_SLOPE = 1.0f;            // Q
 
     //
@@ -50,7 +50,7 @@
      */
     public SynthProxy(String nativeSoLib) {
         boolean applyFilter = nativeSoLib.toLowerCase().contains("pico");
-        Log.v(TtsService.SERVICE_TAG, "about to load "+ nativeSoLib + ", applyFilter="+applyFilter);
+        Log.v(TtsService.SERVICE_TAG, "About to load "+ nativeSoLib + ", applyFilter="+applyFilter);
         native_setup(new WeakReference<SynthProxy>(this), nativeSoLib);
         native_setLowShelf(applyFilter, PICO_FILTER_GAIN, PICO_FILTER_LOWSHELF_ATTENUATION,
                 PICO_FILTER_TRANSITION_FREQ, PICO_FILTER_SHELF_SLOPE);
diff --git a/preloaded-classes b/preloaded-classes
index 28cbba3..5672c66 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -57,15 +57,15 @@
 android.appwidget.AppWidgetManager
 android.appwidget.AppWidgetProvider
 android.appwidget.AppWidgetProviderInfo
-android.backup.BackupDataInput
-android.backup.BackupDataInput$EntityHeader
-android.backup.BackupDataOutput
-android.backup.BackupHelperAgent
-android.backup.BackupHelperDispatcher
-android.backup.BackupHelperDispatcher$Header
-android.backup.FileBackupHelperBase
-android.backup.IBackupManager$Stub
-android.backup.RestoreSet
+android.app.backup.BackupDataInput
+android.app.backup.BackupDataInput$EntityHeader
+android.app.backup.BackupDataOutput
+android.app.backup.BackupHelperAgent
+android.app.backup.BackupHelperDispatcher
+android.app.backup.BackupHelperDispatcher$Header
+android.app.backup.FileBackupHelperBase
+android.app.backup.IBackupManager$Stub
+android.app.backup.RestoreSet
 android.bluetooth.BluetoothAdapter
 android.bluetooth.BluetoothAudioGateway
 android.bluetooth.BluetoothSocket
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index 8d00deb..7aa092a 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -765,7 +765,9 @@
             pw.println(prefix + "mMinTime=" + mMinTime + " mMinDistance=" + mMinDistance);
             pw.println(prefix + "mUid=" + mUid);
             pw.println(prefix + "mLastFixBroadcast:");
-            mLastFixBroadcast.dump(new PrintWriterPrinter(pw), prefix + "  ");
+            if (mLastFixBroadcast != null) {
+                mLastFixBroadcast.dump(new PrintWriterPrinter(pw), prefix + "  ");
+            }
             pw.println(prefix + "mLastStatusBroadcast=" + mLastStatusBroadcast);
         }
     }
@@ -1954,6 +1956,13 @@
                     i.getValue().dump(pw, "      ");
                 }
             }
+            for (LocationProviderInterface provider: mProviders) {
+                String state = provider.getInternalState();
+                if (state != null) {
+                    pw.println(provider.getName() + " Internal State:");
+                    pw.write(state);
+                }
+            }
         }
     }
 }
diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java
index 71826ff..5f23a90 100644
--- a/services/java/com/android/server/UiModeManagerService.java
+++ b/services/java/com/android/server/UiModeManagerService.java
@@ -347,11 +347,13 @@
                 }
             }
             if (mKeyguardLock != null) {
+                long ident = Binder.clearCallingIdentity();
                 if (enabled) {
                     mKeyguardLock.disableKeyguard();
                 } else {
                     mKeyguardLock.reenableKeyguard();
                 }
+                Binder.restoreCallingIdentity(ident);
             }
         }
     }