Merge "Fix NPE on devices that don't have NFC." into ics-mr1
diff --git a/Android.mk b/Android.mk
index 586eb4a..a748b7b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -412,6 +412,8 @@
 		            resources/samples/BackupRestore "Backup and Restore" \
 		-samplecode $(sample_dir)/BluetoothChat \
 		            resources/samples/BluetoothChat "Bluetooth Chat" \
+		-samplecode $(sample_dir)/BluetoothHDP \
+		            resources/samples/BluetoothHDP "Bluetooth HDP Demo" \
 		-samplecode $(sample_dir)/BusinessCard \
 		            resources/samples/BusinessCard "Business Card" \
 		-samplecode $(sample_dir)/ContactManager \
diff --git a/api/current.txt b/api/current.txt
index f33c6cb..cc50ff9 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -83,6 +83,7 @@
     field public static final java.lang.String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE";
     field public static final java.lang.String READ_PROFILE = "android.permission.READ_PROFILE";
     field public static final java.lang.String READ_SMS = "android.permission.READ_SMS";
+    field public static final java.lang.String READ_SOCIAL_STREAM = "android.permission.READ_SOCIAL_STREAM";
     field public static final java.lang.String READ_SYNC_SETTINGS = "android.permission.READ_SYNC_SETTINGS";
     field public static final java.lang.String READ_SYNC_STATS = "android.permission.READ_SYNC_STATS";
     field public static final java.lang.String REBOOT = "android.permission.REBOOT";
@@ -127,6 +128,7 @@
     field public static final java.lang.String WRITE_SECURE_SETTINGS = "android.permission.WRITE_SECURE_SETTINGS";
     field public static final java.lang.String WRITE_SETTINGS = "android.permission.WRITE_SETTINGS";
     field public static final java.lang.String WRITE_SMS = "android.permission.WRITE_SMS";
+    field public static final java.lang.String WRITE_SOCIAL_STREAM = "android.permission.WRITE_SOCIAL_STREAM";
     field public static final java.lang.String WRITE_SYNC_SETTINGS = "android.permission.WRITE_SYNC_SETTINGS";
   }
 
@@ -14237,6 +14239,13 @@
     method public static void texSubImage2D(int, int, int, int, android.graphics.Bitmap, int, int);
   }
 
+  public abstract class ManagedEGLContext {
+    ctor public ManagedEGLContext(javax.microedition.khronos.egl.EGLContext);
+    method public javax.microedition.khronos.egl.EGLContext getContext();
+    method public abstract void onTerminate(javax.microedition.khronos.egl.EGLContext);
+    method public void terminate();
+  }
+
   public class Matrix {
     ctor public Matrix();
     method public static void frustumM(float[], int, float, float, float, float, float, float);
@@ -18419,14 +18428,14 @@
     ctor public RSSurfaceView(android.content.Context);
     ctor public RSSurfaceView(android.content.Context, android.util.AttributeSet);
     method public android.renderscript.RenderScriptGL createRenderScriptGL(android.renderscript.RenderScriptGL.SurfaceConfig);
-    method public void destroyRenderScriptGL();
+    method public synchronized void destroyRenderScriptGL();
     method public android.renderscript.RenderScriptGL getRenderScriptGL();
     method public void pause();
     method public void resume();
     method public void setRenderScriptGL(android.renderscript.RenderScriptGL);
-    method public void surfaceChanged(android.view.SurfaceHolder, int, int, int);
+    method public synchronized void surfaceChanged(android.view.SurfaceHolder, int, int, int);
     method public void surfaceCreated(android.view.SurfaceHolder);
-    method public void surfaceDestroyed(android.view.SurfaceHolder);
+    method public synchronized void surfaceDestroyed(android.view.SurfaceHolder);
   }
 
   public class RSTextureView extends android.view.TextureView implements android.view.TextureView.SurfaceTextureListener {
@@ -25145,7 +25154,7 @@
     method public synchronized java.lang.String getFixedFontFamily();
     method public synchronized boolean getJavaScriptCanOpenWindowsAutomatically();
     method public synchronized boolean getJavaScriptEnabled();
-    method public deprecated synchronized android.webkit.WebSettings.LayoutAlgorithm getLayoutAlgorithm();
+    method public synchronized android.webkit.WebSettings.LayoutAlgorithm getLayoutAlgorithm();
     method public boolean getLightTouchEnabled();
     method public boolean getLoadWithOverviewMode();
     method public synchronized boolean getLoadsImagesAutomatically();
@@ -25192,7 +25201,7 @@
     method public synchronized void setGeolocationEnabled(boolean);
     method public synchronized void setJavaScriptCanOpenWindowsAutomatically(boolean);
     method public synchronized void setJavaScriptEnabled(boolean);
-    method public deprecated synchronized void setLayoutAlgorithm(android.webkit.WebSettings.LayoutAlgorithm);
+    method public synchronized void setLayoutAlgorithm(android.webkit.WebSettings.LayoutAlgorithm);
     method public void setLightTouchEnabled(boolean);
     method public void setLoadWithOverviewMode(boolean);
     method public synchronized void setLoadsImagesAutomatically(boolean);
@@ -25227,12 +25236,12 @@
     field public static final int LOAD_NO_CACHE = 2; // 0x2
   }
 
-  public static final deprecated class WebSettings.LayoutAlgorithm extends java.lang.Enum {
+  public static final class WebSettings.LayoutAlgorithm extends java.lang.Enum {
     method public static android.webkit.WebSettings.LayoutAlgorithm valueOf(java.lang.String);
     method public static final android.webkit.WebSettings.LayoutAlgorithm[] values();
     enum_constant public static final android.webkit.WebSettings.LayoutAlgorithm NARROW_COLUMNS;
     enum_constant public static final android.webkit.WebSettings.LayoutAlgorithm NORMAL;
-    enum_constant public static final android.webkit.WebSettings.LayoutAlgorithm SINGLE_COLUMN;
+    enum_constant public static final deprecated android.webkit.WebSettings.LayoutAlgorithm SINGLE_COLUMN;
   }
 
   public static final class WebSettings.PluginState extends java.lang.Enum {
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index aa62cd7..a2038c9 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -784,12 +784,12 @@
                 // machine.  We don't handle AVCTP signals currently. We only send
                 // intents for AVDTP state changes. We need to handle both of them in
                 // some cases. For now, just don't move to incoming state in this case.
-                mBluetoothService.notifyIncomingA2dpConnection(address, true);
+                mBluetoothService.notifyIncomingA2dpConnection(address, false);
             } else {
                 Log.i(TAG, "" + authorized +
                       "Incoming A2DP / AVRCP connection from " + address);
                 mA2dp.allowIncomingConnect(device, authorized);
-                mBluetoothService.notifyIncomingA2dpConnection(address, false);
+                mBluetoothService.notifyIncomingA2dpConnection(address, true);
             }
         } else if (BluetoothUuid.isInputDevice(uuid)) {
             // We can have more than 1 input device connected.
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index e0167d8..8e39d6e 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -22,6 +22,9 @@
 import android.graphics.Rect;
 import android.graphics.SurfaceTexture;
 import android.opengl.GLUtils;
+import android.opengl.ManagedEGLContext;
+import android.os.Handler;
+import android.os.Looper;
 import android.os.SystemClock;
 import android.os.SystemProperties;
 import android.util.Log;
@@ -409,7 +412,8 @@
         static final Object[] sEglLock = new Object[0];
         int mWidth = -1, mHeight = -1;
 
-        static final ThreadLocal<EGLContext> sEglContextStorage = new ThreadLocal<EGLContext>();
+        static final ThreadLocal<Gl20Renderer.MyEGLContext> sEglContextStorage
+                = new ThreadLocal<Gl20Renderer.MyEGLContext>();
 
         EGLContext mEglContext;
         Thread mEglThread;
@@ -561,12 +565,13 @@
                 }
             }
 
-            mEglContext = sEglContextStorage.get();
+            Gl20Renderer.MyEGLContext managedContext = sEglContextStorage.get();
+            mEglContext = managedContext != null ? managedContext.getContext() : null;
             mEglThread = Thread.currentThread();
 
             if (mEglContext == null) {
                 mEglContext = createContext(sEgl, sEglDisplay, sEglConfig);
-                sEglContextStorage.set(mEglContext);
+                sEglContextStorage.set(new Gl20Renderer.MyEGLContext(mEglContext));
             }
         }
 
@@ -904,6 +909,51 @@
         private static EGLSurface sPbuffer;
         private static final Object[] sPbufferLock = new Object[0];
 
+        static class MyEGLContext extends ManagedEGLContext {
+            final Handler mHandler = new Handler();
+
+            public MyEGLContext(EGLContext context) {
+                super(context);
+            }
+
+            @Override
+            public void onTerminate(final EGLContext eglContext) {
+                // Make sure we do this on the correct thread.
+                if (mHandler.getLooper() != Looper.myLooper()) {
+                    mHandler.post(new Runnable() {
+                        @Override public void run() {
+                            onTerminate(eglContext);
+                        }
+                    });
+                    return;
+                }
+
+                synchronized (sEglLock) {
+                    if (sEgl == null) return;
+
+                    if (EGLImpl.getInitCount(sEglDisplay) == 1) {
+                        usePbufferSurface(eglContext);
+                        GLES20Canvas.terminateCaches();
+
+                        sEgl.eglDestroyContext(sEglDisplay, eglContext);
+                        sEglContextStorage.remove();
+
+                        sEgl.eglDestroySurface(sEglDisplay, sPbuffer);
+                        sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+
+                        sEgl.eglReleaseThread();
+                        sEgl.eglTerminate(sEglDisplay);
+
+                        sEgl = null;
+                        sEglDisplay = null;
+                        sEglConfig = null;
+                        sPbuffer = null;
+                        sEglContextStorage.set(null);
+                    }
+                }
+            }
+        }
+
         Gl20Renderer(boolean translucent) {
             super(2, translucent);
         }
@@ -1020,12 +1070,12 @@
         static void trimMemory(int level) {
             if (sEgl == null || sEglConfig == null) return;
 
-            EGLContext eglContext = sEglContextStorage.get();
+            Gl20Renderer.MyEGLContext managedContext = sEglContextStorage.get();
             // We do not have OpenGL objects
-            if (eglContext == null) {
+            if (managedContext == null) {
                 return;
             } else {
-                usePbufferSurface(eglContext);
+                usePbufferSurface(managedContext.getContext());
             }
 
             switch (level) {
@@ -1052,33 +1102,5 @@
             }
             sEgl.eglMakeCurrent(sEglDisplay, sPbuffer, sPbuffer, eglContext);
         }
-
-        static void terminate() {
-            synchronized (sEglLock) {
-                if (sEgl == null) return;
-    
-                if (EGLImpl.getInitCount(sEglDisplay) == 1) {
-                    EGLContext eglContext = sEglContextStorage.get();
-                    if (eglContext == null) return;
-
-                    usePbufferSurface(eglContext);
-                    GLES20Canvas.terminateCaches();
-
-                    sEgl.eglDestroyContext(sEglDisplay, eglContext);
-                    sEglContextStorage.remove();
-        
-                    sEgl.eglDestroySurface(sEglDisplay, sPbuffer);
-                    sEgl.eglMakeCurrent(sEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
-
-                    sEgl.eglReleaseThread();
-                    sEgl.eglTerminate(sEglDisplay);
-                    
-                    sEgl = null;
-                    sEglDisplay = null;
-                    sEglConfig = null;
-                    sPbuffer = null;
-                }
-            }
-        }
     }
 }
diff --git a/core/java/android/view/WindowManagerImpl.java b/core/java/android/view/WindowManagerImpl.java
index d89bc36..660e3f4 100644
--- a/core/java/android/view/WindowManagerImpl.java
+++ b/core/java/android/view/WindowManagerImpl.java
@@ -21,6 +21,7 @@
 import android.content.res.CompatibilityInfo;
 import android.content.res.Configuration;
 import android.graphics.PixelFormat;
+import android.opengl.ManagedEGLContext;
 import android.os.IBinder;
 import android.util.AndroidRuntimeException;
 import android.util.Log;
@@ -428,7 +429,7 @@
                             }
                         }
                         // Terminate the hardware renderer to free all resources
-                        HardwareRenderer.terminate();                        
+                        ManagedEGLContext.doTerminate();
                         break;
                     }
                     // high end gfx devices fall through to next case
diff --git a/core/java/android/view/textservice/SpellCheckerSession.java b/core/java/android/view/textservice/SpellCheckerSession.java
index 0eb6e27..489587e 100644
--- a/core/java/android/view/textservice/SpellCheckerSession.java
+++ b/core/java/android/view/textservice/SpellCheckerSession.java
@@ -201,7 +201,7 @@
         private static final int TASK_CLOSE = 3;
         private final Queue<SpellCheckerParams> mPendingTasks =
                 new LinkedList<SpellCheckerParams>();
-        private final Handler mHandler;
+        private Handler mHandler;
 
         private boolean mOpened;
         private ISpellCheckerSession mISpellCheckerSession;
@@ -334,6 +334,7 @@
             try {
                 mISpellCheckerSession.onClose();
                 mISpellCheckerSession = null;
+                mHandler = null;
             } catch (RemoteException e) {
                 Log.e(TAG, "Failed to close " + e);
             }
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index f240a2e..f947f95 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -42,12 +42,14 @@
      * SINGLE_COLUMN moves all content into one column that is the width of the
      * view.
      * NARROW_COLUMNS makes all columns no wider than the screen if possible.
-     * @deprecated This enum is now obsolete.
      */
     // XXX: These must match LayoutAlgorithm in Settings.h in WebCore.
-    @Deprecated
     public enum LayoutAlgorithm {
         NORMAL,
+        /**
+         * @deprecated This algorithm is now obsolete.
+         */
+        @Deprecated
         SINGLE_COLUMN,
         NARROW_COLUMNS
     }
@@ -799,7 +801,7 @@
     public void setDefaultZoom(ZoomDensity zoom) {
         if (mDefaultZoom != zoom) {
             mDefaultZoom = zoom;
-            mWebView.updateDefaultZoomDensity(zoom.value);
+            mWebView.adjustDefaultZoomDensity(zoom.value);
         }
     }
 
