Merge "Make the corresponding frameworks change to add VoiceRecognitionService to the list of SDK sample apps."
diff --git a/api/current.xml b/api/current.xml
index b62cc9a..08de474 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -20396,7 +20396,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="4"
+ value="3"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -20414,17 +20414,6 @@
  visibility="public"
 >
 </field>
-<field name="USES_POLICY_LIMIT_UNLOCK"
- type="int"
- transient="false"
- volatile="false"
- value="3"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="USES_POLICY_RESET_PASSWORD"
  type="int"
  transient="false"
@@ -20451,7 +20440,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="5"
+ value="4"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -43268,6 +43257,19 @@
 <parameter name="activity" type="android.content.ComponentName">
 </parameter>
 </method>
+<method name="canonicalToCurrentPackageNames"
+ return="java.lang.String[]"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="names" type="java.lang.String[]">
+</parameter>
+</method>
 <method name="checkPermission"
  return="int"
  abstract="true"
@@ -43326,6 +43328,19 @@
 <parameter name="packageName" type="java.lang.String">
 </parameter>
 </method>
+<method name="currentToCanonicalPackageNames"
+ return="java.lang.String[]"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="names" type="java.lang.String[]">
+</parameter>
+</method>
 <method name="getActivityIcon"
  return="android.graphics.drawable.Drawable"
  abstract="true"
@@ -140878,7 +140893,7 @@
  type="android.test.ActivityInstrumentationTestCase2"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <parameter name="pkg" type="java.lang.String">
@@ -140886,6 +140901,16 @@
 <parameter name="activityClass" type="java.lang.Class&lt;T&gt;">
 </parameter>
 </constructor>
+<constructor name="ActivityInstrumentationTestCase2"
+ type="android.test.ActivityInstrumentationTestCase2"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="activityClass" type="java.lang.Class&lt;T&gt;">
+</parameter>
+</constructor>
 <method name="getActivity"
  return="T"
  abstract="false"
@@ -146006,6 +146031,19 @@
 <parameter name="activity" type="android.content.ComponentName">
 </parameter>
 </method>
+<method name="canonicalToCurrentPackageNames"
+ return="java.lang.String[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="names" type="java.lang.String[]">
+</parameter>
+</method>
 <method name="checkPermission"
  return="int"
  abstract="false"
@@ -146064,6 +146102,19 @@
 <parameter name="packageName" type="java.lang.String">
 </parameter>
 </method>
+<method name="currentToCanonicalPackageNames"
+ return="java.lang.String[]"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="names" type="java.lang.String[]">
+</parameter>
+</method>
 <method name="getActivityIcon"
  return="android.graphics.drawable.Drawable"
  abstract="false"
@@ -164685,6 +164736,17 @@
  visibility="public"
 >
 </field>
+<field name="SCROLL_BARRIER"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="VIRTUAL_KEY"
  type="int"
  transient="false"
@@ -173099,6 +173161,25 @@
 <parameter name="heightMeasureSpec" type="int">
 </parameter>
 </method>
+<method name="onOverscrolled"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+<parameter name="scrollX" type="int">
+</parameter>
+<parameter name="scrollY" type="int">
+</parameter>
+<parameter name="clampedX" type="boolean">
+</parameter>
+<parameter name="clampedY" type="boolean">
+</parameter>
+</method>
 <method name="onRestoreInstanceState"
  return="void"
  abstract="false"
@@ -173252,6 +173333,33 @@
 <parameter name="visibility" type="int">
 </parameter>
 </method>
+<method name="overscrollBy"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="protected"
+>
+<parameter name="deltaX" type="int">
+</parameter>
+<parameter name="deltaY" type="int">
+</parameter>
+<parameter name="scrollX" type="int">
+</parameter>
+<parameter name="scrollY" type="int">
+</parameter>
+<parameter name="scrollRangeX" type="int">
+</parameter>
+<parameter name="scrollRangeY" type="int">
+</parameter>
+<parameter name="maxOverscrollX" type="int">
+</parameter>
+<parameter name="maxOverscrollY" type="int">
+</parameter>
+</method>
 <method name="performClick"
  return="boolean"
  abstract="false"
diff --git a/camera/libcameraservice/Android.mk b/camera/libcameraservice/Android.mk
index ecaebff..df5c166 100644
--- a/camera/libcameraservice/Android.mk
+++ b/camera/libcameraservice/Android.mk
@@ -48,7 +48,9 @@
     libutils \
     libbinder \
     libcutils \
-    libmedia
+    libmedia \
+    libcamera_client \
+    libsurfaceflinger_client
 
 LOCAL_MODULE:= libcameraservice
 
diff --git a/camera/libcameraservice/CameraHardwareStub.h b/camera/libcameraservice/CameraHardwareStub.h
index 8a67024..957813a4 100644
--- a/camera/libcameraservice/CameraHardwareStub.h
+++ b/camera/libcameraservice/CameraHardwareStub.h
@@ -20,7 +20,7 @@
 
 #include "FakeCamera.h"
 #include <utils/threads.h>
-#include <ui/CameraHardwareInterface.h>
+#include <camera/CameraHardwareInterface.h>
 #include <binder/MemoryBase.h>
 #include <binder/MemoryHeapBase.h>
 #include <utils/threads.h>
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index 405d471..86a6fac 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -25,7 +25,9 @@
 #include <utils/Errors.h>
 #include <binder/MemoryBase.h>
 #include <binder/MemoryHeapBase.h>
-#include <ui/ICameraService.h>
+#include <camera/ICameraService.h>
+#include <surfaceflinger/ISurface.h>
+#include <ui/Overlay.h>
 
 #include <media/mediaplayer.h>
 #include <media/AudioSystem.h>
diff --git a/camera/libcameraservice/CameraService.h b/camera/libcameraservice/CameraService.h
index b3d20f6..bc49b1d 100644
--- a/camera/libcameraservice/CameraService.h
+++ b/camera/libcameraservice/CameraService.h
@@ -19,9 +19,9 @@
 #ifndef ANDROID_SERVERS_CAMERA_CAMERASERVICE_H
 #define ANDROID_SERVERS_CAMERA_CAMERASERVICE_H
 
-#include <ui/ICameraService.h>
-#include <ui/CameraHardwareInterface.h>
-#include <ui/Camera.h>
+#include <camera/ICameraService.h>
+#include <camera/CameraHardwareInterface.h>
+#include <camera/Camera.h>
 
 namespace android {
 
diff --git a/camera/tests/CameraServiceTest/Android.mk b/camera/tests/CameraServiceTest/Android.mk
index 8da7c1f..9bb190a 100644
--- a/camera/tests/CameraServiceTest/Android.mk
+++ b/camera/tests/CameraServiceTest/Android.mk
@@ -17,6 +17,8 @@
 		libbinder \
                 libcutils \
                 libutils \
-                libui
+                libui \
+                libcamera_client \
+                libsurfaceflinger_client
 
 include $(BUILD_EXECUTABLE)
diff --git a/camera/tests/CameraServiceTest/CameraServiceTest.cpp b/camera/tests/CameraServiceTest/CameraServiceTest.cpp
index f89d9d3..9fc795b 100644
--- a/camera/tests/CameraServiceTest/CameraServiceTest.cpp
+++ b/camera/tests/CameraServiceTest/CameraServiceTest.cpp
@@ -6,13 +6,13 @@
 #include <sys/types.h>
 #include <sys/wait.h>
 #include <unistd.h>
-#include <ui/ISurface.h>
-#include <ui/Camera.h>
-#include <ui/CameraParameters.h>
+#include <surfaceflinger/ISurface.h>
+#include <camera/Camera.h>
+#include <camera/CameraParameters.h>
 #include <ui/GraphicBuffer.h>
-#include <ui/ICamera.h>
-#include <ui/ICameraClient.h>
-#include <ui/ICameraService.h>
+#include <camera/ICamera.h>
+#include <camera/ICameraClient.h>
+#include <camera/ICameraService.h>
 #include <ui/Overlay.h>
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
diff --git a/cmds/bootanimation/Android.mk b/cmds/bootanimation/Android.mk
index 939b63f..2b89759 100644
--- a/cmds/bootanimation/Android.mk
+++ b/cmds/bootanimation/Android.mk
@@ -21,7 +21,8 @@
     libui \
 	libskia \
     libEGL \
-    libGLESv1_CM
+    libGLESv1_CM \
+    libsurfaceflinger_client
 
 LOCAL_C_INCLUDES := \
 	$(call include-path-for, corecg graphics)
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index ce36c4b..ac2eb0d 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -34,11 +34,12 @@
 #include <ui/Rect.h>
 #include <ui/Region.h>
 #include <ui/DisplayInfo.h>
-#include <ui/ISurfaceComposer.h>
-#include <ui/ISurfaceFlingerClient.h>
 #include <ui/FramebufferNativeWindow.h>
 #include <ui/EGLUtils.h>
 
+#include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/ISurfaceFlingerClient.h>
+
 #include <core/SkBitmap.h>
 #include <images/SkImageDecoder.h>
 
diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h
index e53ba8b..8e28bba 100644
--- a/cmds/bootanimation/BootAnimation.h
+++ b/cmds/bootanimation/BootAnimation.h
@@ -23,8 +23,8 @@
 #include <utils/threads.h>
 #include <utils/AssetManager.h>
 
-#include <ui/ISurfaceComposer.h>
-#include <ui/SurfaceComposerClient.h>
+#include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
 
 #include <EGL/egl.h>
 #include <GLES/gl.h>
diff --git a/cmds/bootanimation/bootanimation_main.cpp b/cmds/bootanimation/bootanimation_main.cpp
index 3c82fe5..5f8b744 100644
--- a/cmds/bootanimation/bootanimation_main.cpp
+++ b/cmds/bootanimation/bootanimation_main.cpp
@@ -25,7 +25,7 @@
 #include <utils/Log.h>
 #include <utils/threads.h>
 
-#include <ui/ISurfaceComposer.h>
+#include <surfaceflinger/ISurfaceComposer.h>
 
 #if defined(HAVE_PTHREADS)
 # include <pthread.h>
diff --git a/cmds/runtime/main_runtime.cpp b/cmds/runtime/main_runtime.cpp
index 21e0e4d..83cb533 100644
--- a/cmds/runtime/main_runtime.cpp
+++ b/cmds/runtime/main_runtime.cpp
@@ -19,7 +19,7 @@
 
 #include <private/utils/Static.h>
 
-#include <ui/ISurfaceComposer.h>
+#include <surfaceflinger/ISurfaceComposer.h>
 
 #include <android_runtime/AndroidRuntime.h>
 
diff --git a/common/java/com/android/common/Base64.java b/common/java/com/android/common/Base64.java
index 772d567..d65e24e 100644
--- a/common/java/com/android/common/Base64.java
+++ b/common/java/com/android/common/Base64.java
@@ -51,6 +51,13 @@
      */
     public static final int WEB_SAFE = 8;
 
+    /**
+     * Flag to pass to Base64OutputStream to indicate that it should
+     * not close the output stream it is wrapping when it itself is
+     * closed.
+     */
+    public static final int NO_CLOSE = 16;
+
     //  --------------------------------------------------------
     //  decoding
     //  --------------------------------------------------------
diff --git a/common/java/com/android/common/Base64InputStream.java b/common/java/com/android/common/Base64InputStream.java
new file mode 100644
index 0000000..1969bc4
--- /dev/null
+++ b/common/java/com/android/common/Base64InputStream.java
@@ -0,0 +1,169 @@
+/*
+ * 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 com.android.common;
+
+import java.io.FilterInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * An OutputStream that does either Base64 encoding or decoding on the
+ * data written to it, writing the resulting data to another
+ * OutputStream.
+ */
+public class Base64InputStream extends FilterInputStream {
+    private final boolean encode;
+    private final Base64.EncoderState estate;
+    private final Base64.DecoderState dstate;
+
+    private static byte[] EMPTY = new byte[0];
+
+    private static final int BUFFER_SIZE = 2048;
+    private boolean eof;
+    private byte[] inputBuffer;
+    private byte[] outputBuffer;
+    private int outputStart;
+    private int outputEnd;
+
+    /**
+     * An InputStream that performs Base64 decoding on the data read
+     * from the wrapped stream.
+     *
+     * @param in the InputStream to read the source data from
+     * @param flags bit flags for controlling the decoder; see the
+     *        constants in {@link Base64}
+     */
+    public Base64InputStream(InputStream out, int flags) {
+        this(out, flags, false);
+    }
+
+    /**
+     * Performs Base64 encoding or decoding on the data read from the
+     * wrapped InputStream.
+     *
+     * @param in the InputStream to read the source data from
+     * @param flags bit flags for controlling the decoder; see the
+     *        constants in {@link Base64}
+     * @param encode true to encode, false to decode
+     */
+    public Base64InputStream(InputStream out, int flags, boolean encode) {
+        super(out);
+        this.encode = encode;
+        eof = false;
+        inputBuffer = new byte[BUFFER_SIZE];
+        if (encode) {
+            // len*8/5+10 is an overestimate of the most bytes the
+            // encoder can produce for len bytes of input.
+            outputBuffer = new byte[BUFFER_SIZE * 8/5 + 10];
+            estate = new Base64.EncoderState(flags, outputBuffer);
+            dstate = null;
+        } else {
+            // len*3/4+10 is an overestimate of the most bytes the
+            // decoder can produce for len bytes of input.
+            outputBuffer = new byte[BUFFER_SIZE * 3/4 + 10];
+            estate = null;
+            dstate = new Base64.DecoderState(flags, outputBuffer);
+        }
+        outputStart = 0;
+        outputEnd = 0;
+    }
+
+    public boolean markSupported() {
+        return false;
+    }
+
+    public void mark(int readlimit) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void reset() {
+        throw new UnsupportedOperationException();
+    }
+
+    public void close() throws IOException {
+        in.close();
+        inputBuffer = null;
+    }
+
+    public int available() {
+        return outputEnd - outputStart;
+    }
+
+    public long skip(long n) throws IOException {
+        if (outputStart >= outputEnd) {
+            refill();
+        }
+        if (outputStart >= outputEnd) {
+            return 0;
+        }
+        long bytes = Math.min(n, outputEnd-outputStart);
+        outputStart += bytes;
+        return bytes;
+    }
+
+    public int read() throws IOException {
+        if (outputStart >= outputEnd) {
+            refill();
+        }
+        if (outputStart >= outputEnd) {
+            return -1;
+        } else {
+            return outputBuffer[outputStart++];
+        }
+    }
+
+    public int read(byte[] b, int off, int len) throws IOException {
+        if (outputStart >= outputEnd) {
+            refill();
+        }
+        if (outputStart >= outputEnd) {
+            return -1;
+        }
+        int bytes = Math.min(len, outputEnd-outputStart);
+        System.arraycopy(outputBuffer, outputStart, b, off, bytes);
+        outputStart += bytes;
+        return bytes;
+    }
+
+    /**
+     * Read data from the input stream into inputBuffer, then
+     * decode/encode it into the empty outputBuffer, and reset the
+     * outputStart and outputEnd pointers.
+     */
+    private void refill() throws IOException {
+        if (eof) return;
+        int bytesRead = in.read(inputBuffer);
+        if (encode) {
+            if (bytesRead == -1) {
+                eof = true;
+                Base64.encodeInternal(EMPTY, 0, 0, estate, true);
+            } else {
+                Base64.encodeInternal(inputBuffer, 0, bytesRead, estate, false);
+            }
+            outputEnd = estate.op;
+        } else {
+            if (bytesRead == -1) {
+                eof = true;
+                Base64.decodeInternal(EMPTY, 0, 0, dstate, true);
+            } else {
+                Base64.decodeInternal(inputBuffer, 0, bytesRead, dstate, false);
+            }
+            outputEnd = dstate.op;
+        }
+        outputStart = 0;
+    }
+}
diff --git a/common/java/com/android/common/Base64OutputStream.java b/common/java/com/android/common/Base64OutputStream.java
index 7c37428..76e1b6a 100644
--- a/common/java/com/android/common/Base64OutputStream.java
+++ b/common/java/com/android/common/Base64OutputStream.java
@@ -29,6 +29,7 @@
     private final boolean encode;
     private final Base64.EncoderState estate;
     private final Base64.DecoderState dstate;
+    private final int flags;
 
     private byte[] buffer = null;
     private int bpos = 0;
@@ -59,6 +60,7 @@
      */
     public Base64OutputStream(OutputStream out, int flags, boolean encode) {
         super(out);
+        this.flags = flags;
         this.encode = encode;
         if (encode) {
             estate = new Base64.EncoderState(flags, null);
@@ -106,7 +108,11 @@
     public void close() throws IOException {
         flushBuffer();
         internalWrite(EMPTY, 0, 0, true);
-        out.close();
+        if ((flags & Base64.NO_CLOSE) == 0) {
+            out.close();
+        } else {
+            out.flush();
+        }
     }
 
     /**
diff --git a/common/java/com/android/common/ui/PointerLocationView.java b/common/java/com/android/common/ui/PointerLocationView.java
new file mode 100644
index 0000000..e83c5ae
--- /dev/null
+++ b/common/java/com/android/common/ui/PointerLocationView.java
@@ -0,0 +1,333 @@
+package com.android.common.ui;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Paint.FontMetricsInt;
+import android.util.Log;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
+
+import java.util.ArrayList;
+
+public class PointerLocationView extends View {
+    public static class PointerState {
+        private final ArrayList<Float> mXs = new ArrayList<Float>();
+        private final ArrayList<Float> mYs = new ArrayList<Float>();
+        private boolean mCurDown;
+        private int mCurX;
+        private int mCurY;
+        private float mCurPressure;
+        private float mCurSize;
+        private int mCurWidth;
+        private VelocityTracker mVelocity;
+    }
+
+    private final ViewConfiguration mVC;
+    private final Paint mTextPaint;
+    private final Paint mTextBackgroundPaint;
+    private final Paint mTextLevelPaint;
+    private final Paint mPaint;
+    private final Paint mTargetPaint;
+    private final Paint mPathPaint;
+    private final FontMetricsInt mTextMetrics = new FontMetricsInt();
+    private int mHeaderBottom;
+    private boolean mCurDown;
+    private int mCurNumPointers;
+    private int mMaxNumPointers;
+    private final ArrayList<PointerState> mPointers
+             = new ArrayList<PointerState>();
+    
+    private boolean mPrintCoords = true;
+    
+    public PointerLocationView(Context c) {
+        super(c);
+        mVC = ViewConfiguration.get(c);
+        mTextPaint = new Paint();
+        mTextPaint.setAntiAlias(true);
+        mTextPaint.setTextSize(10
+                * getResources().getDisplayMetrics().density);
+        mTextPaint.setARGB(255, 0, 0, 0);
+        mTextBackgroundPaint = new Paint();
+        mTextBackgroundPaint.setAntiAlias(false);
+        mTextBackgroundPaint.setARGB(128, 255, 255, 255);
+        mTextLevelPaint = new Paint();
+        mTextLevelPaint.setAntiAlias(false);
+        mTextLevelPaint.setARGB(192, 255, 0, 0);
+        mPaint = new Paint();
+        mPaint.setAntiAlias(true);
+        mPaint.setARGB(255, 255, 255, 255);
+        mPaint.setStyle(Paint.Style.STROKE);
+        mPaint.setStrokeWidth(2);
+        mTargetPaint = new Paint();
+        mTargetPaint.setAntiAlias(false);
+        mTargetPaint.setARGB(255, 0, 0, 192);
+        mPathPaint = new Paint();
+        mPathPaint.setAntiAlias(false);
+        mPathPaint.setARGB(255, 0, 96, 255);
+        mPaint.setStyle(Paint.Style.STROKE);
+        mPaint.setStrokeWidth(1);
+        
+        PointerState ps = new PointerState();
+        ps.mVelocity = VelocityTracker.obtain();
+        mPointers.add(ps);
+    }
+
+    public void setPrintCoords(boolean state) {
+        mPrintCoords = state;
+    }
+    
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        mTextPaint.getFontMetricsInt(mTextMetrics);
+        mHeaderBottom = -mTextMetrics.ascent+mTextMetrics.descent+2;
+        if (false) {
+            Log.i("foo", "Metrics: ascent=" + mTextMetrics.ascent
+                    + " descent=" + mTextMetrics.descent
+                    + " leading=" + mTextMetrics.leading
+                    + " top=" + mTextMetrics.top
+                    + " bottom=" + mTextMetrics.bottom);
+        }
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        synchronized (mPointers) {
+            final int w = getWidth();
+            final int itemW = w/7;
+            final int base = -mTextMetrics.ascent+1;
+            final int bottom = mHeaderBottom;
+            
+            final int NP = mPointers.size();
+            
+            if (NP > 0) {
+                final PointerState ps = mPointers.get(0);
+                canvas.drawRect(0, 0, itemW-1, bottom,mTextBackgroundPaint);
+                canvas.drawText("P: " + mCurNumPointers + " / " + mMaxNumPointers,
+                        1, base, mTextPaint);
+                
+                final int N = ps.mXs.size();
+                if ((mCurDown && ps.mCurDown) || N == 0) {
+                    canvas.drawRect(itemW, 0, (itemW * 2) - 1, bottom, mTextBackgroundPaint);
+                    canvas.drawText("X: " + ps.mCurX, 1 + itemW, base, mTextPaint);
+                    canvas.drawRect(itemW * 2, 0, (itemW * 3) - 1, bottom, mTextBackgroundPaint);
+                    canvas.drawText("Y: " + ps.mCurY, 1 + itemW * 2, base, mTextPaint);
+                } else {
+                    float dx = ps.mXs.get(N-1) - ps.mXs.get(0);
+                    float dy = ps.mYs.get(N-1) - ps.mYs.get(0);
+                    canvas.drawRect(itemW, 0, (itemW * 2) - 1, bottom,
+                            Math.abs(dx) < mVC.getScaledTouchSlop()
+                            ? mTextBackgroundPaint : mTextLevelPaint);
+                    canvas.drawText("dX: " + String.format("%.1f", dx), 1 + itemW, base, mTextPaint);
+                    canvas.drawRect(itemW * 2, 0, (itemW * 3) - 1, bottom,
+                            Math.abs(dy) < mVC.getScaledTouchSlop()
+                            ? mTextBackgroundPaint : mTextLevelPaint);
+                    canvas.drawText("dY: " + String.format("%.1f", dy), 1 + itemW * 2, base, mTextPaint);
+                }
+                
+                canvas.drawRect(itemW * 3, 0, (itemW * 4) - 1, bottom, mTextBackgroundPaint);
+                int velocity = ps.mVelocity == null ? 0 : (int) (ps.mVelocity.getXVelocity() * 1000);
+                canvas.drawText("Xv: " + velocity, 1 + itemW * 3, base, mTextPaint);
+                
+                canvas.drawRect(itemW * 4, 0, (itemW * 5) - 1, bottom, mTextBackgroundPaint);
+                velocity = ps.mVelocity == null ? 0 : (int) (ps.mVelocity.getYVelocity() * 1000);
+                canvas.drawText("Yv: " + velocity, 1 + itemW * 4, base, mTextPaint);
+                
+                canvas.drawRect(itemW * 5, 0, (itemW * 6) - 1, bottom, mTextBackgroundPaint);
+                canvas.drawRect(itemW * 5, 0, (itemW * 5) + (ps.mCurPressure * itemW) - 1,
+                        bottom, mTextLevelPaint);
+                canvas.drawText("Prs: " + String.format("%.2f", ps.mCurPressure), 1 + itemW * 5,
+                        base, mTextPaint);
+                
+                canvas.drawRect(itemW * 6, 0, w, bottom, mTextBackgroundPaint);
+                canvas.drawRect(itemW * 6, 0, (itemW * 6) + (ps.mCurSize * itemW) - 1,
+                        bottom, mTextLevelPaint);
+                canvas.drawText("Size: " + String.format("%.2f", ps.mCurSize), 1 + itemW * 6,
+                        base, mTextPaint);
+            }
+            
+            for (int p=0; p<NP; p++) {
+                final PointerState ps = mPointers.get(p);
+                
+                if (mCurDown && ps.mCurDown) {
+                    canvas.drawLine(0, (int)ps.mCurY, getWidth(), (int)ps.mCurY, mTargetPaint);
+                    canvas.drawLine((int)ps.mCurX, 0, (int)ps.mCurX, getHeight(), mTargetPaint);
+                    int pressureLevel = (int)(ps.mCurPressure*255);
+                    mPaint.setARGB(255, pressureLevel, 128, 255-pressureLevel);
+                    canvas.drawPoint(ps.mCurX, ps.mCurY, mPaint);
+                    canvas.drawCircle(ps.mCurX, ps.mCurY, ps.mCurWidth, mPaint);
+                }
+            }
+            
+            for (int p=0; p<NP; p++) {
+                final PointerState ps = mPointers.get(p);
+                
+                final int N = ps.mXs.size();
+                float lastX=0, lastY=0;
+                boolean haveLast = false;
+                boolean drawn = false;
+                mPaint.setARGB(255, 128, 255, 255);
+                for (int i=0; i<N; i++) {
+                    float x = ps.mXs.get(i);
+                    float y = ps.mYs.get(i);
+                    if (Float.isNaN(x)) {
+                        haveLast = false;
+                        continue;
+                    }
+                    if (haveLast) {
+                        canvas.drawLine(lastX, lastY, x, y, mPathPaint);
+                        canvas.drawPoint(lastX, lastY, mPaint);
+                        drawn = true;
+                    }
+                    lastX = x;
+                    lastY = y;
+                    haveLast = true;
+                }
+                
+                if (drawn) {
+                    if (ps.mVelocity != null) {
+                        mPaint.setARGB(255, 255, 64, 128);
+                        float xVel = ps.mVelocity.getXVelocity() * (1000/60);
+                        float yVel = ps.mVelocity.getYVelocity() * (1000/60);
+                        canvas.drawLine(lastX, lastY, lastX+xVel, lastY+yVel, mPaint);
+                    } else {
+                        canvas.drawPoint(lastX, lastY, mPaint);
+                    }
+                }
+            }
+        }
+    }
+
+    public void addTouchEvent(MotionEvent event) {
+        synchronized (mPointers) {
+            int action = event.getAction();
+            
+            //Log.i("Pointer", "Motion: action=0x" + Integer.toHexString(action)
+            //        + " pointers=" + event.getPointerCount());
+            
+            int NP = mPointers.size();
+            
+            //mRect.set(0, 0, getWidth(), mHeaderBottom+1);
+            //invalidate(mRect);
+            //if (mCurDown) {
+            //    mRect.set(mCurX-mCurWidth-3, mCurY-mCurWidth-3,
+            //            mCurX+mCurWidth+3, mCurY+mCurWidth+3);
+            //} else {
+            //    mRect.setEmpty();
+            //}
+            if (action == MotionEvent.ACTION_DOWN) {
+                for (int p=0; p<NP; p++) {
+                    final PointerState ps = mPointers.get(p);
+                    ps.mXs.clear();
+                    ps.mYs.clear();
+                    ps.mVelocity = VelocityTracker.obtain();
+                    ps.mCurDown = false;
+                }
+                mPointers.get(0).mCurDown = true;
+                mMaxNumPointers = 0;
+                if (mPrintCoords) {
+                    Log.i("Pointer", "Pointer 1: DOWN");
+                }
+            }
+            
+            if ((action&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN) {
+                final int id = (action&MotionEvent.ACTION_POINTER_ID_MASK)
+                        >> MotionEvent.ACTION_POINTER_ID_SHIFT;
+                while (NP <= id) {
+                    PointerState ps = new PointerState();
+                    ps.mVelocity = VelocityTracker.obtain();
+                    mPointers.add(ps);
+                    NP++;
+                }
+                final PointerState ps = mPointers.get(id);
+                ps.mVelocity = VelocityTracker.obtain();
+                ps.mCurDown = true;
+                if (mPrintCoords) {
+                    Log.i("Pointer", "Pointer " + (id+1) + ": DOWN");
+                }
+            }
+            
+            final int NI = event.getPointerCount();
+            
+            mCurDown = action != MotionEvent.ACTION_UP
+                    && action != MotionEvent.ACTION_CANCEL;
+            mCurNumPointers = mCurDown ? NI : 0;
+            if (mMaxNumPointers < mCurNumPointers) {
+                mMaxNumPointers = mCurNumPointers;
+            }
+            
+            for (int i=0; i<NI; i++) {
+                final PointerState ps = mPointers.get(event.getPointerId(i));
+                ps.mVelocity.addMovement(event);
+                ps.mVelocity.computeCurrentVelocity(1);
+                final int N = event.getHistorySize();
+                for (int j=0; j<N; j++) {
+                    if (mPrintCoords) {
+                        Log.i("Pointer", "Pointer " + (i+1) + ": ("
+                                + event.getHistoricalX(i, j)
+                                + ", " + event.getHistoricalY(i, j) + ")"
+                                + " Prs=" + event.getHistoricalPressure(i, j)
+                                + " Size=" + event.getHistoricalSize(i, j));
+                    }
+                    ps.mXs.add(event.getHistoricalX(i, j));
+                    ps.mYs.add(event.getHistoricalY(i, j));
+                }
+                if (mPrintCoords) {
+                    Log.i("Pointer", "Pointer " + (i+1) + ": ("
+                            + event.getX(i) + ", " + event.getY(i) + ")"
+                            + " Prs=" + event.getPressure(i)
+                            + " Size=" + event.getSize(i));
+                }
+                ps.mXs.add(event.getX(i));
+                ps.mYs.add(event.getY(i));
+                ps.mCurX = (int)event.getX(i);
+                ps.mCurY = (int)event.getY(i);
+                //Log.i("Pointer", "Pointer #" + p + ": (" + ps.mCurX
+                //        + "," + ps.mCurY + ")");
+                ps.mCurPressure = event.getPressure(i);
+                ps.mCurSize = event.getSize(i);
+                ps.mCurWidth = (int)(ps.mCurSize*(getWidth()/3));
+            }
+            
+            if ((action&MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_UP) {
+                final int id = (action&MotionEvent.ACTION_POINTER_ID_MASK)
+                        >> MotionEvent.ACTION_POINTER_ID_SHIFT;
+                final PointerState ps = mPointers.get(id);
+                ps.mXs.add(Float.NaN);
+                ps.mYs.add(Float.NaN);
+                ps.mCurDown = false;
+                if (mPrintCoords) {
+                    Log.i("Pointer", "Pointer " + (id+1) + ": UP");
+                }
+            }
+            
+            if (action == MotionEvent.ACTION_UP) {
+                for (int i=0; i<NI; i++) {
+                    final PointerState ps = mPointers.get(event.getPointerId(i));
+                    if (ps.mCurDown) {
+                        ps.mCurDown = false;
+                        if (mPrintCoords) {
+                            Log.i("Pointer", "Pointer " + (i+1) + ": UP");
+                        }
+                    }
+                }
+            }
+            
+            //if (mCurDown) {
+            //    mRect.union(mCurX-mCurWidth-3, mCurY-mCurWidth-3,
+            //            mCurX+mCurWidth+3, mCurY+mCurWidth+3);
+            //}
+            //invalidate(mRect);
+            postInvalidate();
+        }
+    }
+    
+    @Override
+    public boolean onTouchEvent(MotionEvent event) {
+        addTouchEvent(event);
+        return true;
+    }
+}
diff --git a/common/tests/src/com/android/common/Base64Test.java b/common/tests/src/com/android/common/Base64Test.java
index e6b491f..1064625f2 100644
--- a/common/tests/src/com/android/common/Base64Test.java
+++ b/common/tests/src/com/android/common/Base64Test.java
@@ -18,6 +18,7 @@
 
 import junit.framework.TestCase;
 
+import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.util.Random;
 
@@ -228,8 +229,13 @@
     /**
      * Tests that Base64.encodeInternal does correct handling of the
      * tail for each call.
+     *
+     * This test is disabled because while it passes if you can get it
+     * to run, android's test infrastructure currently doesn't allow
+     * us to get at package-private members (Base64.EncoderState in
+     * this case).
      */
-    public void testEncodeInternal() throws Exception {
+    public void XXXtestEncodeInternal() throws Exception {
         byte[] input = { (byte) 0x61, (byte) 0x62, (byte) 0x63 };
         byte[] output = new byte[100];
 
@@ -272,6 +278,132 @@
         assertEquals("YQ".getBytes(), 2, state.output, state.op);
     }
 
+    private static final String lipsum =
+            "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " +
+            "Quisque congue eleifend odio, eu ornare nulla facilisis eget. " +
+            "Integer eget elit diam, sit amet laoreet nibh. Quisque enim " +
+            "urna, pharetra vitae consequat eget, adipiscing eu ante. " +
+            "Aliquam venenatis arcu nec nibh imperdiet tempor. In id dui " +
+            "eget lorem aliquam rutrum vel vitae eros. In placerat ornare " +
+            "pretium. Curabitur non fringilla mi. Fusce ultricies, turpis " +
+            "eu ultrices suscipit, ligula nisi consectetur eros, dapibus " +
+            "aliquet dui sapien a turpis. Donec ultricies varius ligula, " +
+            "ut hendrerit arcu malesuada at. Praesent sed elit pretium " +
+            "eros luctus gravida. In ac dolor lorem. Cras condimentum " +
+            "convallis elementum. Phasellus vel felis in nulla ultrices " +
+            "venenatis. Nam non tortor non orci convallis convallis. " +
+            "Nam tristique lacinia hendrerit. Pellentesque habitant morbi " +
+            "tristique senectus et netus et malesuada fames ac turpis " +
+            "egestas. Vivamus cursus, nibh eu imperdiet porta, magna " +
+            "ipsum mollis mauris, sit amet fringilla mi nisl eu mi. " +
+            "Phasellus posuere, leo at ultricies vehicula, massa risus " +
+            "volutpat sapien, eu tincidunt diam ipsum eget nulla. Cras " +
+            "molestie dapibus commodo. Ut vel tellus at massa gravida " +
+            "semper non sed orci.";
+
+    public void testInputStream() throws Exception {
+        int[] flagses = { Base64.DEFAULT,
+                          Base64.NO_PADDING,
+                          Base64.NO_WRAP,
+                          Base64.NO_PADDING | Base64.NO_WRAP,
+                          Base64.CRLF,
+                          Base64.WEB_SAFE };
+        int[] writeLengths = { -10, -5, -1, 0, 1, 1, 2, 2, 3, 10, 100 };
+        Random rng = new Random(32176L);
+
+        // Test input needs to be at least 2048 bytes to fill up the
+        // read buffer of Base64InputStream.
+        byte[] plain = (lipsum + lipsum + lipsum + lipsum + lipsum).getBytes();
+
+        for (int flags: flagses) {
+            byte[] encoded = Base64.encode(plain, flags);
+
+            ByteArrayInputStream bais;
+            Base64InputStream b64is;
+            byte[] actual = new byte[plain.length * 2];
+            int ap;
+            int b;
+
+            // ----- test decoding ("encoded" -> "plain") -----
+
+            // read as much as it will give us in one chunk
+            bais = new ByteArrayInputStream(encoded);
+            b64is = new Base64InputStream(bais, flags);
+            ap = 0;
+            while ((b = b64is.read(actual, ap, actual.length-ap)) != -1) {
+                ap += b;
+            }
+            assertEquals(actual, ap, plain);
+
+            // read individual bytes
+            bais = new ByteArrayInputStream(encoded);
+            b64is = new Base64InputStream(bais, flags);
+            ap = 0;
+            while ((b = b64is.read()) != -1) {
+                actual[ap++] = (byte) b;
+            }
+            assertEquals(actual, ap, plain);
+
+            // mix reads of variously-sized arrays with one-byte reads
+            bais = new ByteArrayInputStream(encoded);
+            b64is = new Base64InputStream(bais, flags);
+            ap = 0;
+            readloop: while (true) {
+                int l = writeLengths[rng.nextInt(writeLengths.length)];
+                if (l >= 0) {
+                    b = b64is.read(actual, ap, l);
+                    if (b == -1) break readloop;
+                    ap += b;
+                } else {
+                    for (int i = 0; i < -l; ++i) {
+                        if ((b = b64is.read()) == -1) break readloop;
+                        actual[ap++] = (byte) b;
+                    }
+                }
+            }
+            assertEquals(actual, ap, plain);
+
+            // ----- test encoding ("plain" -> "encoded") -----
+
+            // read as much as it will give us in one chunk
+            bais = new ByteArrayInputStream(plain);
+            b64is = new Base64InputStream(bais, flags, true);
+            ap = 0;
+            while ((b = b64is.read(actual, ap, actual.length-ap)) != -1) {
+                ap += b;
+            }
+            assertEquals(actual, ap, encoded);
+
+            // read individual bytes
+            bais = new ByteArrayInputStream(plain);
+            b64is = new Base64InputStream(bais, flags, true);
+            ap = 0;
+            while ((b = b64is.read()) != -1) {
+                actual[ap++] = (byte) b;
+            }
+            assertEquals(actual, ap, encoded);
+
+            // mix reads of variously-sized arrays with one-byte reads
+            bais = new ByteArrayInputStream(plain);
+            b64is = new Base64InputStream(bais, flags, true);
+            ap = 0;
+            readloop: while (true) {
+                int l = writeLengths[rng.nextInt(writeLengths.length)];
+                if (l >= 0) {
+                    b = b64is.read(actual, ap, l);
+                    if (b == -1) break readloop;
+                    ap += b;
+                } else {
+                    for (int i = 0; i < -l; ++i) {
+                        if ((b = b64is.read()) == -1) break readloop;
+                        actual[ap++] = (byte) b;
+                    }
+                }
+            }
+            assertEquals(actual, ap, encoded);
+        }
+    }
+
     /**
      * Tests that Base64OutputStream produces exactly the same results
      * as calling Base64.encode/.decode on an in-memory array.
@@ -286,125 +418,103 @@
         int[] writeLengths = { -10, -5, -1, 0, 1, 1, 2, 2, 3, 10, 100 };
         Random rng = new Random(32176L);
 
-        // input needs to be at least 1024 bytes to test filling up
-        // the write(int) buffer.
-        byte[] input = ("Lorem ipsum dolor sit amet, consectetur adipiscing elit. " +
-                        "Quisque congue eleifend odio, eu ornare nulla facilisis eget. " +
-                        "Integer eget elit diam, sit amet laoreet nibh. Quisque enim " +
-                        "urna, pharetra vitae consequat eget, adipiscing eu ante. " +
-                        "Aliquam venenatis arcu nec nibh imperdiet tempor. In id dui " +
-                        "eget lorem aliquam rutrum vel vitae eros. In placerat ornare " +
-                        "pretium. Curabitur non fringilla mi. Fusce ultricies, turpis " +
-                        "eu ultrices suscipit, ligula nisi consectetur eros, dapibus " +
-                        "aliquet dui sapien a turpis. Donec ultricies varius ligula, " +
-                        "ut hendrerit arcu malesuada at. Praesent sed elit pretium " +
-                        "eros luctus gravida. In ac dolor lorem. Cras condimentum " +
-                        "convallis elementum. Phasellus vel felis in nulla ultrices " +
-                        "venenatis. Nam non tortor non orci convallis convallis. " +
-                        "Nam tristique lacinia hendrerit. Pellentesque habitant morbi " +
-                        "tristique senectus et netus et malesuada fames ac turpis " +
-                        "egestas. Vivamus cursus, nibh eu imperdiet porta, magna " +
-                        "ipsum mollis mauris, sit amet fringilla mi nisl eu mi. " +
-                        "Phasellus posuere, leo at ultricies vehicula, massa risus " +
-                        "volutpat sapien, eu tincidunt diam ipsum eget nulla. Cras " +
-                        "molestie dapibus commodo. Ut vel tellus at massa gravida " +
-                        "semper non sed orci.").getBytes();
+        // Test input needs to be at least 1024 bytes to test filling
+        // up the write(int) buffer of Base64OutputStream.
+        byte[] plain = (lipsum + lipsum).getBytes();
 
-        for (int f = 0; f < flagses.length; ++f) {
-            int flags = flagses[f];
-
-            byte[] expected = Base64.encode(input, flags);
+        for (int flags: flagses) {
+            byte[] encoded = Base64.encode(plain, flags);
 
             ByteArrayOutputStream baos;
             Base64OutputStream b64os;
             byte[] actual;
             int p;
 
-            // ----- test encoding ("input" -> "expected") -----
+            // ----- test encoding ("plain" -> "encoded") -----
 
             // one large write(byte[]) of the whole input
             baos = new ByteArrayOutputStream();
             b64os = new Base64OutputStream(baos, flags);
-            b64os.write(input);
+            b64os.write(plain);
             b64os.close();
             actual = baos.toByteArray();
-            assertEquals(expected, actual);
+            assertEquals(encoded, actual);
 
             // many calls to write(int)
             baos = new ByteArrayOutputStream();
             b64os = new Base64OutputStream(baos, flags);
-            for (int i = 0; i < input.length; ++i) {
-                b64os.write(input[i]);
+            for (int i = 0; i < plain.length; ++i) {
+                b64os.write(plain[i]);
             }
             b64os.close();
             actual = baos.toByteArray();
-            assertEquals(expected, actual);
+            assertEquals(encoded, actual);
 
             // intermixed sequences of write(int) with
             // write(byte[],int,int) of various lengths.
             baos = new ByteArrayOutputStream();
             b64os = new Base64OutputStream(baos, flags);
             p = 0;
-            while (p < input.length) {
+            while (p < plain.length) {
                 int l = writeLengths[rng.nextInt(writeLengths.length)];
-                l = Math.min(l, input.length-p);
+                l = Math.min(l, plain.length-p);
                 if (l >= 0) {
-                    b64os.write(input, p, l);
+                    b64os.write(plain, p, l);
                     p += l;
                 } else {
-                    l = Math.min(-l, input.length-p);
+                    l = Math.min(-l, plain.length-p);
                     for (int i = 0; i < l; ++i) {
-                        b64os.write(input[p+i]);
+                        b64os.write(plain[p+i]);
                     }
                     p += l;
                 }
             }
             b64os.close();
             actual = baos.toByteArray();
-            assertEquals(expected, actual);
+            assertEquals(encoded, actual);
 
-            // ----- test decoding ("expected" -> "input") -----
+            // ----- test decoding ("encoded" -> "plain") -----
 
             // one large write(byte[]) of the whole input
             baos = new ByteArrayOutputStream();
             b64os = new Base64OutputStream(baos, flags, false);
-            b64os.write(expected);
+            b64os.write(encoded);
             b64os.close();
             actual = baos.toByteArray();
-            assertEquals(input, actual);
+            assertEquals(plain, actual);
 
             // many calls to write(int)
             baos = new ByteArrayOutputStream();
             b64os = new Base64OutputStream(baos, flags, false);
-            for (int i = 0; i < expected.length; ++i) {
-                b64os.write(expected[i]);
+            for (int i = 0; i < encoded.length; ++i) {
+                b64os.write(encoded[i]);
             }
             b64os.close();
             actual = baos.toByteArray();
-            assertEquals(input, actual);
+            assertEquals(plain, actual);
 
             // intermixed sequences of write(int) with
             // write(byte[],int,int) of various lengths.
             baos = new ByteArrayOutputStream();
             b64os = new Base64OutputStream(baos, flags, false);
             p = 0;
-            while (p < expected.length) {
+            while (p < encoded.length) {
                 int l = writeLengths[rng.nextInt(writeLengths.length)];
-                l = Math.min(l, expected.length-p);
+                l = Math.min(l, encoded.length-p);
                 if (l >= 0) {
-                    b64os.write(expected, p, l);
+                    b64os.write(encoded, p, l);
                     p += l;
                 } else {
-                    l = Math.min(-l, expected.length-p);
+                    l = Math.min(-l, encoded.length-p);
                     for (int i = 0; i < l; ++i) {
-                        b64os.write(expected[p+i]);
+                        b64os.write(encoded[p+i]);
                     }
                     p += l;
                 }
             }
             b64os.close();
             actual = baos.toByteArray();
-            assertEquals(input, actual);
+            assertEquals(plain, actual);
         }
     }
 }
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 0a18fe5..b4fe698 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1615,6 +1615,24 @@
         }
 
         @Override
+        public String[] currentToCanonicalPackageNames(String[] names) {
+            try {
+                return mPM.currentToCanonicalPackageNames(names);
+            } catch (RemoteException e) {
+                throw new RuntimeException("Package manager has died", e);
+            }
+        }
+        
+        @Override
+        public String[] canonicalToCurrentPackageNames(String[] names) {
+            try {
+                return mPM.canonicalToCurrentPackageNames(names);
+            } catch (RemoteException e) {
+                throw new RuntimeException("Package manager has died", e);
+            }
+        }
+        
+        @Override
         public Intent getLaunchIntentForPackage(String packageName) {
             // First see if the package has an INFO activity; the existence of
             // such an activity is implied to be the desired front-door for the
diff --git a/core/java/android/app/DeviceAdminInfo.java b/core/java/android/app/DeviceAdminInfo.java
index ab9c44f..159fa75 100644
--- a/core/java/android/app/DeviceAdminInfo.java
+++ b/core/java/android/app/DeviceAdminInfo.java
@@ -80,23 +80,15 @@
     public static final int USES_POLICY_RESET_PASSWORD = 2;
 
     /**
-     * A type of policy that this device admin can use: able to limit the
+     * A type of policy that this device admin can use: able to force the device
+     * to lock via{@link DevicePolicyManager#lockNow} or limit the
      * maximum lock timeout for the device via
      * {@link DevicePolicyManager#setMaximumTimeToLock}.
      * 
-     * <p>To control this policy, the device admin must have a "limit-unlock"
-     * tag in the "uses-policies" section of its meta-data.
-     */
-    public static final int USES_POLICY_LIMIT_UNLOCK = 3;
-
-    /**
-     * A type of policy that this device admin can use: able to force the device
-     * to lock via{@link DevicePolicyManager#lockNow}.
-     * 
      * <p>To control this policy, the device admin must have a "force-lock"
      * tag in the "uses-policies" section of its meta-data.
      */
-    public static final int USES_POLICY_FORCE_LOCK = 4;
+    public static final int USES_POLICY_FORCE_LOCK = 3;
 
     /**
      * A type of policy that this device admin can use: able to factory
@@ -106,7 +98,7 @@
      * <p>To control this policy, the device admin must have a "wipe-data"
      * tag in the "uses-policies" section of its meta-data.
      */
-    public static final int USES_POLICY_WIPE_DATA = 5;
+    public static final int USES_POLICY_WIPE_DATA = 4;
 
     /** @hide */
     public static class PolicyInfo {
@@ -140,9 +132,6 @@
         sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_WATCH_LOGIN, "watch-login",
                 com.android.internal.R.string.policylab_watchLogin,
                 com.android.internal.R.string.policydesc_watchLogin));
-        sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_LIMIT_UNLOCK, "limit-unlock",
-                com.android.internal.R.string.policylab_limitUnlock,
-                com.android.internal.R.string.policydesc_limitUnlock));
         sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_FORCE_LOCK, "force-lock",
                 com.android.internal.R.string.policylab_forceLock,
                 com.android.internal.R.string.policydesc_forceLock));
