Merge change 25826 into eclair

* changes:
  Suppressed the invalidFrameRate as the framework is not throwing the IOException anymore.
diff --git a/Android.mk b/Android.mk
index 4e7b14e..90f2acb 100644
--- a/Android.mk
+++ b/Android.mk
@@ -341,6 +341,7 @@
     -since ./frameworks/base/api/2.xml 2 \
     -since ./frameworks/base/api/3.xml 3 \
     -since ./frameworks/base/api/4.xml 4 \
+    -since ./frameworks/base/api/current.xml Eclair \
 		-error 1 -error 2 -warning 3 -error 4 -error 6 -error 8 \
 		-overview $(LOCAL_PATH)/core/java/overview.html
 
diff --git a/api/current.xml b/api/current.xml
index 612b305..b38176d 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -77640,8 +77640,8 @@
 <parameter name="tag" type="java.lang.String">
 </parameter>
 </method>
-<method name="getDateTime"
- return="long"
+<method name="getAttributeInt"
+ return="int"
  abstract="false"
  native="false"
  synchronized="false"
@@ -77650,9 +77650,13 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<parameter name="tag" type="java.lang.String">
+</parameter>
+<parameter name="defaultValue" type="int">
+</parameter>
 </method>
 <method name="getLatLong"
- return="float[]"
+ return="boolean"
  abstract="false"
  native="false"
  synchronized="false"
@@ -77661,17 +77665,8 @@
  deprecated="not deprecated"
  visibility="public"
 >
-</method>
-<method name="getOrientationString"
- return="java.lang.String"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
+<parameter name="output" type="float[]">
+</parameter>
 </method>
 <method name="getThumbnail"
  return="byte[]"
@@ -77684,17 +77679,6 @@
  visibility="public"
 >
 </method>