@@ -936,9 +938,7 @@
      * WebView.
      * @param l A LayoutAlgorithm enum specifying the algorithm to use.
      * @see WebSettings.LayoutAlgorithm
-     * @deprecated This method is now obsolete.
      */
-    @Deprecated
     public synchronized void setLayoutAlgorithm(LayoutAlgorithm l) {
         // XXX: This will only be affective if libwebcore was built with
         // ANDROID_LAYOUT defined.
@@ -953,9 +953,7 @@
      * @return LayoutAlgorithm enum value describing the layout algorithm
      *         being used.
      * @see WebSettings.LayoutAlgorithm
-     * @deprecated This method is now obsolete.
      */
-    @Deprecated
     public synchronized LayoutAlgorithm getLayoutAlgorithm() {
         return mLayoutAlgorithm;
     }
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 8aafc3d..f18a396 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -17,8 +17,10 @@
 package android.webkit;
 
 import android.content.Context;
+import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
+import android.graphics.Paint.Style;
 import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
 import android.os.Bundle;
@@ -49,6 +51,7 @@
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
+import android.widget.AbsoluteLayout;
 import android.widget.AbsoluteLayout.LayoutParams;
 import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
@@ -71,6 +74,9 @@
 
     static final String LOGTAG = "webtextview";
 
+    private Paint mRingPaint;
+    private int mRingInset;
+
     private WebView         mWebView;
     private boolean         mSingle;
     private int             mWidthSpec;
@@ -201,7 +207,13 @@
                 }
             }
         };
+        float ringWidth = 4f * context.getResources().getDisplayMetrics().density;
         mReceiver = new MyResultReceiver(mHandler);
+        mRingPaint = new Paint();
+        mRingPaint.setColor(0x6633b5e5);
+        mRingPaint.setStrokeWidth(ringWidth);
+        mRingPaint.setStyle(Style.FILL);
+        mRingInset = (int) ringWidth;
     }
 
     public void setAutoFillable(int queryId) {
@@ -211,6 +223,40 @@
     }
 
     @Override
+    protected void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+        if (isFocused()) {
+            final int ib = getHeight() - mRingInset;
+            canvas.drawRect(0, 0, getWidth(), mRingInset, mRingPaint);
+            canvas.drawRect(0, ib, getWidth(), getHeight(), mRingPaint);
+            canvas.drawRect(0, mRingInset, mRingInset, ib, mRingPaint);
+            canvas.drawRect(getWidth() - mRingInset, mRingInset, getWidth(), ib, mRingPaint);
+        }
+    }
+
+    private void growOrShrink(boolean grow) {
+        AbsoluteLayout.LayoutParams lp = (AbsoluteLayout.LayoutParams) getLayoutParams();
+        if (grow) {
+            Log.i("webtextview", "grow");
+            lp.x -= mRingInset;
+            lp.y -= mRingInset;
+            lp.width += 2 * mRingInset;
+            lp.height += 2 * mRingInset;
+            setPadding(getPaddingLeft() + mRingInset, getPaddingTop() + mRingInset,
+                    getPaddingRight() + mRingInset, getPaddingBottom() + mRingInset);
+        } else {
+            Log.i("webtextview", "shrink");
+            lp.x += mRingInset;
+            lp.y += mRingInset;
+            lp.width -= 2 * mRingInset;
+            lp.height -= 2 * mRingInset;
+            setPadding(getPaddingLeft() - mRingInset, getPaddingTop() - mRingInset,
+                    getPaddingRight() - mRingInset, getPaddingBottom() - mRingInset);
+        }
+        setLayoutParams(lp);
+    }
+
+    @Override
     public boolean dispatchKeyEvent(KeyEvent event) {
         if (event.isSystem()) {
             return super.dispatchKeyEvent(event);
@@ -511,6 +557,7 @@
         } else if (!mInsideRemove) {
             mWebView.setActive(false);
         }
+        growOrShrink(focused);
         mFromFocusChange = false;
     }
 
@@ -567,7 +614,6 @@
                 mPreChange.substring(0, mMaxLength).equals(postChange))) {
             return;
         }