@@ -314,8 +303,8 @@
      * Return true if the device admin has requested that it be able to use
      * the given policy control.  The possible policy identifier inputs are:
      * {@link #USES_POLICY_LIMIT_PASSWORD}, {@link #USES_POLICY_WATCH_LOGIN},
-     * {@link #USES_POLICY_RESET_PASSWORD}, {@link #USES_POLICY_LIMIT_UNLOCK},
-     * {@link #USES_POLICY_FORCE_LOCK}, {@link #USES_POLICY_WIPE_DATA}.
+     * {@link #USES_POLICY_RESET_PASSWORD}, {@link #USES_POLICY_FORCE_LOCK},
+     * {@link #USES_POLICY_WIPE_DATA}.
      */
     public boolean usesPolicy(int policyIdent) {
         return (mUsesPolicies & (1<<policyIdent)) != 0;
diff --git a/core/java/android/app/DevicePolicyManager.java b/core/java/android/app/DevicePolicyManager.java
index 847e879..82c43dc 100644
--- a/core/java/android/app/DevicePolicyManager.java
+++ b/core/java/android/app/DevicePolicyManager.java
@@ -410,7 +410,7 @@
      * the length that the user can set.  It takes effect immediately.
      * 
      * <p>The calling device admin must have requested
-     * {@link DeviceAdminInfo#USES_POLICY_LIMIT_UNLOCK} to be able to call
+     * {@link DeviceAdminInfo#USES_POLICY_FORCE_LOCK} to be able to call
      * this method; if it has not, a security exception will be thrown.
      * 
      * @param admin Which {@link DeviceAdmin} this request is associated with.
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index bdbe341..45f361e 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -31,6 +31,7 @@
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
 import android.os.ServiceManager;
+import android.os.SystemClock;
 import android.text.TextUtils;
 import android.util.Config;
 import android.util.EventLog;
@@ -243,13 +244,13 @@
             return null;
         }
         try {
-            long startTime = System.currentTimeMillis();
+            long startTime = SystemClock.uptimeMillis();
             Cursor qCursor = provider.query(uri, projection, selection, selectionArgs, sortOrder);
             if (qCursor == null) {
                 releaseProvider(provider);
                 return null;
             }
-            long durationMillis = System.currentTimeMillis() - startTime;
+            long durationMillis = SystemClock.uptimeMillis() - startTime;
             maybeLogQueryToEventLog(durationMillis, uri, projection, selection, sortOrder);
             // Wrap the cursor object into CursorWrapperInner object
             return new CursorWrapperInner(qCursor, provider);
@@ -583,9 +584,9 @@
             throw new IllegalArgumentException("Unknown URL " + url);
         }
         try {
-            long startTime = System.currentTimeMillis();
+            long startTime = SystemClock.uptimeMillis();
             Uri createdRow = provider.insert(url, values);
-            long durationMillis = System.currentTimeMillis() - startTime;
+            long durationMillis = SystemClock.uptimeMillis() - startTime;
             maybeLogUpdateToEventLog(durationMillis, url, "insert", null /* where */);
             return createdRow;
         } catch (RemoteException e) {
@@ -642,9 +643,9 @@
             throw new IllegalArgumentException("Unknown URL " + url);
         }
         try {
-            long startTime = System.currentTimeMillis();
+            long startTime = SystemClock.uptimeMillis();
             int rowsCreated = provider.bulkInsert(url, values);
-            long durationMillis = System.currentTimeMillis() - startTime;
+            long durationMillis = SystemClock.uptimeMillis() - startTime;
             maybeLogUpdateToEventLog(durationMillis, url, "bulkinsert", null /* where */);
             return rowsCreated;
         } catch (RemoteException e) {
@@ -671,9 +672,9 @@
             throw new IllegalArgumentException("Unknown URL " + url);
         }
         try {
-            long startTime = System.currentTimeMillis();
+            long startTime = SystemClock.uptimeMillis();
             int rowsDeleted = provider.delete(url, where, selectionArgs);
-            long durationMillis = System.currentTimeMillis() - startTime;
+            long durationMillis = SystemClock.uptimeMillis() - startTime;
             maybeLogUpdateToEventLog(durationMillis, url, "delete", where);
             return rowsDeleted;
         } catch (RemoteException e) {
@@ -703,9 +704,9 @@
             throw new IllegalArgumentException("Unknown URI " + uri);
         }
         try {
-            long startTime = System.currentTimeMillis();
+            long startTime = SystemClock.uptimeMillis();
             int rowsUpdated = provider.update(uri, values, where, selectionArgs);
-            long durationMillis = System.currentTimeMillis() - startTime;
+            long durationMillis = SystemClock.uptimeMillis() - startTime;
             maybeLogUpdateToEventLog(durationMillis, uri, "update", where);
             return rowsUpdated;
         } catch (RemoteException e) {
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 2c8c112..47789a5 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -47,6 +47,9 @@
     PackageInfo getPackageInfo(String packageName, int flags);
     int getPackageUid(String packageName);
     int[] getPackageGids(String packageName);
+    
+    String[] currentToCanonicalPackageNames(in String[] names);
+    String[] canonicalToCurrentPackageNames(in String[] names);
 
     PermissionInfo getPermissionInfo(String name, int flags);
     
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index a61eab9..17bee48 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -691,6 +691,23 @@
             throws NameNotFoundException;
 
     /**
+     * Map from the current package names in use on the device to whatever
+     * the current canonical name of that package is.
+     * @param names Array of current names to be mapped.
+     * @return Returns an array of the same size as the original, containing
+     * the canonical name for each package.
+     */
+    public abstract String[] currentToCanonicalPackageNames(String[] names);
+    
+    /**
+     * Map from a packages canonical name to the current name in use on the device.
+     * @param names Array of new names to be mapped.
+     * @return Returns an array of the same size as the original, containing
+     * the current name for each package.
+     */
+    public abstract String[] canonicalToCurrentPackageNames(String[] names);
+    
+    /**
      * Return a "good" intent to launch a front-door activity in a package,
      * for use for example to implement an "open" button when browsing through
      * packages.  The current implementation will look first for a main
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index 5d1e7cf..a7e6ca0 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -202,7 +202,7 @@
     private long mLastLockMessageTime = 0L;
 
     // always log queries which take 100ms+; shorter queries are sampled accordingly
-    private static final int QUERY_LOG_TIME_IN_NANOS = 100 * 1000000;
+    private static final int QUERY_LOG_TIME_IN_MILLIS = 100;
     private static final int QUERY_LOG_SQL_LENGTH = 64;
     private final Random mRandom = new Random();
 
@@ -1650,7 +1650,7 @@
      * @throws SQLException If the SQL string is invalid for some reason
      */
     public void execSQL(String sql) throws SQLException {
-        long timeStart = Debug.threadCpuTimeNanos();
+        long timeStart = SystemClock.uptimeMillis();
         lock();
         try {
             native_execSQL(sql);
@@ -1676,7 +1676,7 @@
         if (bindArgs == null) {
             throw new IllegalArgumentException("Empty bindArgs");
         }
-        long timeStart = Debug.threadCpuTimeNanos();
+        long timeStart = SystemClock.uptimeMillis();
         lock();
         SQLiteStatement statement = null;
         try {
@@ -1785,17 +1785,17 @@
 
 
 
-    /* package */ void logTimeStat(String sql, long beginNanos) {
+    /* package */ void logTimeStat(String sql, long beginMillis) {
         // Sample fast queries in proportion to the time taken.
         // Quantize the % first, so the logged sampling probability
         // exactly equals the actual sampling rate for this query.
 
         int samplePercent;
-        long nanos = Debug.threadCpuTimeNanos() - beginNanos;
-        if (nanos >= QUERY_LOG_TIME_IN_NANOS) {
+        long durationMillis = SystemClock.uptimeMillis() - beginMillis;
+        if (durationMillis >= QUERY_LOG_TIME_IN_MILLIS) {
             samplePercent = 100;
         } else {
-            samplePercent = (int) (100 * nanos / QUERY_LOG_TIME_IN_NANOS) + 1;
+            samplePercent = (int) (100 * durationMillis / QUERY_LOG_TIME_IN_MILLIS) + 1;
             if (mRandom.nextInt(100) >= samplePercent) return;
         }
 
@@ -1812,8 +1812,8 @@
         String blockingPackage = ActivityThread.currentPackageName();
         if (blockingPackage == null) blockingPackage = "";
 
-        int millis = (int) (nanos / 1000000);
-        EventLog.writeEvent(EVENT_DB_OPERATION, mPath, sql, millis, blockingPackage, samplePercent);
+        EventLog.writeEvent(
+            EVENT_DB_OPERATION, mPath, sql, durationMillis, blockingPackage, samplePercent);
     }
 
     /**
diff --git a/core/java/android/database/sqlite/SQLiteQuery.java b/core/java/android/database/sqlite/SQLiteQuery.java
index 5bcad4b..7cd9561 100644
--- a/core/java/android/database/sqlite/SQLiteQuery.java
+++ b/core/java/android/database/sqlite/SQLiteQuery.java
@@ -17,7 +17,7 @@
 package android.database.sqlite;
 
 import android.database.CursorWindow;
-import android.os.Debug;
+import android.os.SystemClock;
 import android.util.Log;
 
 /**
@@ -57,7 +57,7 @@
      */
     /* package */ int fillWindow(CursorWindow window,  
             int maxRead, int lastPos) {
-        long timeStart = Debug.threadCpuTimeNanos();
+        long timeStart = SystemClock.uptimeMillis();
         mDatabase.lock();
 
         try {
diff --git a/core/java/android/database/sqlite/SQLiteStatement.java b/core/java/android/database/sqlite/SQLiteStatement.java
index f1f5a2a..f29b69f 100644
--- a/core/java/android/database/sqlite/SQLiteStatement.java
+++ b/core/java/android/database/sqlite/SQLiteStatement.java
@@ -16,7 +16,7 @@
 
 package android.database.sqlite;
 
-import android.os.Debug;
+import android.os.SystemClock;
 
 /**
  * A pre-compiled statement against a {@link SQLiteDatabase} that can be reused.
@@ -44,7 +44,7 @@
      *         some reason
      */
     public void execute() {
-        long timeStart = Debug.threadCpuTimeNanos();
+        long timeStart = SystemClock.uptimeMillis();
         mDatabase.lock();
 
         acquireReference();
@@ -68,7 +68,7 @@
      *         some reason
      */
     public long executeInsert() {
-        long timeStart = Debug.threadCpuTimeNanos();
+        long timeStart = SystemClock.uptimeMillis();
         mDatabase.lock();
 
         acquireReference();
@@ -91,7 +91,7 @@
      * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows
      */
     public long simpleQueryForLong() {
-        long timeStart = Debug.threadCpuTimeNanos();
+        long timeStart = SystemClock.uptimeMillis();
         mDatabase.lock();
 
         acquireReference();
@@ -114,7 +114,7 @@
      * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows
      */
     public String simpleQueryForString() {
-        long timeStart = Debug.threadCpuTimeNanos();
+        long timeStart = SystemClock.uptimeMillis();
         mDatabase.lock();
 
         acquireReference();
diff --git a/core/java/android/inputmethodservice/KeyboardView.java b/core/java/android/inputmethodservice/KeyboardView.java
index 28a86b8..9201e3b 100644
--- a/core/java/android/inputmethodservice/KeyboardView.java
+++ b/core/java/android/inputmethodservice/KeyboardView.java
@@ -165,6 +165,7 @@
 
     private static final int DELAY_BEFORE_PREVIEW = 0;
     private static final int DELAY_AFTER_PREVIEW = 70;
+    private static final int DEBOUNCE_TIME = 70;
     
     private int mVerticalCorrection;
     private int mProximityThreshold;
@@ -1122,7 +1123,8 @@
         mSwipeTracker.addMovement(me);
 
         // Ignore all motion events until a DOWN.
-        if (mAbortKey && action != MotionEvent.ACTION_DOWN) {
+        if (mAbortKey
+                && action != MotionEvent.ACTION_DOWN && action != MotionEvent.ACTION_CANCEL) {
             return true;
         }
 
@@ -1206,6 +1208,7 @@
                     }
                 }
                 showPreview(mCurrentKey);
+                mLastMoveTime = eventTime;
                 break;
 
             case MotionEvent.ACTION_UP:
@@ -1219,7 +1222,8 @@
                     mCurrentKey = keyIndex;
                     mCurrentKeyTime = 0;
                 }
-                if (mCurrentKeyTime < mLastKeyTime && mLastKey != NOT_A_KEY) {
+                if (mCurrentKeyTime < mLastKeyTime && mCurrentKeyTime < DEBOUNCE_TIME
+                        && mLastKey != NOT_A_KEY) {
                     mCurrentKey = mLastKey;
                     touchX = mLastCodeX;
                     touchY = mLastCodeY;
diff --git a/core/java/android/net/Downloads.java b/core/java/android/net/Downloads.java
new file mode 100644
index 0000000..b86a0e2
--- /dev/null
+++ b/core/java/android/net/Downloads.java
@@ -0,0 +1,306 @@
+/*
+ * Copyright (C) 2008 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.net;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.SystemClock;
+import android.provider.BaseColumns;
+import android.util.Log;
+
+import java.io.File;
+
+/**
+ * The Download Manager
+ *
+ * @pending
+ */
+public final class Downloads {
+
+    public static final class ByUri {
+
+        /** @hide */
+        private ByUri() {}
+
+        /**
+          * Initiate a download where the download will be tracked by its URI.
+          * @pending
+          */
+        public static boolean startDownloadByUri(
+                Context context,
+                String url,
+                boolean showDownload,
+                boolean allowRoaming,
+                String title,
+                String notification_package,
+                String notification_class) {
+            ContentResolver cr = context.getContentResolver();
+
+            // Tell download manager to start downloading update.
+            ContentValues values = new ContentValues();
+            values.put(android.provider.Downloads.Impl.COLUMN_URI, url);
+            values.put(android.provider.Downloads.Impl.COLUMN_VISIBILITY,
+                       showDownload ? android.provider.Downloads.Impl.VISIBILITY_VISIBLE
+                       : android.provider.Downloads.Impl.VISIBILITY_HIDDEN);
+            if (title != null) {
+                values.put(android.provider.Downloads.Impl.COLUMN_TITLE, title);
+            }
+            values.put(android.provider.Downloads.Impl.COLUMN_APP_DATA, url);
+            values.put(android.provider.Downloads.Impl.COLUMN_DESTINATION,
+                       allowRoaming ? android.provider.Downloads.Impl.DESTINATION_CACHE_PARTITION :
+                       android.provider.Downloads.Impl.DESTINATION_CACHE_PARTITION_NOROAMING);
+            values.put(android.provider.Downloads.Impl.COLUMN_NO_INTEGRITY, true);  // Don't check ETag
+            if (notification_package != null && notification_class != null) {
+                values.put(android.provider.Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE, notification_package);
+                values.put(android.provider.Downloads.Impl.COLUMN_NOTIFICATION_CLASS, notification_class);
+            }
+
+            if (cr.insert(android.provider.Downloads.Impl.CONTENT_URI, values) == null) {
+                return false;
+            }
+            return true;
+        }
+
+        public static final class StatusInfo {
+            public boolean completed = false;
+            /** The filename of the active download. */
+            public String filename = null;
+            /** An opaque id for the download */
+            public long id = -1;
+            /** An opaque status code for the download */
+            public int statusCode = -1;
+            /** Approximate number of bytes downloaded so far, for debugging purposes. */
+            public long bytesSoFar = -1;
+        }
+
+        /** @hide */
+        private static final int STATUS_INVALID = 0;
+        /** @hide */
+        private static final int STATUS_DOWNLOADING_UPDATE = 3;
+        /** @hide */
+        private static final int STATUS_DOWNLOADED_UPDATE = 4;
+
+        /**
+         * Column projection for the query to the download manager. This must match
+         * with the constants DOWNLOADS_COLUMN_*.
+          * @hide
+         */
+        private static final String[] DOWNLOADS_PROJECTION = {
+            BaseColumns._ID,
+            android.provider.Downloads.Impl.COLUMN_APP_DATA,
+            android.provider.Downloads.Impl.COLUMN_STATUS,
+            android.provider.Downloads.Impl._DATA,
+            android.provider.Downloads.Impl.COLUMN_LAST_MODIFICATION,
+            android.provider.Downloads.Impl.COLUMN_CURRENT_BYTES,
+        };
+
+        /**
+          * The column index for the ID.
+          * @hide
+          */
+        private static final int DOWNLOADS_COLUMN_ID = 0;
+        /**
+          * The column index for the URI.
+          * @hide
+          */
+        private static final int DOWNLOADS_COLUMN_URI = 1;
+        /**
+          * The column index for the status code.
+          * @hide
+          */
+        private static final int DOWNLOADS_COLUMN_STATUS = 2;
+        /**
+          * The column index for the filename.
+          * @hide
+          */
+        private static final int DOWNLOADS_COLUMN_FILENAME = 3;
+        /**
+          * The column index for the last modification time.
+          * @hide
+          */
+        private static final int DOWNLOADS_COLUMN_LAST_MODIFICATION = 4;
+        /**
+          * The column index for the number of bytes downloaded so far.
+          * @hide
+          */
+        private static final int DOWNLOADS_COLUMN_CURRENT_BYTES = 5;
+
+        /**
+         * Gets the status of a download.
+         *
+         * @param c A Cursor pointing to a download.  The URL column is assumed to be valid.
+         * @return The status of the download.
+         * @hide
+         */
+        private static final int getStatusOfDownload(
+                Cursor c,
+                long redownload_threshold) {
+            int status = c.getInt(DOWNLOADS_COLUMN_STATUS);
+            long realtime = SystemClock.elapsedRealtime();
+
+            // TODO(dougz): special handling of 503, 404?  (eg, special
+            // explanatory messages to user)
+
+            if (!android.provider.Downloads.Impl.isStatusCompleted(status)) {
+                // Check if it's stuck
+                long modified = c.getLong(DOWNLOADS_COLUMN_LAST_MODIFICATION);
+                long now = System.currentTimeMillis();
+                if (now < modified || now - modified > redownload_threshold) {
+                    return STATUS_INVALID;
+                }
+
+                return STATUS_DOWNLOADING_UPDATE;
+            }
+
+            if (android.provider.Downloads.Impl.isStatusError(status)) {
+                return STATUS_INVALID;
+            }
+
+            String filename = c.getString(DOWNLOADS_COLUMN_FILENAME);
+            if (filename == null) {
+                return STATUS_INVALID;
+            }
+
+            return STATUS_DOWNLOADED_UPDATE;
+        }
+
+        /**
+         * Gets a Cursor pointing to the download(s) of the current system update.
+         * @hide
+         */
+        private static final Cursor getCurrentOtaDownloads(Context context, String url) {
+            return context.getContentResolver().query(
+                    android.provider.Downloads.Impl.CONTENT_URI,
+                    DOWNLOADS_PROJECTION,
+                    android.provider.Downloads.Impl.COLUMN_APP_DATA + "='" + url.replace("'", "''") + "'",
+                    null,
+                    null);
+        }
+
+        /**
+         * Returns a StatusInfo with the result of trying to download the
+         * given URL.  Returns null if no attempts have been made.
+         * @pending
+         */
+        public static final StatusInfo getStatus(
+                Context context,
+                String url,
+                long redownload_threshold) {
+            StatusInfo result = null;
+            boolean hasFailedDownload = false;
+            long failedDownloadModificationTime = 0;
+            Cursor c = getCurrentOtaDownloads(context, url);
+            try {
+                while (c != null && c.moveToNext()) {
+                    if (result == null) {
+                        result = new StatusInfo();
+                    }
+                    int status = getStatusOfDownload(c, redownload_threshold);
+                    if (status == STATUS_DOWNLOADING_UPDATE ||
+                        status == STATUS_DOWNLOADED_UPDATE) {
+                        result.completed = (status == STATUS_DOWNLOADED_UPDATE);
+                        result.filename = c.getString(DOWNLOADS_COLUMN_FILENAME);
+                        result.id = c.getLong(DOWNLOADS_COLUMN_ID);
+                        result.statusCode = c.getInt(DOWNLOADS_COLUMN_STATUS);
+                        result.bytesSoFar = c.getLong(DOWNLOADS_COLUMN_CURRENT_BYTES);
+                        return result;
+                    }
+
+                    long modTime = c.getLong(DOWNLOADS_COLUMN_LAST_MODIFICATION);
+                    if (hasFailedDownload &&
+                        modTime < failedDownloadModificationTime) {
+                        // older than the one already in result; skip it.
+                        continue;
+                    }
+
+                    hasFailedDownload = true;
+                    failedDownloadModificationTime = modTime;
+                    result.statusCode = c.getInt(DOWNLOADS_COLUMN_STATUS);
+                    result.bytesSoFar = c.getLong(DOWNLOADS_COLUMN_CURRENT_BYTES);
+                }
+            } finally {
+                c.close();
+            }
+            return result;
+        }
+
+        /**
+         * Query where clause for general querying.
+         * @hide
+         */
+        private static final String QUERY_WHERE_CLAUSE =
+                android.provider.Downloads.Impl.COLUMN_NOTIFICATION_PACKAGE + "=? AND " +
+                android.provider.Downloads.Impl.COLUMN_NOTIFICATION_CLASS + "=?";
+
+        /**
+         * Delete all the downloads for a package/class pair.
+         * @pending
+         */
+        public static final void removeAllDownloadsByPackage(
+                Context context,
+                String notification_package,
+                String notification_class) {
+            context.getContentResolver().delete(
+                    android.provider.Downloads.Impl.CONTENT_URI,
+                    QUERY_WHERE_CLAUSE,
+                    new String[] { notification_package, notification_class });
+        }
+
+        /**
+         * @pending
+         */
+        public static final int getProgressColumnId() {
+            return 0;
+        }
+
+        /**
+         * @pending
+         */
+        public static final int getProgressColumnCurrentBytes() {
+            return 1;
+        }
+
+        /**
+         * @pending
+         */
+        public static final int getProgressColumnTotalBytes() {
+            return 2;
+        }
+
+        /** @hide */
+        private static final String[] PROJECTION = {
+            BaseColumns._ID, android.provider.Downloads.Impl.COLUMN_CURRENT_BYTES, android.provider.Downloads.Impl.COLUMN_TOTAL_BYTES
+        };
+
+        /**
+         * @pending
+         */
+        public static final Cursor getProgressCursor(Context context, long id) {
+            Uri downloadUri = Uri.withAppendedPath(android.provider.Downloads.Impl.CONTENT_URI, String.valueOf(id));
+            return context.getContentResolver().query(downloadUri, PROJECTION, null, null, null);
+        }
+    }
+
+    /**
+     * @hide
+     */
+    private Downloads() {}
+}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index ee7193b..bfab30a 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1489,6 +1489,14 @@
         public static final String DEFAULT_INSTALL_LOCATION = "default_install_location";
 
         /**
+         * Show pointer location on screen?
+         * 0 = no
+         * 1 = yes
+         * @hide
+         */
+        public static final String POINTER_LOCATION = "pointer_location";
+
+        /**
          * Settings to backup. This is here so that it's in the same place as the settings
          * keys and easy to update.
          * @hide
diff --git a/core/java/android/speech/RecognitionManager.java b/core/java/android/speech/RecognitionManager.java
index 74b9fce..7f55ad6 100644
--- a/core/java/android/speech/RecognitionManager.java
+++ b/core/java/android/speech/RecognitionManager.java
@@ -171,7 +171,7 @@
      */
     public static boolean isRecognitionAvailable(final Context context) {
         final List<ResolveInfo> list = context.getPackageManager().queryIntentServices(
-                new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);
+                new Intent(RecognitionService.SERVICE_INTERFACE), 0);
         return list != null && list.size() != 0;
     }
 
diff --git a/core/java/android/speech/tts/TextToSpeech.java b/core/java/android/speech/tts/TextToSpeech.java
index bbbeb3f..0db2198 100755
--- a/core/java/android/speech/tts/TextToSpeech.java
+++ b/core/java/android/speech/tts/TextToSpeech.java
@@ -256,6 +256,31 @@
          * the TextToSpeech engine specifies the locale associated with each resource file.
          */
         public static final String EXTRA_VOICE_DATA_FILES_INFO = "dataFilesInfo";
+        /**
+         * Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent where
+         * the TextToSpeech engine returns an ArrayList<String> of all the available voices.
+         * The format of each voice is: lang-COUNTRY-variant where COUNTRY and variant are
+         * optional (ie, "eng" or "eng-USA" or "eng-USA-FEMALE").
+         * {@hide}
+         */
+        public static final String EXTRA_AVAILABLE_VOICES = "availableVoices";
+        /**
+         * Extra information received with the {@link #ACTION_CHECK_TTS_DATA} intent where
+         * the TextToSpeech engine returns an ArrayList<String> of all the unavailable voices.
+         * The format of each voice is: lang-COUNTRY-variant where COUNTRY and variant are
+         * optional (ie, "eng" or "eng-USA" or "eng-USA-FEMALE").
+         * {@hide}
+         */
+        public static final String EXTRA_UNAVAILABLE_VOICES = "unavailableVoices";
+        /**
+         * Extra information sent with the {@link #ACTION_CHECK_TTS_DATA} intent where the
+         * caller indicates to the TextToSpeech engine which specific sets of voice data to
+         * check for by sending an ArrayList<String> of the voices that are of interest.
+         * The format of each voice is: lang-COUNTRY-variant where COUNTRY and variant are
+         * optional (ie, "eng" or "eng-USA" or "eng-USA-FEMALE").
+         * {@hide}
+         */
+        public static final String EXTRA_CHECK_VOICE_DATA_FOR = "checkVoiceDataFor";
 
         // extras for a TTS engine's data installation
         /**
diff --git a/core/java/android/view/HapticFeedbackConstants.java b/core/java/android/view/HapticFeedbackConstants.java
index e1f2823..ccbd8d4 100644
--- a/core/java/android/view/HapticFeedbackConstants.java
+++ b/core/java/android/view/HapticFeedbackConstants.java
@@ -36,6 +36,11 @@
     public static final int VIRTUAL_KEY = 1;
     
     /**
+     * The user has hit the barrier point while scrolling a view.
+     */
+    public static final int SCROLL_BARRIER = 2;
+    
+    /**
      * This is a private constant.  Feel free to renumber as desired.
      * @hide
      */
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index fb19dcf..57fdd8b 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8547,7 +8547,119 @@
         LayoutInflater factory = LayoutInflater.from(context);
         return factory.inflate(resource, root);
     }
+    
+    /**
+     * Scroll the view with standard behavior for scrolling beyond the normal
+     * content boundaries. Views that call this method should override
+     * {@link #onOverscrolled(int, int, boolean, boolean)} to respond to the
+     * results of an overscroll operation.
+     * 
+     * Views can use this method to handle any touch or fling-based scrolling.
+     * 
+     * @param deltaX Change in X in pixels 
+     * @param deltaY Change in Y in pixels
+     * @param scrollX Current X scroll value in pixels before applying deltaX
+     * @param scrollY Current Y scroll value in pixels before applying deltaY
+     * @param scrollRangeX Maximum content scroll range along the X axis
+     * @param scrollRangeY Maximum content scroll range along the Y axis
+     * @param maxOverscrollX Number of pixels to overscroll by in either direction
+     *          along the X axis.
+     * @param maxOverscrollY Number of pixels to overscroll by in either direction
+     *          along the Y axis.
+     * @return true if scrolling was clamped to an overscroll boundary along either
+     *          axis, false otherwise.
+     */
+    protected boolean overscrollBy(int deltaX, int deltaY,
+            int scrollX, int scrollY,
+            int scrollRangeX, int scrollRangeY,
+            int maxOverscrollX, int maxOverscrollY) {
+        // Scale the scroll amount if we're in the dropoff zone
+        final int dropoffX = maxOverscrollX / 2;
+        final int dropoffLeft = -dropoffX;
+        final int dropoffRight = dropoffX + scrollRangeX;
+        int newScrollX;
+        if ((scrollX < dropoffLeft && deltaX < 0) ||
+                (scrollX > dropoffRight && deltaX > 0)) {
+            newScrollX = scrollX + deltaX / 2;
+        } else {
+            newScrollX = scrollX + deltaX;
+            if (newScrollX > dropoffRight && deltaX > 0) {
+                int extra = newScrollX - dropoffRight;
+                newScrollX = dropoffRight + extra / 2;
+            } else if (newScrollX < dropoffLeft && deltaX < 0) {
+                int extra = newScrollX - dropoffLeft;
+                newScrollX = dropoffLeft + extra / 2;
+            }
+        }
+        
+        final int dropoffY = maxOverscrollY / 2;
+        final int dropoffTop = -dropoffY;
+        final int dropoffBottom = dropoffY + scrollRangeY;
+        int newScrollY;
+        if ((scrollY < dropoffTop && deltaY < 0) ||
+                (scrollY > dropoffBottom && deltaY > 0)) {
+            newScrollY = scrollY + deltaY / 2;
+        } else {
+            newScrollY = scrollY + deltaY;
+            if (newScrollY > dropoffBottom && deltaY > 0) {
+                int extra = newScrollY - dropoffBottom;
+                newScrollY = dropoffBottom + extra / 2;
+            } else if (newScrollY < dropoffTop && deltaY < 0) {
+                int extra = newScrollY - dropoffTop;
+                newScrollY = dropoffTop + extra / 2;
+            }
+        }
 
+        // Clamp values if at the limits and record
+        final int left = -maxOverscrollX;
+        final int right = maxOverscrollX + scrollRangeX;
+        final int top = -maxOverscrollY;
+        final int bottom = maxOverscrollY + scrollRangeY;
+
+        boolean clampedX = false;
+        if (newScrollX > right) {
+            newScrollX = right;
+            clampedX = true;
+        } else if (newScrollX < left) {
+            newScrollX = left;
+            clampedX = true;
+        }
+        
+        boolean clampedY = false;
+        if (newScrollY > bottom) {
+            newScrollY = bottom;
+            clampedY = true;
+        } else if (newScrollY < top) {
+            newScrollY = top;
+            clampedY = true;
+        }
+        
+        // Bump the device with some haptic feedback if we're at the edge
+        // and didn't start there.
+        if ((clampedX && scrollX != left && scrollX != right) ||
+                (clampedY && scrollY != top && scrollY != bottom)) {
+            performHapticFeedback(HapticFeedbackConstants.SCROLL_BARRIER);
+        }
+
+        onOverscrolled(newScrollX, newScrollY, clampedX, clampedY);
+        
+        return clampedX || clampedY;
+    }
+    
+    /**
+     * Called by {@link #overscrollBy(int, int, int, int, int, int, int, int)} to
+     * respond to the results of an overscroll operation.
+     * 
+     * @param scrollX New X scroll value in pixels
+     * @param scrollY New Y scroll value in pixels
+     * @param clampedX True if scrollX was clamped to an overscroll boundary
+     * @param clampedY True if scrollY was clamped to an overscroll boundary
+     */
+    protected void onOverscrolled(int scrollX, int scrollY,
+            boolean clampedX, boolean clampedY) {
+        // Intentionally empty.
+    }
+    
     /**
      * A MeasureSpec encapsulates the layout requirements passed from parent to child.
      * Each MeasureSpec represents a requirement for either the width or the height.
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 7bc5cce..ab3260e 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -851,6 +851,11 @@
      */
     public boolean isCheekPressedAgainstScreen(MotionEvent ev);
     
+    /**
+     * Called every time the window manager is dispatching a pointer event.
+     */
+    public void dispatchedPointerEventLw(MotionEvent ev, int targetX, int targetY);
+    
     public void setCurrentOrientationLw(int newOrientation);
     
     /**
diff --git a/core/java/android/webkit/JWebCoreJavaBridge.java b/core/java/android/webkit/JWebCoreJavaBridge.java
index e496d97..9dc7079 100644
--- a/core/java/android/webkit/JWebCoreJavaBridge.java
+++ b/core/java/android/webkit/JWebCoreJavaBridge.java
@@ -21,6 +21,8 @@
 import android.os.Message;
 import android.util.Log;
 
+import java.util.Set;
+
 final class JWebCoreJavaBridge extends Handler {
     // Identifier for the timer message.
     private static final int TIMER_MESSAGE = 1;
@@ -248,4 +250,7 @@
             boolean reload);
     public native void setNetworkOnLine(boolean online);
     public native void setNetworkType(String type, String subtype);
+    public native void addPackageNames(Set<String> packageNames);
+    public native void addPackageName(String packageName);
+    public native void removePackageName(String packageName);
 }
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index b0233ab..9148a18 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -86,6 +86,7 @@
 import java.util.List;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Set;
 
 import junit.framework.Assert;
 
@@ -213,8 +214,6 @@
     // true means redraw the screen all-the-time. Only with AUTO_REDRAW_HACK
     private boolean mAutoRedraw;
     private int mRootLayer; // C++ pointer to the root layer
-    private boolean mLayersHaveAnimations;
-    private EvaluateLayersAnimations mEvaluateThread;
 
     static final String LOGTAG = "webview";
 
@@ -2904,6 +2903,45 @@
         return mWebViewCore.getSettings();
     }
 
+    /**
+     * Use this method to inform the webview about packages that are installed
+     * in the system. This information will be used by the
+     * navigator.isApplicationInstalled() API.
+     * @param packageNames is a set of package names that are known to be
+     * installed in the system.
+     *
+     * @hide not a public API
+     */
+    public void addPackageNames(Set<String> packageNames) {
+        mWebViewCore.sendMessage(EventHub.ADD_PACKAGE_NAMES, packageNames);
+    }
+
+    /**
+     * Use this method to inform the webview about single packages that are
+     * installed in the system. This information will be used by the
+     * navigator.isApplicationInstalled() API.
+     * @param packageName is the name of a package that is known to be
+     * installed in the system.
+     *
+     * @hide not a public API
+     */
+    public void addPackageName(String packageName) {
+        mWebViewCore.sendMessage(EventHub.ADD_PACKAGE_NAME, packageName);
+    }
+
+    /**
+     * Use this method to inform the webview about packages that are uninstalled
+     * in the system. This information will be used by the
+     * navigator.isApplicationInstalled() API.
+     * @param packageName is the name of a package that has been uninstalled in
+     * the system.
+     *
+     * @hide not a public API
+     */
+    public void removePackageName(String packageName) {
+        mWebViewCore.sendMessage(EventHub.REMOVE_PACKAGE_NAME, packageName);
+    }
+
    /**
     * Return the list of currently loaded plugins.
     * @return The list of currently loaded plugins.
@@ -3072,6 +3110,15 @@
             int scrollY = computeVerticalScrollOffset();
             int viewHeight = getHeight() - getVisibleTitleHeight();
 
+            // Currently for each draw we compute the animation values;
+            // We may in the future decide to do that independently.
+            if (nativeEvaluateLayersAnimations(mRootLayer)) {
+                // If we have unfinished (or unstarted) animations,
+                // we ask for a repaint.
+                invalidate();
+            }
+
+            // We can now draw the layers.
             nativeDrawLayers(mRootLayer, mScrollX, scrollY,
                              getWidth(), viewHeight,
                              mActualScale, canvas);
@@ -3415,40 +3462,6 @@
     }
 
     /*
-     * This class runs the layers animations in their own thread,
-     * so that we do not slow down the UI.
-     */
-    private class EvaluateLayersAnimations extends Thread {
-        boolean mRunning = true;
-        // delay corresponds to 40fps, no need to go faster.
-        int mDelay = 25; // in ms
-        public void run() {
-            while (mRunning) {
-                if (mLayersHaveAnimations && mRootLayer != 0) {
-                    // updates is a C++ pointer to a Vector of AnimationValues
-                    int updates = nativeEvaluateLayersAnimations(mRootLayer);
-                    if (updates == 0) {
-                        mRunning = false;
-                    }
-                    Message.obtain(mPrivateHandler,
-                          WebView.IMMEDIATE_REPAINT_MSG_ID,
-                          updates, 0).sendToTarget();
-                } else {
-                    mRunning = false;
-                }
-                try {
-                    Thread.currentThread().sleep(mDelay);
-                } catch (InterruptedException e) {
-                    mRunning = false;
-                }
-            }
-        }
-        public void cancel() {
-            mRunning = false;
-        }
-    }
-
-    /*
      * This class requests an Adapter for the WebTextView which shows past
      * entries stored in the database.  It is a Runnable so that it can be done
      * in its own thread, without slowing down the UI.
@@ -5929,13 +5942,6 @@
                     break;
                 }
                 case IMMEDIATE_REPAINT_MSG_ID: {
-                    int updates = msg.arg1;
-                    if (updates != 0) {
-                        // updates is a C++ pointer to a Vector of
-                        // AnimationValues that we apply to the layers.
-                        // The Vector is deallocated in nativeUpdateLayers().
-                        nativeUpdateLayers(updates);
-                    }
                     invalidate();
                     break;
                 }
@@ -5945,18 +5951,6 @@
                     if (oldLayer > 0) {
                         nativeDestroyLayer(oldLayer);
                     }
-                    if (mRootLayer == 0) {
-                        mLayersHaveAnimations = false;
-                    }
-                    if (mEvaluateThread != null) {
-                        mEvaluateThread.cancel();
-                        mEvaluateThread = null;
-                    }
-                    if (nativeLayersHaveAnimations(mRootLayer)) {
-                        mLayersHaveAnimations = true;
-                        mEvaluateThread = new EvaluateLayersAnimations();
-                        mEvaluateThread.start();
-                    }
                     invalidate();
                     break;
                 }
@@ -6729,9 +6723,7 @@
     private native void     nativeDestroy();
     private native void     nativeDrawCursorRing(Canvas content);
     private native void     nativeDestroyLayer(int layer);
-    private native int      nativeEvaluateLayersAnimations(int layer);
-    private native boolean  nativeLayersHaveAnimations(int layer);
-    private native void     nativeUpdateLayers(int updates);
+    private native boolean  nativeEvaluateLayersAnimations(int layer);
     private native void     nativeDrawLayers(int layer,
                                              int scrollX, int scrollY,
                                              int width, int height,
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 9c91919..3a3e445 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -892,6 +892,11 @@
 
         static final int SET_NETWORK_TYPE = 183;
 
+        // navigator.isApplicationInstalled()
+        static final int ADD_PACKAGE_NAMES = 184;
+        static final int ADD_PACKAGE_NAME = 185;
+        static final int REMOVE_PACKAGE_NAME = 186;
+
         // private message ids
         private static final int DESTROY =     200;
 
@@ -1363,6 +1368,33 @@
                         case HIDE_FULLSCREEN:
                             nativeFullScreenPluginHidden(msg.arg1);
                             break;
+
+                        case ADD_PACKAGE_NAMES:
+                            if (BrowserFrame.sJavaBridge == null) {
+                                throw new IllegalStateException("No WebView " +
+                                        "has been created in this process!");
+                            }
+                            BrowserFrame.sJavaBridge.addPackageNames(
+                                    (Set<String>) msg.obj);
+                            break;
+
+                        case ADD_PACKAGE_NAME:
+                            if (BrowserFrame.sJavaBridge == null) {
+                                throw new IllegalStateException("No WebView " +
+                                        "has been created in this process!");
+                            }
+                            BrowserFrame.sJavaBridge.addPackageName(
+                                    (String) msg.obj);
+                            break;
+
+                        case REMOVE_PACKAGE_NAME:
+                            if (BrowserFrame.sJavaBridge == null) {
+                                throw new IllegalStateException("No WebView " +
+                                        "has been created in this process!");
+                            }
+                            BrowserFrame.sJavaBridge.removePackageName(
+                                    (String) msg.obj);
+                            break;
                     }
                 }
             };
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 2f96aef..4c77bdc 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -377,6 +377,16 @@
     int mResurrectToPosition = INVALID_POSITION;
 
     private ContextMenuInfo mContextMenuInfo = null;
+    
+    /**
+     * Maximum distance to overscroll by
+     */
+    private int mOverscrollMax;
+    
+    /**
+     * Content height divided by this is the overscroll limit.
+     */
+    private static final int OVERSCROLL_LIMIT_DIVISOR = 3;
 
     /**
      * Used to request a layout when we changed touch mode
@@ -1048,7 +1058,8 @@
                 final int top = view.getTop();
                 int height = view.getHeight();
                 if (height > 0) {
-                    return Math.max(firstPosition * 100 - (top * 100) / height, 0);
+                    return Math.max(firstPosition * 100 - (top * 100) / height +
+                            (int)((float)mScrollY / getHeight() * mItemCount * 100), 0);
                 }
             } else {
                 int index;
@@ -1068,7 +1079,17 @@
 
     @Override
     protected int computeVerticalScrollRange() {
-        return mSmoothScrollbarEnabled ? Math.max(mItemCount * 100, 0) : mItemCount;
+        int result;
+        if (mSmoothScrollbarEnabled) {
+            result = Math.max(mItemCount * 100, 0);
+            if (mScrollY != 0) {
+                // Compensate for overscroll
+                result += Math.abs((int) ((float) mScrollY / getHeight() * mItemCount * 100));
+            }
+        } else {
+            result = mItemCount;
+        }
+        return result;
     }
 
     @Override
@@ -1129,6 +1150,8 @@
         mInLayout = true;
         layoutChildren();
         mInLayout = false;
+        
+        mOverscrollMax = (b - t) / OVERSCROLL_LIMIT_DIVISOR;
     }
 
     /**
@@ -2078,11 +2101,13 @@
                         // Check if the top of the motion view is where it is
                         // supposed to be
                         final int motionViewRealTop = motionView.getTop();
-                        final int motionViewNewTop = mMotionViewNewTop;
                         if (atEdge) {
                             // Apply overscroll
                             
-                            mScrollY -= incrementalDeltaY - (motionViewRealTop - motionViewPrevTop);
+                            int overscroll = -incrementalDeltaY - 
+                                    (motionViewRealTop - motionViewPrevTop);
+                            overscrollBy(0, overscroll, 0, mScrollY, 0, 0,
+                                    0, getOverscrollMax());
                             mTouchMode = TOUCH_MODE_OVERSCROLL;
                             invalidate();
                         }
@@ -2126,7 +2151,8 @@
                             mMotionPosition = motionPosition;
                         }
                     } else {
-                        mScrollY -= incrementalDeltaY;
+                        overscrollBy(0, -incrementalDeltaY, 0, mScrollY, 0, 0,
+                                0, getOverscrollMax());
                         invalidate();
                     }
                     mLastY = y;
@@ -2311,6 +2337,28 @@
 
         return true;
     }
+    
+    @Override
+    protected void onOverscrolled(int scrollX, int scrollY,
+            boolean clampedX, boolean clampedY) {
+        mScrollY = scrollY;
+        if (clampedY) {
+            // Velocity is broken by hitting the limit; don't start a fling off of this.
+            if (mVelocityTracker != null) {
+                mVelocityTracker.clear();
+            }
+        }
+    }
+    
+    private int getOverscrollMax() {
+        final int childCount = getChildCount();
+        if (childCount > 0) {
+            return Math.min(mOverscrollMax,
+                    getChildAt(childCount - 1).getBottom() / OVERSCROLL_LIMIT_DIVISOR);
+        } else {
+            return mOverscrollMax;
+        }
+    }
 
     @Override
     public void draw(Canvas canvas) {
@@ -2532,22 +2580,23 @@
                     delta = Math.max(-(getHeight() - mPaddingBottom - mPaddingTop - 1), delta);
                 }
 
-                // Do something different on overscroll - offsetChildrenTopAndBottom()
-                trackMotionScroll(delta, delta);
-
                 // Check to see if we have bumped into the scroll limit
                 View motionView = getChildAt(mMotionPosition - mFirstPosition);
+                int oldTop = 0;
                 if (motionView != null) {
-                    // Check if the top of the motion view is where it is
-                    // supposed to be
-                    if (motionView.getTop() != mMotionViewNewTop) {
-                       float vel = scroller.getCurrVelocity();
-                       if (delta > 0) {
-                           vel = -vel;
-                       }
-                       startOverfling(Math.round(vel));
-                       break;
+                    oldTop = motionView.getTop();
+                }
+                if (trackMotionScroll(delta, delta)) {
+                    if (motionView != null) {
+                        // Tweak the scroll for how far we overshot
+                        mScrollY -= delta - (motionView.getTop() - oldTop);
                     }
+                    float vel = scroller.getCurrVelocity();
+                    if (delta > 0) {
+                        vel = -vel;
+                    }
+                    startOverfling(Math.round(vel));
+                    break;
                 }
 
                 if (more) {
@@ -2570,9 +2619,14 @@
             case TOUCH_MODE_OVERFLING: {
                 final OverScroller scroller = mScroller;
                 if (scroller.computeScrollOffset()) {
-                    mScrollY = scroller.getCurrY();
-                    invalidate();
-                    post(this);
+                    final int scrollY = mScrollY;
+                    final int deltaY = scroller.getCurrY() - scrollY;
+                    if (overscrollBy(0, deltaY, 0, scrollY, 0, 0, 0, getOverscrollMax())) {
+                        startSpringback();
+                    } else {
+                        invalidate();
+                        post(this);
+                    }
                 } else {
                     endFling();
                 }
@@ -2702,6 +2756,10 @@
             case MOVE_DOWN_POS: {
                 final int lastViewIndex = getChildCount() - 1;
                 final int lastPos = firstPos + lastViewIndex;
+                
+                if (lastViewIndex < 0) {
+                    return;
+                }
 
                 if (lastPos == mLastSeenPos) {
                     // No new views, let things keep going.
@@ -2764,6 +2822,9 @@
                 }
 
                 final View firstView = getChildAt(0);
+                if (firstView == null) {
+                    return;
+                }
                 final int firstViewTop = firstView.getTop();
 
                 smoothScrollBy(firstViewTop - mExtraScroll, mScrollDuration);
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 0078fec..c62724c 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -461,7 +461,8 @@
                 final int deltaX = (int) (mLastMotionX - x);
                 mLastMotionX = x;
 
-                super.scrollTo(mScrollX + deltaX, mScrollY);
+                overscrollBy(deltaX, 0, mScrollX, 0, getScrollRange(), 0,
+                        getOverscrollMax(), 0);
                 break;
             case MotionEvent.ACTION_UP:
                 final VelocityTracker velocityTracker = mVelocityTracker;
@@ -472,8 +473,7 @@
                     if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
                         fling(-initialVelocity);
                     } else {
-                        final int right = Math.max(0, getChildAt(0).getHeight() - 
-                                (getHeight() - mPaddingRight - mPaddingLeft));
+                        final int right = getScrollRange();
                         if (mScroller.springback(mScrollX, mScrollY, 0, 0, right, 0)) {
                             invalidate();
                         }
@@ -487,6 +487,41 @@
         }
         return true;
     }
+    
+    @Override
+    protected void onOverscrolled(int scrollX, int scrollY,
+            boolean clampedX, boolean clampedY) {
+        // Treat animating scrolls differently; see #computeScroll() for why.
+        if (!mScroller.isFinished()) {
+            mScrollX = scrollX;
+            mScrollY = scrollY;
+            if (clampedX) {
+                mScroller.springback(mScrollX, mScrollY, 0, getScrollRange(), 0, 0);
+            }
+        } else {
+            super.scrollTo(scrollX, scrollY);
+        }
+    }
+    
+    private int getOverscrollMax() {
+        int childCount = getChildCount();
+        int containerOverscroll = (getWidth() - mPaddingLeft - mPaddingRight) / 3;
+        if (childCount > 0) {
+            return Math.min(containerOverscroll, getChildAt(0).getWidth() / 3);
+        } else {
+            return containerOverscroll;
+        }
+    }
+    
+    private int getScrollRange() {
+        int scrollRange = 0;
+        if (getChildCount() > 0) {
+            View child = getChildAt(0);
+            scrollRange = Math.max(0,
+                    child.getWidth() - getWidth() - mPaddingLeft - mPaddingRight);
+        }
+        return scrollRange;
+    }
 
     /**
      * <p>
@@ -856,9 +891,26 @@
     @Override
     protected int computeHorizontalScrollRange() {
         int count = getChildCount();
-        return count == 0 ? getWidth() : getChildAt(0).getRight();
+        if (count == 0) {
+            return getWidth();
+        }
+        
+        int scrollRange = getChildAt(0).getRight();
+        int scrollX = mScrollX;
+        int overscrollRight = scrollRange - getWidth() - mPaddingLeft - mPaddingRight;
+        if (scrollX < 0) {
+            scrollRange -= scrollX;
+        } else if (scrollX > overscrollRight) {
+            scrollRange += scrollX - overscrollRight;
+        }
+        
+        return scrollRange;
     }
-
+    
+    @Override
+    protected int computeHorizontalScrollOffset() {
+        return Math.max(0, super.computeHorizontalScrollOffset());
+    }
 
     @Override
     protected void measureChild(View child, int parentWidthMeasureSpec, int parentHeightMeasureSpec) {
@@ -913,10 +965,9 @@
             int x = mScroller.getCurrX();
             int y = mScroller.getCurrY();
 
-            mScrollX = x;
-            mScrollY = y;
-
-            if (oldX != mScrollX || oldY != mScrollY) {
+            if (oldX != x || oldY != y) {
+                overscrollBy(x - oldX, y - oldY, oldX, oldY, getScrollRange(), 0,
+                        getOverscrollMax(), 0);
                 onScrollChanged(mScrollX, mScrollY, oldX, oldY);
             }
 
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 401e7ff..c428dc0 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -2916,7 +2916,14 @@
 
             if (!mStackFromBottom) {
                 int bottom;
-                int listBottom = mBottom - mTop - mListPadding.bottom;
+                int listBottom = mBottom - mTop - mListPadding.bottom + mScrollY;
+                
+                // Draw top divider for overscroll
+                if (count > 0 && mScrollY < 0) {
+                    bounds.bottom = 0;
+                    bounds.top = -dividerHeight;
+                    drawDivider(canvas, bounds, -1);
+                }
 
                 for (int i = 0; i < count; i++) {
                     if ((headerDividers || first + i >= headerCount) &&
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 4a1d871..2ee7ad5 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -459,7 +459,8 @@
                 final int deltaY = (int) (mLastMotionY - y);
                 mLastMotionY = y;
 
-                super.scrollTo(mScrollX, mScrollY + deltaY);
+                overscrollBy(0, deltaY, 0, mScrollY, 0, getScrollRange(),
+                        0, getOverscrollMax());
                 break;
             case MotionEvent.ACTION_UP:
                 final VelocityTracker velocityTracker = mVelocityTracker;
@@ -470,8 +471,7 @@
                     if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
                         fling(-initialVelocity);
                     } else {
-                        final int bottom = Math.max(0, getChildAt(0).getHeight() - 
-                                (getHeight() - mPaddingBottom - mPaddingTop));
+                        final int bottom = getScrollRange();
                         if (mScroller.springback(mScrollX, mScrollY, 0, 0, 0, bottom)) {
                             invalidate();
                         }
@@ -485,6 +485,41 @@
         }
         return true;
     }
+    
+    @Override
+    protected void onOverscrolled(int scrollX, int scrollY,
+            boolean clampedX, boolean clampedY) {
+        // Treat animating scrolls differently; see #computeScroll() for why.
+        if (!mScroller.isFinished()) {
+            mScrollX = scrollX;
+            mScrollY = scrollY;
+            if (clampedY) {
+                mScroller.springback(mScrollX, mScrollY, 0, 0, 0, getScrollRange());
+            }
+        } else {
+            super.scrollTo(scrollX, scrollY);
+        }
+    }
+    
+    private int getOverscrollMax() {
+        int childCount = getChildCount();
+        int containerOverscroll = (getHeight() - mPaddingBottom - mPaddingTop) / 3;
+        if (childCount > 0) {
+            return Math.min(containerOverscroll, getChildAt(0).getHeight() / 3);
+        } else {
+            return containerOverscroll;
+        }
+    }
+    
+    private int getScrollRange() {
+        int scrollRange = 0;
+        if (getChildCount() > 0) {
+            View child = getChildAt(0);
+            scrollRange = Math.max(0,
+                    child.getHeight() - getHeight() - mPaddingBottom - mPaddingTop);
+        }
+        return scrollRange;
+    }
 
     /**
      * <p>
@@ -858,9 +893,26 @@
     @Override
     protected int computeVerticalScrollRange() {
         int count = getChildCount();
-        return count == 0 ? getHeight() : (getChildAt(0)).getBottom();
+        if (count == 0) {
+            return getHeight();
+        }
+        
+        int scrollRange = getChildAt(0).getBottom();
+        int scrollY = mScrollY;
+        int overscrollBottom = scrollRange - getHeight() - mPaddingBottom - mPaddingTop;
+        if (scrollY < 0) {
+            scrollRange -= scrollY;
+        } else if (scrollY > overscrollBottom) {
+            scrollRange += scrollY - overscrollBottom;
+        }
+        
+        return scrollRange;
     }
 
+    @Override
+    protected int computeVerticalScrollOffset() {
+        return Math.max(0, super.computeVerticalScrollOffset());
+    }
 
     @Override
     protected void measureChild(View child, int parentWidthMeasureSpec, int parentHeightMeasureSpec) {
@@ -915,10 +967,9 @@
             int x = mScroller.getCurrX();
             int y = mScroller.getCurrY();
 
-            mScrollX = x;
-            mScrollY = y;
-
-            if (oldX != mScrollX || oldY != mScrollY) {
+            if (oldX != x || oldY != y) {
+                overscrollBy(x - oldX, y - oldY, oldX, oldY, 0, getScrollRange(),
+                        0, getOverscrollMax());
                 onScrollChanged(mScrollX, mScrollY, oldX, oldY);
             }
             
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboard.java b/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
index c9014723..e1a6737 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
@@ -93,7 +93,7 @@
         LatinKey key = new LatinKey(res, parent, x, y, parser);
         final int code = key.codes[0];
         if (code >=0 && code != '\n' && (code < 32 || code > 127)) {
-            Log.w(TAG, "Key code for " + key.label + " is not latin-1");
+            // Log.w(TAG, "Key code for " + key.label + " is not latin-1");
             key.label = " ";
             key.setEnabled(false);
         }
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 1ffd265..e8749ed 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -159,6 +159,8 @@
 	libbinder \
 	libnetutils \
 	libui \
+	libsurfaceflinger_client \
+	libcamera_client \
 	libskiagl \
 	libskia \
 	libsqlite \
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index 03107a4..9c0e282 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -25,8 +25,8 @@
 
 #include <utils/Vector.h>
 
-#include <ui/Surface.h>
-#include <ui/Camera.h>
+#include <surfaceflinger/Surface.h>
+#include <camera/Camera.h>
 #include <binder/IMemory.h>
 
 using namespace android;
diff --git a/core/jni/android_view_Display.cpp b/core/jni/android_view_Display.cpp
index bb7b5ef..2e160ae 100644
--- a/core/jni/android_view_Display.cpp
+++ b/core/jni/android_view_Display.cpp
@@ -17,7 +17,7 @@
 #include <stdio.h>
 #include <assert.h>
 
-#include <ui/SurfaceComposerClient.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
 #include <ui/PixelFormat.h>
 #include <ui/DisplayInfo.h>
 
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 40c8aa0..723205a 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -18,7 +18,7 @@
 
 #include "android_util_Binder.h"
 
-#include <ui/SurfaceComposerClient.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
 #include <ui/Region.h>
 #include <ui/Rect.h>
 
diff --git a/core/jni/com_google_android_gles_jni_EGLImpl.cpp b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
index 974fc0b..6a8c4b9 100644
--- a/core/jni/com_google_android_gles_jni_EGLImpl.cpp
+++ b/core/jni/com_google_android_gles_jni_EGLImpl.cpp
@@ -21,7 +21,7 @@
 #include <EGL/egl.h>
 #include <GLES/gl.h>
 
-#include <ui/Surface.h>
+#include <surfaceflinger/Surface.h>
 #include <SkBitmap.h>
 #include <SkPixelRef.h>
 
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 2b8ddc4..7bd07a5 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -156,6 +156,14 @@
         <item>600</item>
     </integer-array>
 
+    <!-- Vibrator pattern for feedback about hitting a scroll barrier -->
+    <integer-array name="config_scrollBarrierVibePattern">
+        <item>0</item>
+        <item>15</item>
+        <item>10</item>
+        <item>10</item>
+    </integer-array>
+
     <bool name="config_use_strict_phone_number_comparation">false</bool>
 
     <!-- Display low battery warning when battery level dips to this value -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 7f66111..9e596ef 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1218,16 +1218,11 @@
     <string name="policydesc_resetPassword">Force your password
         to a new value, requiring the administrator give it to you
         before you can log in.</string>
-    <!-- Title of policy access to limiting the user's unlock timeout -->
-    <string name="policylab_limitUnlock">Limit lock timeout</string>
-    <!-- Description of policy access to limiting the user's unlock timeout -->
-    <string name="policydesc_limitUnlock">Restrict the unlock timeout
-        durations you can select.</string>
     <!-- Title of policy access to force lock the device -->
     <string name="policylab_forceLock">Force lock</string>
     <!-- Description of policy access to limiting the user's password choices -->
-    <string name="policydesc_forceLock">Force the device to immediately lock,
-        requiring that you re-enter its password.</string>
+    <string name="policydesc_forceLock">Control when device locks,
+        requiring you re-enter its password.</string>
     <!-- Title of policy access to wipe the user's data -->
     <string name="policylab_wipeData">Erase all data</string>
     <!-- Description of policy access to wipe the user's data -->
diff --git a/core/res/res/xml-land/password_kbd_qwerty.xml b/core/res/res/xml-land/password_kbd_qwerty.xml
index 8245cc1..700c527 100755
--- a/core/res/res/xml-land/password_kbd_qwerty.xml
+++ b/core/res/res/xml-land/password_kbd_qwerty.xml
@@ -77,10 +77,9 @@
             android:iconPreview="@drawable/sym_keyboard_feedback_space"
             android:keyWidth="20%p"/>
         <Key android:keyLabel="=" />
-        <Key android:keyLabel="."
-            android:keyWidth="10%p"/>
-        <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_return"
-            android:iconPreview="@drawable/sym_keyboard_feedback_return"
+        <Key android:keyLabel="." android:keyWidth="10%p"/>
+        <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_ok"
+            android:iconPreview="@drawable/sym_keyboard_feedback_ok"
             android:keyWidth="20%p" android:keyEdgeFlags="right"/>
     </Row>
 
diff --git a/core/res/res/xml-land/password_kbd_qwerty_shifted.xml b/core/res/res/xml-land/password_kbd_qwerty_shifted.xml
index 6117e78..1e37b6c 100755
--- a/core/res/res/xml-land/password_kbd_qwerty_shifted.xml
+++ b/core/res/res/xml-land/password_kbd_qwerty_shifted.xml
@@ -79,8 +79,8 @@
             android:keyWidth="20%p"/>
         <Key android:keyLabel="+" />
         <Key android:keyLabel="."/>
-        <Key android:keyIcon="@drawable/sym_keyboard_return"
-            android:iconPreview="@drawable/sym_keyboard_feedback_return"
+        <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_ok"
+            android:iconPreview="@drawable/sym_keyboard_feedback_ok"
             android:keyWidth="20%p" android:keyEdgeFlags="right"/>
     </Row>
 
diff --git a/graphics/jni/Android.mk b/graphics/jni/Android.mk
index 799fcbb..8476be1 100644
--- a/graphics/jni/Android.mk
+++ b/graphics/jni/Android.mk
@@ -19,7 +19,8 @@
         libcutils \
         libskia \
         libutils \
-        libui
+        libui \
+        libsurfaceflinger_client 
 
 LOCAL_STATIC_LIBRARIES :=
 
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 4d35c37..0ffdf71 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -23,7 +23,7 @@
 #include <math.h>
 #include <utils/misc.h>
 
-#include <ui/Surface.h>
+#include <surfaceflinger/Surface.h>
 
 #include <core/SkBitmap.h>
 #include <core/SkPixelRef.h>
diff --git a/include/ui/Camera.h b/include/camera/Camera.h
similarity index 98%
rename from include/ui/Camera.h
rename to include/camera/Camera.h
index c506fb8..ee2b30c 100644
--- a/include/ui/Camera.h
+++ b/include/camera/Camera.h
@@ -19,10 +19,12 @@
 #define ANDROID_HARDWARE_CAMERA_H
 
 #include <utils/Timers.h>
-#include <ui/ICameraClient.h>
+#include <camera/ICameraClient.h>
 
 namespace android {
 
+class ISurface;
+
 /*
  * A set of bit masks for specifying how the received preview frames are
  * handled before the previewCallback() call.
diff --git a/include/ui/CameraHardwareInterface.h b/include/camera/CameraHardwareInterface.h
similarity index 98%
rename from include/ui/CameraHardwareInterface.h
rename to include/camera/CameraHardwareInterface.h
index 240c134..d877c74 100644
--- a/include/ui/CameraHardwareInterface.h
+++ b/include/camera/CameraHardwareInterface.h
@@ -19,12 +19,14 @@
 
 #include <binder/IMemory.h>
 #include <utils/RefBase.h>
-#include <ui/ISurface.h>
-#include <ui/Camera.h>
-#include <ui/CameraParameters.h>
-#include <ui/Overlay.h>
+#include <surfaceflinger/ISurface.h>
+#include <camera/Camera.h>
+#include <camera/CameraParameters.h>
 
 namespace android {
+
+class Overlay;
+
 /**
  *  The size of image for display.
  */
diff --git a/include/ui/CameraParameters.h b/include/camera/CameraParameters.h
similarity index 100%
rename from include/ui/CameraParameters.h
rename to include/camera/CameraParameters.h
diff --git a/include/ui/ICamera.h b/include/camera/ICamera.h
similarity index 97%
rename from include/ui/ICamera.h
rename to include/camera/ICamera.h
index 5642691..6fcf9e5 100644
--- a/include/ui/ICamera.h
+++ b/include/camera/ICamera.h
@@ -20,10 +20,10 @@
 #include <utils/RefBase.h>
 #include <binder/IInterface.h>
 #include <binder/Parcel.h>
-#include <ui/ISurface.h>
+#include <surfaceflinger/ISurface.h>
 #include <binder/IMemory.h>
 #include <utils/String8.h>
-#include <ui/Camera.h>
+#include <camera/Camera.h>
 
 namespace android {
 
diff --git a/include/ui/ICameraClient.h b/include/camera/ICameraClient.h
similarity index 100%
rename from include/ui/ICameraClient.h
rename to include/camera/ICameraClient.h
diff --git a/include/ui/ICameraService.h b/include/camera/ICameraService.h
similarity index 95%
rename from include/ui/ICameraService.h
rename to include/camera/ICameraService.h
index 061681a..82b1283 100644
--- a/include/ui/ICameraService.h
+++ b/include/camera/ICameraService.h
@@ -21,8 +21,8 @@
 #include <binder/IInterface.h>
 #include <binder/Parcel.h>
 
-#include <ui/ICameraClient.h>
-#include <ui/ICamera.h>
+#include <camera/ICameraClient.h>
+#include <camera/ICamera.h>
 
 namespace android {
 
diff --git a/include/media/IMediaPlayer.h b/include/media/IMediaPlayer.h
index b6f654f..2619691 100644
--- a/include/media/IMediaPlayer.h
+++ b/include/media/IMediaPlayer.h
@@ -46,6 +46,8 @@
     virtual status_t        setAudioStreamType(int type) = 0;
     virtual status_t        setLooping(int loop) = 0;
     virtual status_t        setVolume(float leftVolume, float rightVolume) = 0;
+    virtual status_t        suspend() = 0;
+    virtual status_t        resume() = 0;
 
     // Invoke a generic method on the player by using opaque parcels
     // for the request and reply.
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index be06e33..9e606d9 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -20,7 +20,6 @@
 #ifdef __cplusplus
 
 #include <sys/types.h>
-#include <ui/ISurface.h>
 #include <utils/Errors.h>
 #include <utils/KeyedVector.h>
 #include <utils/String8.h>
@@ -33,6 +32,8 @@
 namespace android {
 
 class Parcel;
+class ISurface;
+
 template<typename T> class SortedVector;
 
 enum player_type {
@@ -117,6 +118,9 @@
     virtual status_t    reset() = 0;
     virtual status_t    setLooping(int loop) = 0;
     virtual player_type playerType() = 0;
+    virtual status_t    suspend() { return INVALID_OPERATION; }
+    virtual status_t    resume() { return INVALID_OPERATION; }
+
     virtual void        setNotifyCallback(void* cookie, notify_callback_f notifyFunc) {
                             mCookie = cookie; mNotify = notifyFunc; }
     // Invoke a generic method on the player by using opaque parcels
diff --git a/include/media/mediametadataretriever.h b/include/media/mediametadataretriever.h
index 022b849..9b12410 100644
--- a/include/media/mediametadataretriever.h
+++ b/include/media/mediametadataretriever.h
@@ -55,6 +55,7 @@
     METADATA_KEY_WRITER          = 21,
     METADATA_KEY_MIMETYPE        = 22,
     METADATA_KEY_DISC_NUMBER     = 23,
+    METADATA_KEY_ALBUMARTIST     = 24,
     // Add more here...
 };
 
diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h
index c9198d6..7fad1b7 100644
--- a/include/media/mediaplayer.h
+++ b/include/media/mediaplayer.h
@@ -18,7 +18,6 @@
 #define ANDROID_MEDIAPLAYER_H
 
 #include <binder/IMemory.h>
-#include <ui/Surface.h>
 #include <media/IMediaPlayerClient.h>
 #include <media/IMediaPlayer.h>
 #include <media/IMediaDeathNotifier.h>
@@ -28,6 +27,8 @@
 
 namespace android {
 
+class Surface;
+
 enum media_event_type {
     MEDIA_NOP               = 0, // interface test message
     MEDIA_PREPARED          = 1,
@@ -164,6 +165,8 @@
             status_t        invoke(const Parcel& request, Parcel *reply);
             status_t        setMetadataFilter(const Parcel& filter);
             status_t        getMetadata(bool update_only, bool apply_filter, Parcel *metadata);
+            status_t        suspend();
+            status_t        resume();
 private:
             void            clear_l();
             status_t        seekTo_l(int msec);
diff --git a/include/media/stagefright/HardwareAPI.h b/include/media/stagefright/HardwareAPI.h
index b7daddc..221c679 100644
--- a/include/media/stagefright/HardwareAPI.h
+++ b/include/media/stagefright/HardwareAPI.h
@@ -20,7 +20,7 @@
 
 #include <media/stagefright/OMXPluginBase.h>
 #include <media/stagefright/VideoRenderer.h>
-#include <ui/ISurface.h>
+#include <surfaceflinger/ISurface.h>
 #include <utils/RefBase.h>
 
 #include <OMX_Component.h>
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index 8f423f7..45cc4f6 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -51,6 +51,7 @@
 
     kKeyAlbum             = 'albu',  // cstring
     kKeyArtist            = 'arti',  // cstring
+    kKeyAlbumArtist       = 'aart',  // cstring
     kKeyComposer          = 'comp',  // cstring
     kKeyGenre             = 'genr',  // cstring
     kKeyTitle             = 'titl',  // cstring
diff --git a/include/private/ui/LayerState.h b/include/private/surfaceflinger/LayerState.h
similarity index 91%
rename from include/private/ui/LayerState.h
rename to include/private/surfaceflinger/LayerState.h
index f1a2618..d7fe572e 100644
--- a/include/private/ui/LayerState.h
+++ b/include/private/surfaceflinger/LayerState.h
@@ -14,17 +14,18 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_COMPOSER_LAYER_STATE_H
-#define ANDROID_COMPOSER_LAYER_STATE_H
+#ifndef ANDROID_SF_LAYER_STATE_H
+#define ANDROID_SF_LAYER_STATE_H
 
 #include <stdint.h>
 #include <sys/types.h>
 
 #include <utils/Errors.h>
 
-#include <ui/ISurfaceFlingerClient.h>
 #include <ui/Region.h>
 
+#include <surfaceflinger/ISurface.h>
+
 namespace android {
 
 class Parcel;
@@ -69,5 +70,5 @@
 
 }; // namespace android
 
-#endif // ANDROID_COMPOSER_LAYER_STATE_H
+#endif // ANDROID_SF_LAYER_STATE_H
 
diff --git a/include/private/ui/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h
similarity index 98%
rename from include/private/ui/SharedBufferStack.h
rename to include/private/surfaceflinger/SharedBufferStack.h
index bbc1822..9b5a1e0 100644
--- a/include/private/ui/SharedBufferStack.h
+++ b/include/private/surfaceflinger/SharedBufferStack.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_UI_SHARED_BUFFER_STACK_H
-#define ANDROID_UI_SHARED_BUFFER_STACK_H
+#ifndef ANDROID_SF_SHARED_BUFFER_STACK_H
+#define ANDROID_SF_SHARED_BUFFER_STACK_H
 
 #include <stdint.h>
 #include <sys/types.h>
@@ -356,4 +356,4 @@
 // ---------------------------------------------------------------------------
 }; // namespace android
 
-#endif /* ANDROID_UI_SHARED_BUFFER_STACK_H */
+#endif /* ANDROID_SF_SHARED_BUFFER_STACK_H */
diff --git a/include/ui/ISurface.h b/include/surfaceflinger/ISurface.h
similarity index 96%
rename from include/ui/ISurface.h
rename to include/surfaceflinger/ISurface.h
index c7f181c..472f759 100644
--- a/include/ui/ISurface.h
+++ b/include/surfaceflinger/ISurface.h
@@ -14,15 +14,17 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_ISURFACE_H
-#define ANDROID_ISURFACE_H
+#ifndef ANDROID_SF_ISURFACE_H
+#define ANDROID_SF_ISURFACE_H
 
 #include <stdint.h>
 #include <sys/types.h>
 
 #include <utils/Errors.h>
-#include <binder/IInterface.h>
 #include <utils/RefBase.h>
+
+#include <binder/IInterface.h>
+
 #include <ui/PixelFormat.h>
 
 #include <hardware/hardware.h>
@@ -107,4 +109,4 @@
 
 }; // namespace android
 
-#endif // ANDROID_ISURFACE_H
+#endif // ANDROID_SF_ISURFACE_H
diff --git a/include/ui/ISurfaceComposer.h b/include/surfaceflinger/ISurfaceComposer.h
similarity index 89%
rename from include/ui/ISurfaceComposer.h
rename to include/surfaceflinger/ISurfaceComposer.h
index 25d954c..d1e7785 100644
--- a/include/ui/ISurfaceComposer.h
+++ b/include/surfaceflinger/ISurfaceComposer.h
@@ -14,25 +14,24 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_ISURFACE_COMPOSER_H
-#define ANDROID_ISURFACE_COMPOSER_H
+#ifndef ANDROID_SF_ISURFACE_COMPOSER_H
+#define ANDROID_SF_ISURFACE_COMPOSER_H
 
 #include <stdint.h>
 #include <sys/types.h>
 
 #include <utils/RefBase.h>
 #include <utils/Errors.h>
+
 #include <binder/IInterface.h>
 
 #include <ui/PixelFormat.h>
-#include <ui/ISurfaceFlingerClient.h>
+
+#include <surfaceflinger/ISurfaceFlingerClient.h>
 
 namespace android {
-
 // ----------------------------------------------------------------------------
 
-class DisplayInfo;
-
 class ISurfaceComposer : public IInterface
 {
 public:
@@ -92,19 +91,19 @@
     /* retrieve the control block */
     virtual sp<IMemoryHeap> getCblk() const = 0;
 
-    /* open/close transactions. recquires ACCESS_SURFACE_FLINGER permission */
+    /* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */
     virtual void openGlobalTransaction() = 0;
     virtual void closeGlobalTransaction() = 0;
 
-    /* [un]freeze display. recquires ACCESS_SURFACE_FLINGER permission */
+    /* [un]freeze display. requires ACCESS_SURFACE_FLINGER permission */
     virtual status_t freezeDisplay(DisplayID dpy, uint32_t flags) = 0;
     virtual status_t unfreezeDisplay(DisplayID dpy, uint32_t flags) = 0;
 
-    /* Set display orientation. recquires ACCESS_SURFACE_FLINGER permission */
+    /* Set display orientation. requires ACCESS_SURFACE_FLINGER permission */
     virtual int setOrientation(DisplayID dpy, int orientation, uint32_t flags) = 0;
 
     /* signal that we're done booting.
-     * recquires ACCESS_SURFACE_FLINGER permission
+     * Requires ACCESS_SURFACE_FLINGER permission
      */
     virtual void bootFinished() = 0;
 
@@ -143,4 +142,4 @@
 
 }; // namespace android
 
-#endif // ANDROID_ISURFACE_COMPOSER_H
+#endif // ANDROID_SF_ISURFACE_COMPOSER_H
diff --git a/include/ui/ISurfaceFlingerClient.h b/include/surfaceflinger/ISurfaceFlingerClient.h
similarity index 92%
rename from include/ui/ISurfaceFlingerClient.h
rename to include/surfaceflinger/ISurfaceFlingerClient.h
index 5d231e6d..1fba162 100644
--- a/include/ui/ISurfaceFlingerClient.h
+++ b/include/surfaceflinger/ISurfaceFlingerClient.h
@@ -14,28 +14,26 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_ISURFACE_FLINGER_CLIENT_H
-#define ANDROID_ISURFACE_FLINGER_CLIENT_H
+#ifndef ANDROID_SF_ISURFACE_FLINGER_CLIENT_H
+#define ANDROID_SF_ISURFACE_FLINGER_CLIENT_H
 
 #include <stdint.h>
 #include <sys/types.h>
 
 #include <utils/Errors.h>
-#include <binder/IInterface.h>
 #include <utils/RefBase.h>
 
-#include <ui/ISurface.h>
+#include <binder/IInterface.h>
 
 #include <ui/PixelFormat.h>
   
+#include <surfaceflinger/ISurface.h>
+
 namespace android {
 
 // ----------------------------------------------------------------------------
 
-class Rect;
-class Point;
-class IMemory;
-class ISurface;
+class IMemoryHeap;
 
 typedef int32_t    ClientID;
 typedef int32_t    DisplayID;
@@ -89,4 +87,4 @@
 
 }; // namespace android
 
-#endif // ANDROID_ISURFACE_FLINGER_CLIENT_H
+#endif // ANDROID_SF_ISURFACE_FLINGER_CLIENT_H
diff --git a/include/ui/Surface.h b/include/surfaceflinger/Surface.h
similarity index 97%
rename from include/ui/Surface.h
rename to include/surfaceflinger/Surface.h
index 008c297..9808832 100644
--- a/include/ui/Surface.h
+++ b/include/surfaceflinger/Surface.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_UI_SURFACE_H
-#define ANDROID_UI_SURFACE_H
+#ifndef ANDROID_SF_SURFACE_H
+#define ANDROID_SF_SURFACE_H
 
 #include <stdint.h>
 #include <sys/types.h>
@@ -23,13 +23,13 @@
 #include <utils/RefBase.h>
 #include <utils/threads.h>
 
-#include <ui/ISurface.h>
 #include <ui/PixelFormat.h>
 #include <ui/Region.h>
-#include <ui/ISurfaceFlingerClient.h>
-
 #include <ui/egl/android_natives.h>
 
+#include <surfaceflinger/ISurface.h>
+#include <surfaceflinger/ISurfaceFlingerClient.h>
+
 namespace android {
 
 // ---------------------------------------------------------------------------
@@ -250,5 +250,5 @@
 
 }; // namespace android
 
-#endif // ANDROID_UI_SURFACE_H
+#endif // ANDROID_SF_SURFACE_H
 
diff --git a/include/ui/SurfaceComposerClient.h b/include/surfaceflinger/SurfaceComposerClient.h
similarity index 95%
rename from include/ui/SurfaceComposerClient.h
rename to include/surfaceflinger/SurfaceComposerClient.h
index 777b878..49e83c0 100644
--- a/include/ui/SurfaceComposerClient.h
+++ b/include/surfaceflinger/SurfaceComposerClient.h
@@ -14,8 +14,8 @@
  * limitations under the License.
  */
 
-#ifndef ANDROID_SURFACE_COMPOSER_CLIENT_H
-#define ANDROID_SURFACE_COMPOSER_CLIENT_H
+#ifndef ANDROID_SF_SURFACE_COMPOSER_CLIENT_H
+#define ANDROID_SF_SURFACE_COMPOSER_CLIENT_H
 
 #include <stdint.h>
 #include <sys/types.h>
@@ -27,17 +27,18 @@
 #include <utils/threads.h>
 
 #include <ui/PixelFormat.h>
-#include <ui/ISurfaceComposer.h>
 #include <ui/Region.h>
-#include <ui/Surface.h>
+
+#include <surfaceflinger/Surface.h>
 
 namespace android {
 
 // ---------------------------------------------------------------------------
 
 class Region;
-class SurfaceFlingerSynchro;
 class SharedClient;
+class ISurfaceComposer;
+class DisplayInfo;
 
 class SurfaceComposerClient : virtual public RefBase
 {
@@ -158,5 +159,5 @@
 
 }; // namespace android
 
-#endif // ANDROID_SURFACE_COMPOSER_CLIENT_H
+#endif // ANDROID_SF_SURFACE_COMPOSER_CLIENT_H
 
diff --git a/include/utils/AndroidUnicode.h b/include/utils/AndroidUnicode.h
index 563fcd0..2b185d3 100644
--- a/include/utils/AndroidUnicode.h
+++ b/include/utils/AndroidUnicode.h
@@ -79,69 +79,6 @@
         };
 
         /**
-         * Character types as specified in the Unicode standard. These map directly to
-         * java.lang.Character.
-         */
-        enum CharType {
-            CHARTYPE_UNASSIGNED = 0,
-            CHARTYPE_UPPERCASE_LETTER,
-            CHARTYPE_LOWERCASE_LETTER,
-            CHARTYPE_TITLECASE_LETTER,
-            CHARTYPE_MODIFIER_LETTER,
-            CHARTYPE_OTHER_LETTER,
-            CHARTYPE_NON_SPACING_MARK,
-            CHARTYPE_ENCLOSING_MARK,
-            CHARTYPE_COMBINING_SPACING_MARK,
-            CHARTYPE_DECIMAL_DIGIT_NUMBER,
-            CHARTYPE_LETTER_NUMBER,
-            CHARTYPE_OTHER_NUMBER,
-            CHARTYPE_SPACE_SEPARATOR,
-            CHARTYPE_LINE_SEPARATOR,
-            CHARTYPE_PARAGRAPH_SEPARATOR,
-            CHARTYPE_CONTROL,
-            CHARTYPE_FORMAT,
-            CHARTYPE_MISSING_VALUE_FOR_JAVA,    /* This is the mysterious missing 17 value from the java constants */
-            CHARTYPE_PRIVATE_USE,
-            CHARTYPE_SURROGATE,
-            CHARTYPE_DASH_PUNCTUATION,
-            CHARTYPE_START_PUNCTUATION,
-            CHARTYPE_END_PUNCTUATION,
-            CHARTYPE_CONNECTOR_PUNCTUATION,
-            CHARTYPE_OTHER_PUNCTUATION,
-            CHARTYPE_MATH_SYMBOL,
-            CHARTYPE_CURRENCY_SYMBOL,
-            CHARTYPE_MODIFIER_SYMBOL,
-            CHARTYPE_OTHER_SYMBOL,
-            CHARTYPE_INITIAL_QUOTE_PUNCTUATION,
-            CHARTYPE_FINAL_QUOTE_PUNCTUATION
-        };
-
-        /**
-         * Decomposition types as described by the unicode standard. These values map to
-         * the same values in uchar.h in ICU.
-         */
-        enum DecompositionType {
-            DECOMPOSITION_NONE = 0,
-            DECOMPOSITION_CANONICAL,
-            DECOMPOSITION_COMPAT,
-            DECOMPOSITION_CIRCLE,
-            DECOMPOSITION_FINAL,
-            DECOMPOSITION_FONT,
-            DECOMPOSITION_FRACTION,
-            DECOMPOSITION_INITIAL,
-            DECOMPOSITION_ISOLATED,
-            DECOMPOSITION_MEDIAL,
-            DECOMPOSITION_NARROW,
-            DECOMPOSITION_NOBREAK,
-            DECOMPOSITION_SMALL,
-            DECOMPOSITION_SQUARE,
-            DECOMPOSITION_SUB,
-            DECOMPOSITION_SUPER,
-            DECOMPOSITION_VERTICAL,
-            DECOMPOSITION_WIDE
-        };
-
-        /**
          * Returns the packed data for java calls
          * @param c The unicode character.
          * @return The packed data for the character.
@@ -162,61 +99,6 @@
         static uint32_t getPackedData(UChar32 c);
         
         /**
-         * Get the Character type.
-         * @param c The unicode character.
-         * @return The character's type or CHARTYPE_UNASSIGNED if the character is invalid
-         *         or has an unassigned class.
-         */
-        static CharType getType(UChar32 c);    
-
-        /**
-         * Get the Character's decomposition type.
-         * @param c The unicode character.
-         * @return The character's decomposition type or DECOMPOSITION_NONE is there 
-         *         is no decomposition.
-         */
-        static DecompositionType getDecompositionType(UChar32 c);
-        
-        /**
-         * Returns the digit value of a character or -1 if the character
-         * is not within the specified radix.
-         *
-         * The digit value is computed for integer characters and letters
-         * within the given radix. This function does not handle Roman Numerals,
-         * fractions, or any other characters that may represent numbers.
-         * 
-         * @param c The unicode character
-         * @param radix The intended radix.
-         * @return The digit value or -1 if there is no digit value or if the value is outside the radix.
-         */
-        static int getDigitValue(UChar32 c, int radix = 10);
-
-        /**
-         * Return the numeric value of a character
-         *
-         * @param c The unicode character.
-         * @return The numeric value of the character. -1 if the character has no numeric value, 
-         *         -2 if the character has a numeric value that is not representable by an integer.
-         */
-        static int getNumericValue(UChar32 c);
-
-        /**
-         * Convert the character to lowercase
-         * @param c The unicode character.
-         * @return The lowercase character equivalent of c. If c does not have a lowercase equivalent,
-         *         the original character is returned.
-         */
-        static UChar32 toLower(UChar32 c);
-            
-        /**
-         * Convert the character to uppercase
-         * @param c The unicode character.
-         * @return The uppercase character equivalent of c. If c does not have an uppercase equivalent,
-         *         the original character is returned.
-         */
-        static UChar32 toUpper(UChar32 c);
-    
-        /**
          * Get the directionality of the character.
          * @param c The unicode character.
          * @return The direction of the character or DIRECTIONALITY_UNDEFINED.
@@ -239,15 +121,6 @@
          * @see isMirrored
          */
         static UChar32 toMirror(UChar32 c);
-        
-        /**
-         * Convert the character to title case.
-         * @param c The unicode character.
-         * @return The titlecase equivalent of c. If c does not have a titlecase equivalent,
-         *         the original character is returned.
-         */
-        static UChar32 toTitle(UChar32 c);
-
    };
 
 }
diff --git a/libs/camera/Android.mk b/libs/camera/Android.mk
new file mode 100644
index 0000000..03ff229
--- /dev/null
+++ b/libs/camera/Android.mk
@@ -0,0 +1,25 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	Camera.cpp \
+	CameraParameters.cpp \
+	ICamera.cpp \
+	ICameraClient.cpp \
+	ICameraService.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+	libutils \
+	libbinder \
+	libhardware \
+	libsurfaceflinger_client \
+	libui
+
+LOCAL_MODULE:= libcamera_client
+
+ifeq ($(TARGET_SIMULATOR),true)
+    LOCAL_LDLIBS += -lpthread
+endif
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/ui/Camera.cpp b/libs/camera/Camera.cpp
similarity index 98%
rename from libs/ui/Camera.cpp
rename to libs/camera/Camera.cpp
index f374fbc..8620e71 100644
--- a/libs/ui/Camera.cpp
+++ b/libs/camera/Camera.cpp
@@ -19,12 +19,15 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "Camera"
 #include <utils/Log.h>
-#include <binder/IServiceManager.h>
 #include <utils/threads.h>
+
+#include <binder/IServiceManager.h>
 #include <binder/IMemory.h>
-#include <ui/Surface.h>
-#include <ui/Camera.h>
-#include <ui/ICameraService.h>
+
+#include <camera/Camera.h>
+#include <camera/ICameraService.h>
+
+#include <surfaceflinger/Surface.h>
 
 namespace android {
 
diff --git a/libs/ui/CameraParameters.cpp b/libs/camera/CameraParameters.cpp
similarity index 99%
rename from libs/ui/CameraParameters.cpp
rename to libs/camera/CameraParameters.cpp
index 493b9c1..1bf1759 100644
--- a/libs/ui/CameraParameters.cpp
+++ b/libs/camera/CameraParameters.cpp
@@ -20,7 +20,7 @@
 
 #include <string.h>
 #include <stdlib.h>
-#include <ui/CameraParameters.h>
+#include <camera/CameraParameters.h>
 
 namespace android {
 // Parameter keys to communicate between camera application and driver.
diff --git a/libs/ui/ICamera.cpp b/libs/camera/ICamera.cpp
similarity index 99%
rename from libs/ui/ICamera.cpp
rename to libs/camera/ICamera.cpp
index 4154b05a..724bd20 100644
--- a/libs/ui/ICamera.cpp
+++ b/libs/camera/ICamera.cpp
@@ -21,7 +21,7 @@
 #include <stdint.h>
 #include <sys/types.h>
 #include <binder/Parcel.h>
-#include <ui/ICamera.h>
+#include <camera/ICamera.h>
 
 namespace android {
 
diff --git a/libs/ui/ICameraClient.cpp b/libs/camera/ICameraClient.cpp
similarity index 98%
rename from libs/ui/ICameraClient.cpp
rename to libs/camera/ICameraClient.cpp
index 42b4da4..cb3bd0c 100644
--- a/libs/ui/ICameraClient.cpp
+++ b/libs/camera/ICameraClient.cpp
@@ -20,7 +20,7 @@
 #include <utils/Log.h>
 #include <stdint.h>
 #include <sys/types.h>
-#include <ui/ICameraClient.h>
+#include <camera/ICameraClient.h>
 
 namespace android {
 
diff --git a/libs/ui/ICameraService.cpp b/libs/camera/ICameraService.cpp
similarity index 98%
rename from libs/ui/ICameraService.cpp
rename to libs/camera/ICameraService.cpp
index 84986c6..46b5478 100644
--- a/libs/ui/ICameraService.cpp
+++ b/libs/camera/ICameraService.cpp
@@ -22,7 +22,7 @@
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 
-#include <ui/ICameraService.h>
+#include <camera/ICameraService.h>
 
 namespace android {
 
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index ac115d3..10e5285 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -29,7 +29,7 @@
 ContextSetSurface {
 	param uint32_t width
 	param uint32_t height
-	param void *sur
+	param android_native_window_t *sur
 	}
 
 ContextDump {
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 2e47ea3..dec993a 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -19,6 +19,7 @@
 #include "rsThreadIO.h"
 #include <ui/FramebufferNativeWindow.h>
 #include <ui/EGLUtils.h>
+#include <ui/egl/android_natives.h>
 
 #include <sys/types.h>
 #include <sys/resource.h>
@@ -460,7 +461,7 @@
     objDestroyOOBDestroy();
 }
 
-void Context::setSurface(uint32_t w, uint32_t h, Surface *sur)
+void Context::setSurface(uint32_t w, uint32_t h, android_native_window_t *sur)
 {
     rsAssert(mIsGraphicsContext);
 
@@ -856,9 +857,9 @@
     rsc->resume();
 }
 
-void rsi_ContextSetSurface(Context *rsc, uint32_t w, uint32_t h, void *sur)
+void rsi_ContextSetSurface(Context *rsc, uint32_t w, uint32_t h, android_native_window_t *sur)
 {
-    rsc->setSurface(w, h, (Surface *)sur);
+    rsc->setSurface(w, h, sur);
 }
 
 void rsi_ContextSetPriority(Context *rsc, int32_t p)
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index 31d8cc8..03e65f1 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -19,8 +19,6 @@
 
 #include "rsUtils.h"
 
-#include <ui/Surface.h>
-
 #include "rsThreadIO.h"
 #include "rsType.h"
 #include "rsMatrix.h"
@@ -43,9 +41,11 @@
 #include "rsgApiStructs.h"
 #include "rsLocklessFifo.h"
 
+#include <ui/egl/android_natives.h>
 
 // ---------------------------------------------------------------------------
 namespace android {
+
 namespace renderscript {
 
 class Context
@@ -98,7 +98,7 @@
 
     void pause();
     void resume();
-    void setSurface(uint32_t w, uint32_t h, Surface *sur);
+    void setSurface(uint32_t w, uint32_t h, android_native_window_t *sur);
     void setPriority(int32_t p);
 
     void assignName(ObjectBase *obj, const char *name, uint32_t len);
@@ -238,7 +238,7 @@
 
     static void * threadProc(void *);
 
-    Surface *mWndSurface;
+    android_native_window_t *mWndSurface;
 
     Vector<ObjectBase *> mNames;
 
diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk
index b3fed58..395a937 100644
--- a/libs/surfaceflinger/Android.mk
+++ b/libs/surfaceflinger/Android.mk
@@ -39,7 +39,8 @@
 	libEGL \
 	libGLESv1_CM \
 	libbinder \
-	libui
+	libui \
+	libsurfaceflinger_client
 
 LOCAL_C_INCLUDES := \
 	$(call include-path-for, corecg graphics)
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index 1870d3a..f38efab 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -27,7 +27,8 @@
 
 #include <ui/GraphicBuffer.h>
 #include <ui/PixelFormat.h>
-#include <ui/Surface.h>
+
+#include <surfaceflinger/Surface.h>
 
 #include "clz.h"
 #include "Layer.h"
diff --git a/libs/surfaceflinger/LayerBase.h b/libs/surfaceflinger/LayerBase.h
index f73ea0c..a49faf7 100644
--- a/libs/surfaceflinger/LayerBase.h
+++ b/libs/surfaceflinger/LayerBase.h
@@ -23,14 +23,15 @@
 #include <EGL/egl.h>
 #include <EGL/eglext.h>
 
-#include <private/ui/SharedBufferStack.h>
-#include <private/ui/LayerState.h>
-
 #include <utils/RefBase.h>
 
 #include <ui/Region.h>
 #include <ui/Overlay.h>
 
+#include <surfaceflinger/ISurfaceFlingerClient.h>
+#include <private/surfaceflinger/SharedBufferStack.h>
+#include <private/surfaceflinger/LayerState.h>
+
 #include <pixelflinger/pixelflinger.h>
 
 #include "Transform.h"
diff --git a/libs/surfaceflinger/LayerBlur.h b/libs/surfaceflinger/LayerBlur.h
index 2e9d7c6..5b63dec 100644
--- a/libs/surfaceflinger/LayerBlur.h
+++ b/libs/surfaceflinger/LayerBlur.h
@@ -20,8 +20,6 @@
 #include <stdint.h>
 #include <sys/types.h>
 
-#include <private/ui/LayerState.h>
-
 #include <ui/Region.h>
 
 #include "LayerBase.h"
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index 2b7820c..4520c0e 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -31,11 +31,8 @@
 #include <binder/Permission.h>
 
 #include <ui/PixelFormat.h>
-#include <ui/ISurfaceComposer.h>
-#include <ui/ISurfaceFlingerClient.h>
-
-#include <private/ui/SharedBufferStack.h>
-#include <private/ui/LayerState.h>
+#include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/ISurfaceFlingerClient.h>
 
 #include "Barrier.h"
 #include "Layer.h"
diff --git a/libs/surfaceflinger/tests/overlays/Android.mk b/libs/surfaceflinger/tests/overlays/Android.mk
index dc47e45..592b601 100644
--- a/libs/surfaceflinger/tests/overlays/Android.mk
+++ b/libs/surfaceflinger/tests/overlays/Android.mk
@@ -7,7 +7,8 @@
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
 	libutils \
-    libui
+    libui \
+    libsurfaceflinger_client
 
 LOCAL_MODULE:= test-overlays
 
diff --git a/libs/surfaceflinger/tests/overlays/overlays.cpp b/libs/surfaceflinger/tests/overlays/overlays.cpp
index 0b9322e..c248a61 100644
--- a/libs/surfaceflinger/tests/overlays/overlays.cpp
+++ b/libs/surfaceflinger/tests/overlays/overlays.cpp
@@ -3,10 +3,11 @@
 #include <binder/IServiceManager.h>
 #include <utils/Log.h>
 
-#include <ui/Surface.h>
-#include <ui/ISurface.h>
 #include <ui/Overlay.h>
-#include <ui/SurfaceComposerClient.h>
+
+#include <surfaceflinger/Surface.h>
+#include <surfaceflinger/ISurface.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
 
 using namespace android;
 
diff --git a/libs/surfaceflinger/tests/resize/Android.mk b/libs/surfaceflinger/tests/resize/Android.mk
index ef1532f..24c2d01 100644
--- a/libs/surfaceflinger/tests/resize/Android.mk
+++ b/libs/surfaceflinger/tests/resize/Android.mk
@@ -7,7 +7,8 @@
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
 	libutils \
-    libui
+    libui \
+    libsurfaceflinger_client
 
 LOCAL_MODULE:= test-resize
 
diff --git a/libs/surfaceflinger/tests/resize/resize.cpp b/libs/surfaceflinger/tests/resize/resize.cpp
index 21c6ab6..127cca3 100644
--- a/libs/surfaceflinger/tests/resize/resize.cpp
+++ b/libs/surfaceflinger/tests/resize/resize.cpp
@@ -1,14 +1,16 @@
 #include <cutils/memory.h>
 
-#include <utils/IPCThreadState.h>
-#include <utils/ProcessState.h>
-#include <utils/IServiceManager.h>
 #include <utils/Log.h>
 
-#include <ui/Surface.h>
-#include <ui/ISurface.h>
+#include <binder/IPCThreadState.h>
+#include <binder/ProcessState.h>
+#include <binder/IServiceManager.h>
+
+#include <surfaceflinger/Surface.h>
+#include <surfaceflinger/ISurface.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
+
 #include <ui/Overlay.h>
-#include <ui/SurfaceComposerClient.h>
 
 using namespace android;
 
diff --git a/libs/surfaceflinger_client/Android.mk b/libs/surfaceflinger_client/Android.mk
new file mode 100644
index 0000000..fe85b34
--- /dev/null
+++ b/libs/surfaceflinger_client/Android.mk
@@ -0,0 +1,26 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+	ISurfaceComposer.cpp \
+	ISurface.cpp \
+	ISurfaceFlingerClient.cpp \
+	LayerState.cpp \
+	SharedBufferStack.cpp \
+	Surface.cpp \
+	SurfaceComposerClient.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+	libcutils \
+	libutils \
+	libbinder \
+	libhardware \
+	libui
+
+LOCAL_MODULE:= libsurfaceflinger_client
+
+ifeq ($(TARGET_SIMULATOR),true)
+    LOCAL_LDLIBS += -lpthread
+endif
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/ui/ISurface.cpp b/libs/surfaceflinger_client/ISurface.cpp
similarity index 98%
rename from libs/ui/ISurface.cpp
rename to libs/surfaceflinger_client/ISurface.cpp
index 6f3d762..9125146 100644
--- a/libs/ui/ISurface.cpp
+++ b/libs/surfaceflinger_client/ISurface.cpp
@@ -23,12 +23,12 @@
 #include <binder/Parcel.h>
 #include <binder/IMemory.h>
 
-#include <ui/ISurface.h>
 #include <ui/Overlay.h>
-#include <ui/Surface.h>
-
 #include <ui/GraphicBuffer.h>
 
+#include <surfaceflinger/Surface.h>
+#include <surfaceflinger/ISurface.h>
+
 namespace android {
 
 // ----------------------------------------------------------------------
diff --git a/libs/ui/ISurfaceComposer.cpp b/libs/surfaceflinger_client/ISurfaceComposer.cpp
similarity index 98%
rename from libs/ui/ISurfaceComposer.cpp
rename to libs/surfaceflinger_client/ISurfaceComposer.cpp
index fd2a590..b6f4e24 100644
--- a/libs/ui/ISurfaceComposer.cpp
+++ b/libs/surfaceflinger_client/ISurfaceComposer.cpp
@@ -25,9 +25,10 @@
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 
-#include <ui/ISurfaceComposer.h>
 #include <ui/DisplayInfo.h>
 
+#include <surfaceflinger/ISurfaceComposer.h>
+
 // ---------------------------------------------------------------------------
 
 #define LIKELY( exp )       (__builtin_expect( (exp) != 0, true  ))
diff --git a/libs/ui/ISurfaceFlingerClient.cpp b/libs/surfaceflinger_client/ISurfaceFlingerClient.cpp
similarity index 97%
rename from libs/ui/ISurfaceFlingerClient.cpp
rename to libs/surfaceflinger_client/ISurfaceFlingerClient.cpp
index 4a6a1d7..e636c52 100644
--- a/libs/ui/ISurfaceFlingerClient.cpp
+++ b/libs/surfaceflinger_client/ISurfaceFlingerClient.cpp
@@ -26,12 +26,12 @@
 #include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 
-#include <ui/ISurface.h>
-#include <ui/ISurfaceFlingerClient.h>
 #include <ui/Point.h>
 #include <ui/Rect.h>
 
-#include <private/ui/LayerState.h>
+#include <surfaceflinger/ISurface.h>
+#include <surfaceflinger/ISurfaceFlingerClient.h>
+#include <private/surfaceflinger/LayerState.h>
 
 // ---------------------------------------------------------------------------
 
diff --git a/libs/ui/LayerState.cpp b/libs/surfaceflinger_client/LayerState.cpp
similarity index 82%
rename from libs/ui/LayerState.cpp
rename to libs/surfaceflinger_client/LayerState.cpp
index a53ffb7..114a9e9 100644
--- a/libs/ui/LayerState.cpp
+++ b/libs/surfaceflinger_client/LayerState.cpp
@@ -16,37 +16,25 @@
 
 #include <utils/Errors.h>
 #include <binder/Parcel.h>
-#include <private/ui/LayerState.h>
+#include <private/surfaceflinger/LayerState.h>
 
 namespace android {
 
 status_t layer_state_t::write(Parcel& output) const
 {
     size_t size = sizeof(layer_state_t);
-
-    //output.writeStrongBinder(surface->asBinder());
-    //size -= sizeof(surface);
-
     transparentRegion.write(output);
     size -= sizeof(transparentRegion);
-    
     output.write(this, size);
-    
     return NO_ERROR;
 }
 
 status_t layer_state_t::read(const Parcel& input)
 {
     size_t size = sizeof(layer_state_t);
-
-    //surface = interface_cast<ISurface>(input.readStrongBinder());
-    //size -= sizeof(surface);
-
     transparentRegion.read(input);
     size -= sizeof(transparentRegion);
-
     input.read(this, size);
-    
     return NO_ERROR;
 }
 
diff --git a/libs/ui/SharedBufferStack.cpp b/libs/surfaceflinger_client/SharedBufferStack.cpp
similarity index 99%
rename from libs/ui/SharedBufferStack.cpp
rename to libs/surfaceflinger_client/SharedBufferStack.cpp
index 46b6766..ceb5e59 100644
--- a/libs/ui/SharedBufferStack.cpp
+++ b/libs/surfaceflinger_client/SharedBufferStack.cpp
@@ -23,7 +23,7 @@
 #include <utils/Log.h>
 #include <utils/threads.h>
 
-#include <private/ui/SharedBufferStack.h>
+#include <private/surfaceflinger/SharedBufferStack.h>
 
 #include <ui/Rect.h>
 #include <ui/Region.h>
diff --git a/libs/ui/Surface.cpp b/libs/surfaceflinger_client/Surface.cpp
similarity index 98%
rename from libs/ui/Surface.cpp
rename to libs/surfaceflinger_client/Surface.cpp
index c7be05b..eb3457b 100644
--- a/libs/ui/Surface.cpp
+++ b/libs/surfaceflinger_client/Surface.cpp
@@ -26,22 +26,25 @@
 #include <utils/Errors.h>
 #include <utils/threads.h>
 #include <utils/CallStack.h>
+#include <utils/Log.h>
+
+#include <pixelflinger/pixelflinger.h>
+
 #include <binder/IPCThreadState.h>
 #include <binder/IMemory.h>
-#include <utils/Log.h>
 
 #include <ui/DisplayInfo.h>
 #include <ui/GraphicBuffer.h>
 #include <ui/GraphicBufferMapper.h>
-#include <ui/ISurface.h>
-#include <ui/Surface.h>
-#include <ui/SurfaceComposerClient.h>
 #include <ui/Rect.h>
 
-#include <pixelflinger/pixelflinger.h>
+#include <surfaceflinger/Surface.h>
+#include <surfaceflinger/ISurface.h>
+#include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
 
-#include <private/ui/SharedBufferStack.h>
-#include <private/ui/LayerState.h>
+#include <private/surfaceflinger/SharedBufferStack.h>
+#include <private/surfaceflinger/LayerState.h>
 
 namespace android {
 
diff --git a/libs/ui/SurfaceComposerClient.cpp b/libs/surfaceflinger_client/SurfaceComposerClient.cpp
similarity index 97%
rename from libs/ui/SurfaceComposerClient.cpp
rename to libs/surfaceflinger_client/SurfaceComposerClient.cpp
index eda84ef..0b5e504 100644
--- a/libs/ui/SurfaceComposerClient.cpp
+++ b/libs/surfaceflinger_client/SurfaceComposerClient.cpp
@@ -29,19 +29,21 @@
 #include <utils/Errors.h>
 #include <utils/threads.h>
 #include <utils/KeyedVector.h>
-#include <binder/IServiceManager.h>
-#include <binder/IMemory.h>
 #include <utils/Log.h>
 
+#include <binder/IServiceManager.h>
+#include <binder/IMemory.h>
+
 #include <ui/DisplayInfo.h>
-#include <ui/ISurfaceComposer.h>
-#include <ui/ISurfaceFlingerClient.h>
-#include <ui/ISurface.h>
-#include <ui/SurfaceComposerClient.h>
 #include <ui/Rect.h>
 
-#include <private/ui/LayerState.h>
-#include <private/ui/SharedBufferStack.h>
+#include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/ISurfaceFlingerClient.h>
+#include <surfaceflinger/ISurface.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
+
+#include <private/surfaceflinger/LayerState.h>
+#include <private/surfaceflinger/SharedBufferStack.h>
 
 #define VERBOSE(...)	((void)0)
 //#define VERBOSE			LOGD
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
index 84aec61..f7acd97 100644
--- a/libs/ui/Android.mk
+++ b/libs/ui/Android.mk
@@ -2,8 +2,6 @@
 include $(CLEAR_VARS)
 
 LOCAL_SRC_FILES:= \
-	Camera.cpp \
-	CameraParameters.cpp \
 	EGLUtils.cpp \
 	EventHub.cpp \
 	EventRecurrence.cpp \
@@ -13,21 +11,11 @@
 	GraphicBufferMapper.cpp \
 	KeyLayoutMap.cpp \
 	KeyCharacterMap.cpp \
-	ICamera.cpp \
-	ICameraClient.cpp \
-	ICameraService.cpp \
 	IOverlay.cpp \
-	ISurfaceComposer.cpp \
-	ISurface.cpp \
-	ISurfaceFlingerClient.cpp \
-	LayerState.cpp \
 	Overlay.cpp \
 	PixelFormat.cpp \
 	Rect.cpp \
-	Region.cpp \
-	SharedBufferStack.cpp \
-	Surface.cpp \
-	SurfaceComposerClient.cpp
+	Region.cpp
 
 LOCAL_SHARED_LIBRARIES := \
 	libcutils \
diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp
index c5e22e5..1fa2c68 100644
--- a/libs/ui/FramebufferNativeWindow.cpp
+++ b/libs/ui/FramebufferNativeWindow.cpp
@@ -27,7 +27,6 @@
 #include <utils/threads.h>
 #include <utils/RefBase.h>
 
-#include <ui/SurfaceComposerClient.h>
 #include <ui/Rect.h>
 #include <ui/FramebufferNativeWindow.h>
 
diff --git a/libs/utils/CharacterData.h b/libs/utils/CharacterData.h
index e931d99..d9b7c56 100644
--- a/libs/utils/CharacterData.h
+++ b/libs/utils/CharacterData.h
@@ -615,32 +615,6 @@
         {0, 0}
     };
 
-    // Array of uppercase differences
-    static const short UCDIFF[] = {
-            0,   -32,   743,   121,    -1,  -232,  -300,    97, 
-          163,   130,    56,    -2,   -79,  -210,  -206,  -205, 
-         -202,  -203,  -207,  -209,  -211,  -213,  -214,  -218, 
-         -217,  -219,   -83,    84,   -38,   -37,   -31,   -64, 
-          -63,   -62,   -57,   -47,   -54,   -86,   -80,     7, 
-          -96,   -48,   -59,     8,    74,    86,   100,   128, 
-          112,   126,     9, -7205,   -16,   -26, -7264,   -40
-    };
-
-    // Array of lowercase differences
-    static const short LCDIFF[] = {
-            0,    32,     1,  -199,  -121,   210,   206,   205, 
-           79,   202,   203,   207,   211,   209,   213,   214, 
-          218,   217,   219,     2,   -97,   -56,  -130,  -163, 
-           83,    38,    37,    64,    63,   -60,    -7,    80, 
-           48,  7264,    -8,   -74,    -9,   -86,  -100,  -112, 
-         -128,  -126, -7517, -8383, -8262,    16,    26,    40
-    };
-
-    // Array of titlecase differences
-    static const short TCDIFF[] = {
-            3,     1,     0,    -1
-    };
-
     // Array of mirrored character differences
     static const short MIRROR_DIFF[] = {
             0,     1,    -1,     2,    -2,    16,   -16,     3, 
@@ -649,21 +623,6 @@
         -2108
     };
 
-   // Array of all possible numeric values
-   static const int NUMERICS[] = {
-            -1,      0,      1,      2,      3,      4,      5,      6, 
-             7,      8,      9,     10,     11,     12,     13,     14, 
-            15,     16,     17,     18,     19,     20,     21,     22, 
-            23,     24,     25,     26,     27,     28,     29,     30, 
-            31,     32,     33,     34,     35,     -2,    100,   1000, 
-            40,     50,     60,     70,     80,     90,  10000,    500, 
-          5000,     36,     37,     38,     39,     41,     42,     43, 
-            44,     45,     46,     47,     48,     49,    200,    300, 
-           400,    600,    700,    800,    900,   2000,   3000,   4000, 
-          6000,   7000,   8000,   9000,  20000,  30000,  40000,  50000, 
-         60000,  70000,  80000,  90000
-    };
-
     // All possible packed data values, no duplicates
     static const uint32_t PACKED_DATA[] = {
         0x00000000, 0x0000012F, 0x0000016F, 0x0000014F, 0x0000018F, 0x0000018C, 0x000001B8, 0x000000B8, 
diff --git a/libs/utils/Unicode.cpp b/libs/utils/Unicode.cpp
index f92703e..65dbb4a 100644
--- a/libs/utils/Unicode.cpp
+++ b/libs/utils/Unicode.cpp
@@ -103,55 +103,6 @@
     return CharacterData::PACKED_DATA[findCharacterValue(c) & 0x7FF];
 }
 
-android::Unicode::CharType android::Unicode::getType(UChar32 c)
-{
-    if (c < 0 || c >= 0x10FFFF)
-        return CHARTYPE_UNASSIGNED;
-    return (CharType)((getPackedData(c) >> TYPE_SHIFT) & TYPE_MASK);
-}
-
-android::Unicode::DecompositionType android::Unicode::getDecompositionType(UChar32 c)
-{
-    // findCharacterValue returns a 16-bit value with the top 5 bits containing a decomposition type
-    // and the remaining bits containing an index.
-    return (DecompositionType)((findCharacterValue(c) >> DECOMPOSITION_SHIFT) & DECOMPOSITION_MASK);
-}
-
-int android::Unicode::getDigitValue(UChar32 c, int radix)
-{
-    if (radix < MIN_RADIX || radix > MAX_RADIX)
-        return -1;
-
-    int tempValue = radix;
-    
-    if (c >= '0' && c <= '9')
-        tempValue = c - '0';
-    else if (c >= 'a' && c <= 'z')
-        tempValue = c - 'a' + 10;
-    else if (c >= 'A' && c <= 'Z')
-        tempValue = c - 'A' + 10;
-    
-    return tempValue < radix ? tempValue : -1;
-}
-
-int android::Unicode::getNumericValue(UChar32 c)
-{
-    if (isMirrored(c))
-        return -1;
-    
-    return (int) CharacterData::NUMERICS[((getPackedData(c) >> NUMERIC_SHIFT) & NUMERIC_MASK)];
-}
-
-UChar32 android::Unicode::toLower(UChar32 c)
-{
-    return c + CharacterData::LCDIFF[(getPackedData(c) >> TOLOWER_SHIFT) & TOLOWER_MASK];
-}
-
-UChar32 android::Unicode::toUpper(UChar32 c)
-{
-    return c + CharacterData::UCDIFF[(getPackedData(c) >> TOUPPER_SHIFT) & TOUPPER_MASK];
-}
-
 android::Unicode::Direction android::Unicode::getDirectionality(UChar32 c)
 {
     uint32_t data = getPackedData(c);
@@ -179,15 +130,3 @@
 
     return c + CharacterData::MIRROR_DIFF[(getPackedData(c) >> MIRROR_SHIFT) & MIRROR_MASK];
 }
-
-UChar32 android::Unicode::toTitle(UChar32 c)
-{
-    int32_t diff = CharacterData::TCDIFF[(getPackedData(c) >> TOTITLE_SHIFT) & TOTITLE_MASK];
-
-    if (TOTITLE_MASK == diff)
-        return toUpper(c);
-    
-    return c + diff;
-}
-
-
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index 171881f..70c27c2 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -751,6 +751,8 @@
      */
     public boolean isWiredHeadsetOn() {
         if (AudioSystem.getDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADSET,"")
+                == AudioSystem.DEVICE_STATE_UNAVAILABLE &&
+            AudioSystem.getDeviceConnectionState(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE,"")
                 == AudioSystem.DEVICE_STATE_UNAVAILABLE) {
             return false;
         } else {
diff --git a/media/java/android/media/MediaMetadataRetriever.java b/media/java/android/media/MediaMetadataRetriever.java
index 04f8b5d..681751b 100644
--- a/media/java/android/media/MediaMetadataRetriever.java
+++ b/media/java/android/media/MediaMetadataRetriever.java
@@ -21,10 +21,10 @@
 import android.content.res.AssetFileDescriptor;
 import android.graphics.Bitmap;
 import android.net.Uri;
-import android.os.ParcelFileDescriptor;
+
 import java.io.FileDescriptor;
-import java.io.IOException;
 import java.io.FileNotFoundException;
+import java.io.IOException;
 
 /**
  * MediaMetadataRetriever class provides a unified interface for retrieving
@@ -256,5 +256,7 @@
     public static final int METADATA_KEY_VIDEO_WIDTH     = 20;
     public static final int METADATA_KEY_WRITER          = 21;
     public static final int METADATA_KEY_MIMETYPE        = 22;
+    public static final int METADATA_KEY_DISCNUMBER      = 23;
+    public static final int METADATA_KEY_ALBUMARTIST     = 24;
     // Add more here...
 }
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index 89ee7d3..e8b89e0 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -1064,6 +1064,53 @@
     private native void _reset();
 
     /**
+     * Suspends the MediaPlayer. The only methods that may be called while
+     * suspended are {@link #reset()}, {@link #release()} and {@link #resume()}.
+     * MediaPlayer will release its hardware resources as far as
+     * possible and reasonable. A successfully suspended MediaPlayer will
+     * cease sending events.
+     * If suspension is successful, this method returns true, otherwise
+     * false is returned and the player's state is not affected.
+     * @hide
+     */
+    public boolean suspend() {
+        if (native_suspend_resume(true) < 0) {
+            return false;
+        }
+
+        stayAwake(false);
+
+        // make sure none of the listeners get called anymore
+        mEventHandler.removeCallbacksAndMessages(null);
+
+        return true;
+    }
+
+    /**
+     * Resumes the MediaPlayer. Only to be called after a previous (successful)
+     * call to {@link #suspend()}.
+     * MediaPlayer will return to a state close to what it was in before
+     * suspension.
+     * @hide
+     */
+    public boolean resume() {
+        if (native_suspend_resume(false) < 0) {
+            return false;
+        }
+
+        if (isPlaying()) {
+            stayAwake(true);
+        }
+
+        return true;
+    }
+
+    /**
+     * @hide
+     */
+    private native int native_suspend_resume(boolean isSuspend);
+
+    /**
      * Sets the audio stream type for this MediaPlayer. See {@link AudioManager}
      * for a list of stream types.
      *
diff --git a/media/jni/Android.mk b/media/jni/Android.mk
index d83f493..a6a25cd 100644
--- a/media/jni/Android.mk
+++ b/media/jni/Android.mk
@@ -21,7 +21,9 @@
     libmedia \
     libskia \
     libui \
-    libcutils
+    libcutils \
+    libsurfaceflinger_client \
+    libcamera_client
 
 ifneq ($(BUILD_WITHOUT_PV),true)
 
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 76d1674..8ed3730 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -35,7 +35,7 @@
 #include "utils/String8.h"
 #include "android_util_Binder.h"
 #include <binder/Parcel.h>
-
+#include <surfaceflinger/Surface.h>
 
 // ----------------------------------------------------------------------------
 
@@ -692,6 +692,19 @@
     return ret;
 }
 
+static jint
+android_media_MediaPlayer_native_suspend_resume(
+        JNIEnv *env, jobject thiz, jboolean isSuspend) {
+    LOGV("suspend_resume(%d)", isSuspend);
+    sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
+    if (mp == NULL ) {
+        jniThrowException(env, "java/lang/IllegalStateException", NULL);
+        return UNKNOWN_ERROR;
+    }
+
+    return isSuspend ? mp->suspend() : mp->resume();
+}
+
 // ----------------------------------------------------------------------------
 
 static JNINativeMethod gMethods[] = {
@@ -724,6 +737,7 @@
     {"native_setup",        "(Ljava/lang/Object;)V",            (void *)android_media_MediaPlayer_native_setup},
     {"native_finalize",     "()V",                              (void *)android_media_MediaPlayer_native_finalize},
     {"snoop",               "([SI)I",                           (void *)android_media_MediaPlayer_snoop},
+    {"native_suspend_resume", "(Z)I",                           (void *)android_media_MediaPlayer_native_suspend_resume},
 };
 
 static const char* const kClassPathName = "android/media/MediaPlayer";
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index cad65b3..3063f15 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -18,9 +18,9 @@
 #define LOG_TAG "MediaRecorderJNI"
 #include <utils/Log.h>
 
-#include <ui/SurfaceComposerClient.h>
-#include <ui/ICameraService.h>
-#include <ui/Camera.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
+#include <camera/ICameraService.h>
+#include <camera/Camera.h>
 #include <media/mediarecorder.h>
 #include <stdio.h>
 #include <assert.h>
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index c59d323..3adabcc 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -29,7 +29,7 @@
     MediaProfiles.cpp
 
 LOCAL_SHARED_LIBRARIES := \
-	libui libcutils libutils libbinder libsonivox libicuuc libexpat
+	libui libcutils libutils libbinder libsonivox libicuuc libexpat libsurfaceflinger_client libcamera_client
 
 LOCAL_MODULE:= libmedia
 
diff --git a/media/libmedia/IMediaPlayer.cpp b/media/libmedia/IMediaPlayer.cpp
index 5d9db10..ed792b3 100644
--- a/media/libmedia/IMediaPlayer.cpp
+++ b/media/libmedia/IMediaPlayer.cpp
@@ -21,7 +21,7 @@
 #include <binder/Parcel.h>
 
 #include <media/IMediaPlayer.h>
-#include <ui/ISurface.h>
+#include <surfaceflinger/ISurface.h>
 
 namespace android {
 
@@ -43,6 +43,8 @@
     INVOKE,
     SET_METADATA_FILTER,
     GET_METADATA,
+    SUSPEND,
+    RESUME,
 };
 
 class BpMediaPlayer: public BpInterface<IMediaPlayer>
@@ -199,6 +201,26 @@
         remote()->transact(GET_METADATA, request, reply);
         return reply->readInt32();
     }
+
+    status_t suspend() {
+        Parcel request;
+        request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
+
+        Parcel reply;
+        remote()->transact(SUSPEND, request, &reply);
+
+        return reply.readInt32();
+    }
+
+    status_t resume() {
+        Parcel request;
+        request.writeInterfaceToken(IMediaPlayer::getInterfaceDescriptor());
+
+        Parcel reply;
+        remote()->transact(RESUME, request, &reply);
+
+        return reply.readInt32();
+    }
 };
 
 IMPLEMENT_META_INTERFACE(MediaPlayer, "android.media.IMediaPlayer");
@@ -299,6 +321,16 @@
             reply->writeInt32(setMetadataFilter(data));
             return NO_ERROR;
         } break;
+        case SUSPEND: {
+            CHECK_INTERFACE(IMediaPlayer, data, reply);
+            reply->writeInt32(suspend());
+            return NO_ERROR;
+        } break;
+        case RESUME: {
+            CHECK_INTERFACE(IMediaPlayer, data, reply);
+            reply->writeInt32(resume());
+            return NO_ERROR;
+        } break;
         case GET_METADATA: {
             CHECK_INTERFACE(IMediaPlayer, data, reply);
             const status_t retcode = getMetadata(data.readInt32(), data.readInt32(), reply);
diff --git a/media/libmedia/IMediaRecorder.cpp b/media/libmedia/IMediaRecorder.cpp
index df7d301..2bc2a7e 100644
--- a/media/libmedia/IMediaRecorder.cpp
+++ b/media/libmedia/IMediaRecorder.cpp
@@ -19,8 +19,8 @@
 #define LOG_TAG "IMediaRecorder"
 #include <utils/Log.h>
 #include <binder/Parcel.h>
-#include <ui/ISurface.h>
-#include <ui/ICamera.h>
+#include <surfaceflinger/ISurface.h>
+#include <camera/ICamera.h>
 #include <media/IMediaPlayerClient.h>
 #include <media/IMediaRecorder.h>
 
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 0469fd5..01b6737 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -5,8 +5,8 @@
 #include <binder/IMemory.h>
 #include <binder/Parcel.h>
 #include <media/IOMX.h>
-#include <ui/ISurface.h>
-#include <ui/Surface.h>
+#include <surfaceflinger/ISurface.h>
+#include <surfaceflinger/Surface.h>
 
 namespace android {
 
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index cb5ee4b..2157814 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -30,6 +30,8 @@
 #include <media/mediaplayer.h>
 #include <media/AudioTrack.h>
 
+#include <surfaceflinger/Surface.h>
+
 #include <binder/MemoryBase.h>
 
 #include <utils/KeyedVector.h>
@@ -165,6 +167,16 @@
     return INVALID_OPERATION;
 }
 
+status_t MediaPlayer::suspend() {
+    Mutex::Autolock _l(mLock);
+    return mPlayer->suspend();
+}
+
+status_t MediaPlayer::resume() {
+    Mutex::Autolock _l(mLock);
+    return mPlayer->resume();
+}
+
 status_t MediaPlayer::setMetadataFilter(const Parcel& filter)
 {
     LOGD("setMetadataFilter");
diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp
index 7b5dabb..23024e9 100644
--- a/media/libmedia/mediarecorder.cpp
+++ b/media/libmedia/mediarecorder.cpp
@@ -18,7 +18,7 @@
 //#define LOG_NDEBUG 0
 #define LOG_TAG "MediaRecorder"
 #include <utils/Log.h>
-#include <ui/Surface.h>
+#include <surfaceflinger/Surface.h>
 #include <media/mediarecorder.h>
 #include <binder/IServiceManager.h>
 #include <utils/String8.h>
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index 12872bc..a9a0fde 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -13,7 +13,7 @@
     TestPlayerStub.cpp          \
     VorbisPlayer.cpp            \
     VorbisMetadataRetriever.cpp \
-    MidiMetadataRetriever.cpp \
+    MidiMetadataRetriever.cpp 	\
     MidiFile.cpp
 
 ifeq ($(BUILD_WITH_FULL_STAGEFRIGHT),true)
@@ -30,17 +30,18 @@
 LOCAL_LDLIBS += -ldl -lpthread
 endif
 
-LOCAL_SHARED_LIBRARIES :=     \
-	libcutils             \
-	libutils              \
-	libbinder             \
-	libvorbisidec         \
-	libsonivox            \
-	libmedia              \
-	libandroid_runtime    \
-	libstagefright        \
-	libstagefright_omx    \
-	libstagefright_color_conversion
+LOCAL_SHARED_LIBRARIES :=     		\
+	libcutils             			\
+	libutils              			\
+	libbinder             			\
+	libvorbisidec         			\
+	libsonivox            			\
+	libmedia              			\
+	libandroid_runtime    			\
+	libstagefright        			\
+	libstagefright_omx    			\
+	libstagefright_color_conversion \
+	libsurfaceflinger_client
 
 ifneq ($(BUILD_WITHOUT_PV),true)
 LOCAL_SHARED_LIBRARIES += \
@@ -54,7 +55,7 @@
 LOCAL_SHARED_LIBRARIES += libdl
 endif
 
-LOCAL_C_INCLUDES :=                                                     \
+LOCAL_C_INCLUDES :=                                                 \
 	$(JNI_H_INCLUDE)                                                \
 	$(call include-path-for, graphics corecg)                       \
 	$(TOP)/external/opencore/extern_libs_v2/khronos/openmax/include \
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 55b06f4..b4fc035 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -970,6 +970,20 @@
     return OK;
 }
 
+status_t MediaPlayerService::Client::suspend() {
+    sp<MediaPlayerBase> p = getPlayer();
+    if (p == 0) return UNKNOWN_ERROR;
+
+    return p->suspend();
+}
+
+status_t MediaPlayerService::Client::resume() {
+    sp<MediaPlayerBase> p = getPlayer();
+    if (p == 0) return UNKNOWN_ERROR;
+
+    return p->resume();
+}
+
 status_t MediaPlayerService::Client::prepareAsync()
 {
     LOGV("[%d] prepareAsync", mConnId);
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 5c03e47..2408c62 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -25,7 +25,6 @@
 #include <utils/KeyedVector.h>
 #include <utils/String8.h>
 #include <utils/Vector.h>
-#include <ui/SurfaceComposerClient.h>
 
 #include <media/IMediaPlayerService.h>
 #include <media/MediaPlayerInterface.h>
@@ -223,6 +222,8 @@
         virtual status_t        getMetadata(bool update_only,
                                             bool apply_filter,
                                             Parcel *reply);
+        virtual status_t        suspend();
+        virtual status_t        resume();
 
         sp<MediaPlayerBase>     createPlayer(player_type playerType);
 
diff --git a/media/libmediaplayerservice/StagefrightPlayer.cpp b/media/libmediaplayerservice/StagefrightPlayer.cpp
index 1bfcf65..7776b4e 100644
--- a/media/libmediaplayerservice/StagefrightPlayer.cpp
+++ b/media/libmediaplayerservice/StagefrightPlayer.cpp
@@ -136,6 +136,16 @@
     return STAGEFRIGHT_PLAYER;
 }
 
+status_t StagefrightPlayer::suspend() {
+    LOGV("suspend");
+    return mPlayer->suspend();
+}
+
+status_t StagefrightPlayer::resume() {
+    LOGV("resume");
+    return mPlayer->resume();
+}
+
 status_t StagefrightPlayer::invoke(const Parcel &request, Parcel *reply) {
     return INVALID_OPERATION;
 }
diff --git a/media/libmediaplayerservice/StagefrightPlayer.h b/media/libmediaplayerservice/StagefrightPlayer.h
index 9e6674a..4446582 100644
--- a/media/libmediaplayerservice/StagefrightPlayer.h
+++ b/media/libmediaplayerservice/StagefrightPlayer.h
@@ -50,6 +50,8 @@
     virtual player_type playerType();
     virtual status_t invoke(const Parcel &request, Parcel *reply);
     virtual void setAudioSink(const sp<AudioSink> &audioSink);
+    virtual status_t suspend();
+    virtual status_t resume();
 
 private:
     AwesomePlayer *mPlayer;
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 1a8109c..531fd11 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -29,8 +29,8 @@
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/OMXClient.h>
 #include <media/stagefright/OMXCodec.h>
-#include <ui/ICamera.h>
-#include <ui/ISurface.h>
+#include <camera/ICamera.h>
+#include <surfaceflinger/ISurface.h>
 #include <utils/Errors.h>
 
 namespace android {
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 88d61a6..1db398e 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -65,7 +65,9 @@
         libcutils         \
         libui             \
         libsonivox        \
-        libvorbisidec
+        libvorbisidec     \
+        libsurfaceflinger_client \
+        libcamera_client
 
 LOCAL_STATIC_LIBRARIES := \
         libstagefright_aacdec \
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index b6dcf46..41e6911 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -36,6 +36,8 @@
 #include <media/stagefright/MetaData.h>
 #include <media/stagefright/OMXCodec.h>
 
+#include <surfaceflinger/ISurface.h>
+
 namespace android {
 
 struct AwesomeEvent : public TimedEventQueue::Event {
@@ -167,7 +169,8 @@
       mAudioPlayer(NULL),
       mFlags(0),
       mLastVideoBuffer(NULL),
-      mVideoBuffer(NULL) {
+      mVideoBuffer(NULL),
+      mSuspensionState(NULL) {
     CHECK_EQ(mClient.connect(), OK);
 
     DataSource::RegisterDefaultSniffers();
@@ -219,7 +222,11 @@
 status_t AwesomePlayer::setDataSource(
         const char *uri, const KeyedVector<String8, String8> *headers) {
     Mutex::Autolock autoLock(mLock);
+    return setDataSource_l(uri, headers);
+}
 
+status_t AwesomePlayer::setDataSource_l(
+        const char *uri, const KeyedVector<String8, String8> *headers) {
     reset_l();
 
     mUri = uri;
@@ -241,15 +248,22 @@
 
     reset_l();
 
-    sp<DataSource> source = new FileSource(fd, offset, length);
+    sp<DataSource> dataSource = new FileSource(fd, offset, length);
 
-    status_t err = source->initCheck();
+    status_t err = dataSource->initCheck();
 
     if (err != OK) {
         return err;
     }
 
-    sp<MediaExtractor> extractor = MediaExtractor::Create(source);
+    mFileSource = dataSource;
+
+    return setDataSource_l(dataSource);
+}
+
+status_t AwesomePlayer::setDataSource_l(
+        const sp<DataSource> &dataSource) {
+    sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
 
     if (extractor == NULL) {
         return UNKNOWN_ERROR;
@@ -297,6 +311,26 @@
 
     cancelPlayerEvents();
 
+    if (mPrefetcher != NULL) {
+        CHECK_EQ(mPrefetcher->getStrongCount(), 1);
+    }
+    mPrefetcher.clear();
+
+    // Shutdown audio first, so that the respone to the reset request
+    // appears to happen instantaneously as far as the user is concerned
+    // If we did this later, audio would continue playing while we
+    // shutdown the video-related resources and the player appear to
+    // not be as responsive to a reset request.
+    mAudioSource.clear();
+
+    if (mTimeSource != mAudioPlayer) {
+        delete mTimeSource;
+    }
+    mTimeSource = NULL;
+
+    delete mAudioPlayer;
+    mAudioPlayer = NULL;
+
     mVideoRenderer.clear();
 
     if (mLastVideoBuffer) {
@@ -323,16 +357,6 @@
         IPCThreadState::self()->flushCommands();
     }
 
-    mAudioSource.clear();
-
-    if (mTimeSource != mAudioPlayer) {
-        delete mTimeSource;
-    }
-    mTimeSource = NULL;
-
-    delete mAudioPlayer;
-    mAudioPlayer = NULL;
-
     mDurationUs = -1;
     mFlags = 0;
     mVideoWidth = mVideoHeight = -1;
@@ -342,10 +366,13 @@
     mSeeking = false;
     mSeekTimeUs = 0;
 
-    mPrefetcher.clear();
-
     mUri.setTo("");
     mUriHeaders.clear();
+
+    mFileSource.clear();
+
+    delete mSuspensionState;
+    mSuspensionState = NULL;
 }
 
 void AwesomePlayer::notifyListener_l(int msg, int ext1, int ext2) {
@@ -401,7 +428,10 @@
 
 status_t AwesomePlayer::play() {
     Mutex::Autolock autoLock(mLock);
+    return play_l();
+}
 
+status_t AwesomePlayer::play_l() {
     if (mFlags & PLAYING) {
         return OK;
     }
@@ -577,7 +607,10 @@
 
 status_t AwesomePlayer::getPosition(int64_t *positionUs) {
     Mutex::Autolock autoLock(mLock);
+    return getPosition_l(positionUs);
+}
 
+status_t AwesomePlayer::getPosition_l(int64_t *positionUs) {
     if (mVideoSource != NULL) {
         *positionUs = mVideoTimeUs;
     } else if (mAudioPlayer != NULL) {
@@ -695,7 +728,11 @@
 
 void AwesomePlayer::onVideoEvent() {
     Mutex::Autolock autoLock(mLock);
-
+    if (!mVideoEventPending) {
+        // The event has been cancelled in reset_l() but had already
+        // been scheduled for execution at that time.
+        return;
+    }
     mVideoEventPending = false;
 
     if (mSeeking) {
@@ -983,6 +1020,7 @@
 
     if (prefetcher != NULL) {
         prefetcher->prepare();
+        prefetcher.clear();
     }
 
     Mutex::Autolock autoLock(mLock);
@@ -1004,5 +1042,75 @@
     mPreparedCondition.broadcast();
 }
 
+status_t AwesomePlayer::suspend() {
+    LOGI("suspend");
+    Mutex::Autolock autoLock(mLock);
+
+    if (mSuspensionState != NULL) {
+        return INVALID_OPERATION;
+    }
+
+    while (mFlags & PREPARING) {
+        mPreparedCondition.wait(mLock);
+    }
+
+    SuspensionState *state = new SuspensionState;
+    state->mUri = mUri;
+    state->mUriHeaders = mUriHeaders;
+    state->mFileSource = mFileSource;
+
+    state->mFlags = mFlags & (PLAYING | LOOPING);
+    getPosition_l(&state->mPositionUs);
+
+    reset_l();
+
+    mSuspensionState = state;
+
+    return OK;
+}
+
+status_t AwesomePlayer::resume() {
+    LOGI("resume");
+    Mutex::Autolock autoLock(mLock);
+
+    if (mSuspensionState == NULL) {
+        return INVALID_OPERATION;
+    }
+
+    SuspensionState *state = mSuspensionState;
+    mSuspensionState = NULL;
+
+    status_t err;
+    if (state->mFileSource != NULL) {
+        err = setDataSource_l(state->mFileSource);
+
+        if (err == OK) {
+            mFileSource = state->mFileSource;
+        }
+    } else {
+        err = setDataSource_l(state->mUri, &state->mUriHeaders);
+    }
+
+    if (err != OK) {
+        delete state;
+        state = NULL;
+
+        return err;
+    }
+
+    seekTo_l(state->mPositionUs);
+
+    mFlags = state->mFlags & LOOPING;
+
+    if (state->mFlags & PLAYING) {
+        play_l();
+    }
+
+    delete state;
+    state = NULL;
+
+    return OK;
+}
+
 }  // namespace android
 
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index 8cd572e..075b1e3 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -25,11 +25,11 @@
 #include <media/stagefright/MediaDefs.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MetaData.h>
-#include <ui/Camera.h>
-#include <ui/CameraParameters.h>
+#include <camera/Camera.h>
+#include <camera/CameraParameters.h>
 #include <ui/GraphicBuffer.h>
-#include <ui/ISurface.h>
 #include <ui/Overlay.h>
+#include <surfaceflinger/ISurface.h>
 #include <utils/String8.h>
 
 namespace android {
diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp
index 79b7674..ab38bca 100644
--- a/media/libstagefright/MP3Extractor.cpp
+++ b/media/libstagefright/MP3Extractor.cpp
@@ -731,6 +731,7 @@
     static const Map kMap[] = {
         { kKeyAlbum, "TALB", "TAL" },
         { kKeyArtist, "TPE1", "TP1" },
+        { kKeyAlbumArtist, "TPE2", "TP2" },
         { kKeyComposer, "TCOM", "TCM" },
         { kKeyGenre, "TCON", "TCO" },
         { kKeyTitle, "TIT2", "TT2" },
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 1ff38ee..16635d3 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -60,6 +60,8 @@
     virtual ~MPEG4Source();
 
 private:
+    Mutex mLock;
+
     sp<MetaData> mFormat;
     sp<DataSource> mDataSource;
     int32_t mTimescale;
@@ -1045,6 +1047,11 @@
             metadataKey = kKeyArtist;
             break;
         }
+        case FOURCC('a', 'A', 'R', 'T'):
+        {
+            metadataKey = kKeyAlbumArtist;
+            break;
+        }
         case FOURCC(0xa9, 'd', 'a', 'y'):
         {
             metadataKey = kKeyYear;
@@ -1295,6 +1302,8 @@
 }
 
 status_t MPEG4Source::start(MetaData *params) {
+    Mutex::Autolock autoLock(mLock);
+
     CHECK(!mStarted);
 
     int32_t val;
@@ -1320,6 +1329,8 @@
 }
 
 status_t MPEG4Source::stop() {
+    Mutex::Autolock autoLock(mLock);
+
     CHECK(mStarted);
 
     if (mBuffer != NULL) {
@@ -1340,6 +1351,8 @@
 }
 
 sp<MetaData> MPEG4Source::getFormat() {
+    Mutex::Autolock autoLock(mLock);
+
     return mFormat;
 }
 
@@ -1364,6 +1377,8 @@
 
 status_t MPEG4Source::read(
         MediaBuffer **out, const ReadOptions *options) {
+    Mutex::Autolock autoLock(mLock);
+
     CHECK(mStarted);
 
     *out = NULL;
@@ -1423,6 +1438,7 @@
                 return ERROR_IO;
             }
 
+            CHECK(mBuffer != NULL);
             mBuffer->set_range(0, size);
             mBuffer->meta_data()->clear();
             mBuffer->meta_data()->setInt64(
@@ -1456,8 +1472,10 @@
         }
 
         MediaBuffer *clone = mBuffer->clone();
+        CHECK(clone != NULL);
         clone->set_range(mBuffer->range_offset() + mNALLengthSize, nal_size);
 
+        CHECK(mBuffer != NULL);
         mBuffer->set_range(
                 mBuffer->range_offset() + mNALLengthSize + nal_size,
                 mBuffer->range_length() - mNALLengthSize - nal_size);
@@ -1516,6 +1534,7 @@
         }
         CHECK_EQ(srcOffset, size);
 
+        CHECK(mBuffer != NULL);
         mBuffer->set_range(0, dstOffset);
         mBuffer->meta_data()->clear();
         mBuffer->meta_data()->setInt64(
diff --git a/media/libstagefright/Prefetcher.cpp b/media/libstagefright/Prefetcher.cpp
index 835e167..cb03979 100644
--- a/media/libstagefright/Prefetcher.cpp
+++ b/media/libstagefright/Prefetcher.cpp
@@ -31,7 +31,6 @@
 
 struct PrefetchedSource : public MediaSource {
     PrefetchedSource(
-            const sp<Prefetcher> &prefetcher,
             size_t index,
             const sp<MediaSource> &source);
 
@@ -52,13 +51,13 @@
     Mutex mLock;
     Condition mCondition;
 
-    sp<Prefetcher> mPrefetcher;
     sp<MediaSource> mSource;
     size_t mIndex;
     bool mStarted;
     bool mReachedEOS;
     int64_t mSeekTimeUs;
     int64_t mCacheDurationUs;
+    bool mPrefetcherStopped;
 
     List<MediaBuffer *> mCachedBuffers;
 
@@ -69,6 +68,7 @@
     void clearCache_l();
 
     void cacheMore();
+    void onPrefetcherStopped();
 
     PrefetchedSource(const PrefetchedSource &);
     PrefetchedSource &operator=(const PrefetchedSource &);
@@ -88,7 +88,7 @@
     Mutex::Autolock autoLock(mLock);
 
     sp<PrefetchedSource> psource =
-        new PrefetchedSource(this, mSources.size(), source);
+        new PrefetchedSource(mSources.size(), source);
 
     mSources.add(psource);
 
@@ -130,8 +130,6 @@
     for (;;) {
         Mutex::Autolock autoLock(mLock);
         if (mDone) {
-            mThreadExited = true;
-            mCondition.signal();
             break;
         }
         mCondition.waitRelative(mLock, 10000000ll);
@@ -169,6 +167,19 @@
             source->cacheMore();
         }
     }
+
+    for (size_t i = 0; i < mSources.size(); ++i) {
+        sp<PrefetchedSource> source = mSources[i].promote();
+
+        if (source == NULL) {
+            continue;
+        }
+
+        source->onPrefetcherStopped();
+    }
+
+    mThreadExited = true;
+    mCondition.signal();
 }
 
 int64_t Prefetcher::getCachedDurationUs(bool *noMoreData) {
@@ -219,16 +230,15 @@
 ////////////////////////////////////////////////////////////////////////////////
 
 PrefetchedSource::PrefetchedSource(
-        const sp<Prefetcher> &prefetcher,
         size_t index,
         const sp<MediaSource> &source)
-    : mPrefetcher(prefetcher),
-      mSource(source),
+    : mSource(source),
       mIndex(index),
       mStarted(false),
       mReachedEOS(false),
       mSeekTimeUs(0),
-      mCacheDurationUs(0) {
+      mCacheDurationUs(0),
+      mPrefetcherStopped(false) {
 }
 
 PrefetchedSource::~PrefetchedSource() {
@@ -238,6 +248,8 @@
 }
 
 status_t PrefetchedSource::start(MetaData *params) {
+    CHECK(!mStarted);
+
     Mutex::Autolock autoLock(mLock);
 
     status_t err = mSource->start(params);
@@ -252,6 +264,8 @@
 }
 
 status_t PrefetchedSource::stop() {
+    CHECK(mStarted);
+
     Mutex::Autolock autoLock(mLock);
 
     clearCache_l();
@@ -281,7 +295,7 @@
         mSeekTimeUs = seekTimeUs;
     }
 
-    while (!mReachedEOS && mCachedBuffers.empty()) {
+    while (!mPrefetcherStopped && !mReachedEOS && mCachedBuffers.empty()) {
         mCondition.wait(mLock);
     }
 
@@ -390,4 +404,10 @@
     updateCacheDuration_l();
 }
 
+void PrefetchedSource::onPrefetcherStopped() {
+    Mutex::Autolock autoLock(mLock);
+    mPrefetcherStopped = true;
+    mCondition.signal();
+}
+
 }  // namespace android
diff --git a/media/libstagefright/StagefrightMediaScanner.cpp b/media/libstagefright/StagefrightMediaScanner.cpp
index 22f701c..b1eca2b 100644
--- a/media/libstagefright/StagefrightMediaScanner.cpp
+++ b/media/libstagefright/StagefrightMediaScanner.cpp
@@ -194,6 +194,7 @@
             { "discnumber", METADATA_KEY_DISC_NUMBER },
             { "album", METADATA_KEY_ALBUM },
             { "artist", METADATA_KEY_ARTIST },
+            { "albumartist", METADATA_KEY_ALBUMARTIST },
             { "composer", METADATA_KEY_COMPOSER },
             { "genre", METADATA_KEY_GENRE },
             { "title", METADATA_KEY_TITLE },
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index f617fe8..df6235f 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -308,6 +308,7 @@
         { kKeyDiscNumber, METADATA_KEY_DISC_NUMBER },
         { kKeyAlbum, METADATA_KEY_ALBUM },
         { kKeyArtist, METADATA_KEY_ARTIST },
+        { kKeyAlbumArtist, METADATA_KEY_ALBUMARTIST },
         { kKeyAuthor, METADATA_KEY_AUTHOR },
         { kKeyComposer, METADATA_KEY_COMPOSER },
         { kKeyDate, METADATA_KEY_DATE },
diff --git a/media/libstagefright/colorconversion/Android.mk b/media/libstagefright/colorconversion/Android.mk
index c08ce3a..e7a571a 100644
--- a/media/libstagefright/colorconversion/Android.mk
+++ b/media/libstagefright/colorconversion/Android.mk
@@ -13,7 +13,9 @@
         libmedia                \
         libutils                \
         libui                   \
-        libcutils
+        libcutils				\
+        libsurfaceflinger_client\
+        libcamera_client
 
 LOCAL_PRELINK_MODULE:= false
 
diff --git a/media/libstagefright/colorconversion/SoftwareRenderer.cpp b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
index 56c5102..4c11c36 100644
--- a/media/libstagefright/colorconversion/SoftwareRenderer.cpp
+++ b/media/libstagefright/colorconversion/SoftwareRenderer.cpp
@@ -22,7 +22,7 @@
 #include <binder/MemoryHeapBase.h>
 #include <binder/MemoryHeapPmem.h>
 #include <media/stagefright/MediaDebug.h>
-#include <ui/ISurface.h>
+#include <surfaceflinger/ISurface.h>
 
 namespace android {
 
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index a19784b..ee2aca0 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -27,6 +27,7 @@
 namespace android {
 
 struct AudioPlayer;
+struct DataSource;
 struct MediaBuffer;
 struct MediaExtractor;
 struct MediaSource;
@@ -78,6 +79,9 @@
 
     status_t getVideoDimensions(int32_t *width, int32_t *height) const;
 
+    status_t suspend();
+    status_t resume();
+
 private:
     friend struct AwesomeEvent;
 
@@ -103,6 +107,8 @@
     String8 mUri;
     KeyedVector<String8, String8> mUriHeaders;
 
+    sp<DataSource> mFileSource;
+
     sp<MediaSource> mVideoSource;
     sp<AwesomeRenderer> mVideoRenderer;
 
@@ -140,12 +146,29 @@
     void postBufferingEvent_l();
     void postStreamDoneEvent_l();
     void postCheckAudioStatusEvent_l();
+    status_t getPosition_l(int64_t *positionUs);
+    status_t play_l();
 
     MediaBuffer *mLastVideoBuffer;
     MediaBuffer *mVideoBuffer;
 
     sp<Prefetcher> mPrefetcher;
 
+    struct SuspensionState {
+        String8 mUri;
+        KeyedVector<String8, String8> mUriHeaders;
+        sp<DataSource> mFileSource;
+
+        uint32_t mFlags;
+        int64_t mPositionUs;
+
+    } *mSuspensionState;
+
+    status_t setDataSource_l(
+            const char *uri,
+            const KeyedVector<String8, String8> *headers = NULL);
+
+    status_t setDataSource_l(const sp<DataSource> &dataSource);
     status_t setDataSource_l(const sp<MediaExtractor> &extractor);
     void reset_l();
     status_t seekTo_l(int64_t timeUs);
diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java
index 1625d9f..0a6c72e 100644
--- a/services/java/com/android/server/DevicePolicyManagerService.java
+++ b/services/java/com/android/server/DevicePolicyManagerService.java
@@ -608,7 +608,7 @@
                 throw new NullPointerException("ComponentName is null");
             }
             ActiveAdmin ap = getActiveAdminForCallerLocked(who,
-                    DeviceAdminInfo.USES_POLICY_LIMIT_UNLOCK);
+                    DeviceAdminInfo.USES_POLICY_FORCE_LOCK);
             if (ap.maximumTimeToUnlock != timeMs) {
                 ap.maximumTimeToUnlock = timeMs;
                 
diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java
index 742a7d8..c907368 100644
--- a/services/java/com/android/server/DockObserver.java
+++ b/services/java/com/android/server/DockObserver.java
@@ -21,6 +21,7 @@
 import android.app.IActivityManager;
 import android.app.IUiModeManager;
 import android.app.KeyguardManager;
+import android.app.StatusBarManager;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
 import android.content.ActivityNotFoundException;
@@ -71,6 +72,8 @@
     private boolean mKeyguardDisabled;
     private LockPatternUtils mLockPatternUtils;
 
+    private StatusBarManager mStatusBarManager;    
+
     // The broadcast receiver which receives the result of the ordered broadcast sent when
     // the dock state changes. The original ordered broadcast is sent with an initial result
     // code of RESULT_OK. If any of the registered broadcast receivers changes this value, e.g.,
@@ -234,6 +237,21 @@
             // Disabling the car mode clears the night mode.
             setMode(Configuration.UI_MODE_TYPE_NORMAL, MODE_NIGHT_NO);
         }
+
+        if (mStatusBarManager == null) {
+            mStatusBarManager = (StatusBarManager) mContext.getSystemService(Context.STATUS_BAR_SERVICE);
+        }
+
+        // Fear not: StatusBarService manages a list of requests to disable
+        // features of the status bar; these are ORed together to form the
+        // active disabled list. So if (for example) the device is locked and
+        // the status bar should be totally disabled, the calls below will
+        // have no effect until the device is unlocked.
+        if (mStatusBarManager != null) {
+            mStatusBarManager.disable(enabled 
+                ? StatusBarManager.DISABLE_NOTIFICATION_TICKER
+                : StatusBarManager.DISABLE_NONE);
+        }
     }
 
     private void setMode(int modeType, int modeNight) throws RemoteException {
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 4a60445..a5213a0 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -1076,6 +1076,28 @@
         return null;
     }
 
+    public String[] currentToCanonicalPackageNames(String[] names) {
+        String[] out = new String[names.length];
+        synchronized (mPackages) {
+            for (int i=names.length-1; i>=0; i--) {
+                PackageSetting ps = mSettings.mPackages.get(names[i]);
+                out[i] = ps != null && ps.realName != null ? ps.realName : names[i];
+            }
+        }
+        return out;
+    }
+    
+    public String[] canonicalToCurrentPackageNames(String[] names) {
+        String[] out = new String[names.length];
+        synchronized (mPackages) {
+            for (int i=names.length-1; i>=0; i--) {
+                String cur = mSettings.mRenamedPackages.get(names[i]);
+                out[i] = cur != null ? cur : names[i];
+            }
+        }
+        return out;
+    }
+    
     public int getPackageUid(String packageName) {
         synchronized (mPackages) {
             PackageParser.Package p = mPackages.get(packageName);
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 73223ee..7fcf900 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -1773,6 +1773,32 @@
         }
     }
 
+    void dispatchPointerElsewhereLocked(WindowState srcWin, WindowState relWin,
+            MotionEvent pointer, long eventTime, boolean skipped) {
+        if (relWin != null) {
+            mPolicy.dispatchedPointerEventLw(pointer, relWin.mFrame.left, relWin.mFrame.top);
+        } else {
+            mPolicy.dispatchedPointerEventLw(pointer, 0, 0);
+        }
+        
+        // If we sent an initial down to the wallpaper, then continue
+        // sending events until the final up.
+        if (mSendingPointersToWallpaper) {
+            if (skipped) {
+                Log.i(TAG, "Sending skipped pointer to wallpaper!");
+            }
+            sendPointerToWallpaperLocked(relWin, pointer, eventTime);
+            
+        // If we are on top of the wallpaper, then the wallpaper also
+        // gets to see this movement.
+        } else if (srcWin != null
+                && pointer.getAction() == MotionEvent.ACTION_DOWN
+                && mWallpaperTarget == srcWin
+                && srcWin.mAttrs.type != WindowManager.LayoutParams.TYPE_KEYGUARD) {
+            sendPointerToWallpaperLocked(relWin, pointer, eventTime);
+        }
+    }
+    
     public int addWindow(Session session, IWindow client,
             WindowManager.LayoutParams attrs, int viewVisibility,
             Rect outContentInsets) {
@@ -4918,10 +4944,7 @@
                 Log.w(TAG, "No window to dispatch pointer action " + ev.getAction());
             }
             synchronized (mWindowMap) {
-                if (mSendingPointersToWallpaper) {
-                    Log.i(TAG, "Sending skipped pointer to wallpaper!");
-                    sendPointerToWallpaperLocked(null, ev, ev.getEventTime());
-                }
+                dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), true);
             }
             if (qev != null) {
                 mQueue.recycleEvent(qev);
@@ -4931,10 +4954,7 @@
         }
         if (targetObj == mKeyWaiter.CONSUMED_EVENT_TOKEN) {
             synchronized (mWindowMap) {
-                if (mSendingPointersToWallpaper) {
-                    Log.i(TAG, "Sending skipped pointer to wallpaper!");
-                    sendPointerToWallpaperLocked(null, ev, ev.getEventTime());
-                }
+                dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), true);
             }
             if (qev != null) {
                 mQueue.recycleEvent(qev);
@@ -5059,9 +5079,7 @@
             if (!target.isVisibleLw()) {
                 // During this motion dispatch, the target window has become
                 // invisible.
-                if (mSendingPointersToWallpaper) {
-                    sendPointerToWallpaperLocked(null, ev, eventTime);
-                }
+                dispatchPointerElsewhereLocked(null, null, ev, ev.getEventTime(), false);
                 if (qev != null) {
                     mQueue.recycleEvent(qev);
                 }
@@ -5094,13 +5112,7 @@
                     }
                 }
 
-                // If we are on top of the wallpaper, then the wallpaper also
-                // gets to see this movement.
-                if ((mWallpaperTarget == target &&
-                        target.mAttrs.type != WindowManager.LayoutParams.TYPE_KEYGUARD)
-                        || mSendingPointersToWallpaper) {
-                    sendPointerToWallpaperLocked(null, ev, eventTime);
-                }
+                dispatchPointerElsewhereLocked(target, null, ev, ev.getEventTime(), false);
 
                 final Rect frame = target.mFrame;
                 ev.offsetLocation(-(float)frame.left, -(float)frame.top);
@@ -5610,7 +5622,7 @@
                             // If an app switch key has been pressed, and we have
                             // waited too long for the current app to finish
                             // processing keys, then wait no more!
-                            doFinishedKeyLocked(true);
+                            doFinishedKeyLocked(false);
                             continue;
                         }
                         long switchTimeout = mTimeToSwitch - now;
@@ -6008,7 +6020,7 @@
                         + ((mLastWin != null) ? mLastWin.mToken.paused : "null"));
                     if (mLastWin != null && (!mLastWin.mToken.paused || force
                             || !mEventDispatching)) {
-                        doFinishedKeyLocked(false);
+                        doFinishedKeyLocked(true);
                     } else {
                         // Make sure to wake up anyone currently waiting to
                         // dispatch a key, so they can re-evaluate their
@@ -6031,11 +6043,7 @@
 
             if (res != null && returnWhat == RETURN_PENDING_POINTER) {
                 synchronized (mWindowMap) {
-                    if ((mWallpaperTarget == win &&
-                            win.mAttrs.type != WindowManager.LayoutParams.TYPE_KEYGUARD)
-                            || mSendingPointersToWallpaper) {
-                        sendPointerToWallpaperLocked(win, res, res.getEventTime());
-                    }
+                    dispatchPointerElsewhereLocked(win, win, res, res.getEventTime(), false);
                 }
             }
 
@@ -6086,13 +6094,9 @@
                         // The new window is above the old; finish pending input to the last
                         // window and start directing it to the new one.
                         mLastWin.mToken.paused = false;
-                        doFinishedKeyLocked(true);  // does a notifyAll()
+                        doFinishedKeyLocked(false);  // does a notifyAll()
+                        return;
                     }
-                    // Either the new window is lower, so there is no need to wake key waiters,
-                    // or we just finished key input to the previous window, which implicitly
-                    // notified the key waiters.  In both cases, we don't need to issue the
-                    // notification here.
-                    return;
                 }
 
                 // Now that we've put a new window state in place, make the event waiter
@@ -6134,7 +6138,7 @@
                         + token.paused);
                     token.paused = false;
                     if (mLastWin != null && mLastWin.mToken == token && mFinished) {
-                        doFinishedKeyLocked(true);
+                        doFinishedKeyLocked(false);
                     } else {
                         notifyAll();
                     }
@@ -6162,14 +6166,14 @@
             }
         }
 
-        private final void doFinishedKeyLocked(boolean doRecycle) {
+        private final void doFinishedKeyLocked(boolean force) {
             if (mLastWin != null) {
                 releasePendingPointerLocked(mLastWin.mSession);
                 releasePendingTrackballLocked(mLastWin.mSession);
             }
 
-            if (mLastWin == null || !mLastWin.mToken.paused
-                || !mLastWin.isVisibleLw()) {
+            if (force || mLastWin == null || !mLastWin.mToken.paused
+                    || !mLastWin.isVisibleLw()) {
                 // If the current window has been paused, we aren't -really-
                 // finished...  so let the waiters still wait.
                 mLastWin = null;
diff --git a/telephony/java/android/telephony/cdma/CdmaCellLocation.java b/telephony/java/android/telephony/cdma/CdmaCellLocation.java
index 7ef7747..2a0f8cd 100644
--- a/telephony/java/android/telephony/cdma/CdmaCellLocation.java
+++ b/telephony/java/android/telephony/cdma/CdmaCellLocation.java
@@ -26,12 +26,17 @@
     private int mBaseStationId = -1;
 
     /**
+     * @hide
+     */
+    public final static int INVALID_LAT_LONG = Integer.MAX_VALUE;
+
+    /**
      * Latitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0.
      * It is represented in units of 0.25 seconds and ranges from -1296000
      * to 1296000, both values inclusive (corresponding to a range of -90
      * to +90 degrees). Integer.MAX_VALUE is considered invalid value.
      */
-    private int mBaseStationLatitude = Integer.MAX_VALUE;
+    private int mBaseStationLatitude = INVALID_LAT_LONG;
 
     /**
      * Longitude is a decimal number as specified in 3GPP2 C.S0005-A v6.0.
@@ -39,7 +44,7 @@
      * to 2592000, both values inclusive (corresponding to a range of -180
      * to +180 degrees). Integer.MAX_VALUE is considered invalid value.
      */
-    private int mBaseStationLongitude = Integer.MAX_VALUE;
+    private int mBaseStationLongitude = INVALID_LAT_LONG;
 
     private int mSystemId = -1;
     private int mNetworkId = -1;
@@ -51,8 +56,8 @@
      */
     public CdmaCellLocation() {
         this.mBaseStationId = -1;
-        this.mBaseStationLatitude = Integer.MAX_VALUE;
-        this.mBaseStationLongitude = Integer.MAX_VALUE;
+        this.mBaseStationLatitude = INVALID_LAT_LONG;
+        this.mBaseStationLongitude = INVALID_LAT_LONG;
         this.mSystemId = -1;
         this.mNetworkId = -1;
     }
@@ -60,12 +65,12 @@
     /**
      * Initialize the object from a bundle.
      */
-    public CdmaCellLocation(Bundle bundleWithValues) {
-        this.mBaseStationId = bundleWithValues.getInt("baseStationId");
-        this.mBaseStationLatitude = bundleWithValues.getInt("baseStationLatitude");
-        this.mBaseStationLongitude = bundleWithValues.getInt("baseStationLongitude");
-        this.mSystemId = bundleWithValues.getInt("systemId");
-        this.mNetworkId = bundleWithValues.getInt("networkId");
+    public CdmaCellLocation(Bundle bundle) {
+        this.mBaseStationId = bundle.getInt("baseStationId", mBaseStationId);
+        this.mBaseStationLatitude = bundle.getInt("baseStationLatitude", mBaseStationLatitude);
+        this.mBaseStationLongitude = bundle.getInt("baseStationLongitude", mBaseStationLongitude);
+        this.mSystemId = bundle.getInt("systemId", mSystemId);
+        this.mNetworkId = bundle.getInt("networkId", mNetworkId);
     }
 
     /**
@@ -108,8 +113,8 @@
      */
     public void setStateInvalid() {
         this.mBaseStationId = -1;
-        this.mBaseStationLatitude = Integer.MAX_VALUE;
-        this.mBaseStationLongitude = Integer.MAX_VALUE;
+        this.mBaseStationLatitude = INVALID_LAT_LONG;
+        this.mBaseStationLongitude = INVALID_LAT_LONG;
         this.mSystemId = -1;
         this.mNetworkId = -1;
     }
diff --git a/telephony/java/android/telephony/gsm/GsmCellLocation.java b/telephony/java/android/telephony/gsm/GsmCellLocation.java
index 637a11c..0d4e0be 100644
--- a/telephony/java/android/telephony/gsm/GsmCellLocation.java
+++ b/telephony/java/android/telephony/gsm/GsmCellLocation.java
@@ -38,8 +38,8 @@
      * Initialize the object from a bundle.
      */
     public GsmCellLocation(Bundle bundle) {
-        mLac = bundle.getInt("lac");
-        mCid = bundle.getInt("cid");
+        mLac = bundle.getInt("lac", mLac);
+        mCid = bundle.getInt("cid", mCid);
     }
 
     /**
@@ -120,5 +120,3 @@
         m.putInt("cid", mCid);
     }
 }
-
-
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
index b64e5bd..c351289 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaServiceStateTracker.java
@@ -357,8 +357,8 @@
             if (ar.exception == null) {
                 String states[] = (String[])ar.result;
                 int baseStationId = -1;
-                int baseStationLatitude = Integer.MAX_VALUE;
-                int baseStationLongitude = Integer.MAX_VALUE;
+                int baseStationLatitude = CdmaCellLocation.INVALID_LAT_LONG;
+                int baseStationLongitude = CdmaCellLocation.INVALID_LAT_LONG;
                 int systemId = -1;
                 int networkId = -1;
 
@@ -373,6 +373,11 @@
                         if (states[6] != null) {
                             baseStationLongitude = Integer.parseInt(states[6]);
                         }
+                        // Some carriers only return lat-lngs of 0,0
+                        if (baseStationLatitude == 0 && baseStationLongitude == 0) {
+                            baseStationLatitude  = CdmaCellLocation.INVALID_LAT_LONG;
+                            baseStationLongitude = CdmaCellLocation.INVALID_LAT_LONG;
+                        }
                         if (states[8] != null) {
                             systemId = Integer.parseInt(states[8]);
                         }
@@ -662,8 +667,10 @@
                 int registrationState = 4;     //[0] registrationState
                 int radioTechnology = -1;      //[3] radioTechnology
                 int baseStationId = -1;        //[4] baseStationId
-                int baseStationLatitude = Integer.MAX_VALUE;  //[5] baseStationLatitude
-                int baseStationLongitude = Integer.MAX_VALUE; //[6] baseStationLongitude
+                //[5] baseStationLatitude
+                int baseStationLatitude = CdmaCellLocation.INVALID_LAT_LONG;
+                //[6] baseStationLongitude
+                int baseStationLongitude = CdmaCellLocation.INVALID_LAT_LONG;
                 int cssIndicator = 0;          //[7] init with 0, because it is treated as a boolean
                 int systemId = 0;              //[8] systemId
                 int networkId = 0;             //[9] networkId
@@ -689,6 +696,11 @@
                         if (states[6] != null) {
                             baseStationLongitude = Integer.parseInt(states[6]);
                         }
+                        // Some carriers only return lat-lngs of 0,0
+                        if (baseStationLatitude == 0 && baseStationLongitude == 0) {
+                            baseStationLatitude  = CdmaCellLocation.INVALID_LAT_LONG;
+                            baseStationLongitude = CdmaCellLocation.INVALID_LAT_LONG;
+                        }
                         if (states[7] != null) {
                             cssIndicator = Integer.parseInt(states[7]);
                         }
diff --git a/test-runner/android/test/ActivityInstrumentationTestCase.java b/test-runner/android/test/ActivityInstrumentationTestCase.java
index f6b31ad..d12ff6f 100644
--- a/test-runner/android/test/ActivityInstrumentationTestCase.java
+++ b/test-runner/android/test/ActivityInstrumentationTestCase.java
@@ -40,29 +40,26 @@
     boolean mInitialTouchMode = false;
 
     /**
-     * <b>NOTE:</b> The parameter <i>pkg</i> must refer to the package identifier of the
-     * package hosting the activity to be launched, which is specified in the AndroidManifest.xml
-     * file.  This is not necessarily the same as the java package name.
+     * Creates an {@link ActivityInstrumentationTestCase} in non-touch mode.
      * 
-     * @param pkg The package hosting the activity to be launched.
-     * @param activityClass The activity to test.
+     * @param pkg ignored - no longer in use.
+     * @param activityClass The activity to test. This must be a class in the instrumentation
+     * targetPackage specified in the AndroidManifest.xml
      */
     public ActivityInstrumentationTestCase(String pkg, Class<T> activityClass) {
         this(pkg, activityClass, false);
     }
 
     /**
-     * <b>NOTE:</b> The parameter <i>pkg</i> must refer to the package identifier of the
-     * package hosting the activity to be launched, which is specified in the AndroidManifest.xml
-     * file.  This is not necessarily the same as the java package name.
-     * 
-     * @param pkg The package hosting the activity to be launched.
-     * @param activityClass The activity to test.
+     * Creates an {@link ActivityInstrumentationTestCase}.
+     *
+     * @param pkg ignored - no longer in use.
+     * @param activityClass The activity to test. This must be a class in the instrumentation
+     * targetPackage specified in the AndroidManifest.xml
      * @param initialTouchMode true = in touch mode
      */
     public ActivityInstrumentationTestCase(String pkg, Class<T> activityClass, 
             boolean initialTouchMode) {
-        mPackage = pkg;
         mActivityClass = activityClass;
         mInitialTouchMode = initialTouchMode;
     }
@@ -77,7 +74,8 @@
         super.setUp();
         // set initial touch mode
         getInstrumentation().setInTouchMode(mInitialTouchMode);
-        setActivity(launchActivity(mPackage, mActivityClass, null));
+        final String targetPackageName = getInstrumentation().getTargetContext().getPackageName();
+        setActivity(launchActivity(targetPackageName, mActivityClass, null));
     }
 
     @Override
diff --git a/test-runner/android/test/ActivityInstrumentationTestCase2.java b/test-runner/android/test/ActivityInstrumentationTestCase2.java
index 679f634..e8570bd 100644
--- a/test-runner/android/test/ActivityInstrumentationTestCase2.java
+++ b/test-runner/android/test/ActivityInstrumentationTestCase2.java
@@ -40,21 +40,31 @@
  */
 public abstract class ActivityInstrumentationTestCase2<T extends Activity> 
         extends ActivityTestCase {
-    String mPackage;
     Class<T> mActivityClass;
     boolean mInitialTouchMode = false;
     Intent mActivityIntent = null;
 
     /**
-     * <b>NOTE:</b> The parameter <i>pkg</i> must refer to the package identifier of the
-     * package hosting the activity to be launched, which is specified in the AndroidManifest.xml
-     * file.  This is not necessarily the same as the java package name.
-     * 
-     * @param pkg The package hosting the activity to be launched.
-     * @param activityClass The activity to test.
+     * Creates an {@link ActivityInstrumentationTestCase2}.
+     *
+     * @param pkg ignored - no longer in use.
+     * @param activityClass The activity to test. This must be a class in the instrumentation
+     * targetPackage specified in the AndroidManifest.xml
+     *
+     * @deprecated use {@link #ActivityInstrumentationTestCase2(Class)} instead
      */
+    @Deprecated
     public ActivityInstrumentationTestCase2(String pkg, Class<T> activityClass) {
-        mPackage = pkg;
+        this(activityClass);
+    }
+
+    /**
+     * Creates an {@link ActivityInstrumentationTestCase2}.
+     *
+     * @param activityClass The activity to test. This must be a class in the instrumentation
+     * targetPackage specified in the AndroidManifest.xml
+     */
+    public ActivityInstrumentationTestCase2(Class<T> activityClass) {
         mActivityClass = activityClass;
     }
 
@@ -82,11 +92,12 @@
         if (a == null) {
             // set initial touch mode
             getInstrumentation().setInTouchMode(mInitialTouchMode);
+            final String targetPackage = getInstrumentation().getTargetContext().getPackageName();
             // inject custom intent, if provided
             if (mActivityIntent == null) {
-                a = launchActivity(mPackage, mActivityClass, null);
+                a = launchActivity(targetPackage, mActivityClass, null);
             } else {
-                a = launchActivityWithIntent(mPackage, mActivityClass, mActivityIntent);
+                a = launchActivityWithIntent(targetPackage, mActivityClass, mActivityIntent);
             }
             setActivity(a);
         }
diff --git a/test-runner/android/test/ProviderTestCase2.java b/test-runner/android/test/ProviderTestCase2.java
index a923d2a..f3655fc 100644
--- a/test-runner/android/test/ProviderTestCase2.java
+++ b/test-runner/android/test/ProviderTestCase2.java
@@ -8,6 +8,8 @@
 import android.test.mock.MockContentResolver;
 import android.database.DatabaseUtils;
 
+import java.io.File;
+
 /**
  * This TestCase class provides a framework for isolated testing of a single
  * ContentProvider.  It uses a {@link android.test.mock.MockContentResolver} to
@@ -33,6 +35,13 @@
         public Resources getResources() {
             return getContext().getResources();
         }
+
+        @Override
+        public File getDir(String name, int mode) {
+            // name the directory so the directory will be seperated from
+            // one created through the regular Context
+            return getContext().getDir("mockcontext2_" + name, mode);
+        }
     }
 
     public ProviderTestCase2(Class<T> providerClass, String providerAuthority) {
diff --git a/test-runner/android/test/mock/MockPackageManager.java b/test-runner/android/test/mock/MockPackageManager.java
index c8339ed..2a4b3f7 100644
--- a/test-runner/android/test/mock/MockPackageManager.java
+++ b/test-runner/android/test/mock/MockPackageManager.java
@@ -59,6 +59,16 @@
     }
 
     @Override
+    public String[] currentToCanonicalPackageNames(String[] names) {
+        throw new UnsupportedOperationException();
+    }
+    
+    @Override
+    public String[] canonicalToCurrentPackageNames(String[] names) {
+        throw new UnsupportedOperationException();
+    }
+    
+    @Override
     public Intent getLaunchIntentForPackage(String packageName) {
         throw new UnsupportedOperationException();
     }
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 5d345e6..ee07415 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -741,6 +741,15 @@
                                     error.string());
                             goto bail;
                         }
+                    } else if (tag == "original-package") {
+                        String8 name = getAttribute(tree, NAME_ATTR, &error);
+                        if (name != "" && error == "") {
+                            printf("original-package:'%s'\n", name.string());
+                        } else {
+                            fprintf(stderr, "ERROR getting 'android:name' attribute: %s\n",
+                                    error.string());
+                                goto bail;
+                        }
                     }
                 } else if (depth == 3 && withinApplication) {
                     withinActivity = false;
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java
index 43ff424..71803fc 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeAssetManager.java
@@ -17,12 +17,9 @@
 package com.android.layoutlib.bridge;
 
 import android.content.res.AssetManager;
-import android.content.res.Configuration;
-
-import java.util.Locale;
 
 public class BridgeAssetManager extends AssetManager {
-    
+
     /**
      * This initializes the static field {@link AssetManager#mSystem} which is used
      * by methods who get a global asset manager using {@link AssetManager#getSystem()}.
@@ -40,7 +37,7 @@
         }
         return AssetManager.sSystem;
     }
-    
+
     /**
      * Clears the static {@link AssetManager#sSystem} to make sure we don't leave objects
      * around that would prevent us from unloading the library.
@@ -48,29 +45,7 @@
     /*package*/ static void clearSystem() {
         AssetManager.sSystem = null;
     }
-    
+
     private BridgeAssetManager() {
     }
-    
-    /**
-     * Change the configuration used when retrieving resources.  Not for use by applications.
-     */
-    @Override
-    public void setConfiguration(int mcc, int mnc, String locale,
-            int orientation, int touchscreen, int density, int keyboard,
-            int keyboardHidden, int navigation, int screenWidth, int screenHeight,
-            int screenLayout, int uiMode, int version)  {
-        
-        Configuration c = new Configuration();
-        c.mcc = mcc;
-        c.mnc = mnc;
-        c.locale = new Locale(locale);
-        c.touchscreen = touchscreen;
-        c.keyboard = keyboard;
-        c.keyboardHidden = keyboardHidden;
-        c.navigation = navigation;
-        c.orientation = orientation;
-        c.screenLayout = screenLayout;
-        c.uiMode = uiMode;
-    }
 }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
index 57b5d4e..73a3986 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContext.java
@@ -66,14 +66,14 @@
  */
 public final class BridgeContext extends Context {
 
-    private Resources mResources;
-    private Theme mTheme;
-    private HashMap<View, Object> mViewKeyMap = new HashMap<View, Object>();
-    private IStyleResourceValue mThemeValues;
+    private final Resources mResources;
+    private final Theme mTheme;
+    private final HashMap<View, Object> mViewKeyMap = new HashMap<View, Object>();
+    private final IStyleResourceValue mThemeValues;
     private final Object mProjectKey;
-    private Map<String, Map<String, IResourceValue>> mProjectResources;
-    private Map<String, Map<String, IResourceValue>> mFrameworkResources;
-    private Map<IStyleResourceValue, IStyleResourceValue> mStyleInheritanceMap;
+    private final Map<String, Map<String, IResourceValue>> mProjectResources;
+    private final Map<String, Map<String, IResourceValue>> mFrameworkResources;
+    private final Map<IStyleResourceValue, IStyleResourceValue> mStyleInheritanceMap;
 
     // maps for dynamically generated id representing style objects (IStyleResourceValue)
     private Map<Integer, IStyleResourceValue> mDynamicIdToStyleMap;
@@ -927,7 +927,6 @@
         return null;
     }
 
-    @Override
     public File getExternalCacheDir() {
         // TODO Auto-generated method stub
         return null;
@@ -965,7 +964,6 @@
         return null;
     }
 
-    @Override
     public File getExternalFilesDir(String type) {
         // TODO Auto-generated method stub
         return null;