-<method name="getWhiteBalanceString"
- return="java.lang.String"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
 <method name="hasThumbnail"
  return="boolean"
  abstract="false"
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 96a927b..1fc22fe 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -573,6 +573,7 @@
 
     /**
      * Validate a Bluetooth address, such as "00:43:A8:23:10:F0"
+     * <p>Alphabetic characters must be uppercase to be valid.
      *
      * @param address Bluetooth address as string
      * @return true if the address is valid, false otherwise
@@ -586,8 +587,9 @@
             switch (i % 3) {
             case 0:
             case 1:
-                if (Character.digit(c, 16) != -1) {
-                    break;  // hex character, OK
+                if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F')) {
+                    // hex character, OK
+                    break;
                 }
                 return false;
             case 2:
diff --git a/core/java/android/bluetooth/ScoSocket.java b/core/java/android/bluetooth/ScoSocket.java
index 1bf786f..116310a 100644
--- a/core/java/android/bluetooth/ScoSocket.java
+++ b/core/java/android/bluetooth/ScoSocket.java
@@ -87,7 +87,7 @@
      *  Does not block.
      */
     public synchronized boolean connect(String address) {
-        if (VDBG) log("connect() " + this);
+        if (DBG) log("connect() " + this);
         if (mState != STATE_READY) {
             if (DBG) log("connect(): Bad state");
             return false;
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 93ee3ba..bdddc28 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -682,7 +682,8 @@
      * definition and some generic columns. Each data type can define the meaning for each of
      * the generic columns.
      */
-    public static final class Data implements BaseColumns, DataColumns {
+    public static final class Data implements BaseColumns, DataColumns, RawContactsColumns,
+            ContactsColumns {
         /**
          * This utility class cannot be instantiated
          */
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 920bcc7..1d41df2 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3599,6 +3599,14 @@
                 "search_per_source_concurrent_query_limit";
 
         /**
+         * Flag for allowing ActivityManagerService to send ACTION_APP_ERROR intents
+         * on application crashes and ANRs. If this is disabled, the crash/ANR dialog
+         * will never display the "Report" button.
+         * Type: int ( 0 = disallow, 1 = allow )
+         */
+        public static final String SEND_ACTION_APP_ERROR = "send_action_app_error";
+
+        /**
          * @deprecated
          * @hide
          */
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index bd38b2d..45ff27e 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -436,6 +436,12 @@
     public int subWindowTypeToLayerLw(int type);
 
     /**
+     * Get the highest layer (actually one more than) that the wallpaper is
+     * allowed to be in.
+     */
+    public int getMaxWallpaperLayer();
+    
+    /**
      * Called when the system would like to show a UI to indicate that an
      * application is starting.  You can use this to add a
      * APPLICATION_STARTING_TYPE window with the given appToken to the window
diff --git a/core/java/android/webkit/HTML5VideoViewProxy.java b/core/java/android/webkit/HTML5VideoViewProxy.java
index c10355c..8b783e8 100644
--- a/core/java/android/webkit/HTML5VideoViewProxy.java
+++ b/core/java/android/webkit/HTML5VideoViewProxy.java
@@ -36,10 +36,12 @@
 import android.os.Message;
 import android.util.Log;
 import android.view.MotionEvent;
+import android.view.Gravity;
 import android.view.View;
 import android.view.ViewGroup;
 import android.webkit.ViewManager.ChildView;
 import android.widget.AbsoluteLayout;
+import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.MediaController;
 import android.widget.VideoView;
@@ -90,6 +92,10 @@
         // The VideoView instance. This is a singleton for now, at least until
         // http://b/issue?id=1973663 is fixed.
         private static VideoView mVideoView;
+        // The progress view.
+        private static View mProgressView;
+        // The container for the progress view and video view
+        private static FrameLayout mLayout;
 
         private static final WebChromeClient.CustomViewCallback mCallback =
             new WebChromeClient.CustomViewCallback() {
@@ -101,7 +107,13 @@
                     // is invoked.
                     mCurrentProxy.playbackEnded();
                     mCurrentProxy = null;
+                    mLayout.removeView(mVideoView);
                     mVideoView = null;
+                    if (mProgressView != null) {
+                        mLayout.removeView(mProgressView);
+                        mProgressView = null;
+                    }
+                    mLayout = null;
                 }
             };
 
@@ -113,6 +125,13 @@
                 return;
             }
             mCurrentProxy = proxy;
+            // Create a FrameLayout that will contain the VideoView and the
+            // progress view (if any).
+            mLayout = new FrameLayout(proxy.getContext());
+            FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
+                    ViewGroup.LayoutParams.WRAP_CONTENT,
+                    ViewGroup.LayoutParams.WRAP_CONTENT,
+                    Gravity.CENTER);
             mVideoView = new VideoView(proxy.getContext());
             mVideoView.setWillNotDraw(false);
             mVideoView.setMediaController(new MediaController(proxy.getContext()));
@@ -120,8 +139,15 @@
             mVideoView.setOnCompletionListener(proxy);
             mVideoView.setOnPreparedListener(proxy);
             mVideoView.seekTo(time);
+            mLayout.addView(mVideoView, layoutParams);
+            mProgressView = client.getVideoLoadingProgressView();
+            if (mProgressView != null) {
+                mLayout.addView(mProgressView, layoutParams);
+                mProgressView.setVisibility(View.VISIBLE);
+            }
+            mLayout.setVisibility(View.VISIBLE);
             mVideoView.start();
-            client.onShowCustomView(mVideoView, mCallback);
+            client.onShowCustomView(mLayout, mCallback);
         }
 
         public static void seek(int time, HTML5VideoViewProxy proxy) {
@@ -135,11 +161,20 @@
                 mVideoView.pause();
             }
         }
+
+        public static void onPrepared() {
+            if (mProgressView != null) {
+                mProgressView.setVisibility(View.GONE);
+                mLayout.removeView(mProgressView);
+                mProgressView = null;
+            }
+        }
     }
 
     // A bunch event listeners for our VideoView
     // MediaPlayer.OnPreparedListener
     public void onPrepared(MediaPlayer mp) {
+        VideoPlayer.onPrepared();
         Message msg = Message.obtain(mWebCoreHandler, PREPARED);
         Map<String, Object> map = new HashMap<String, Object>();
         map.put("dur", new Integer(mp.getDuration()));
@@ -166,6 +201,13 @@
         switch (msg.what) {
             case INIT: {
                 mPosterView = new ImageView(mWebView.getContext());
+                WebChromeClient client = mWebView.getWebChromeClient();
+                if (client != null) {
+                    Bitmap poster = client.getDefaultVideoPoster();
+                    if (poster != null) {
+                        mPosterView.setImageBitmap(poster);
+                    }
+                }
                 mChildView.mView = mPosterView;
                 break;
             }
diff --git a/core/java/android/webkit/WebChromeClient.java b/core/java/android/webkit/WebChromeClient.java
index 6421fe7..0e08514 100644
--- a/core/java/android/webkit/WebChromeClient.java
+++ b/core/java/android/webkit/WebChromeClient.java
@@ -273,4 +273,26 @@
      * @hide pending API council.
      */
     public void addMessageToConsole(String message, int lineNumber, String sourceID) {}
+
+    /**
+     * Ask the host application for an icon to represent a <video> element.
+     * This icon will be used if the Web page did not specify a poster attribute.
+     *
+     * @return Bitmap The icon or null if no such icon is available.
+     * @hide pending API Council approval
+     */
+    public Bitmap getDefaultVideoPoster() {
+        return null;
+    }
+
+    /**
+     * Ask the host application for a custom progress view to show while
+     * a <video> is loading.
+     *
+     * @return View The progress view.
+     * @hide pending API Council approval
+     */
+    public View getVideoLoadingProgressView() {
+        return null;
+    }
 }
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 003c1a2..7e8ba8f 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -905,8 +905,9 @@
     /*
      * Return the width of the view where the content of WebView should render
      * to.
+     * Note: this can be called from WebCoreThread.
      */
-    private int getViewWidth() {
+    /* package */ int getViewWidth() {
         if (!isVerticalScrollBarEnabled() || mOverlayVerticalScrollbar) {
             return getWidth();
         } else {
@@ -932,8 +933,9 @@
     /*
      * Return the height of the view where the content of WebView should render
      * to.  Note that this excludes mTitleBar, if there is one.
+     * Note: this can be called from WebCoreThread.
      */
-    private int getViewHeight() {
+    /* package */ int getViewHeight() {
         int height = getHeight();
         if (isHorizontalScrollBarEnabled() && !mOverlayHorizontalScrollbar) {
             height -= getHorizontalScrollbarHeight();
@@ -2482,8 +2484,11 @@
     }
 
     // scale from content to view coordinates, and pin
-    // return true if pin caused the final x/y different than the request cx/cy;
-    // return false if the view scroll to the exact position as it is requested.
+    // return true if pin caused the final x/y different than the request cx/cy,
+    // and a future scroll may reach the request cx/cy after our size has
+    // changed
+    // return false if the view scroll to the exact position as it is requested,
+    // where negative numbers are taken to mean 0
     private boolean setContentScrollTo(int cx, int cy) {
         if (mDrawHistory) {
             // disallow WebView to change the scroll position as History Picture
@@ -2498,7 +2503,9 @@
 //        Log.d(LOGTAG, "content scrollTo [" + cx + " " + cy + "] view=[" +
 //                      vx + " " + vy + "]");
         pinScrollTo(vx, vy, false, 0);
-        if (mScrollX != vx || mScrollY != vy) {
+        // If the request was to scroll to a negative coordinate, treat it as if
+        // it was a request to scroll to 0
+        if ((mScrollX != vx && cx >= 0) || (mScrollY != vy && cy >= 0)) {
             return true;
         } else {
             return false;
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index ac3334c..d4142bb 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -1890,7 +1890,22 @@
         if (mViewportWidth != 0 && !updateRestoreState) return;
 
         // now notify webview
-        int webViewWidth = Math.round(mCurrentViewWidth * mCurrentViewScale);
+        // webViewWidth refers to the width in the view system
+        int webViewWidth;
+        // viewportWidth refers to the width in the document system
+        int viewportWidth = mCurrentViewWidth;
+        if (viewportWidth == 0) {
+            // this may happen when WebView just starts. This is not perfect as
+            // we call WebView method from WebCore thread. But not perfect
+            // reference is better than no reference.
+            webViewWidth = mWebView.getViewWidth();
+            viewportWidth = webViewWidth * 100 / WebView.DEFAULT_SCALE_PERCENT;
+            if (viewportWidth == 0) {
+                Log.w(LOGTAG, "Can't get the viewWidth after the first layout");
+            }
+        } else {
+            webViewWidth = Math.round(viewportWidth * mCurrentViewScale);
+        }
         mRestoreState = new RestoreState();
         mRestoreState.mMinScale = mViewportMinimumScale / 100.0f;
         mRestoreState.mMaxScale = mViewportMaximumScale / 100.0f;
@@ -1942,7 +1957,7 @@
             mEventHub.sendMessageAtFrontOfQueue(Message.obtain(null,
                     EventHub.VIEW_SIZE_CHANGED, data));
         } else if (mSettings.getUseWideViewPort()) {
-            if (mCurrentViewWidth == 0) {
+            if (viewportWidth == 0) {
                 // Trick to ensure VIEW_SIZE_CHANGED will be sent from WebView
                 // to WebViewCore
                 mWebView.mLastWidthSent = 0;
@@ -1956,8 +1971,7 @@
                                 : mRestoreState.mTextWrapScale)
                         : mRestoreState.mViewScale;
                 data.mWidth = Math.round(webViewWidth / data.mScale);
-                data.mHeight = mCurrentViewHeight * data.mWidth
-                        / mCurrentViewWidth;
+                data.mHeight = mCurrentViewHeight * data.mWidth / viewportWidth;
                 data.mTextWrapWidth = Math.round(webViewWidth
                         / mRestoreState.mTextWrapScale);
                 data.mIgnoreHeight = false;
diff --git a/core/java/com/android/internal/widget/ContactHeaderWidget.java b/core/java/com/android/internal/widget/ContactHeaderWidget.java
index 4ec597c..ed375f7 100644
--- a/core/java/com/android/internal/widget/ContactHeaderWidget.java
+++ b/core/java/com/android/internal/widget/ContactHeaderWidget.java
@@ -248,7 +248,9 @@
                                     PHONE_LOOKUP_CONTACT_LOOKUP_KEY_COLUMN_INDEX);
                             bindFromContactUri(Contacts.getLookupUri(contactId, lookupKey));
                         } else {
-                            setDisplayName((String) cookie, null);
+                            String phoneNumber = (String) cookie;
+                            setDisplayName(phoneNumber, null);
+                            mPhotoView.assignContactFromPhone(phoneNumber, true);
                         }
                         break;
                     }
@@ -259,7 +261,9 @@
                                     EMAIL_LOOKUP_CONTACT_LOOKUP_KEY_COLUMN_INDEX);
                             bindFromContactUri(Contacts.getLookupUri(contactId, lookupKey));
                         } else {
-                            setDisplayName((String) cookie, null);
+                            String emailAddress = (String) cookie;
+                            setDisplayName(emailAddress, null);
+                            mPhotoView.assignContactFromEmail(emailAddress, true);
                         }
                         break;
                     }
diff --git a/core/java/com/google/android/mms/pdu/PduPersister.java b/core/java/com/google/android/mms/pdu/PduPersister.java
index df91ea6..568aeb7 100644
--- a/core/java/com/google/android/mms/pdu/PduPersister.java
+++ b/core/java/com/google/android/mms/pdu/PduPersister.java
@@ -810,7 +810,7 @@
     public void updateHeaders(Uri uri, SendReq sendReq) {
         PDU_CACHE_INSTANCE.purge(uri);
 
-        ContentValues values = new ContentValues(9);
+        ContentValues values = new ContentValues(10);
         byte[] contentType = sendReq.getContentType();
         if (contentType != null) {
             values.put(Mms.CONTENT_TYPE, toIsoString(contentType));
@@ -856,6 +856,11 @@
             values.put(Mms.SUBJECT, toIsoString(subject.getTextString()));
             values.put(Mms.SUBJECT_CHARSET, subject.getCharacterSet());
         }
+        
+        long messageSize = sendReq.getMessageSize();
+        if (messageSize > 0) {
+            values.put(Mms.MESSAGE_SIZE, messageSize);
+        }
 
         PduHeaders headers = sendReq.getPduHeaders();
         HashSet<String> recipients = new HashSet<String>();
diff --git a/core/java/com/google/android/mms/pdu/SendReq.java b/core/java/com/google/android/mms/pdu/SendReq.java
index 9081b0c..9ea6e47 100644
--- a/core/java/com/google/android/mms/pdu/SendReq.java
+++ b/core/java/com/google/android/mms/pdu/SendReq.java
@@ -206,6 +206,26 @@
     }
 
     /**
+     * Get X-Mms-MessageSize value.
+     *
+     * Expiry-value = size of message
+     *
+     * @return the value
+     */
+    public long getMessageSize() {
+        return mPduHeaders.getLongInteger(PduHeaders.MESSAGE_SIZE);
+    }
+
+    /**
+     * Set X-Mms-MessageSize value.
+     *
+     * @param value the value
+     */
+    public void setMessageSize(long value) {
+        mPduHeaders.setLongInteger(value, PduHeaders.MESSAGE_SIZE);
+    }
+
+    /**
      * Get From value.
      * From-value = Value-length
      *      (Address-present-token Encoded-string-value | Insert-address-token)
diff --git a/core/res/res/anim/dialog_enter.xml b/core/res/res/anim/dialog_enter.xml
index cc409e8..167f4bc 100644
--- a/core/res/res/anim/dialog_enter.xml
+++ b/core/res/res/anim/dialog_enter.xml
@@ -22,7 +22,7 @@
         android:interpolator="@anim/decelerate_interpolator">
     <scale android:fromXScale="0.9" android:toXScale="1.0"
            android:fromYScale="0.9" android:toYScale="1.0"
-           android:pivotX="50%" android:pivotY="50%"
+           android:pivotX="50%p" android:pivotY="50%p"
            android:duration="@android:integer/config_shortAnimTime" />
     <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
             android:duration="@android:integer/config_shortAnimTime" />
diff --git a/core/res/res/anim/dialog_exit.xml b/core/res/res/anim/dialog_exit.xml
index 8bf8082..d412cfb 100644
--- a/core/res/res/anim/dialog_exit.xml
+++ b/core/res/res/anim/dialog_exit.xml
@@ -21,7 +21,7 @@
         android:interpolator="@anim/accelerate_interpolator">
     <scale android:fromXScale="1.0" android:toXScale="0.9"
            android:fromYScale="1.0" android:toYScale="0.9"
-           android:pivotX="50%" android:pivotY="50%"
+           android:pivotX="50%p" android:pivotY="50%p"
            android:duration="@android:integer/config_shortAnimTime" />
     <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
             android:duration="@android:integer/config_shortAnimTime"/>
diff --git a/core/res/res/anim/recent_enter.xml b/core/res/res/anim/recent_enter.xml
new file mode 100644
index 0000000..deeb96b
--- /dev/null
+++ b/core/res/res/anim/recent_enter.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@anim/decelerate_interpolator">
+    <scale android:fromXScale="2.0" android:toXScale="1.0"
+           android:fromYScale="2.0" android:toYScale="1.0"
+           android:pivotX="50%p" android:pivotY="50%p"
+           android:duration="@android:integer/config_mediumAnimTime" />
+    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
+            android:duration="@android:integer/config_mediumAnimTime"/>
+</set>
diff --git a/core/res/res/anim/recent_exit.xml b/core/res/res/anim/recent_exit.xml
new file mode 100644
index 0000000..fed7014
--- /dev/null
+++ b/core/res/res/anim/recent_exit.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+        android:interpolator="@anim/decelerate_interpolator"
+        android:zAdjustment="top">
+    <scale android:fromXScale="1.0" android:toXScale="2.0"
+           android:fromYScale="1.0" android:toYScale="2.0"
+           android:pivotX="50%p" android:pivotY="50%p"
+           android:duration="@android:integer/config_mediumAnimTime" />
+    <alpha android:fromAlpha="1.0" android:toAlpha="0"
+            android:duration="@android:integer/config_mediumAnimTime"/>
+</set>
diff --git a/core/res/res/drawable-hdpi/dark_header.9.png b/core/res/res/drawable-hdpi/dark_header.9.png
index a2fa569..3e63fa6 100644
--- a/core/res/res/drawable-hdpi/dark_header.9.png
+++ b/core/res/res/drawable-hdpi/dark_header.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/divider_horizontal_bright.9.png b/core/res/res/drawable-hdpi/divider_horizontal_bright.9.png
index c7803a2..99a67b9 100644
--- a/core/res/res/drawable-hdpi/divider_horizontal_bright.9.png
+++ b/core/res/res/drawable-hdpi/divider_horizontal_bright.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/divider_horizontal_bright_opaque.9.png b/core/res/res/drawable-hdpi/divider_horizontal_bright_opaque.9.png
index d8d8aa9..cfe258b 100644
--- a/core/res/res/drawable-hdpi/divider_horizontal_bright_opaque.9.png
+++ b/core/res/res/drawable-hdpi/divider_horizontal_bright_opaque.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/divider_horizontal_dark.9.png b/core/res/res/drawable-hdpi/divider_horizontal_dark.9.png
index 63859f7..30a68d0 100644
--- a/core/res/res/drawable-hdpi/divider_horizontal_dark.9.png
+++ b/core/res/res/drawable-hdpi/divider_horizontal_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/divider_horizontal_dark_opaque.9.png b/core/res/res/drawable-hdpi/divider_horizontal_dark_opaque.9.png
index ced2832..8f35315 100644
--- a/core/res/res/drawable-hdpi/divider_horizontal_dark_opaque.9.png
+++ b/core/res/res/drawable-hdpi/divider_horizontal_dark_opaque.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/divider_vertical_bright.9.png b/core/res/res/drawable-hdpi/divider_vertical_bright.9.png
index 1035656..99a67b9 100644
--- a/core/res/res/drawable-hdpi/divider_vertical_bright.9.png
+++ b/core/res/res/drawable-hdpi/divider_vertical_bright.9.png
Binary files differ
diff --git a/core/res/res/drawable/divider_vertical_bright_opaque.9.png b/core/res/res/drawable-hdpi/divider_vertical_bright_opaque.9.png
similarity index 100%
rename from core/res/res/drawable/divider_vertical_bright_opaque.9.png
rename to core/res/res/drawable-hdpi/divider_vertical_bright_opaque.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/divider_vertical_dark.9.png b/core/res/res/drawable-hdpi/divider_vertical_dark.9.png
new file mode 100644
index 0000000..30a68d0
--- /dev/null
+++ b/core/res/res/drawable-hdpi/divider_vertical_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable/divider_vertical_dark_opaque.9.png b/core/res/res/drawable-hdpi/divider_vertical_dark_opaque.9.png
similarity index 100%
rename from core/res/res/drawable/divider_vertical_dark_opaque.9.png
rename to core/res/res/drawable-hdpi/divider_vertical_dark_opaque.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/light_header.9.png b/core/res/res/drawable-hdpi/light_header.9.png
index 27db59d..6fc53ca 100644
--- a/core/res/res/drawable-hdpi/light_header.9.png
+++ b/core/res/res/drawable-hdpi/light_header.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dark_header.9.png b/core/res/res/drawable-mdpi/dark_header.9.png
index 7242b61..f4a14f1d 100644
--- a/core/res/res/drawable-mdpi/dark_header.9.png
+++ b/core/res/res/drawable-mdpi/dark_header.9.png
Binary files differ
diff --git a/core/res/res/drawable/divider_vertical_bright_opaque.9.png b/core/res/res/drawable-mdpi/divider_vertical_bright_opaque.9.png
similarity index 100%
copy from core/res/res/drawable/divider_vertical_bright_opaque.9.png
copy to core/res/res/drawable-mdpi/divider_vertical_bright_opaque.9.png
Binary files differ
diff --git a/core/res/res/drawable/divider_vertical_dark.9.png b/core/res/res/drawable-mdpi/divider_vertical_dark.9.png
similarity index 100%
rename from core/res/res/drawable/divider_vertical_dark.9.png
rename to core/res/res/drawable-mdpi/divider_vertical_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable/divider_vertical_dark_opaque.9.png b/core/res/res/drawable-mdpi/divider_vertical_dark_opaque.9.png
similarity index 100%
copy from core/res/res/drawable/divider_vertical_dark_opaque.9.png
copy to core/res/res/drawable-mdpi/divider_vertical_dark_opaque.9.png
Binary files differ
diff --git a/core/res/res/layout/tab_indicator.xml b/core/res/res/layout/tab_indicator.xml
index e3ea555..71e4001 100644
--- a/core/res/res/layout/tab_indicator.xml
+++ b/core/res/res/layout/tab_indicator.xml
@@ -18,8 +18,8 @@
     android:layout_width="0dip"
     android:layout_height="64dip"
     android:layout_weight="1"
-    android:layout_marginLeft="-4px"
-    android:layout_marginRight="-4px"
+    android:layout_marginLeft="-3dip"
+    android:layout_marginRight="-3dip"
     android:orientation="vertical"
     android:background="@android:drawable/tab_indicator">
 
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index c967c4c..2f09aca 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -19,7 +19,7 @@
 -->
 <resources>
 	<drawable name="screen_background_light">#ffffffff</drawable>
-	<drawable name="screen_background_dark">#ff202020</drawable>
+	<drawable name="screen_background_dark">#ff1a1a1a</drawable>
     <drawable name="status_bar_closed_default_background">#ff000000</drawable>
     <drawable name="status_bar_opened_default_background">#ff000000</drawable>
     <drawable name="search_bar_default_color">#ff000000</drawable>
@@ -36,7 +36,7 @@
     <color name="white">#ffffffff</color>
     <color name="black">#ff000000</color>
     <color name="transparent">#00000000</color>
-    <color name="background_dark">#ff202020</color>
+    <color name="background_dark">#ff1a1a1a</color>
     <color name="bright_foreground_dark">#ffffffff</color>
     <color name="bright_foreground_dark_disabled">#80ffffff</color>
     <color name="bright_foreground_dark_inverse">#ff000000</color>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 69612e9..35db8ee 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -177,6 +177,13 @@
         <item name="windowExitAnimation">@anim/wallpaper_exit</item>
     </style>
 
+    <!-- A special animation we can use for recent applications,
+         for devices that can support it (do alpha transformations). -->
+    <style name="Animation.RecentApplications">
+        <item name="windowEnterAnimation">@anim/recent_enter</item>
+        <item name="windowExitAnimation">@anim/recent_exit</item>
+    </style>
+
     <!-- Status Bar Styles -->
 
     <style name="TextAppearance.StatusBarTitle">
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 1aa48ee..04402fd 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -500,4 +500,10 @@
         <item name="windowContentOverlay">@null</item>
         <item name="textAppearance">@style/TextAppearance.Theme.Dialog.AppError</item>
     </style>
+    
+    <!-- Special theme for the recent apps dialog, to allow customization
+         with overlays. -->
+    <style name="Theme.Dialog.RecentApplications">
+    </style>
+    
 </resources>
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index eae6f24..c7b5448 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -255,28 +255,24 @@
 
 static void * SF_SaveInt(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
 {
-    LOGE("Save Int");
     _env->SetIntField(_obj, _field, ((int32_t *)buffer)[0]);
     return ((uint8_t *)buffer) + 4;
 }
 
 static void * SF_SaveShort(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
 {
-    LOGE("Save Short");
     _env->SetShortField(_obj, _field, ((int16_t *)buffer)[0]);
     return ((uint8_t *)buffer) + 2;
 }
 
 static void * SF_SaveByte(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
 {
-    LOGE("Save Byte");
     _env->SetByteField(_obj, _field, ((int8_t *)buffer)[0]);
     return ((uint8_t *)buffer) + 1;
 }
 
 static void * SF_SaveFloat(JNIEnv *_env, jobject _obj, jfieldID _field, void *buffer)
 {
-    LOGE("Save Float");
     _env->SetFloatField(_obj, _field, ((float *)buffer)[0]);
     return ((uint8_t *)buffer) + 4;
 }
@@ -601,11 +597,8 @@
     void * buf = bufAlloc;
     rsAllocationRead(con, (RsAllocation)alloc, bufAlloc);
 
-    LOGE("size %i, ", tc->size);
-
     for (int ct=0; ct < tc->fieldCount; ct++) {
         const TypeFieldCache *tfc = &tc->fields[ct];
-        LOGE("ct=%i, buf=%p", ct, buf);
         buf = tfc->readPtr(_env, _o, tfc->field, buf);
     }
     free(bufAlloc);
diff --git a/libs/rs/rsScriptC_Lib.cpp b/libs/rs/rsScriptC_Lib.cpp
index d10076b..6dc3e8b 100644
--- a/libs/rs/rsScriptC_Lib.cpp
+++ b/libs/rs/rsScriptC_Lib.cpp
@@ -321,6 +321,16 @@
     return v * v;
 }
 
+static float SC_fracf(float v)
+{
+    return v - floorf(v);
+}
+
+static float SC_roundf(float v)
+{
+    return floorf(v + 0.4999999999);
+}
+
 static float SC_distf2(float x1, float y1, float x2, float y2)
 {
     float x = x2 - x1;
@@ -1014,8 +1024,12 @@
         "float", "(float, float)" },
     { "floorf", (void *)&floorf,
         "float", "(float)" },
+    { "fracf", (void *)&SC_fracf,
+        "float", "(float)" },
     { "ceilf", (void *)&ceilf,
         "float", "(float)" },
+    { "roundf", (void *)&SC_roundf,
+        "float", "(float)" },
     { "expf", (void *)&expf,
         "float", "(float)" },
     { "logf", (void *)&logf,
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index 73b6483..29409ab 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -63,12 +63,12 @@
 
     private String mFilename;
     private HashMap<String, String> mAttributes;
-    private boolean mHasThumbnail = false;
+    private boolean mHasThumbnail;
 
     // Because the underlying implementation (jhead) uses static variables,
     // there can only be one user at a time for the native functions (and
     // they cannot keep state in the native code across function calls). We
-    // use sLock the serialize the accesses.
+    // use sLock to serialize the accesses.
     private static Object sLock = new Object();
 
     /**
@@ -81,7 +81,7 @@
 
     /**
      * Returns the value of the specified tag or {@code null} if there
-     * is no such tag in the file.
+     * is no such tag in the JPEG file.
      *
      * @param tag the name of the tag.
      */
@@ -90,6 +90,24 @@
     }
 
     /**
+     * Returns the integer value of the specified tag. If there is no such tag
+     * in the JPEG file or the value cannot be parsed as integer, return
+     * @{code defaultValue}.
+     *
+     * @param tag the name of the tag.
+     * @param defaultValue the value to return if the tag is not available.
+     */
+    public int getAttributeInt(String tag, int defaultValue) {
+        String value = mAttributes.get(tag);
+        if (value == null) return defaultValue;
+        try {
+            return Integer.valueOf(value);
+        } catch (NumberFormatException ex) {
+            return defaultValue;
+        }
+    }
+
+    /**
      * Set the value of the specified tag.
      *
      * @param tag the name of the tag.
@@ -109,7 +127,7 @@
      * This function also initialize mHasThumbnail to indicate whether the
      * file has a thumbnail inside.
      */
-    private void loadAttributes() {
+    private void loadAttributes() throws IOException {
         // format of string passed from native C code:
         // "attrCnt attr1=valueLen value1attr2=value2Len value2..."
         // example:
@@ -153,9 +171,9 @@
     /**
      * Save the tag data into the JPEG file. This is expensive because it involves
      * copying all the JPG data from one file to another and deleting the old file
-     * and renaming the other. It's best to use {@link #setAttribute(String,String)} to set all
-     * attributes to write and make a single call rather than multiple calls for
-     * each attribute.
+     * and renaming the other. It's best to use {@link #setAttribute(String,String)}
+     * to set all attributes to write and make a single call rather than multiple
+     * calls for each attribute.
      */
     public void saveAttributes() throws IOException {
         // format of string passed to native C code:
@@ -195,6 +213,8 @@
 
     /**
      * Returns the thumbnail inside the JPEG file, or {@code null} if there is no thumbnail.
+     * The returned data is in JPEG format and can be decoded using
+     * {@link android.graphics.BitmapFactory#decodeByteArray(byte[],int,int)}
      */
     public byte[] getThumbnail() {
         synchronized (sLock) {
@@ -203,98 +223,23 @@
     }
 
     /**
-     * Returns a human-readable string describing the white balance value. Returns empty
-     * string if there is no white balance value or it is not recognized.
+     * Stores the latitude and longitude value in a float array. The first element is
+     * the latitude, and the second element is the longitude. Returns false if the
+     * Exif tags are not available.
      */
-    public String getWhiteBalanceString() {
-        String value = getAttribute(TAG_WHITE_BALANCE);
-        if (value == null) return "";
-
-        int whitebalance;
-        try {
-            whitebalance = Integer.parseInt(value);
-        } catch (NumberFormatException ex) {
-            return "";
-        }
-
-        switch (whitebalance) {
-            case WHITEBALANCE_AUTO:
-                return "Auto";
-            case WHITEBALANCE_MANUAL:
-                return "Manual";
-            default:
-                return "";
-        }
-    }
-
-    /**
-     * Returns a human-readable string describing the orientation value. Returns empty
-     * string if there is no orientation value or it it not recognized.
-     */
-    public String getOrientationString() {
-        // TODO: this function needs to be localized.
-        String value = getAttribute(TAG_ORIENTATION);
-        if (value == null) return "";
-
-        int orientation;
-        try {
-            orientation = Integer.parseInt(value);
-        } catch (NumberFormatException ex) {
-            return "";
-        }
-
-        String orientationString;
-        switch (orientation) {
-            case ORIENTATION_NORMAL:
-                orientationString = "Normal";
-                break;
-            case ORIENTATION_FLIP_HORIZONTAL:
-                orientationString = "Flipped horizontal";
-                break;
-            case ORIENTATION_ROTATE_180:
-                orientationString = "Rotated 180 degrees";
-                break;
-            case ORIENTATION_FLIP_VERTICAL:
-                orientationString = "Upside down mirror";
-                break;
-            case ORIENTATION_TRANSPOSE:
-                orientationString = "Transposed";
-                break;
-            case ORIENTATION_ROTATE_90:
-                orientationString = "Rotated 90 degrees";
-                break;
-            case ORIENTATION_TRANSVERSE:
-                orientationString = "Transversed";
-                break;
-            case ORIENTATION_ROTATE_270:
-                orientationString = "Rotated 270 degrees";
-                break;
-            default:
-                orientationString = "Undefined";
-                break;
-        }
-        return orientationString;
-    }
-
-    /**
-     * Returns the latitude and longitude value in a float array. The first element is
-     * the latitude, and the second element is the longitude.
-     */
-    public float[] getLatLong() {
+    public boolean getLatLong(float output[]) {
         String latValue = mAttributes.get(ExifInterface.TAG_GPS_LATITUDE);
         String latRef = mAttributes.get(ExifInterface.TAG_GPS_LATITUDE_REF);
         String lngValue = mAttributes.get(ExifInterface.TAG_GPS_LONGITUDE);
         String lngRef = mAttributes.get(ExifInterface.TAG_GPS_LONGITUDE_REF);
-        float[] latlng = null;
 
-        if (latValue != null && latRef != null
-                && lngValue != null && lngRef != null) {
-            latlng = new float[2];
-            latlng[0] = convertRationalLatLonToFloat(latValue, latRef);
-            latlng[1] = convertRationalLatLonToFloat(lngValue, lngRef);
+        if (latValue != null && latRef != null && lngValue != null && lngRef != null) {
+            output[0] = convertRationalLatLonToFloat(latValue, latRef);
+            output[1] = convertRationalLatLonToFloat(lngValue, lngRef);
+            return true;
+        } else {
+            return false;
         }
-
-        return latlng;
     }
 
     private static SimpleDateFormat sFormatter =
@@ -303,6 +248,7 @@
     /**
      * Returns number of milliseconds since Jan. 1, 1970, midnight GMT.
      * Returns -1 if the date time information if not available.
+     * @hide
      */
     public long getDateTime() {
         String dateTimeString = mAttributes.get(TAG_DATETIME);
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index d9127e7..37a3bd5 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -726,8 +726,8 @@
                     // exif is null
                 }
                 if (exif != null) {
-                    float[] latlng = exif.getLatLong();
-                    if (latlng != null) {
+                    float[] latlng = new float[2];
+                    if (exif.getLatLong(latlng)) {
                         values.put(Images.Media.LATITUDE, latlng[0]);
                         values.put(Images.Media.LONGITUDE, latlng[1]);
                     }
diff --git a/services/java/com/android/server/BackupManagerService.java b/services/java/com/android/server/BackupManagerService.java
index c6be61d..4186327 100644
--- a/services/java/com/android/server/BackupManagerService.java
+++ b/services/java/com/android/server/BackupManagerService.java
@@ -1018,7 +1018,15 @@
                     backupData = ParcelFileDescriptor.open(backupDataName,
                             ParcelFileDescriptor.MODE_READ_ONLY);
 
-                    if (!transport.performBackup(packInfo, backupData)) throw new Exception();
+                    // TODO - We call finishBackup() for each application backed up, because
+                    // we need to know now whether it succeeded or failed.  Instead, we should
+                    // hold off on finishBackup() until the end, which implies holding off on
+                    // renaming *all* the output state files (see below) until that happens.
+
+                    if (!transport.performBackup(packInfo, backupData) ||
+                        !transport.finishBackup()) {
+                        throw new Exception("Backup transport failed");
+                    }
                 } else {
                     if (DEBUG) Log.i(TAG, "no backup data written; not calling transport");
                 }
@@ -1417,11 +1425,13 @@
                 stateFile.delete();
 
                 // Tell the transport to remove all the persistent storage for the app
+                // STOPSHIP TODO - need to handle failures
                 mTransport.clearBackupData(mPackage);
             } catch (RemoteException e) {
                 // can't happen; the transport is local
             } finally {
                 try {
+                    // STOPSHIP TODO - need to handle failures
                     mTransport.finishBackup();
                 } catch (RemoteException e) {
                     // can't happen; the transport is local
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index d53f002..0cd5949 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -1384,12 +1384,18 @@
                     (mLowerWallpaperTarget == null && foundW.mAppToken != null)
                     ? foundW.mAppToken.animLayerAdjustment : 0;
             
+            final int maxLayer = mPolicy.getMaxWallpaperLayer()
+                    * TYPE_LAYER_MULTIPLIER
+                    + TYPE_LAYER_OFFSET;
+            
             // Now w is the window we are supposed to be behind...  but we
             // need to be sure to also be behind any of its attached windows,
-            // AND any starting window associated with it.
+            // AND any starting window associated with it, AND below the
+            // maximum layer the policy allows for wallpapers.
             while (foundI > 0) {
                 WindowState wb = (WindowState)localmWindows.get(foundI-1);
-                if (wb.mAttachedWindow != foundW &&
+                if (wb.mBaseLayer < maxLayer &&
+                        wb.mAttachedWindow != foundW &&
                         (wb.mAttrs.type != TYPE_APPLICATION_STARTING ||
                                 wb.mToken != foundW.mToken)) {
                     // This window is not related to the previous one in any
@@ -2266,6 +2272,12 @@
                             // Currently in a hide animation... turn this into
                             // an exit.
                             win.mExiting = true;
+                        } else if (win == mWallpaperTarget) {
+                            // If the wallpaper is currently behind this
+                            // window, we need to change both of them inside
+                            // of a transaction to avoid artifacts.
+                            win.mExiting = true;
+                            win.mAnimating = true;
                         } else {
                             if (mInputMethodWindow == win) {
                                 mInputMethodWindow = null;
@@ -3158,6 +3170,10 @@
                     return;
                 }
                 if (ent.array.getBoolean(
+                        com.android.internal.R.styleable.Window_windowIsFloating, false)) {
+                    return;
+                }
+                if (ent.array.getBoolean(
                         com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
                     return;
                 }
@@ -7087,8 +7103,8 @@
                     mAppToken.firstWindowDrawn = true;
                     
                     if (mAppToken.startingData != null) {
-                        if (DEBUG_STARTING_WINDOW) Log.v(TAG, "Finish starting "
-                                + mToken
+                        if (DEBUG_STARTING_WINDOW || DEBUG_ANIM) Log.v(TAG,
+                                "Finish starting " + mToken
                                 + ": first real window is shown, no animation");
                         // If this initial window is animating, stop it -- we
                         // will do an animation to reveal it from behind the
@@ -7305,13 +7321,13 @@
                 // Compute the desired transformation.
                 tmpMatrix.setTranslate(frame.left, frame.top);
                 if (selfTransformation) {
-                    tmpMatrix.preConcat(mTransformation.getMatrix());
+                    tmpMatrix.postConcat(mTransformation.getMatrix());
                 }
                 if (attachedTransformation != null) {
-                    tmpMatrix.preConcat(attachedTransformation.getMatrix());
+                    tmpMatrix.postConcat(attachedTransformation.getMatrix());
                 }
                 if (appTransformation != null) {
-                    tmpMatrix.preConcat(appTransformation.getMatrix());
+                    tmpMatrix.postConcat(appTransformation.getMatrix());
                 }
 
                 // "convert" it into SurfaceFlinger's format
@@ -8928,11 +8944,14 @@
                                 wallpaperMayChange = true;
                             }
                         }
+                        boolean wasAnimating = w.mAnimating;
                         if (w.stepAnimationLocked(currentTime, dw, dh)) {
                             animating = true;
                             //w.dump("  ");
                         }
-
+                        if (wasAnimating && !w.mAnimating && mWallpaperTarget == w) {
+                            wallpaperMayChange = true;
+                        }
                         mPolicy.animatingWindowLw(w, attrs);
                     }
 
@@ -9269,6 +9288,7 @@
             boolean covered = false;
             boolean syswin = false;
             boolean backgroundFillerShown = false;
+            boolean forceHiding = false;
 
             final int N = mWindows.size();
             
@@ -9401,7 +9421,10 @@
                         }
                     }
 
-                    if (w.mAttachedHidden) {
+                    if ((forceHiding
+                            && attrs.type != WindowManager.LayoutParams.TYPE_STATUS_BAR
+                            && attrs.type != WindowManager.LayoutParams.TYPE_WALLPAPER)
+                            || w.mAttachedHidden) {
                         if (!w.mLastHidden) {
                             //dump();
                             w.mLastHidden = true;
@@ -9515,6 +9538,9 @@
                     }
 
                     if (displayed) {
+                        if (attrs.type == WindowManager.LayoutParams.TYPE_KEYGUARD) {
+                            forceHiding = true;
+                        }
                         if (!covered) {
                             if (attrs.width == LayoutParams.FILL_PARENT
                                     && attrs.height == LayoutParams.FILL_PARENT) {
@@ -9597,7 +9623,7 @@
                         }
                         backgroundFillerShown = true;
                         mBackgroundFillerShown = true;
-                    } else if (canBeSeen && !obscured &&
+                    } else if (canBeSeen && !obscured && !forceHiding &&
                             (attrFlags&FLAG_BLUR_BEHIND|FLAG_DIM_BEHIND) != 0) {
                         if (localLOGV) Log.v(TAG, "Win " + w
                                 + ": blurring=" + blurring
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 6dfd781..4db5239 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -8431,6 +8431,13 @@
     }
 
     private ComponentName getErrorReportReceiver(ProcessRecord app) {
+        // check if error reporting is enabled in Gservices
+        int enabled = Settings.Gservices.getInt(mContext.getContentResolver(),
+                Settings.Gservices.SEND_ACTION_APP_ERROR, 0);
+        if (enabled == 0) {
+            return null;
+        }
+
         IPackageManager pm = ActivityThread.getPackageManager();
 
         try {
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index 8d2785a..5581a24 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -127,7 +127,7 @@
 
     /** Retry configuration for secondary networks: 4 tries in 20 sec */
     protected static final String SECONDARY_DATA_RETRY_CONFIG =
-            "max_retries=3; 5000, 5000, 5000";
+            "max_retries=3, 5000, 5000, 5000";
 
     /** Slow poll when attempting connection recovery. */
     protected static final int POLL_NETSTAT_SLOW_MILLIS = 5000;
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
index 0c94e6a..2f4d238 100755
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaConnection.java
@@ -492,6 +492,8 @@
 
         newParent = parentFromDCState(dc.state);
 
+        if (Phone.DEBUG_PHONE) log("parent= " +parent +", newParent= " + newParent);
+
         if (!equalsHandlesNulls(address, dc.number)) {
             if (Phone.DEBUG_PHONE) log("update: phone # changed!");
             address = dc.number;
@@ -509,7 +511,7 @@
             cnapName = dc.name;
         }
 
-        log("--dssds----"+cnapName);
+        if (Phone.DEBUG_PHONE) log("--dssds----"+cnapName);
         cnapNamePresentation = dc.namePresentation;
         numberPresentation = dc.numberPresentation;
 
@@ -529,9 +531,7 @@
         /** Some state-transition events */
 
         if (Phone.DEBUG_PHONE) log(
-                "update: parent=" + parent +
-                ", hasNewParent=" + (newParent != parent) +
-                ", wasConnectingInOrOut=" + wasConnectingInOrOut +
+                "Update, wasConnectingInOrOut=" + wasConnectingInOrOut +
                 ", wasHolding=" + wasHolding +
                 ", isConnectingInOrOut=" + isConnectingInOrOut() +
                 ", changed=" + changed);
@@ -860,10 +860,13 @@
         // Append the PW char
         ret = (isPause(c)) ? PhoneNumberUtils.PAUSE : PhoneNumberUtils.WAIT;
 
-        // if there is a PAUSE in at the beginning of PW character sequences, and this
-        // PW character sequences has more than 2 PAUSE and WAIT Characters,skip PAUSE,
-        // append WAIT.
-        if (isPause(c) && (nextNonPwCharIndex > (currPwIndex + 2))) {
+        // If the nextNonPwCharIndex is greater than currPwIndex + 1,
+        // it means the PW sequence contains not only P characters.
+        // Since for the sequence that only contains P character,
+        // the P character is handled one by one, the nextNonPwCharIndex
+        // equals to currPwIndex + 1.
+        // In this case, skip P, append W.
+        if (nextNonPwCharIndex > (currPwIndex + 1)) {
             ret = PhoneNumberUtils.WAIT;
         }
         return ret;
@@ -882,6 +885,11 @@
      *    and if there is any WAIT in PAUSE/WAIT sequence, treat them like WAIT.
      */
     public static String formatDialString(String phoneNumber) {
+        /**
+         * TODO(cleanup): This function should move to PhoneNumberUtils, and
+         * tests should be added.
+         */
+
         if (phoneNumber == null) {
             return null;
         }
@@ -901,9 +909,9 @@
                         char pC = findPOrWCharToAppend(phoneNumber, currIndex, nextIndex);
                         ret.append(pC);
                         // If PW char sequence has more than 2 PW characters,
-                        // skip to the last character since the sequence already be
+                        // skip to the last PW character since the sequence already be
                         // converted to WAIT character
-                        if (nextIndex > (currIndex + 2)) {
+                        if (nextIndex > (currIndex + 1)) {
                             currIndex = nextIndex - 1;
                         }
                     } else if (nextIndex == length) {
diff --git a/tests/AndroidTests/Android.mk b/tests/AndroidTests/Android.mk
index f5e49d7..ced796a 100644
--- a/tests/AndroidTests/Android.mk
+++ b/tests/AndroidTests/Android.mk
@@ -8,7 +8,7 @@
 LOCAL_STATIC_JAVA_LIBRARIES := googlelogin-client
 
 # Resource unit tests use a private locale
-LOCAL_AAPT_FLAGS = -c xx_YY -c cs
+LOCAL_AAPT_FLAGS = -c xx_YY -c cs -c 160dpi -c 32dpi -c 240dpi
 
 LOCAL_SRC_FILES := \
 	$(call all-subdir-java-files) \