-        mPreChange = postChange;
         if (0 == count) {
             if (before > 0) {
                 // For this and all changes to the text, update our cache
@@ -605,9 +651,9 @@
         // Prefer sending javascript events, so when adding one character,
         // don't replace the unchanged text.
         if (count > 1 && before == count - 1) {
-            String replaceButOne =  s.subSequence(start,
+            String replaceButOne =  mPreChange.subSequence(start,
                     start + before).toString();
-            String replacedString = getText().subSequence(start,
+            String replacedString = s.subSequence(start,
                     start + before).toString();
             if (replaceButOne.equals(replacedString)) {
                 // we're just adding one character
@@ -616,6 +662,7 @@
                 count = 1;
             }
         }
+        mPreChange = postChange;
         // Find the last character being replaced.  If it can be represented by
         // events, we will pass them to native so we can see javascript events.
         // Otherwise, replace the text being changed in the textfield.
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index ec2f55b..35fd945 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -119,6 +119,11 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import static javax.microedition.khronos.egl.EGL10.*;
+
 /**
  * <p>A View that displays web pages. This class is the basis upon which you
  * can roll your own web browser or simply display some online content within your Activity.
@@ -909,6 +914,9 @@
     private Rect mScrollingLayerBounds = new Rect();
     private boolean mSentAutoScrollMessage = false;
 
+    // Temporary hack to work around the context removal upon memory pressure
+    private static boolean mIncrementEGLContextHack = false;
+
     // used for serializing asynchronously handled touch events.
     private final TouchEventQueue mTouchEventQueue = new TouchEventQueue();
 
@@ -1341,9 +1349,13 @@
         }
     }
 
-    /* package */void updateDefaultZoomDensity(int zoomDensity) {
+    /* package */ void adjustDefaultZoomDensity(int zoomDensity) {
         final float density = mContext.getResources().getDisplayMetrics().density
                 * 100 / zoomDensity;
+        updateDefaultZoomDensity(density);
+    }
+
+    /* package */ void updateDefaultZoomDensity(float density) {
         mNavSlop = (int) (16 * density);
         mZoomManager.updateDefaultZoomDensity(density);
     }
@@ -2469,7 +2481,9 @@
      * Set the initial scale for the WebView. 0 means default. If
      * {@link WebSettings#getUseWideViewPort()} is true, it zooms out all the
      * way. Otherwise it starts with 100%. If initial scale is greater than 0,
-     * WebView starts will this value as initial scale.
+     * WebView starts with this value as initial scale.
+     * Please note that unlike the scale properties in the viewport meta tag,
+     * this method doesn't take the screen density into account.
      *
      * @param scaleInPercent The initial scale in percent.
      */
@@ -4219,6 +4233,13 @@
         }
 
         if (canvas.isHardwareAccelerated()) {
+            if (mIncrementEGLContextHack == false) {
+                mIncrementEGLContextHack = true;
+                EGL10 egl = (EGL10) EGLContext.getEGL();
+                EGLDisplay eglDisplay = egl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
+                int[] version = new int[2];
+                egl.eglInitialize(eglDisplay, version);
+            }
             mZoomManager.setHardwareAccelerated();
         }
 
@@ -5658,13 +5679,13 @@
             if (hasFocus()) {
                 // If our window regained focus, and we have focus, then begin
                 // drawing the cursor ring
-                mDrawCursorRing = true;
+                mDrawCursorRing = !inEditingMode();
                 setFocusControllerActive(true);
             } else {
+                mDrawCursorRing = false;
                 if (!inEditingMode()) {
                     // If our window gained focus, but we do not have it, do not
                     // draw the cursor ring.
-                    mDrawCursorRing = false;
                     setFocusControllerActive(false);
                 }
                 // We do not call recordButtons here because we assume
@@ -5739,7 +5760,7 @@
             // When we regain focus, if we have window focus, resume drawing
             // the cursor ring
             if (hasWindowFocus()) {
-                mDrawCursorRing = true;
+                mDrawCursorRing = !inEditingMode();
                 setFocusControllerActive(true);
             //} else {
                 // The WebView has gained focus while we do not have
@@ -5749,8 +5770,8 @@
         } else {
             // When we lost focus, unless focus went to the TextView (which is
             // true if we are in editing mode), stop drawing the cursor ring.
+            mDrawCursorRing = false;
             if (!inEditingMode()) {
-                mDrawCursorRing = false;
                 setFocusControllerActive(false);
             }
             mKeysPressed.clear();
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index cd61481..a97f4dd 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -2336,6 +2336,9 @@
             adjust = (float) mContext.getResources().getDisplayMetrics().densityDpi
                     / mViewportDensityDpi;
         }
+        if (adjust != mWebView.getDefaultZoomScale()) {
+            mWebView.updateDefaultZoomDensity(adjust);
+        }
         int defaultScale = (int) (adjust * 100);
 
         if (mViewportInitialScale > 0) {
@@ -2546,7 +2549,7 @@
     // called by JNI
     private void restoreScale(float scale, float textWrapScale) {
         if (mBrowserFrame.firstLayoutDone() == false) {
-            mIsRestored = scale > 0;
+            mIsRestored = true;
             mRestoredScale = scale;
             if (mSettings.getUseWideViewPort()) {
                 mRestoredTextWrapScale = textWrapScale;
diff --git a/core/java/android/webkit/WebViewDatabase.java b/core/java/android/webkit/WebViewDatabase.java
index e1392ae..695c154 100644
--- a/core/java/android/webkit/WebViewDatabase.java
+++ b/core/java/android/webkit/WebViewDatabase.java
@@ -42,7 +42,7 @@
     // log tag
     protected static final String LOGTAG = "webviewdatabase";
 
-    private static final int DATABASE_VERSION = 10;
+    private static final int DATABASE_VERSION = 11;
     // 2 -> 3 Modified Cache table to allow cache of redirects
     // 3 -> 4 Added Oma-Downloads table
     // 4 -> 5 Modified Cache table to support persistent contentLength
@@ -52,6 +52,9 @@
     // 7 -> 8 Move cache to its own db
     // 8 -> 9 Store both scheme and host when storing passwords
     // 9 -> 10 Update httpauth table UNIQUE
+    // 10 -> 11 Drop cookies and cache now managed by the chromium stack,
+    //          and update the form data table to use the new format
+    //          implemented for b/5265606.
     private static final int CACHE_DATABASE_VERSION = 4;
     // 1 -> 2 Add expires String
     // 2 -> 3 Add content-disposition
@@ -204,7 +207,9 @@
         }
 
         initDatabase(context);
-        if (!JniUtil.useChromiumHttpStack()) {
+        if (JniUtil.useChromiumHttpStack()) {
+            context.deleteDatabase(CACHE_DATABASE_FILE);
+        } else {
             initCacheDatabase(context);
         }
 
@@ -327,15 +332,59 @@
     }
 
     private static void upgradeDatabase() {
+        upgradeDatabaseToV10();
+        upgradeDatabaseFromV10ToV11();
+        // Add future database upgrade functions here, one version at a
+        // time.
+        mDatabase.setVersion(DATABASE_VERSION);
+    }
+
+    private static void upgradeDatabaseFromV10ToV11() {
         int oldVersion = mDatabase.getVersion();
+
+        if (oldVersion >= 11) {
+            // Nothing to do.
+            return;
+        }
+
+        if (JniUtil.useChromiumHttpStack()) {
+            // Clear out old java stack cookies - this data is now stored in
+            // a separate database managed by the Chrome stack.
+            mDatabase.execSQL("DROP TABLE IF EXISTS " + mTableNames[TABLE_COOKIES_ID]);
+
+            // Likewise for the old cache table.
+            mDatabase.execSQL("DROP TABLE IF EXISTS cache");
+        }
+
+        // Update form autocomplete  URLs to match new ICS formatting.
+        Cursor c = mDatabase.query(mTableNames[TABLE_FORMURL_ID], null, null,
+                null, null, null, null);
+        while (c.moveToNext()) {
+            String urlId = Long.toString(c.getLong(c.getColumnIndex(ID_COL)));
+            String url = c.getString(c.getColumnIndex(FORMURL_URL_COL));
+            ContentValues cv = new ContentValues(1);
+            cv.put(FORMURL_URL_COL, WebTextView.urlForAutoCompleteData(url));
+            mDatabase.update(mTableNames[TABLE_FORMURL_ID], cv, ID_COL + "=?",
+                    new String[] { urlId });
+        }
+        c.close();
+    }
+
+    private static void upgradeDatabaseToV10() {
+        int oldVersion = mDatabase.getVersion();
+
+        if (oldVersion >= 10) {
+            // Nothing to do.
+            return;
+        }
+
         if (oldVersion != 0) {
             Log.i(LOGTAG, "Upgrading database from version "
                     + oldVersion + " to "
                     + DATABASE_VERSION + ", which will destroy old data");
         }
-        boolean justPasswords = 8 == oldVersion && 9 == DATABASE_VERSION;
-        boolean justAuth = 9 == oldVersion && 10 == DATABASE_VERSION;
-        if (justAuth) {
+
+        if (9 == oldVersion) {
             mDatabase.execSQL("DROP TABLE IF EXISTS "
                     + mTableNames[TABLE_HTTPAUTH_ID]);
             mDatabase.execSQL("CREATE TABLE " + mTableNames[TABLE_HTTPAUTH_ID]
@@ -348,55 +397,49 @@
             return;
         }
 
-        if (!justPasswords) {
-            mDatabase.execSQL("DROP TABLE IF EXISTS "
-                    + mTableNames[TABLE_COOKIES_ID]);
-            mDatabase.execSQL("DROP TABLE IF EXISTS cache");
-            mDatabase.execSQL("DROP TABLE IF EXISTS "
-                    + mTableNames[TABLE_FORMURL_ID]);
-            mDatabase.execSQL("DROP TABLE IF EXISTS "
-                    + mTableNames[TABLE_FORMDATA_ID]);
-            mDatabase.execSQL("DROP TABLE IF EXISTS "
-                    + mTableNames[TABLE_HTTPAUTH_ID]);
-        }
+        mDatabase.execSQL("DROP TABLE IF EXISTS "
+                + mTableNames[TABLE_COOKIES_ID]);
+        mDatabase.execSQL("DROP TABLE IF EXISTS cache");
+        mDatabase.execSQL("DROP TABLE IF EXISTS "
+                + mTableNames[TABLE_FORMURL_ID]);
+        mDatabase.execSQL("DROP TABLE IF EXISTS "
+                + mTableNames[TABLE_FORMDATA_ID]);
+        mDatabase.execSQL("DROP TABLE IF EXISTS "
+                + mTableNames[TABLE_HTTPAUTH_ID]);
         mDatabase.execSQL("DROP TABLE IF EXISTS "
                 + mTableNames[TABLE_PASSWORD_ID]);
 
-        mDatabase.setVersion(DATABASE_VERSION);
+        // cookies
+        mDatabase.execSQL("CREATE TABLE " + mTableNames[TABLE_COOKIES_ID]
+                + " (" + ID_COL + " INTEGER PRIMARY KEY, "
+                + COOKIES_NAME_COL + " TEXT, " + COOKIES_VALUE_COL
+                + " TEXT, " + COOKIES_DOMAIN_COL + " TEXT, "
+                + COOKIES_PATH_COL + " TEXT, " + COOKIES_EXPIRES_COL
+                + " INTEGER, " + COOKIES_SECURE_COL + " INTEGER" + ");");
+        mDatabase.execSQL("CREATE INDEX cookiesIndex ON "
+                + mTableNames[TABLE_COOKIES_ID] + " (path)");
 
-        if (!justPasswords) {
-            // cookies
-            mDatabase.execSQL("CREATE TABLE " + mTableNames[TABLE_COOKIES_ID]
-                    + " (" + ID_COL + " INTEGER PRIMARY KEY, "
-                    + COOKIES_NAME_COL + " TEXT, " + COOKIES_VALUE_COL
-                    + " TEXT, " + COOKIES_DOMAIN_COL + " TEXT, "
-                    + COOKIES_PATH_COL + " TEXT, " + COOKIES_EXPIRES_COL
-                    + " INTEGER, " + COOKIES_SECURE_COL + " INTEGER" + ");");
-            mDatabase.execSQL("CREATE INDEX cookiesIndex ON "
-                    + mTableNames[TABLE_COOKIES_ID] + " (path)");
+        // formurl
+        mDatabase.execSQL("CREATE TABLE " + mTableNames[TABLE_FORMURL_ID]
+                + " (" + ID_COL + " INTEGER PRIMARY KEY, " + FORMURL_URL_COL
+                + " TEXT" + ");");
 
-            // formurl
-            mDatabase.execSQL("CREATE TABLE " + mTableNames[TABLE_FORMURL_ID]
-                    + " (" + ID_COL + " INTEGER PRIMARY KEY, " + FORMURL_URL_COL
-                    + " TEXT" + ");");
+        // formdata
+        mDatabase.execSQL("CREATE TABLE " + mTableNames[TABLE_FORMDATA_ID]
+                + " (" + ID_COL + " INTEGER PRIMARY KEY, "
+                + FORMDATA_URLID_COL + " INTEGER, " + FORMDATA_NAME_COL
+                + " TEXT, " + FORMDATA_VALUE_COL + " TEXT," + " UNIQUE ("
+                + FORMDATA_URLID_COL + ", " + FORMDATA_NAME_COL + ", "
+                + FORMDATA_VALUE_COL + ") ON CONFLICT IGNORE);");
 
-            // formdata
-            mDatabase.execSQL("CREATE TABLE " + mTableNames[TABLE_FORMDATA_ID]
-                    + " (" + ID_COL + " INTEGER PRIMARY KEY, "
-                    + FORMDATA_URLID_COL + " INTEGER, " + FORMDATA_NAME_COL
-                    + " TEXT, " + FORMDATA_VALUE_COL + " TEXT," + " UNIQUE ("
-                    + FORMDATA_URLID_COL + ", " + FORMDATA_NAME_COL + ", "
-                    + FORMDATA_VALUE_COL + ") ON CONFLICT IGNORE);");
-
-            // httpauth
-            mDatabase.execSQL("CREATE TABLE " + mTableNames[TABLE_HTTPAUTH_ID]
-                    + " (" + ID_COL + " INTEGER PRIMARY KEY, "
-                    + HTTPAUTH_HOST_COL + " TEXT, " + HTTPAUTH_REALM_COL
-                    + " TEXT, " + HTTPAUTH_USERNAME_COL + " TEXT, "
-                    + HTTPAUTH_PASSWORD_COL + " TEXT," + " UNIQUE ("
-                    + HTTPAUTH_HOST_COL + ", " + HTTPAUTH_REALM_COL
-                    + ") ON CONFLICT REPLACE);");
-        }
+        // httpauth
+        mDatabase.execSQL("CREATE TABLE " + mTableNames[TABLE_HTTPAUTH_ID]
+                + " (" + ID_COL + " INTEGER PRIMARY KEY, "
+                + HTTPAUTH_HOST_COL + " TEXT, " + HTTPAUTH_REALM_COL
+                + " TEXT, " + HTTPAUTH_USERNAME_COL + " TEXT, "
+                + HTTPAUTH_PASSWORD_COL + " TEXT," + " UNIQUE ("
+                + HTTPAUTH_HOST_COL + ", " + HTTPAUTH_REALM_COL
+                + ") ON CONFLICT REPLACE);");
         // passwords
         mDatabase.execSQL("CREATE TABLE " + mTableNames[TABLE_PASSWORD_ID]
                 + " (" + ID_COL + " INTEGER PRIMARY KEY, "
@@ -411,7 +454,7 @@
         if (oldVersion != 0) {
             Log.i(LOGTAG, "Upgrading cache database from version "
                     + oldVersion + " to "
-                    + DATABASE_VERSION + ", which will destroy all old data");
+                    + CACHE_DATABASE_VERSION + ", which will destroy all old data");
         }
         mCacheDatabase.execSQL("DROP TABLE IF EXISTS cache");
         mCacheDatabase.setVersion(CACHE_DATABASE_VERSION);
@@ -1150,7 +1193,7 @@
                 cursor = mDatabase.query(mTableNames[TABLE_FORMURL_ID],
                         ID_PROJECTION, urlSelection, new String[] { url }, null,
                         null, null);
-                if (cursor.moveToFirst()) {
+                while (cursor.moveToNext()) {
                     long urlid = cursor.getLong(cursor.getColumnIndex(ID_COL));
                     Cursor dataCursor = null;
                     try {
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index f599dba..84d00c9 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -349,7 +349,7 @@
     }
 
     public final void setInitialScaleInPercent(int scaleInPercent) {
-        mInitialScale = scaleInPercent * mDisplayDensity * 0.01f;
+        mInitialScale = scaleInPercent * 0.01f;
     }
 
     public final float computeScaleWithLimits(float scale) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 230df39..97658a1 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -263,8 +263,7 @@
         android:label="@string/permlab_writeProfile"
         android:description="@string/permdesc_writeProfile" />
 
-    <!-- Allows an application to read from the user's social stream.
-         @hide -->
+    <!-- Allows an application to read from the user's social stream. -->
     <permission android:name="android.permission.READ_SOCIAL_STREAM"
         android:permissionGroup="android.permission-group.PERSONAL_INFO"
         android:protectionLevel="dangerous"
@@ -272,8 +271,7 @@
         android:description="@string/permdesc_readSocialStream" />
 
     <!-- Allows an application to write (but not read) the user's
-         social stream data.
-         @hide -->
+         social stream data. -->
     <permission android:name="android.permission.WRITE_SOCIAL_STREAM"
         android:permissionGroup="android.permission-group.PERSONAL_INFO"
         android:protectionLevel="dangerous"
diff --git a/core/res/res/layout/media_controller.xml b/core/res/res/layout/media_controller.xml
index 582101a..313806cd 100644
--- a/core/res/res/layout/media_controller.xml
+++ b/core/res/res/layout/media_controller.xml
@@ -17,13 +17,9 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:background="#CC666666"
+    android:background="#CC000000"
     android:orientation="vertical">
 
-    <ImageView android:layout_width="match_parent"
-        android:layout_height="1px"
-        android:background="@android:drawable/divider_horizontal_dark" />
-
     <LinearLayout
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 767cafe..25f7d25 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -741,4 +741,7 @@
     <string name="config_wimaxServiceClassname"></string>
     <!-- Name of the wimax state tracker clas -->
     <string name="config_wimaxStateTrackerClassname"></string>
+
+    <!-- Name of screensaver components to look for if none has been chosen by the user -->
+    <string name="config_defaultDreamComponent">com.google.android.deskclock/com.android.deskclock.Screensaver</string>
 </resources>
diff --git a/include/gui/SurfaceTexture.h b/include/gui/SurfaceTexture.h
index d7dd4d6..27d863d 100644
--- a/include/gui/SurfaceTexture.h
+++ b/include/gui/SurfaceTexture.h
@@ -271,7 +271,8 @@
               mRequestBufferCalled(false),
               mTransform(0),
               mScalingMode(NATIVE_WINDOW_SCALING_MODE_FREEZE),
-              mTimestamp(0) {
+              mTimestamp(0),
+              mFrameNumber(0) {
             mCrop.makeInvalid();
         }
 
@@ -340,6 +341,10 @@
         // mTimestamp is the current timestamp for this buffer slot. This gets
         // to set by queueBuffer each time this slot is queued.
         int64_t mTimestamp;
+
+        // mFrameNumber is the number of the queued frame for this slot.
+        uint64_t mFrameNumber;
+
     };
 
     // mSlots is the array of buffer slots that must be mirrored on the client
@@ -476,6 +481,12 @@
     // around a GL driver limitation on the number of FBO attachments, which the
     // browser's tile cache exceeds.
     const GLenum mTexTarget;
+
+    // mFrameCounter is the free running counter, incremented for every buffer queued
+    // with the surface Texture.
+    uint64_t mFrameCounter;
+
+
 };
 
 // ----------------------------------------------------------------------------
diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk
index 9767568..ed319f5 100644
--- a/libs/gui/Android.mk
+++ b/libs/gui/Android.mk
@@ -32,10 +32,6 @@
 
 LOCAL_MODULE:= libgui
 
-ifeq ($(TARGET_BOARD_PLATFORM), tegra)
-	LOCAL_CFLAGS += -DALLOW_DEQUEUE_CURRENT_BUFFER
-endif
-
 include $(BUILD_SHARED_LIBRARY)
 
 ifeq (,$(ONE_SHOT_MAKEFILE))
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 374f3c5..3c0d475 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -36,12 +36,8 @@
 #include <utils/Log.h>
 #include <utils/String8.h>
 
-#ifdef ALLOW_DEQUEUE_CURRENT_BUFFER
-#define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER    true
-#warning "ALLOW_DEQUEUE_CURRENT_BUFFER enabled"
-#else
-#define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER    false
-#endif
+
+#define ALLOW_DEQUEUE_CURRENT_BUFFER    false
 
 // Macros for including the SurfaceTexture name in log messages
 #define ST_LOGV(x, ...) LOGV("[%s] "x, mName.string(), ##__VA_ARGS__)
@@ -116,7 +112,8 @@
     mAllowSynchronousMode(allowSynchronousMode),
     mConnectedApi(NO_CONNECTED_API),
     mAbandoned(false),
-    mTexTarget(texTarget) {
+    mTexTarget(texTarget),
+    mFrameCounter(0) {
     // Choose a name using the PID and a process-unique ID.
     mName = String8::format("unnamed-%d-%d", getpid(), createProcessUniqueId());
 
@@ -264,7 +261,8 @@
 
     status_t returnFlags(OK);
 
-    int found, foundSync;
+    int found = -1;
+    int foundSync = -1;
     int dequeuedCount = 0;
     bool tryAgain = true;
     while (tryAgain) {
@@ -327,7 +325,7 @@
             LOGW_IF((state == BufferSlot::FREE) && (mCurrentTexture==i),
                     "dequeueBuffer: buffer %d is both FREE and current!", i);
 
-            if (FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER) {
+            if (ALLOW_DEQUEUE_CURRENT_BUFFER) {
                 if (state == BufferSlot::FREE || i == mCurrentTexture) {
                     foundSync = i;
                     if (i != mCurrentTexture) {
@@ -337,9 +335,14 @@
                 }
             } else {
                 if (state == BufferSlot::FREE) {
-                    foundSync = i;
-                    found = i;
-                    break;
+                    /** For Asynchronous mode, we need to return the oldest of free buffers
+                    * There is only one instance when the Framecounter overflows, this logic
+                    * might return the earlier buffer to client. Which is a negligible impact
+                    **/
+                    if (found < 0 || mSlots[i].mFrameNumber < mSlots[found].mFrameNumber) {
+                        foundSync = i;
+                        found = i;
+                    }
                 }
             }
         }
@@ -531,6 +534,9 @@
         mSlots[buf].mTransform = mNextTransform;
         mSlots[buf].mScalingMode = mNextScalingMode;
         mSlots[buf].mTimestamp = timestamp;
+        mFrameCounter++;
+        mSlots[buf].mFrameNumber = mFrameCounter;
+
         mDequeueCondition.signal();
 
         *outWidth = mDefaultWidth;
@@ -564,6 +570,7 @@
         return;
     }
     mSlots[buf].mBufferState = BufferSlot::FREE;
+    mSlots[buf].mFrameNumber = 0;
     mDequeueCondition.signal();
 }
 
@@ -897,6 +904,7 @@
 void SurfaceTexture::freeBufferLocked(int i) {
     mSlots[i].mGraphicBuffer = 0;
     mSlots[i].mBufferState = BufferSlot::FREE;
+    mSlots[i].mFrameNumber = 0;
     if (mSlots[i].mEglImage != EGL_NO_IMAGE_KHR) {
         eglDestroyImageKHR(mSlots[i].mEglDisplay, mSlots[i].mEglImage);
         mSlots[i].mEglImage = EGL_NO_IMAGE_KHR;
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 7d9d7ed..f6d054d 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -224,17 +224,18 @@
     mClient.disconnect();
 }
 
-void AwesomePlayer::cancelPlayerEvents(bool keepBufferingGoing) {
+void AwesomePlayer::cancelPlayerEvents(bool keepNotifications) {
     mQueue.cancelEvent(mVideoEvent->eventID());
     mVideoEventPending = false;
-    mQueue.cancelEvent(mStreamDoneEvent->eventID());
-    mStreamDoneEventPending = false;
-    mQueue.cancelEvent(mCheckAudioStatusEvent->eventID());
-    mAudioStatusEventPending = false;
     mQueue.cancelEvent(mVideoLagEvent->eventID());
     mVideoLagEventPending = false;
 
-    if (!keepBufferingGoing) {
+    if (!keepNotifications) {
+        mQueue.cancelEvent(mStreamDoneEvent->eventID());
+        mStreamDoneEventPending = false;
+        mQueue.cancelEvent(mCheckAudioStatusEvent->eventID());
+        mAudioStatusEventPending = false;
+
         mQueue.cancelEvent(mBufferingEvent->eventID());
         mBufferingEventPending = false;
     }
@@ -1095,7 +1096,7 @@
         return OK;
     }
 
-    cancelPlayerEvents(true /* keepBufferingGoing */);
+    cancelPlayerEvents(true /* keepNotifications */);
 
     if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
         if (at_eos) {
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index c13d6cb..0985f47 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -250,7 +250,7 @@
     void notifyVideoSize_l();
     void seekAudioIfNecessary_l();
 
-    void cancelPlayerEvents(bool keepBufferingGoing = false);
+    void cancelPlayerEvents(bool keepNotifications = false);
 
     void setAudioSource(sp<MediaSource> source);
     status_t initAudioDecoder();
diff --git a/opengl/java/android/opengl/ManagedEGLContext.java b/opengl/java/android/opengl/ManagedEGLContext.java
new file mode 100644
index 0000000..d3a3662
--- /dev/null
+++ b/opengl/java/android/opengl/ManagedEGLContext.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+package android.opengl;
+
+import static javax.microedition.khronos.egl.EGL10.EGL_DEFAULT_DISPLAY;
+import static javax.microedition.khronos.egl.EGL10.EGL_NO_DISPLAY;
+
+import java.util.ArrayList;
+
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+
+import android.os.Looper;
+import android.util.Log;
+
+import com.google.android.gles_jni.EGLImpl;
+
+/**
+ * The per-process memory overhead of hardware accelerated graphics can
+ * be quite large on some devices.  For small memory devices, being able to
+ * terminate all EGL contexts so that this graphics driver memory can be
+ * reclaimed can significant improve the overall behavior of the device.  This
+ * class helps app developers participate in releasing their EGL context
+ * when appropriate and possible.
+ * 
+ * <p>To use, simple instantiate this class with the EGLContext you create.
+ * When you have done this, if the device is getting low on memory and all
+ * of the currently created EGL contexts in the process are being managed
+ * through this class, then they will all be asked to terminate through the
+ * call to {@link #onTerminate}.
+ */
+public abstract class ManagedEGLContext {
+    static final String TAG = "ManagedEGLContext";
+
+    static final ArrayList<ManagedEGLContext> sActive
+            = new ArrayList<ManagedEGLContext>();
+
+    final EGLContext mContext;
+
+    /**
+     * Instantiate to manage the given EGLContext.
+     */
+    public ManagedEGLContext(EGLContext context) {
+        mContext = context;
+        synchronized (sActive) {
+            sActive.add(this);
+        }
+    }
+
+    /**
+     * Retrieve the EGLContext being managed by the class.
+     */
+    public EGLContext getContext() {
+        return mContext;
+    }
+
+    /**
+     * Force-terminate the ManagedEGLContext.  This will cause
+     * {@link #onTerminate(EGLContext)} to be called.  You <em>must</em>
+     * call this when destroying the EGLContext, so that the framework
+     * knows to stop managing it.
+     */
+    public void terminate() {
+        execTerminate();
+    }
+
+    void execTerminate() {
+        onTerminate(mContext);
+    }
+
+    /**
+     * Override this method to destroy the EGLContext when appropriate.
+     * <em>Note that this method is always called on the main thread
+     * of the process.</em>  If your EGLContext was created on a different
+     * thread, you will need to implement this method to hand off the work
+     * of destroying the context to that thread.
+     */
+    public abstract void onTerminate(EGLContext context);
+
+    /** @hide */
+    public static boolean doTerminate() {
+        ArrayList<ManagedEGLContext> active;
+
+        if (Looper.getMainLooper() != Looper.myLooper()) {
+            throw new IllegalStateException("Called on wrong thread");
+        }
+
+        synchronized (sActive) {
+            // If there are no active managed contexts, we will not even
+            // try to terminate.
+            if (sActive.size() <= 0) {
+                return false;
+            }
+
+            // Need to check how many EGL contexts are actually running,
+            // to compare with how many we are managing.
+            EGL10 egl = (EGL10) EGLContext.getEGL();
+            EGLDisplay display = egl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
+
+            if (display == EGL_NO_DISPLAY) {
+                Log.w(TAG, "doTerminate failed: no display");
+                return false;
+            }
+
+            if (EGLImpl.getInitCount(display) != sActive.size()) {
+                Log.w(TAG, "doTerminate failed: EGL count is " + EGLImpl.getInitCount(display)
+                        + " but managed count is " + sActive.size());
+                return false;
+            }
+
+            active = new ArrayList<ManagedEGLContext>(sActive);
+            sActive.clear();
+        }
+
+        for (int i=0; i<active.size(); i++) {
+            active.get(i).execTerminate();
+        }
+
+        return true;
+    }
+}
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 862b48d2..31119f9 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -220,15 +220,19 @@
         if (end) {
             // length of the extension string
             const size_t len = end - start;
-            // NOTE: we could avoid the copy if we had strnstr.
-            const String8 ext(start, len);
-            // now go through all implementations and look for this extension
-            for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
-                // if we find it, add this extension string to our list
-                // (and don't forget the space)
-                const char* match = strstr(disp[i].queryString.extensions, ext.string());
-                if (match && (match[len] == ' ' || match[len] == 0)) {
-                    mExtensionString.append(start, len+1);
+            if (len) {
+                // NOTE: we could avoid the copy if we had strnstr.
+                const String8 ext(start, len);
+                // now go through all implementations and look for this extension
+                for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
+                    if (disp[i].queryString.extensions) {
+                        // if we find it, add this extension string to our list
+                        // (and don't forget the space)
+                        const char* match = strstr(disp[i].queryString.extensions, ext.string());
+                        if (match && (match[len] == ' ' || match[len] == 0)) {
+                            mExtensionString.append(start, len+1);
+                        }
+                    }
                 }
             }
             // process the next extension string, and skip the space.
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 5495d08..aa08e64 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -723,6 +723,8 @@
             upgradeVersion = 57;
         }
 
+        /************* The following are Honeycomb changes ************/
+
         if (upgradeVersion == 57) {
             /*
              * New settings to:
@@ -751,13 +753,13 @@
 
         if (upgradeVersion == 58) {
             /* Add default for new Auto Time Zone */
+            int autoTimeValue = getIntValueFromSystem(db, Settings.System.AUTO_TIME, 0);
             db.beginTransaction();
             SQLiteStatement stmt = null;
             try {
-                stmt = db.compileStatement("INSERT INTO secure(name,value)"
-                        + " VALUES(?,?);");
-                loadBooleanSetting(stmt, Settings.System.AUTO_TIME_ZONE,
-                        R.bool.def_auto_time_zone); // Sync timezone to NITZ
+                stmt = db.compileStatement("INSERT INTO system(name,value)" + " VALUES(?,?);");
+                loadSetting(stmt, Settings.System.AUTO_TIME_ZONE,
+                        autoTimeValue); // Sync timezone to NITZ if auto_time was enabled
                 db.setTransactionSuccessful();
             } finally {
                 db.endTransaction();
@@ -784,18 +786,24 @@
         }
 
         if (upgradeVersion == 60) {
-            upgradeScreenTimeout(db);
+            // Don't do this for upgrades from Gingerbread
+            // Were only required for intra-Honeycomb upgrades for testing
+            // upgradeScreenTimeout(db);
             upgradeVersion = 61;
         }
 
         if (upgradeVersion == 61) {
-            upgradeScreenTimeout(db);
+            // Don't do this for upgrades from Gingerbread
+            // Were only required for intra-Honeycomb upgrades for testing
+            // upgradeScreenTimeout(db);
             upgradeVersion = 62;
         }
 
         // Change the default for screen auto-brightness mode
         if (upgradeVersion == 62) {
-            upgradeAutoBrightness(db);
+            // Don't do this for upgrades from Gingerbread
+            // Were only required for intra-Honeycomb upgrades for testing
+            // upgradeAutoBrightness(db);
             upgradeVersion = 63;
         }
 
@@ -839,6 +847,8 @@
             upgradeVersion = 65;
         }
 
+        /************* The following are Ice Cream Sandwich changes ************/
+
         if (upgradeVersion == 65) {
             /*
              * Animations are removed from Settings. Turned on by default
@@ -1232,12 +1242,13 @@
             stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
                     + " VALUES(?,?);");
     
-            // Vibrate off by default for ringer, on for notification
+            // Vibrate on by default for ringer, on for notification
             int vibrate = 0;
             vibrate = AudioService.getValueForVibrateSetting(vibrate,
-                    AudioManager.VIBRATE_TYPE_NOTIFICATION, AudioManager.VIBRATE_SETTING_ON);
+                    AudioManager.VIBRATE_TYPE_NOTIFICATION,
+                    AudioManager.VIBRATE_SETTING_ONLY_SILENT);
             vibrate |= AudioService.getValueForVibrateSetting(vibrate,
-                    AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_OFF);
+                    AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_ONLY_SILENT);
             loadSetting(stmt, Settings.System.VIBRATE_ON, vibrate);
         } finally {
             if (stmt != null) stmt.close();
@@ -1509,4 +1520,20 @@
         loadSetting(stmt, key,
                 Float.toString(mContext.getResources().getFraction(resid, base, base)));
     }
+
+    private int getIntValueFromSystem(SQLiteDatabase db, String name, int defaultValue) {
+        int value = defaultValue;
+        Cursor c = null;
+        try {
+            c = db.query("system", new String[] { Settings.System.VALUE }, "name='" + name + "'",
+                    null, null, null, null);
+            if (c != null && c.moveToFirst()) {
+                String val = c.getString(0);
+                value = val == null ? defaultValue : Integer.parseInt(val);
+            }
+        } finally {
+            if (c != null) c.close();
+        }
+        return value;
+    }
 }
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index eefb9fe..dff41c9 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -46,16 +46,26 @@
             </intent-filter>
         </receiver>
 
-        <!-- handle dock insertion, launch screensaver instead -->
+        <!-- should you need to launch the screensaver, this is a good way to do it -->
         <activity android:name=".DreamsDockLauncher"
+                android:theme="@android:style/Theme.Dialog"
                 android:label="@string/dreams_dock_launcher">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.DESK_DOCK" />
             </intent-filter>
         </activity>
 
+        <!-- launch screensaver on (desk) dock event -->
+        <receiver android:name=".DreamsDockLauncher$DockEventReceiver" 
+            android:exported="true"
+            >
+            <intent-filter>
+                <action android:name="android.intent.action.DOCK_EVENT" />
+            </intent-filter>
+        </receiver>
+
+
         <activity android:name=".usb.UsbStorageActivity"
                 android:excludeFromRecents="true">
         </activity>
@@ -124,7 +134,7 @@
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.DREAM" />
+<!--                <category android:name="android.intent.category.DREAM" />-->
             </intent-filter>
         </activity>
     </application>
diff --git a/packages/SystemUI/res/values-sw600dp/donottranslate.xml b/packages/SystemUI/res/values-sw600dp/donottranslate.xml
new file mode 100644
index 0000000..0996067
--- /dev/null
+++ b/packages/SystemUI/res/values-sw600dp/donottranslate.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2011, 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.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <!-- For formatting day of week and date in DateView.  %1$s is DOW, %2$s is date.
+         We show both (DOW on one line, then the date) but this can be overridden for locales as
+         necessary.
+         -->
+    <string name="status_bar_date_formatter">%1$s\n%2$s</string>
+
+</resources>
+
diff --git a/packages/SystemUI/res/values/donottranslate.xml b/packages/SystemUI/res/values/donottranslate.xml
index 089a54d..4ca2116 100644
--- a/packages/SystemUI/res/values/donottranslate.xml
+++ b/packages/SystemUI/res/values/donottranslate.xml
@@ -21,6 +21,6 @@
          We show both (DOW on one line, then the date) but this can be overridden for locales as
          necessary.
          -->
-    <string name="status_bar_date_formatter">%1$s\n%2$s</string>
+    <string name="status_bar_date_formatter">%2$s</string>
 
 </resources>
diff --git a/packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java b/packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java
index b8cdd73..0035296 100644
--- a/packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java
+++ b/packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java
@@ -12,12 +12,23 @@
 
 public class DreamsDockLauncher extends Activity {
     private static final String TAG = "DreamsDockLauncher";
+
+    // Launch the screen saver if started as an activity.
     @Override
     protected void onCreate (Bundle icicle) {
         super.onCreate(icicle);
+        launchDream(this);
+        finish();
+    }
+
+    private static void launchDream(Context context) {
         try {
             String component = Settings.Secure.getString(
-                    getContentResolver(), Settings.Secure.DREAM_COMPONENT);
+                    context.getContentResolver(), Settings.Secure.DREAM_COMPONENT);
+            if (component == null) {
+                component = context.getResources().getString(
+                    com.android.internal.R.string.config_defaultDreamComponent);
+            }
             if (component != null) {
                 ComponentName cn = ComponentName.unflattenFromString(component);
                 Intent zzz = new Intent(Intent.ACTION_MAIN)
@@ -26,7 +37,8 @@
                         | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
                         | Intent.FLAG_ACTIVITY_NO_USER_ACTION
                         );
-                startActivity(zzz);
+                Slog.v(TAG, "Starting screen saver on dock event: " + component);
+                context.startActivity(zzz);
             } else {
                 Slog.e(TAG, "Couldn't start screen saver: none selected");
             }
@@ -34,6 +46,22 @@
             // no screensaver? give up
             Slog.e(TAG, "Couldn't start screen saver: none installed");
         }
-        finish();
+    }
+
+    // Trap low-level dock events and launch the screensaver.
+    public static class DockEventReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())) {
+                Bundle extras = intent.getExtras();
+                int state = extras
+                        .getInt(Intent.EXTRA_DOCK_STATE, Intent.EXTRA_DOCK_STATE_UNDOCKED);
+                if (state == Intent.EXTRA_DOCK_STATE_DESK
+                        || state == Intent.EXTRA_DOCK_STATE_LE_DESK
+                        || state == Intent.EXTRA_DOCK_STATE_HE_DESK) {
+                    launchDream(context);
+                }
+            }
+        }
     }
 }
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index b4dd07b..e00a54c 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -157,6 +157,11 @@
     static final boolean SHOW_STARTING_ANIMATIONS = true;
     static final boolean SHOW_PROCESSES_ON_ALT_MENU = false;
 
+    // Whether to allow dock apps with METADATA_DOCK_HOME to temporarily take over the Home key.
+    // No longer recommended for desk docks; still useful in car docks.
+    static final boolean ENABLE_CAR_DOCK_HOME_CAPTURE = true;
+    static final boolean ENABLE_DESK_DOCK_HOME_CAPTURE = false;
+
     static final int LONG_PRESS_POWER_NOTHING = 0;
     static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
     static final int LONG_PRESS_POWER_SHUT_OFF = 2;
@@ -3420,6 +3425,9 @@
             try {
                 String component = Settings.Secure.getString(
                         mContext.getContentResolver(), Settings.Secure.DREAM_COMPONENT);
+                if (component == null) {
+                    component = mContext.getResources().getString(R.string.config_defaultDreamComponent);
+                }
                 if (component != null) {
                     ComponentName cn = ComponentName.unflattenFromString(component);
                     Intent intent = new Intent(Intent.ACTION_MAIN)
@@ -3508,21 +3516,35 @@
     }
 
     /**
-     * Return an Intent to launch the currently active dock as home.  Returns
-     * null if the standard home should be launched.
+     * Return an Intent to launch the currently active dock app as home.  Returns
+     * null if the standard home should be launched, which is the case if any of the following is
+     * true:
+     * <ul>
+     *  <li>The device is not in either car mode or desk mode
+     *  <li>The device is in car mode but ENABLE_CAR_DOCK_HOME_CAPTURE is false
+     *  <li>The device is in desk mode but ENABLE_DESK_DOCK_HOME_CAPTURE is false
+     *  <li>The device is in car mode but there's no CAR_DOCK app with METADATA_DOCK_HOME
+     *  <li>The device is in desk mode but there's no DESK_DOCK app with METADATA_DOCK_HOME
+     * </ul>
      * @return
      */
     Intent createHomeDockIntent() {
-        Intent intent;
+        Intent intent = null;
         
         // What home does is based on the mode, not the dock state.  That
         // is, when in car mode you should be taken to car home regardless
         // of whether we are actually in a car dock.
         if (mUiMode == Configuration.UI_MODE_TYPE_CAR) {
-            intent = mCarDockIntent;
+            if (ENABLE_CAR_DOCK_HOME_CAPTURE) {
+                intent = mCarDockIntent;
+            }
         } else if (mUiMode == Configuration.UI_MODE_TYPE_DESK) {
-            intent = mDeskDockIntent;
-        } else {
+            if (ENABLE_DESK_DOCK_HOME_CAPTURE) {
+                intent = mDeskDockIntent;
+            }
+        }
+
+        if (intent == null) {
             return null;
         }
         
diff --git a/services/java/com/android/server/EventLogTags.logtags b/services/java/com/android/server/EventLogTags.logtags
index a7eff93..5408436 100644
--- a/services/java/com/android/server/EventLogTags.logtags
+++ b/services/java/com/android/server/EventLogTags.logtags
@@ -142,5 +142,5 @@
 # ---------------------------
 # NetworkStatsService.java
 # ---------------------------
-51100 netstats_mobile_sample (dev_rx_bytes|2|2),(dev_tx_bytes|2|2),(dev_rx_pkts|2|1),(dev_tx_pkts|2|1),(xt_rx_bytes|2|2),(xt_tx_bytes|2|2),(xt_rx_pkts|2|1),(xt_tx_pkts|2|1),(uid_rx_bytes|2|2),(uid_tx_bytes|2|2),(uid_rx_pkts|2|1),(uid_tx_pkts|2|1),(trusted_time|2|3)
-51101 netstats_wifi_sample (dev_rx_bytes|2|2),(dev_tx_bytes|2|2),(dev_rx_pkts|2|1),(dev_tx_pkts|2|1),(xt_rx_bytes|2|2),(xt_tx_bytes|2|2),(xt_rx_pkts|2|1),(xt_tx_pkts|2|1),(uid_rx_bytes|2|2),(uid_tx_bytes|2|2),(uid_rx_pkts|2|1),(uid_tx_pkts|2|1),(trusted_time|2|3)
+51100 netstats_mobile_sample (dev_rx_bytes|2|2),(dev_tx_bytes|2|2),(dev_rx_pkts|2|1),(dev_tx_pkts|2|1),(xt_rx_bytes|2|2),(xt_tx_bytes|2|2),(xt_rx_pkts|2|1),(xt_tx_pkts|2|1),(uid_rx_bytes|2|2),(uid_tx_bytes|2|2),(uid_rx_pkts|2|1),(uid_tx_pkts|2|1),(trusted_time|2|3),(dev_history_start|2|3)
+51101 netstats_wifi_sample (dev_rx_bytes|2|2),(dev_tx_bytes|2|2),(dev_rx_pkts|2|1),(dev_tx_pkts|2|1),(xt_rx_bytes|2|2),(xt_tx_bytes|2|2),(xt_rx_pkts|2|1),(xt_tx_pkts|2|1),(uid_rx_bytes|2|2),(uid_tx_bytes|2|2),(uid_rx_pkts|2|1),(uid_tx_pkts|2|1),(trusted_time|2|3),(dev_history_start|2|3)
diff --git a/services/java/com/android/server/TextServicesManagerService.java b/services/java/com/android/server/TextServicesManagerService.java
index af9152d..d04b440 100644
--- a/services/java/com/android/server/TextServicesManagerService.java
+++ b/services/java/com/android/server/TextServicesManagerService.java
@@ -360,7 +360,7 @@
         }
         final String sciId = info.getId();
         final InternalServiceConnection connection = new InternalServiceConnection(
-                sciId, locale, scListener, bundle);
+                sciId, locale, bundle);
         final Intent serviceIntent = new Intent(SpellCheckerService.SERVICE_INTERFACE);
         serviceIntent.setComponent(info.getComponent());
         if (DBG) {
@@ -704,15 +704,13 @@
     }
 
     private class InternalServiceConnection implements ServiceConnection {
-        private final ISpellCheckerSessionListener mListener;
         private final String mSciId;
         private final String mLocale;
         private final Bundle mBundle;
         public InternalServiceConnection(
-                String id, String locale, ISpellCheckerSessionListener listener, Bundle bundle) {
+                String id, String locale, Bundle bundle) {
             mSciId = id;
             mLocale = locale;
-            mListener = listener;
             mBundle = bundle;
         }
 
diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java
index 280b329..e6392d7 100644
--- a/services/java/com/android/server/UiModeManagerService.java
+++ b/services/java/com/android/server/UiModeManagerService.java
@@ -63,6 +63,10 @@
 
     private static final String KEY_LAST_UPDATE_INTERVAL = "LAST_UPDATE_INTERVAL";
 
+    // Enable launching of applications when entering the dock.
+    private static final boolean ENABLE_LAUNCH_CAR_DOCK_APP = true;
+    private static final boolean ENABLE_LAUNCH_DESK_DOCK_APP = false;
+
     private static final int MSG_UPDATE_TWILIGHT = 0;
     private static final int MSG_ENABLE_LOCATION_UPDATES = 1;
     private static final int MSG_GET_NEW_LOCATION_UPDATE = 2;
@@ -139,14 +143,16 @@
                 if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(intent.getAction())) {
                     // Only launch car home when car mode is enabled and the caller
                     // has asked us to switch to it.
-                    if ((enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
+                    if (ENABLE_LAUNCH_CAR_DOCK_APP
+                            && (enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
                         category = Intent.CATEGORY_CAR_DOCK;
                     }
                 } else if (UiModeManager.ACTION_ENTER_DESK_MODE.equals(intent.getAction())) {
                     // Only launch car home when desk mode is enabled and the caller
                     // has asked us to switch to it.  Currently re-using the car
                     // mode flag since we don't have a formal API for "desk mode".
-                    if ((enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
+                    if (ENABLE_LAUNCH_DESK_DOCK_APP
+                            && (enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
                         category = Intent.CATEGORY_DESK_DOCK;
                     }
                 } else {
@@ -550,11 +556,13 @@
             } else {
                 Intent homeIntent = null;
                 if (mCarModeEnabled) {
-                    if ((enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
+                    if (ENABLE_LAUNCH_CAR_DOCK_APP
+                            && (enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
                         homeIntent = buildHomeIntent(Intent.CATEGORY_CAR_DOCK);
                     }
                 } else if (isDeskDockState(mDockState)) {
-                    if ((enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
+                    if (ENABLE_LAUNCH_DESK_DOCK_APP
+                            && (enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
                         homeIntent = buildHomeIntent(Intent.CATEGORY_DESK_DOCK);
                     }
                 } else {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index c0af2f6..8023477 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1251,11 +1251,11 @@
                         String[] emptyArgs = new String[] { };
                         StringBuilder tag = new StringBuilder(128);
                         synchronized (ActivityManagerService.this) {
-                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false);
+                            dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
                             catPw.println();
-                            dumpServicesLocked(null, catPw, emptyArgs, 0, false, false);
+                            dumpServicesLocked(null, catPw, emptyArgs, 0, false, false, null);
                             catPw.println();
-                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false);
+                            dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
                             catPw.println();
                         }
                         tag.append("Low on memory -- ");
@@ -1681,7 +1681,9 @@
     final void setFocusedActivityLocked(ActivityRecord r) {
         if (mFocusedActivity != r) {
             mFocusedActivity = r;
-            mWindowManager.setFocusedApp(r.appToken, true);
+            if (r != null) {
+                mWindowManager.setFocusedApp(r.appToken, true);
+            }
         }
     }
 
@@ -7907,6 +7909,7 @@
         
         boolean dumpAll = false;
         boolean dumpClient = false;
+        String dumpPackage = null;
         
         int opti = 0;
         while (opti < args.length) {
@@ -7924,13 +7927,14 @@
                 pw.println("  [-a] [-c] [-h] [cmd] ...");
                 pw.println("  cmd may be one of:");
                 pw.println("    a[ctivities]: activity stack state");
-                pw.println("    b[roadcasts]: broadcast state");
-                pw.println("    i[ntents]: pending intent state");
-                pw.println("    p[rocesses]: process state");
+                pw.println("    b[roadcasts] [PACKAGE_NAME]: broadcast state");
+                pw.println("    i[ntents] [PACKAGE_NAME]: pending intent state");
+                pw.println("    p[rocesses] [PACKAGE_NAME]: process state");
                 pw.println("    o[om]: out of memory management");
                 pw.println("    prov[iders] [COMP_SPEC ...]: content provider state");
                 pw.println("    s[ervices] [COMP_SPEC ...]: service state");
                 pw.println("    service [COMP_SPEC]: service client-side state");
+                pw.println("    package [PACKAGE_NAME]: all state related to given package");
                 pw.println("    all: dump all activities");
                 pw.println("    top: dump the top activity");
                 pw.println("  cmd may also be a COMP_SPEC to dump activities.");
@@ -7951,22 +7955,58 @@
             opti++;
             if ("activities".equals(cmd) || "a".equals(cmd)) {
                 synchronized (this) {
-                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient);
+                    dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, null);
                 }
                 return;
             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
+                String[] newArgs;
+                String name;
+                if (opti >= args.length) {
+                    name = null;
+                    newArgs = EMPTY_STRING_ARRAY;
+                } else {
+                    name = args[opti];
+                    opti++;
+                    newArgs = new String[args.length - opti];
+                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
+                            args.length - opti);
+                }
                 synchronized (this) {
-                    dumpBroadcastsLocked(fd, pw, args, opti, true);
+                    dumpBroadcastsLocked(fd, pw, args, opti, true, name);
                 }
                 return;
             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
+                String[] newArgs;
+                String name;
+                if (opti >= args.length) {
+                    name = null;
+                    newArgs = EMPTY_STRING_ARRAY;
+                } else {
+                    name = args[opti];
+                    opti++;
+                    newArgs = new String[args.length - opti];
+                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
+                            args.length - opti);
+                }
                 synchronized (this) {
-                    dumpPendingIntentsLocked(fd, pw, args, opti, true);
+                    dumpPendingIntentsLocked(fd, pw, args, opti, true, name);
                 }
                 return;
             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
+                String[] newArgs;
+                String name;
+                if (opti >= args.length) {
+                    name = null;
+                    newArgs = EMPTY_STRING_ARRAY;
+                } else {
+                    name = args[opti];
+                    opti++;
+                    newArgs = new String[args.length - opti];
+                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
+                            args.length - opti);
+                }
                 synchronized (this) {
-                    dumpProcessesLocked(fd, pw, args, opti, true);
+                    dumpProcessesLocked(fd, pw, args, opti, true, name);
                 }
                 return;
             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
@@ -7976,7 +8016,7 @@
                 return;
             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
                 synchronized (this) {
-                    dumpProvidersLocked(fd, pw, args, opti, true);
+                    dumpProvidersLocked(fd, pw, args, opti, true, null);
                 }
                 return;
             } else if ("service".equals(cmd)) {
@@ -7989,16 +8029,32 @@
                     name = args[opti];
                     opti++;
                     newArgs = new String[args.length - opti];
-                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
+                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
+                            args.length - opti);
                 }
                 if (!dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
                     pw.println("No services match: " + name);
                     pw.println("Use -h for help.");
                 }
                 return;
+            } else if ("package".equals(cmd)) {
+                String[] newArgs;
+                if (opti >= args.length) {
+                    pw.println("package: no package name specified");
+                    pw.println("Use -h for help.");
+                    return;
+                } else {
+                    dumpPackage = args[opti];
+                    opti++;
+                    newArgs = new String[args.length - opti];
+                    if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
+                            args.length - opti);
+                    args = newArgs;
+                    opti = 0;
+                }
             } else if ("services".equals(cmd) || "s".equals(cmd)) {
                 synchronized (this) {
-                    dumpServicesLocked(fd, pw, args, opti, true, dumpClient);
+                    dumpServicesLocked(fd, pw, args, opti, true, dumpClient, null);
                 }
                 return;
             } else {
@@ -8014,76 +8070,78 @@
         // No piece of data specified, dump everything.
         synchronized (this) {
             boolean needSep;
-            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll);
+            needSep = dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
             if (needSep) {
                 pw.println(" ");
             }
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
             }
-            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll);
+            needSep = dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
             if (needSep) {
                 pw.println(" ");
             }
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
             }
-            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll);
+            needSep = dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
             if (needSep) {
                 pw.println(" ");
             }
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
             }
-            needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient);
+            needSep = dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
             if (needSep) {
                 pw.println(" ");
             }
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
             }
-            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient);
+            needSep = dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
             if (needSep) {
                 pw.println(" ");
             }
             if (dumpAll) {
                 pw.println("-------------------------------------------------------------------------------");
             }
-            dumpProcessesLocked(fd, pw, args, opti, dumpAll);
+            dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
         }
     }
     
     boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
-            int opti, boolean dumpAll, boolean dumpClient) {
+            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
         pw.println("  Main stack:");
-        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient);
+        dumpHistoryList(fd, pw, mMainStack.mHistory, "  ", "Hist", true, !dumpAll, dumpClient,
+                dumpPackage);
         pw.println(" ");
         pw.println("  Running activities (most recent first):");
-        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false);
+        dumpHistoryList(fd, pw, mMainStack.mLRUActivities, "  ", "Run", false, !dumpAll, false,
+                dumpPackage);
         if (mMainStack.mWaitingVisibleActivities.size() > 0) {
             pw.println(" ");
             pw.println("  Activities waiting for another to become visible:");
             dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, "  ", "Wait", false,
-                    !dumpAll, false);
+                    !dumpAll, false, dumpPackage);
         }
         if (mMainStack.mStoppingActivities.size() > 0) {
             pw.println(" ");
             pw.println("  Activities waiting to stop:");
             dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, "  ", "Stop", false,
-                    !dumpAll, false);
+                    !dumpAll, false, dumpPackage);
         }
         if (mMainStack.mGoingToSleepActivities.size() > 0) {
             pw.println(" ");
             pw.println("  Activities waiting to sleep:");
             dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, "  ", "Sleep", false,
-                    !dumpAll, false);
+                    !dumpAll, false, dumpPackage);
         }
         if (mMainStack.mFinishingActivities.size() > 0) {
             pw.println(" ");
             pw.println("  Activities waiting to finish:");
             dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, "  ", "Fin", false,
-                    !dumpAll, false);
+                    !dumpAll, false, dumpPackage);
         }
 
         pw.println(" ");
@@ -8106,6 +8164,12 @@
             final int N = mRecentTasks.size();
             for (int i=0; i<N; i++) {
                 TaskRecord tr = mRecentTasks.get(i);
+                if (dumpPackage != null) {
+                    if (tr.realActivity == null ||
+                            !dumpPackage.equals(tr.realActivity)) {
+                        continue;
+                    }
+                }
                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
                         pw.println(tr);
                 if (dumpAll) {
@@ -8123,7 +8187,7 @@
     }
 
     boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
-            int opti, boolean dumpAll) {
+            int opti, boolean dumpAll, String dumpPackage) {
         boolean needSep = false;
         int numPers = 0;
 
@@ -8133,11 +8197,14 @@
             for (SparseArray<ProcessRecord> procs : mProcessNames.getMap().values()) {
                 final int NA = procs.size();
                 for (int ia=0; ia<NA; ia++) {
+                    ProcessRecord r = procs.valueAt(ia);
+                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
+                        continue;
+                    }
                     if (!needSep) {
                         pw.println("  All known processes:");
                         needSep = true;
                     }
-                    ProcessRecord r = procs.valueAt(ia);
                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
                         pw.print(" UID "); pw.print(procs.keyAt(ia));
                         pw.print(" "); pw.println(r);
@@ -8154,31 +8221,49 @@
             needSep = true;
             pw.println("  Process LRU list (sorted by oom_adj):");
             dumpProcessOomList(pw, this, mLruProcesses, "    ",
-                    "Proc", "PERS", false);
+                    "Proc", "PERS", false, dumpPackage);
             needSep = true;
         }
 
         if (dumpAll) {
             synchronized (mPidsSelfLocked) {
-                if (mPidsSelfLocked.size() > 0) {
-                    if (needSep) pw.println(" ");
-                    needSep = true;
-                    pw.println("  PID mappings:");
-                    for (int i=0; i<mPidsSelfLocked.size(); i++) {
-                        pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
-                            pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
+                boolean printed = false;
+                for (int i=0; i<mPidsSelfLocked.size(); i++) {
+                    ProcessRecord r = mPidsSelfLocked.valueAt(i);
+                    if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
+                        continue;
                     }
+                    if (!printed) {
+                        if (needSep) pw.println(" ");
+                        needSep = true;
+                        pw.println("  PID mappings:");
+                        printed = true;
+                    }
+                    pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
+                        pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
                 }
             }
         }
         
         if (mForegroundProcesses.size() > 0) {
-            if (needSep) pw.println(" ");
-            needSep = true;
-            pw.println("  Foreground Processes:");
-            for (int i=0; i<mForegroundProcesses.size(); i++) {
-                pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
-                        pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
+            synchronized (mPidsSelfLocked) {
+                boolean printed = false;
+                for (int i=0; i<mForegroundProcesses.size(); i++) {
+                    ProcessRecord r = mPidsSelfLocked.get( 
+                            mForegroundProcesses.valueAt(i).pid);
+                    if (dumpPackage != null && (r == null
+                            || !dumpPackage.equals(r.info.packageName))) {
+                        continue;
+                    }
+                    if (!printed) {
+                        if (needSep) pw.println(" ");
+                        needSep = true;
+                        pw.println("  Foreground Processes:");
+                        printed = true;
+                    }
+                    pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
+                            pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
+                }
             }
         }
         
@@ -8187,7 +8272,7 @@
             needSep = true;
             pw.println("  Persisent processes that are starting:");
             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
-                    "Starting Norm", "Restarting PERS");
+                    "Starting Norm", "Restarting PERS", dumpPackage);
         }
 
         if (mRemovedProcesses.size() > 0) {
@@ -8195,7 +8280,7 @@
             needSep = true;
             pw.println("  Processes that are being removed:");
             dumpProcessList(pw, this, mRemovedProcesses, "    ",
-                    "Removed Norm", "Removed PERS");
+                    "Removed Norm", "Removed PERS", dumpPackage);
         }
         
         if (mProcessesOnHold.size() > 0) {
@@ -8203,23 +8288,34 @@
             needSep = true;
             pw.println("  Processes that are on old until the system is ready:");
             dumpProcessList(pw, this, mProcessesOnHold, "    ",
-                    "OnHold Norm", "OnHold PERS");
+                    "OnHold Norm", "OnHold PERS", dumpPackage);
         }
 
-        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
+        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
         
         if (mProcessCrashTimes.getMap().size() > 0) {
-            if (needSep) pw.println(" ");
-            needSep = true;
-            pw.println("  Time since processes crashed:");
+            boolean printed = false;
             long now = SystemClock.uptimeMillis();
             for (Map.Entry<String, SparseArray<Long>> procs
                     : mProcessCrashTimes.getMap().entrySet()) {
+                String pname = procs.getKey();
                 SparseArray<Long> uids = procs.getValue();
                 final int N = uids.size();
                 for (int i=0; i<N; i++) {
-                    pw.print("    Process "); pw.print(procs.getKey());
-                            pw.print(" uid "); pw.print(uids.keyAt(i));
+                    int puid = uids.keyAt(i);
+                    ProcessRecord r = mProcessNames.get(pname, puid);
+                    if (dumpPackage != null && (r == null
+                            || !dumpPackage.equals(r.info.packageName))) {
+                        continue;
+                    }
+                    if (!printed) {
+                        if (needSep) pw.println(" ");
+                        needSep = true;
+                        pw.println("  Time since processes crashed:");
+                        printed = true;
+                    }
+                    pw.print("    Process "); pw.print(pname);
+                            pw.print(" uid "); pw.print(puid);
                             pw.print(": last crashed ");
                             pw.print((now-uids.valueAt(i)));
                             pw.println(" ms ago");
@@ -8228,16 +8324,26 @@
         }
 
         if (mBadProcesses.getMap().size() > 0) {
-            if (needSep) pw.println(" ");
-            needSep = true;
-            pw.println("  Bad processes:");
+            boolean printed = false;
             for (Map.Entry<String, SparseArray<Long>> procs
                     : mBadProcesses.getMap().entrySet()) {
+                String pname = procs.getKey();
                 SparseArray<Long> uids = procs.getValue();
                 final int N = uids.size();
                 for (int i=0; i<N; i++) {
-                    pw.print("    Bad process "); pw.print(procs.getKey());
-                            pw.print(" uid "); pw.print(uids.keyAt(i));
+                    int puid = uids.keyAt(i);
+                    ProcessRecord r = mProcessNames.get(pname, puid);
+                    if (dumpPackage != null && (r == null
+                            || !dumpPackage.equals(r.info.packageName))) {
+                        continue;
+                    }
+                    if (!printed) {
+                        if (needSep) pw.println(" ");
+                        needSep = true;
+                        pw.println("  Bad processes:");
+                    }
+                    pw.print("    Bad process "); pw.print(pname);
+                            pw.print(" uid "); pw.print(puid);
                             pw.print(": crashed at time ");
                             pw.println(uids.valueAt(i));
                 }
@@ -8254,11 +8360,18 @@
         if (dumpAll) {
             pw.println("  mConfigWillChange: " + mMainStack.mConfigWillChange);
             if (mCompatModePackages.getPackages().size() > 0) {
-                pw.println("  mScreenCompatPackages:");
+                boolean printed = false;
                 for (Map.Entry<String, Integer> entry
                         : mCompatModePackages.getPackages().entrySet()) {
                     String pkg = entry.getKey();
                     int mode = entry.getValue();
+                    if (dumpPackage != null && !dumpPackage.equals(pkg)) {
+                        continue;
+                    }
+                    if (!printed) {
+                        pw.println("  mScreenCompatPackages:");
+                        printed = true;
+                    }
                     pw.print("    "); pw.print(pkg); pw.print(": ");
                             pw.print(mode); pw.println();
                 }
@@ -8307,14 +8420,21 @@
     }
 
     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
-            int opti, boolean needSep, boolean dumpAll) {
+            int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
         if (mProcessesToGc.size() > 0) {
-            if (needSep) pw.println(" ");
-            needSep = true;
-            pw.println("  Processes that are waiting to GC:");
+            boolean printed = false;
             long now = SystemClock.uptimeMillis();
             for (int i=0; i<mProcessesToGc.size(); i++) {
                 ProcessRecord proc = mProcessesToGc.get(i);
+                if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
+                    continue;
+                }
+                if (!printed) {
+                    if (needSep) pw.println(" ");
+                    needSep = true;
+                    pw.println("  Processes that are waiting to GC:");
+                    printed = true;
+                }
                 pw.print("    Process "); pw.println(proc);
                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
                         pw.print(", last gced=");
@@ -8354,11 +8474,11 @@
             needSep = true;
             pw.println("  Process OOM control:");
             dumpProcessOomList(pw, this, mLruProcesses, "    ",
-                    "Proc", "PERS", true);
+                    "Proc", "PERS", true, null);
             needSep = true;
         }
 
-        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
+        needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
 
         pw.println();
         pw.println("  mHomeProcess: " + mHomeProcess);
@@ -8658,64 +8778,103 @@
     }
 
     boolean dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
-            int opti, boolean dumpAll) {
+            int opti, boolean dumpAll, String dumpPackage) {
         boolean needSep = false;
         
         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
         if (dumpAll) {
             if (mRegisteredReceivers.size() > 0) {
-                pw.println("  Registered Receivers:");
+                boolean printed = false;
                 Iterator it = mRegisteredReceivers.values().iterator();
                 while (it.hasNext()) {
                     ReceiverList r = (ReceiverList)it.next();
+                    if (dumpPackage != null && (r.app == null ||
+                            !dumpPackage.equals(r.app.info.packageName))) {
+                        continue;
+                    }
+                    if (!printed) {
+                        pw.println("  Registered Receivers:");
+                        needSep = true;
+                        printed = true;
+                    }
                     pw.print("  * "); pw.println(r);
                     r.dump(pw, "    ");
                 }
             }
-    
-            pw.println();
-            pw.println("  Receiver Resolver Table:");
-            mReceiverResolver.dump(pw, null, "    ", null, false);
-            needSep = true;
+
+            if (mReceiverResolver.dump(pw, needSep ?
+                    "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
+                    "    ", dumpPackage, false)) {
+                needSep = true;
+            }
         }
         
         if (mParallelBroadcasts.size() > 0 || mOrderedBroadcasts.size() > 0
                 || mPendingBroadcast != null) {
-            if (mParallelBroadcasts.size() > 0) {
-                pw.println();
-                pw.println("  Active broadcasts:");
-            }
+            boolean printed = false;
             for (int i=mParallelBroadcasts.size()-1; i>=0; i--) {
+                BroadcastRecord br = mParallelBroadcasts.get(i);
+                if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
+                    continue;
+                }
+                if (!printed) {
+                    if (needSep) {
+                        pw.println();
+                    }
+                    needSep = true;
+                    pw.println("  Active broadcasts:");
+                }
                 pw.println("  Broadcast #" + i + ":");
-                mParallelBroadcasts.get(i).dump(pw, "    ");
+                br.dump(pw, "    ");
             }
-            if (mOrderedBroadcasts.size() > 0) {
-                pw.println();
-                pw.println("  Active ordered broadcasts:");
-            }
+            printed = false;
             for (int i=mOrderedBroadcasts.size()-1; i>=0; i--) {
-                pw.println("  Serialized Broadcast #" + i + ":");
+                BroadcastRecord br = mOrderedBroadcasts.get(i);
+                if (dumpPackage != null && !dumpPackage.equals(br.callerPackage)) {
+                    continue;
+                }
+                if (!printed) {
+                    if (needSep) {
+                        pw.println();
+                    }
+                    needSep = true;
+                    pw.println("  Active ordered broadcasts:");
+                }
+                pw.println("  Ordered Broadcast #" + i + ":");
                 mOrderedBroadcasts.get(i).dump(pw, "    ");
             }
-            pw.println();
-            pw.println("  Pending broadcast:");
-            if (mPendingBroadcast != null) {
-                mPendingBroadcast.dump(pw, "    ");
-            } else {
-                pw.println("    (null)");
+            if (dumpPackage == null || (mPendingBroadcast != null
+                    && dumpPackage.equals(mPendingBroadcast.callerPackage))) {
+                if (needSep) {
+                    pw.println();
+                }
+                pw.println("  Pending broadcast:");
+                if (mPendingBroadcast != null) {
+                    mPendingBroadcast.dump(pw, "    ");
+                } else {
+                    pw.println("    (null)");
+                }
+                needSep = true;
             }
-            needSep = true;
         }
 
-        if (needSep) {
-            pw.println();
-        }
-        pw.println("  Historical broadcasts:");
+        boolean printed = false;
         for (int i=0; i<MAX_BROADCAST_HISTORY; i++) {
             BroadcastRecord r = mBroadcastHistory[i];
             if (r == null) {
                 break;
             }
+            if (dumpPackage != null && !dumpPackage.equals(r.callerPackage)) {
+                continue;
+            }
+            if (!printed) {
+                if (needSep) {
+                    pw.println();
+                }
+                needSep = true;
+                pw.println("  Historical broadcasts:");
+                printed = true;
+            }
             if (dumpAll) {
                 pw.print("  Historical Broadcast #"); pw.print(i); pw.println(":");
                 r.dump(pw, "    ");
@@ -8729,8 +8888,11 @@
         }
         needSep = true;
         
-        if (mStickyBroadcasts != null) {
-            pw.println();
+        if (mStickyBroadcasts != null && dumpPackage == null) {
+            if (needSep) {
+                pw.println();
+            }
+            needSep = true;
             pw.println("  Sticky broadcasts:");
             StringBuilder sb = new StringBuilder(128);
             for (Map.Entry<String, ArrayList<Intent>> ent
@@ -8770,7 +8932,7 @@
     }
 
     boolean dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
-            int opti, boolean dumpAll, boolean dumpClient) {
+            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
         boolean needSep = false;
 
         ItemMatcher matcher = new ItemMatcher();
@@ -8778,7 +8940,7 @@
 
         pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
         if (mServices.size() > 0) {
-            pw.println("  Active services:");
+            boolean printed = false;
             long nowReal = SystemClock.elapsedRealtime();
             Iterator<ServiceRecord> it = mServices.values().iterator();
             needSep = false;
@@ -8787,6 +8949,13 @@
                 if (!matcher.match(r, r.name)) {
                     continue;
                 }
+                if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
+                    continue;
+                }
+                if (!printed) {
+                    pw.println("  Active services:");
+                    printed = true;
+                }
                 if (needSep) {
                     pw.println();
                 }
@@ -8838,17 +9007,25 @@
                     needSep = true;
                 }
             }
-            needSep = true;
+            needSep = printed;
         }
 
         if (mPendingServices.size() > 0) {
-            if (needSep) pw.println(" ");
-            pw.println("  Pending services:");
+            boolean printed = false;
             for (int i=0; i<mPendingServices.size(); i++) {
                 ServiceRecord r = mPendingServices.get(i);
                 if (!matcher.match(r, r.name)) {
                     continue;
                 }
+                if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
+                    continue;
+                }
+                if (!printed) {
+                    if (needSep) pw.println(" ");
+                    needSep = true;
+                    pw.println("  Pending services:");
+                    printed = true;
+                }
                 pw.print("  * Pending "); pw.println(r);
                 r.dump(pw, "    ");
             }
@@ -8856,13 +9033,21 @@
         }
 
         if (mRestartingServices.size() > 0) {
-            if (needSep) pw.println(" ");
-            pw.println("  Restarting services:");
+            boolean printed = false;
             for (int i=0; i<mRestartingServices.size(); i++) {
                 ServiceRecord r = mRestartingServices.get(i);
                 if (!matcher.match(r, r.name)) {
                     continue;
                 }
+                if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
+                    continue;
+                }
+                if (!printed) {
+                    if (needSep) pw.println(" ");
+                    needSep = true;
+                    pw.println("  Restarting services:");
+                    printed = true;
+                }
                 pw.print("  * Restarting "); pw.println(r);
                 r.dump(pw, "    ");
             }
@@ -8870,13 +9055,21 @@
         }
 
         if (mStoppingServices.size() > 0) {
-            if (needSep) pw.println(" ");
-            pw.println("  Stopping services:");
+            boolean printed = false;
             for (int i=0; i<mStoppingServices.size(); i++) {
                 ServiceRecord r = mStoppingServices.get(i);
                 if (!matcher.match(r, r.name)) {
                     continue;
                 }
+                if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
+                    continue;
+                }
+                if (!printed) {
+                    if (needSep) pw.println(" ");
+                    needSep = true;
+                    pw.println("  Stopping services:");
+                    printed = true;
+                }
                 pw.print("  * Stopping "); pw.println(r);
                 r.dump(pw, "    ");
             }
@@ -8885,8 +9078,7 @@
 
         if (dumpAll) {
             if (mServiceConnections.size() > 0) {
-                if (needSep) pw.println(" ");
-                pw.println("  Connection bindings to services:");
+                boolean printed = false;
                 Iterator<ArrayList<ConnectionRecord>> it
                         = mServiceConnections.values().iterator();
                 while (it.hasNext()) {
@@ -8896,6 +9088,16 @@
                         if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
                             continue;
                         }
+                        if (dumpPackage != null && (cr.binding.client == null
+                                || !dumpPackage.equals(cr.binding.client.info.packageName))) {
+                            continue;
+                        }
+                        if (!printed) {
+                            if (needSep) pw.println(" ");
+                            needSep = true;
+                            pw.println("  Connection bindings to services:");
+                            printed = true;
+                        }
                         pw.print("  * "); pw.println(cr);
                         cr.dump(pw, "    ");
                     }
@@ -8908,7 +9110,7 @@
     }
 
     boolean dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
-            int opti, boolean dumpAll) {
+            int opti, boolean dumpAll, String dumpPackage) {
         boolean needSep = false;
 
         ItemMatcher matcher = new ItemMatcher();
@@ -8916,8 +9118,7 @@
 
         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
         if (mProvidersByClass.size() > 0) {
-            if (needSep) pw.println(" ");
-            pw.println("  Published content providers (by class):");
+            boolean printed = false;
             Iterator<Map.Entry<ComponentName, ContentProviderRecord>> it
                     = mProvidersByClass.entrySet().iterator();
             while (it.hasNext()) {
@@ -8932,6 +9133,15 @@
                 if (!matcher.match(r, comp)) {
                     continue;
                 }
+                if (dumpPackage != null && !dumpPackage.equals(comp.getPackageName())) {
+                    continue;
+                }
+                if (!printed) {
+                    if (needSep) pw.println(" ");
+                    needSep = true;
+                    pw.println("  Published content providers (by class):");
+                    printed = true;
+                }
                 pw.print("  * "); pw.print(cls); pw.print(" (");
                         pw.print(comp.flattenToShortString()); pw.println(")");
                 if (dumpAll) {
@@ -8950,13 +9160,11 @@
                     }
                 }
             }
-            needSep = true;
         }
     
         if (dumpAll) {
             if (mProvidersByName.size() > 0) {
-                pw.println(" ");
-                pw.println("  Authority to provider mappings:");
+                boolean printed = false;
                 Iterator<Map.Entry<String, ContentProviderRecord>> it
                         = mProvidersByName.entrySet().iterator();
                 while (it.hasNext()) {
@@ -8965,25 +9173,42 @@
                     if (!matcher.match(r, r.name)) {
                         continue;
                     }
+                    if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
+                        continue;
+                    }
+                    if (!printed) {
+                        if (needSep) pw.println(" ");
+                        needSep = true;
+                        pw.println("  Authority to provider mappings:");
+                        printed = true;
+                    }
                     pw.print("  "); pw.print(e.getKey()); pw.println(":");
                     pw.print("    "); pw.println(r);
                 }
-                needSep = true;
             }
         }
 
         if (mLaunchingProviders.size() > 0) {
-            if (needSep) pw.println(" ");
-            pw.println("  Launching content providers:");
+            boolean printed = false;
             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
+                ContentProviderRecord r = mLaunchingProviders.get(i);
+                if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
+                    continue;
+                }
+                if (!printed) {
+                    if (needSep) pw.println(" ");
+                    needSep = true;
+                    pw.println("  Launching content providers:");
+                    printed = true;
+                }
                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
-                        pw.println(mLaunchingProviders.get(i));
+                        pw.println(r);
             }
-            needSep = true;
         }
 
         if (mGrantedUriPermissions.size() > 0) {
-            pw.println();
+            if (needSep) pw.println();
+            needSep = true;
             pw.println("Granted Uri Permissions:");
             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
                 int uid = mGrantedUriPermissions.keyAt(i);
@@ -9005,16 +9230,24 @@
     }
 
     boolean dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
-            int opti, boolean dumpAll) {
+            int opti, boolean dumpAll, String dumpPackage) {
         boolean needSep = false;
         
-        if (this.mIntentSenderRecords.size() > 0) {
-            pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
+        if (mIntentSenderRecords.size() > 0) {
+            boolean printed = false;
             Iterator<WeakReference<PendingIntentRecord>> it
                     = mIntentSenderRecords.values().iterator();
             while (it.hasNext()) {
                 WeakReference<PendingIntentRecord> ref = it.next();
                 PendingIntentRecord rec = ref != null ? ref.get(): null;
+                if (dumpPackage != null && (rec == null
+                        || !dumpPackage.equals(rec.key.packageName))) {
+                    continue;
+                }
+                if (!printed) {
+                    pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
+                    printed = true;
+                }
                 needSep = true;
                 if (rec != null) {
                     pw.print("  * "); pw.println(rec);
@@ -9031,13 +9264,17 @@
     }
 
     private static final void dumpHistoryList(FileDescriptor fd, PrintWriter pw, List list,
-            String prefix, String label, boolean complete, boolean brief, boolean client) {
+            String prefix, String label, boolean complete, boolean brief, boolean client,
+            String dumpPackage) {
         TaskRecord lastTask = null;
         boolean needNL = false;
         final String innerPrefix = prefix + "      ";
         final String[] args = new String[0];
         for (int i=list.size()-1; i>=0; i--) {
             final ActivityRecord r = (ActivityRecord)list.get(i);
+            if (dumpPackage != null && !dumpPackage.equals(r.packageName)) {
+                continue;
+            }
             final boolean full = !brief && (complete || !r.isInHistory());
             if (needNL) {
                 pw.println(" ");
@@ -9105,11 +9342,15 @@
     
     private static final int dumpProcessList(PrintWriter pw,
             ActivityManagerService service, List list,
-            String prefix, String normalLabel, String persistentLabel) {
+            String prefix, String normalLabel, String persistentLabel,
+            String dumpPackage) {
         int numPers = 0;
         final int N = list.size()-1;
         for (int i=N; i>=0; i--) {
             ProcessRecord r = (ProcessRecord)list.get(i);
+            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
+                continue;
+            }
             pw.println(String.format("%s%s #%2d: %s",
                     prefix, (r.persistent ? persistentLabel : normalLabel),
                     i, r.toString()));
@@ -9120,17 +9361,25 @@
         return numPers;
     }
 
-    private static final void dumpProcessOomList(PrintWriter pw,
+    private static final boolean dumpProcessOomList(PrintWriter pw,
             ActivityManagerService service, List<ProcessRecord> origList,
             String prefix, String normalLabel, String persistentLabel,
-            boolean inclDetails) {
+            boolean inclDetails, String dumpPackage) {
 
         ArrayList<Pair<ProcessRecord, Integer>> list
                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
         for (int i=0; i<origList.size(); i++) {
+            ProcessRecord r = origList.get(i);
+            if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
+                continue;
+            }
             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
         }
 
+        if (list.size() <= 0) {
+            return false;
+        }
+ 
         Comparator<Pair<ProcessRecord, Integer>> comparator
                 = new Comparator<Pair<ProcessRecord, Integer>>() {
             @Override
@@ -9153,8 +9402,7 @@
         final long curUptime = SystemClock.uptimeMillis();
         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
 
-        final int N = list.size()-1;
-        for (int i=N; i>=0; i--) {
+        for (int i=list.size()-1; i>=0; i--) {
             ProcessRecord r = list.get(i).first;
             String oomAdj;
             if (r.setAdj >= ProcessList.HIDDEN_APP_MIN_ADJ) {
@@ -9206,8 +9454,8 @@
             }
             pw.println(String.format("%s%s #%2d: adj=%s/%s%s trm=%2d %s (%s)",
                     prefix, (r.persistent ? persistentLabel : normalLabel),
-                    N-list.get(i).second, oomAdj, schedGroup, foreground, r.trimMemoryLevel,
-                    r.toShortString(), r.adjType));
+                    (origList.size()-1)-list.get(i).second, oomAdj, schedGroup,
+                    foreground, r.trimMemoryLevel, r.toShortString(), r.adjType));
             if (r.adjSource != null || r.adjTarget != null) {
                 pw.print(prefix);
                 pw.print("    ");
@@ -9279,6 +9527,7 @@
                 }
             }
         }
+        return true;
     }
 
     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, String[] args) {
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index 2a1b1db..8c0f1e0 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -393,6 +393,7 @@
             // on background handler thread, and verified
             // READ_NETWORK_USAGE_HISTORY permission above.
 
+            maybeRefreshTrustedTime();
             synchronized (mRulesLock) {
                 updateNetworkEnabledLocked();
                 updateNotificationsLocked();
@@ -445,7 +446,7 @@
         // cycle boundary to recompute notifications.
 
         // examine stats for each active policy
-        final long currentTime = currentTimeMillis(true);
+        final long currentTime = currentTimeMillis();
         for (NetworkPolicy policy : mNetworkPolicy.values()) {
             // ignore policies that aren't relevant to user
             if (!isTemplateRelevant(policy.template)) continue;
@@ -683,6 +684,8 @@
         public void onReceive(Context context, Intent intent) {
             // on background handler thread, and verified CONNECTIVITY_INTERNAL
             // permission above.
+
+            maybeRefreshTrustedTime();
             synchronized (mRulesLock) {
                 ensureActiveMobilePolicyLocked();
                 updateNetworkEnabledLocked();
@@ -702,7 +705,7 @@
         // TODO: reset any policy-disabled networks when any policy is removed
         // completely, which is currently rare case.
 
-        final long currentTime = currentTimeMillis(true);
+        final long currentTime = currentTimeMillis();
         for (NetworkPolicy policy : mNetworkPolicy.values()) {
             // shortcut when policy has no limit
             if (policy.limitBytes == LIMIT_DISABLED) {
@@ -802,7 +805,7 @@
 
         // apply each policy that we found ifaces for; compute remaining data
         // based on current cycle and historical stats, and push to kernel.
-        final long currentTime = currentTimeMillis(true);
+        final long currentTime = currentTimeMillis();
         for (NetworkPolicy policy : mNetworkRules.keySet()) {
             final String[] ifaces = mNetworkRules.get(policy);
 
@@ -1092,6 +1095,7 @@
     public void setNetworkPolicies(NetworkPolicy[] policies) {
         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
 
+        maybeRefreshTrustedTime();
         synchronized (mRulesLock) {
             mNetworkPolicy.clear();
             for (NetworkPolicy policy : policies) {
@@ -1119,7 +1123,8 @@
     public void snoozePolicy(NetworkTemplate template) {
         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
 
-        final long currentTime = currentTimeMillis(true);
+        maybeRefreshTrustedTime();
+        final long currentTime = currentTimeMillis();
         synchronized (mRulesLock) {
             // find and snooze local policy that matches
             final NetworkPolicy policy = mNetworkPolicy.get(template);
@@ -1140,6 +1145,7 @@
     public void setRestrictBackground(boolean restrictBackground) {
         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
 
+        maybeRefreshTrustedTime();
         synchronized (mRulesLock) {
             mRestrictBackground = restrictBackground;
             updateRulesForRestrictBackgroundLocked();
@@ -1193,7 +1199,7 @@
             return null;
         }
 
-        final long currentTime = currentTimeMillis(false);
+        final long currentTime = currentTimeMillis();
 
         // find total bytes used under policy
         final long start = computeLastCycleBoundary(currentTime, policy);
@@ -1472,6 +1478,7 @@
                 case MSG_LIMIT_REACHED: {
                     final String iface = (String) msg.obj;
 
+                    maybeRefreshTrustedTime();
                     synchronized (mRulesLock) {
                         if (mMeteredIfaces.contains(iface)) {
                             try {
@@ -1551,12 +1558,16 @@
         }
     }
 
-    private long currentTimeMillis(boolean allowRefresh) {
-        // try refreshing time source when stale
-        if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE && allowRefresh) {
+    /**
+     * Try refreshing {@link #mTime} when stale.
+     */
+    private void maybeRefreshTrustedTime() {
+        if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE) {
             mTime.forceRefresh();
         }
+    }
 
+    private long currentTimeMillis() {
         return mTime.hasCache() ? mTime.currentTimeMillis() : System.currentTimeMillis();
     }
 
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index 28cb983..871ed68 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -203,6 +203,8 @@
     /** Set of historical {@code xtables} stats for known UIDs. */
     private HashMap<UidStatsKey, NetworkStatsHistory> mUidStats = Maps.newHashMap();
 
+    /** Flag if {@link #mNetworkDevStats} have been loaded from disk. */
+    private boolean mNetworkStatsLoaded = false;
     /** Flag if {@link #mUidStats} have been loaded from disk. */
     private boolean mUidStatsLoaded = false;
 
@@ -272,6 +274,7 @@
             // until actually needed.
             readNetworkDevStatsLocked();
             readNetworkXtStatsLocked();
+            mNetworkStatsLoaded = true;
         }
 
         // bootstrap initial stats to prevent double-counting later
@@ -322,14 +325,17 @@
 
         mTeleManager.listen(mPhoneListener, LISTEN_NONE);
 
-        writeNetworkDevStatsLocked();
-        writeNetworkXtStatsLocked();
+        if (mNetworkStatsLoaded) {
+            writeNetworkDevStatsLocked();
+            writeNetworkXtStatsLocked();
+        }
         if (mUidStatsLoaded) {
             writeUidStatsLocked();
         }
         mNetworkDevStats.clear();
         mNetworkXtStats.clear();
         mUidStats.clear();
+        mNetworkStatsLoaded = false;
         mUidStatsLoaded = false;
     }
 
@@ -472,6 +478,18 @@
         }
     }
 
+    private long getHistoryStartLocked(
+            NetworkTemplate template, HashMap<NetworkIdentitySet, NetworkStatsHistory> source) {
+        long start = Long.MAX_VALUE;
+        for (NetworkIdentitySet ident : source.keySet()) {
+            if (templateMatches(template, ident)) {
+                final NetworkStatsHistory history = source.get(ident);
+                start = Math.min(start, history.getStart());
+            }
+        }
+        return start;
+    }
+
     @Override
     public NetworkStats getSummaryForAllUid(
             NetworkTemplate template, long start, long end, boolean includeTags) {
@@ -771,6 +789,12 @@
     private void performPoll(int flags) {
         synchronized (mStatsLock) {
             mWakeLock.acquire();
+
+            // try refreshing time source when stale
+            if (mTime.getCacheAge() > mSettings.getTimeCacheMaxAge()) {
+                mTime.forceRefresh();
+            }
+
             try {
                 performPollLocked(flags);
             } finally {
@@ -791,11 +815,6 @@
         final boolean persistUid = (flags & FLAG_PERSIST_UID) != 0;
         final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0;
 
-        // try refreshing time source when stale
-        if (mTime.getCacheAge() > mSettings.getTimeCacheMaxAge()) {
-            mTime.forceRefresh();
-        }
-
         // TODO: consider marking "untrusted" times in historical stats
         final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
                 : System.currentTimeMillis();
@@ -981,6 +1000,7 @@
         final long start = end - largestBucketSize;
 
         final long trustedTime = mTime.hasCache() ? mTime.currentTimeMillis() : -1;
+        long devHistoryStart = Long.MAX_VALUE;
 
         NetworkTemplate template = null;
         NetworkStats.Entry devTotal = null;
@@ -990,24 +1010,27 @@
         // collect mobile sample
         template = buildTemplateMobileAll(getActiveSubscriberId(mContext));
         devTotal = getSummaryForNetworkDev(template, start, end).getTotal(devTotal);
+        devHistoryStart = getHistoryStartLocked(template, mNetworkDevStats);
         xtTotal = getSummaryForNetworkXt(template, start, end).getTotal(xtTotal);
         uidTotal = getSummaryForAllUid(template, start, end, false).getTotal(uidTotal);
+
         EventLogTags.writeNetstatsMobileSample(
                 devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
                 xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
                 uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
-                trustedTime);
+                trustedTime, devHistoryStart);
 
         // collect wifi sample
         template = buildTemplateWifi();
         devTotal = getSummaryForNetworkDev(template, start, end).getTotal(devTotal);
+        devHistoryStart = getHistoryStartLocked(template, mNetworkDevStats);
         xtTotal = getSummaryForNetworkXt(template, start, end).getTotal(xtTotal);
         uidTotal = getSummaryForAllUid(template, start, end, false).getTotal(uidTotal);
         EventLogTags.writeNetstatsWifiSample(
                 devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
                 xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
                 uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
-                trustedTime);
+                trustedTime, devHistoryStart);
     }
 
     /**
@@ -1243,11 +1266,28 @@
 
         // trim any history beyond max
         if (mTime.hasCache()) {
-            final long currentTime = Math.min(
-                    System.currentTimeMillis(), mTime.currentTimeMillis());
+            final long systemCurrentTime = System.currentTimeMillis();
+            final long trustedCurrentTime = mTime.currentTimeMillis();
+
+            final long currentTime = Math.min(systemCurrentTime, trustedCurrentTime);
             final long maxHistory = mSettings.getNetworkMaxHistory();
+
             for (NetworkStatsHistory history : input.values()) {
+                final int beforeSize = history.size();
                 history.removeBucketsBefore(currentTime - maxHistory);
+                final int afterSize = history.size();
+
+                if (beforeSize > 24 && afterSize < beforeSize / 2) {
+                    // yikes, dropping more than half of significant history
+                    final StringBuilder builder = new StringBuilder();
+                    builder.append("yikes, dropping more than half of history").append('\n');
+                    builder.append("systemCurrentTime=").append(systemCurrentTime).append('\n');
+                    builder.append("trustedCurrentTime=").append(trustedCurrentTime).append('\n');
+                    builder.append("maxHistory=").append(maxHistory).append('\n');
+                    builder.append("beforeSize=").append(beforeSize).append('\n');
+                    builder.append("afterSize=").append(afterSize).append('\n');
+                    mDropBox.addText(TAG_NETSTATS_ERROR, builder.toString());
+                }
             }
         }
 
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 0e9f64c..7005541 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -7947,7 +7947,7 @@
 
             if (dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
                 boolean printedSomething = false;
-                for (PackageParser.Provider p : mProviders.values()) {
+                for (PackageParser.Provider p : mProvidersByComponent.values()) {
                     if (packageName != null && !packageName.equals(p.info.packageName)) {
                         continue;
                     }
@@ -7957,8 +7957,23 @@
                         pw.println("Registered ContentProviders:");
                         printedSomething = true;
                     }
-                    pw.print("  ["); pw.print(p.info.authority); pw.print("]: ");
-                            pw.println(p.toString());
+                    pw.print("  "); pw.print(p.getComponentShortName()); pw.println(":");
+                    pw.print("    "); pw.println(p.toString());
+                }
+                printedSomething = false;
+                for (Map.Entry<String, PackageParser.Provider> entry : mProviders.entrySet()) {
+                    PackageParser.Provider p = entry.getValue();
+                    if (packageName != null && !packageName.equals(p.info.packageName)) {
+                        continue;
+                    }
+                    if (!printedSomething) {
+                        if (dumpState.onTitlePrinted())
+                            pw.println(" ");
+                        pw.println("ContentProvider Authorities:");
+                        printedSomething = true;
+                    }
+                    pw.print("  ["); pw.print(entry.getKey()); pw.println("]:");
+                    pw.print("    "); pw.println(p.toString());
                 }
             }
             
diff --git a/services/surfaceflinger/Android.mk b/services/surfaceflinger/Android.mk
index 53502db..61a8358 100644
--- a/services/surfaceflinger/Android.mk
+++ b/services/surfaceflinger/Android.mk
@@ -30,10 +30,6 @@
 	LOCAL_CFLAGS += -DHAS_CONTEXT_PRIORITY -DNEVER_DEFAULT_TO_ASYNC_MODE
 endif
 
-ifneq (,$(findstring $(TARGET_DEVICE),tuna toro maguro))
-	LOCAL_CFLAGS += -DREFRESH_RATE=59
-endif
-
 
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index 0618374..7c61e9a 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -693,12 +693,13 @@
             expectSetInterfaceQuota(TEST_IFACE, Long.MAX_VALUE);
             expectMeteredIfacesChanged(TEST_IFACE);
 
-            expectClearNotifications();
+            future = expectClearNotifications();
             tagFuture = expectEnqueueNotification();
 
             replay();
             mService.snoozePolicy(sTemplateWifi);
             assertNotificationType(TYPE_LIMIT_SNOOZED, tagFuture.get());
+            future.get();
             verifyAndReset();
         }
     }
@@ -734,9 +735,11 @@
         expectLastCall().atLeastOnce();
     }
 
-    private void expectClearNotifications() throws Exception {
+    private Future<Void> expectClearNotifications() throws Exception {
+        final FutureAnswer future = new FutureAnswer();
         mNotifManager.cancelNotificationWithTag(isA(String.class), isA(String.class), anyInt());
-        expectLastCall().anyTimes();
+        expectLastCall().andAnswer(future).anyTimes();
+        return future;
     }
 
     private Future<String> expectEnqueueNotification() throws Exception {
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index f2ccb5b..56a0a2c 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -1575,6 +1575,17 @@
         // If the number passed in is null, just return false:
         if (number == null) return false;
 
+        // If the number passed in is a SIP address, return false, since the
+        // concept of "emergency numbers" is only meaningful for calls placed
+        // over the cell network.
+        // (Be sure to do this check *before* calling extractNetworkPortionAlt(),
+        // since the whole point of extractNetworkPortionAlt() is to filter out
+        // any non-dialable characters (which would turn 'abc911def@example.com'
+        // into '911', for example.))
+        if (isUriNumber(number)) {
+            return false;
+        }
+
         // Strip the separators from the number before comparing it
         // to the list.
         number = extractNetworkPortionAlt(number);
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 8ead45e..db78e2e 100755
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -60,16 +60,16 @@
 
     /** @hide */
     public TelephonyManager(Context context) {
-        context = context.getApplicationContext();
         if (sContext == null) {
-            sContext = context;
+            Context appContext = context.getApplicationContext();
+            if (appContext != null) {
+                sContext = appContext;
+            } else {
+                sContext = context;
+            }
 
             sRegistry = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
                     "telephony.registry"));
-        } else if (sContext != context) {
-            Log.e(TAG, "Hidden constructor called more than once per process!");
-            Log.e(TAG, "Original: " + sContext.getPackageName() + ", new: " +
-                    context.getPackageName());
         }
     }