Merge "Add support for transformations."
diff --git a/api/current.xml b/api/current.xml
index e634dac..c46d7df 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -20336,6 +20336,17 @@
  visibility="public"
 >
 </method>
+<method name="isImmersive"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
 <method name="isTaskRoot"
  return="boolean"
  abstract="false"
@@ -21313,6 +21324,19 @@
 <parameter name="uri" type="android.net.Uri">
 </parameter>
 </method>
+<method name="setImmersive"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="i" type="boolean">
+</parameter>
+</method>
 <method name="setIntent"
  return="void"
  abstract="false"
@@ -28293,7 +28317,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<implements name="android.view.InputConsumer.Callback">
+<implements name="android.view.InputQueue.Callback">
 </implements>
 <implements name="android.view.SurfaceHolder.Callback">
 </implements>
@@ -28305,7 +28329,7 @@
  visibility="public"
 >
 </constructor>
-<method name="onInputConsumerCreated"
+<method name="onInputQueueCreated"
  return="void"
  abstract="false"
  native="false"
@@ -28315,10 +28339,10 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="consumer" type="android.view.InputConsumer">
+<parameter name="queue" type="android.view.InputQueue">
 </parameter>
 </method>
-<method name="onInputConsumerDestroyed"
+<method name="onInputQueueDestroyed"
  return="void"
  abstract="false"
  native="false"
@@ -28328,7 +28352,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="consumer" type="android.view.InputConsumer">
+<parameter name="queue" type="android.view.InputQueue">
 </parameter>
 </method>
 <method name="surfaceChanged"
@@ -85067,17 +85091,6 @@
  visibility="public"
 >
 </method>
-<method name="getPriority"
- return="int"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
 <method name="getSpeedAccuracy"
  return="int"
  abstract="false"
@@ -85235,19 +85248,6 @@
 <parameter name="level" type="int">
 </parameter>
 </method>
-<method name="setPreferredPriority"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="priority" type="int">
-</parameter>
-</method>
 <method name="setSpeedAccuracy"
  return="void"
  abstract="false"
@@ -85302,17 +85302,6 @@
 <parameter name="flags" type="int">
 </parameter>
 </method>
-<field name="ACCURACY_BEST"
- type="int"
- transient="false"
- volatile="false"
- value="4"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="ACCURACY_COARSE"
  type="int"
  transient="false"
@@ -85368,17 +85357,6 @@
  visibility="public"
 >
 </field>
-<field name="BEARING_ACCURACY_PRIORITY"
- type="int"
- transient="false"
- volatile="false"
- value="4"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="CREATOR"
  type="android.os.Parcelable.Creator"
  transient="false"
@@ -85389,17 +85367,6 @@
  visibility="public"
 >
 </field>
-<field name="HORIZONTAL_ACCURACY_PRIORITY"
- type="int"
- transient="false"
- volatile="false"
- value="1"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="NO_REQUIREMENT"
  type="int"
  transient="false"
@@ -85444,39 +85411,6 @@
  visibility="public"
 >
 </field>
-<field name="POWER_REQUIREMENT_PRIORITY"
- type="int"
- transient="false"
- volatile="false"
- value="5"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="SPEED_ACCURACY_PRIORITY"
- type="int"
- transient="false"
- volatile="false"
- value="3"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="VERTICAL_ACCURACY_PRIORITY"
- type="int"
- transient="false"
- volatile="false"
- value="2"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 </class>
 <class name="Geocoder"
  extends="java.lang.Object"
@@ -176354,23 +176288,23 @@
 </parameter>
 </constructor>
 </class>
-<class name="InputConsumer"
+<class name="InputQueue"
  extends="java.lang.Object"
  abstract="false"
  static="false"
- final="false"
+ final="true"
  deprecated="not deprecated"
  visibility="public"
 >
 </class>
-<interface name="InputConsumer.Callback"
+<interface name="InputQueue.Callback"
  abstract="true"
  static="true"
  final="false"
  deprecated="not deprecated"
  visibility="public"
 >
-<method name="onInputConsumerCreated"
+<method name="onInputQueueCreated"
  return="void"
  abstract="true"
  native="false"
@@ -176380,10 +176314,10 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="consumer" type="android.view.InputConsumer">
+<parameter name="queue" type="android.view.InputQueue">
 </parameter>
 </method>
-<method name="onInputConsumerDestroyed"
+<method name="onInputQueueDestroyed"
  return="void"
  abstract="true"
  native="false"
@@ -176393,7 +176327,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="consumer" type="android.view.InputConsumer">
+<parameter name="queue" type="android.view.InputQueue">
 </parameter>
 </method>
 </interface>
@@ -190900,7 +190834,7 @@
 <parameter name="event" type="android.view.MotionEvent">
 </parameter>
 </method>
-<method name="takeInputChannel"
+<method name="takeInputQueue"
  return="void"
  abstract="true"
  native="false"
@@ -190910,7 +190844,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="callback" type="android.view.InputConsumer.Callback">
+<parameter name="callback" type="android.view.InputQueue.Callback">
 </parameter>
 </method>
 <method name="takeKeyEvents"
@@ -223810,7 +223744,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="arg0" type="T">
+<parameter name="t" type="T">
 </parameter>
 </method>
 </interface>
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 382f1bd..4a47b66 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -3933,6 +3933,46 @@
         }
     }
 
+    /**
+     * Bit indicating that this activity is "immersive" and should not be
+     * interrupted by notifications if possible.
+     *
+     * This value is initially set by the manifest property
+     * <code>android:immersive</code> but may be changed at runtime by
+     * {@link #setImmersive}.
+     *
+     * @see android.content.pm.ActivityInfo#FLAG_IMMERSIVE
+     */
+    public boolean isImmersive() {
+        try {
+            return ActivityManagerNative.getDefault().isImmersive(mToken);
+        } catch (RemoteException e) {
+            return false;
+        }
+    }
+
+    /**
+     * Adjust the current immersive mode setting.
+     * 
+     * Note that changing this value will have no effect on the activity's
+     * {@link android.content.pm.ActivityInfo} structure; that is, if
+     * <code>android:immersive</code> is set to <code>true</code>
+     * in the application's manifest entry for this activity, the {@link
+     * android.content.pm.ActivityInfo#flags ActivityInfo.flags} member will
+     * always have its {@link android.content.pm.ActivityInfo#FLAG_IMMERSIVE
+     * FLAG_IMMERSIVE} bit set.
+     *
+     * @see #isImmersive
+     * @see android.content.pm.ActivityInfo#FLAG_IMMERSIVE
+     */
+    public void setImmersive(boolean i) {
+        try {
+            ActivityManagerNative.getDefault().setImmersive(mToken, i);
+        } catch (RemoteException e) {
+            // pass
+        }
+    }
+
     // ------------------ Internal API ------------------
     
     final void setParent(Activity parent) {
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 2c1f2da..63b2f08 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1268,6 +1268,31 @@
             reply.writeNoException();
             return true;
         }
+
+        case IS_IMMERSIVE_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            reply.writeInt(isImmersive(token) ? 1 : 0);
+            reply.writeNoException();
+            return true;
+        }
+
+        case SET_IMMERSIVE_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            IBinder token = data.readStrongBinder();
+            boolean imm = data.readInt() == 1;
+            setImmersive(token, imm);
+            reply.writeNoException();
+            return true;
+        }
+        
+        case IS_TOP_ACTIVITY_IMMERSIVE_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            reply.writeInt(isTopActivityImmersive() ? 1 : 0);
+            reply.writeNoException();
+            return true;
+        }
+
         }
         
         return super.onTransact(code, data, reply, flags);
@@ -2802,5 +2827,45 @@
         reply.recycle();
     }
     
+    public void setImmersive(IBinder token, boolean immersive)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        data.writeInt(immersive ? 1 : 0);
+        mRemote.transact(SET_IMMERSIVE_TRANSACTION, data, reply, 0);
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+    }
+
+    public boolean isImmersive(IBinder token)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeStrongBinder(token);
+        mRemote.transact(IS_IMMERSIVE_TRANSACTION, data, reply, 0);
+        boolean res = reply.readInt() == 1;
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+        return res;
+    }
+
+    public boolean isTopActivityImmersive()
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        mRemote.transact(IS_TOP_ACTIVITY_IMMERSIVE_TRANSACTION, data, reply, 0);
+        boolean res = reply.readInt() == 1;
+        reply.readException();
+        data.recycle();
+        reply.recycle();
+        return res;
+    }
+
     private IBinder mRemote;
 }
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 542bc41..3a86ead 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -311,6 +311,10 @@
     public boolean isUserAMonkey() throws RemoteException;
     
     public void finishHeavyWeightApp() throws RemoteException;
+
+    public void setImmersive(IBinder token, boolean immersive) throws RemoteException;
+    public boolean isImmersive(IBinder token) throws RemoteException;
+    public boolean isTopActivityImmersive() throws RemoteException;
     
     /*
      * Private non-Binder interfaces
@@ -524,4 +528,7 @@
     int GET_RUNNING_EXTERNAL_APPLICATIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+107;
     int FINISH_HEAVY_WEIGHT_APP_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+108;
     int HANDLE_APPLICATION_STRICT_MODE_VIOLATION_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+109;
+    int IS_IMMERSIVE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+110;
+    int SET_IMMERSIVE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+111;
+    int IS_TOP_ACTIVITY_IMMERSIVE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+112;
 }
diff --git a/core/java/android/app/NativeActivity.java b/core/java/android/app/NativeActivity.java
index 973ad60..429d164 100644
--- a/core/java/android/app/NativeActivity.java
+++ b/core/java/android/app/NativeActivity.java
@@ -7,7 +7,7 @@
 import android.content.pm.PackageManager;
 import android.os.Bundle;
 import android.view.InputChannel;
-import android.view.InputConsumer;
+import android.view.InputQueue;
 import android.view.SurfaceHolder;
 
 import java.io.File;
@@ -17,7 +17,7 @@
  * purely in native code.  That is, a game (or game-like thing).
  */
 public class NativeActivity extends Activity implements SurfaceHolder.Callback,
-        InputConsumer.Callback {
+        InputQueue.Callback {
     public static final String META_DATA_LIB_NAME = "android.app.lib_name";
     
     private int mNativeHandle;
@@ -45,7 +45,7 @@
         ActivityInfo ai;
         
         getWindow().takeSurface(this);
-        getWindow().takeInputChannel(this);
+        getWindow().takeInputQueue(this);
         
         try {
             ai = getPackageManager().getActivityInfo(
@@ -145,11 +145,11 @@
         onSurfaceDestroyedNative(mNativeHandle, holder);
     }
     
-    public void onInputConsumerCreated(InputConsumer consumer) {
-        onInputChannelCreatedNative(mNativeHandle, consumer.getInputChannel());
+    public void onInputQueueCreated(InputQueue queue) {
+        onInputChannelCreatedNative(mNativeHandle, queue.getInputChannel());
     }
     
-    public void onInputConsumerDestroyed(InputConsumer consumer) {
-        onInputChannelDestroyedNative(mNativeHandle, consumer.getInputChannel());
+    public void onInputQueueDestroyed(InputQueue queue) {
+        onInputChannelDestroyedNative(mNativeHandle, queue.getInputChannel());
     }
 }
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 40ed980..9a3c618 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -317,22 +317,23 @@
             // Log.v(TAG, "getThumbnail: origId="+origId+", kind="+kind+", isVideo="+isVideo);
             // If the magic is non-zero, we simply return thumbnail if it does exist.
             // querying MediaProvider and simply return thumbnail.
-            MiniThumbFile thumbFile = MiniThumbFile.instance(baseUri);
-            long magic = thumbFile.getMagic(origId);
-            if (magic != 0) {
-                if (kind == MICRO_KIND) {
-                    byte[] data = new byte[MiniThumbFile.BYTES_PER_MINTHUMB];
-                    if (thumbFile.getMiniThumbFromFile(origId, data) != null) {
-                        bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
-                        if (bitmap == null) {
-                            Log.w(TAG, "couldn't decode byte array.");
+            MiniThumbFile thumbFile = new MiniThumbFile(isVideo ? Video.Media.EXTERNAL_CONTENT_URI
+                    : Images.Media.EXTERNAL_CONTENT_URI);
+            Cursor c = null;
+            try {
+                long magic = thumbFile.getMagic(origId);
+                if (magic != 0) {
+                    if (kind == MICRO_KIND) {
+                        byte[] data = new byte[MiniThumbFile.BYTES_PER_MINTHUMB];
+                        if (thumbFile.getMiniThumbFromFile(origId, data) != null) {
+                            bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
+                            if (bitmap == null) {
+                                Log.w(TAG, "couldn't decode byte array.");
+                            }
                         }
-                    }
-                    return bitmap;
-                } else if (kind == MINI_KIND) {
-                    String column = isVideo ? "video_id=" : "image_id=";
-                    Cursor c = null;
-                    try {
+                        return bitmap;
+                    } else if (kind == MINI_KIND) {
+                        String column = isVideo ? "video_id=" : "image_id=";
                         c = cr.query(baseUri, PROJECTION, column + origId, null, null);
                         if (c != null && c.moveToFirst()) {
                             bitmap = getMiniThumbFromFile(c, baseUri, cr, options);
@@ -340,17 +341,13 @@
                                 return bitmap;
                             }
                         }
-                    } finally {
-                        if (c != null) c.close();
                     }
                 }
-            }
 
-            Cursor c = null;
-            try {
                 Uri blockingUri = baseUri.buildUpon().appendQueryParameter("blocking", "1")
                         .appendQueryParameter("orig_id", String.valueOf(origId))
                         .appendQueryParameter("group_id", String.valueOf(groupId)).build();
+                if (c != null) c.close();
                 c = cr.query(blockingUri, PROJECTION, null, null, null);
                 // This happens when original image/video doesn't exist.
                 if (c == null) return null;
@@ -397,6 +394,9 @@
                 Log.w(TAG, ex);
             } finally {
                 if (c != null) c.close();
+                // To avoid file descriptor leak in application process.
+                thumbFile.deactivate();
+                thumbFile = null;
             }
             return bitmap;
         }
diff --git a/core/java/android/view/InputConsumer.java b/core/java/android/view/InputConsumer.java
deleted file mode 100644
index 63b26c6..0000000
--- a/core/java/android/view/InputConsumer.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.view;
-
-/**
- * Handle for consuming raw input events.
- */
-public class InputConsumer {
-    public static interface Callback {
-        void onInputConsumerCreated(InputConsumer consumer);
-        void onInputConsumerDestroyed(InputConsumer consumer);
-    }
-
-    final InputChannel mChannel;
-    
-    /** @hide */
-    public InputConsumer(InputChannel channel) {
-        mChannel = channel;
-    }
-    
-    /** @hide */
-    public InputChannel getInputChannel() {
-        return mChannel;
-    }
-}
diff --git a/core/java/android/view/InputQueue.java b/core/java/android/view/InputQueue.java
index b38f7d5..7feee38 100644
--- a/core/java/android/view/InputQueue.java
+++ b/core/java/android/view/InputQueue.java
@@ -21,16 +21,25 @@
 
 /**
  * An input queue provides a mechanism for an application to receive incoming
- * input events sent over an input channel.  Signalling is implemented by MessageQueue.
- * @hide
+ * input events.  Currently only usable from native code.
  */
 public final class InputQueue {
     private static final String TAG = "InputQueue";
     
+    public static interface Callback {
+        void onInputQueueCreated(InputQueue queue);
+        void onInputQueueDestroyed(InputQueue queue);
+    }
+
+    final InputChannel mChannel;
+    
     // Describes the interpretation of an event.
     // XXX This concept is tentative.  See comments in android/input.h.
+    /** @hide */
     public static final int INPUT_EVENT_NATURE_KEY = 1;
+    /** @hide */
     public static final int INPUT_EVENT_NATURE_TOUCH = 2;
+    /** @hide */
     public static final int INPUT_EVENT_NATURE_TRACKBALL = 3;
     
     private static Object sLock = new Object();
@@ -40,7 +49,14 @@
     private static native void nativeUnregisterInputChannel(InputChannel inputChannel);
     private static native void nativeFinished(long finishedToken);
     
-    private InputQueue() {
+    /** @hide */
+    public InputQueue(InputChannel channel) {
+        mChannel = channel;
+    }
+    
+    /** @hide */
+    public InputChannel getInputChannel() {
+        return mChannel;
     }
     
     /**
@@ -48,6 +64,7 @@
      * @param inputChannel The input channel to register.
      * @param inputHandler The input handler to input events send to the target.
      * @param messageQueue The message queue on whose thread the handler should be invoked.
+     * @hide
      */
     public static void registerInputChannel(InputChannel inputChannel, InputHandler inputHandler,
             MessageQueue messageQueue) {
@@ -71,6 +88,7 @@
      * Unregisters an input channel.
      * Does nothing if the channel is not currently registered.
      * @param inputChannel The input channel to unregister.
+     * @hide
      */
     public static void unregisterInputChannel(InputChannel inputChannel) {
         if (inputChannel == null) {
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 907306c..34777ce 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -236,8 +236,9 @@
 
     /**
      * When set, this ViewGroup should not intercept touch events.
+     * {@hide}
      */
-    private static final int FLAG_DISALLOW_INTERCEPT = 0x80000;
+    protected static final int FLAG_DISALLOW_INTERCEPT = 0x80000;
 
     /**
      * Indicates which types of drawing caches are to be kept in memory.
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 7f3a500..70049ed 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -147,8 +147,8 @@
 
     final View.AttachInfo mAttachInfo;
     InputChannel mInputChannel;
-    InputConsumer.Callback mInputConsumerCallback;
-    InputConsumer mInputConsumer;
+    InputQueue.Callback mInputQueueCallback;
+    InputQueue mInputQueue;
     
     final Rect mTempRect; // used in the transaction to not thrash the heap.
     final Rect mVisRect; // used to retrieve visible rect of focused view.
@@ -442,12 +442,12 @@
 
                 if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
                     if (view instanceof RootViewSurfaceTaker) {
-                        mInputConsumerCallback =
-                            ((RootViewSurfaceTaker)view).willYouTakeTheInputConsumer();
+                        mInputQueueCallback =
+                            ((RootViewSurfaceTaker)view).willYouTakeTheInputQueue();
                     }
-                    if (mInputConsumerCallback != null) {
-                        mInputConsumer = new InputConsumer(mInputChannel);
-                        mInputConsumerCallback.onInputConsumerCreated(mInputConsumer);
+                    if (mInputQueueCallback != null) {
+                        mInputQueue = new InputQueue(mInputChannel);
+                        mInputQueueCallback.onInputQueueCreated(mInputQueue);
                     } else {
                         InputQueue.registerInputChannel(mInputChannel, mInputHandler,
                                 Looper.myQueue());
@@ -1598,9 +1598,9 @@
 
         if (WindowManagerPolicy.ENABLE_NATIVE_INPUT_DISPATCH) {
             if (mInputChannel != null) {
-                if (mInputConsumerCallback != null) {
-                    mInputConsumerCallback.onInputConsumerDestroyed(mInputConsumer);
-                    mInputConsumerCallback = null;
+                if (mInputQueueCallback != null) {
+                    mInputQueueCallback.onInputQueueDestroyed(mInputQueue);
+                    mInputQueueCallback = null;
                 } else {
                     InputQueue.unregisterInputChannel(mInputChannel);
                 }
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index 095e585..9b31b9c 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -488,11 +488,11 @@
     public abstract void takeSurface(SurfaceHolder.Callback callback);
     
     /**
-     * Take ownership of this window's InputChannel.  The window will no
-     * longer read and dispatch input events from the channel; it is your
+     * Take ownership of this window's InputQueue.  The window will no
+     * longer read and dispatch input events from the queue; it is your
      * responsibility to do so.
      */
-    public abstract void takeInputChannel(InputConsumer.Callback callback);
+    public abstract void takeInputQueue(InputQueue.Callback callback);
     
     /**
      * Return whether this window is being displayed with a floating style
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 6de6995..fabda08 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -1237,6 +1237,7 @@
     /**
      * Sets whether XSS Auditor is enabled.
      * @param flag Whether XSS Auditor should be enabled.
+     * @hide Only used by LayoutTestController.
      */
     public synchronized void setXSSAuditorEnabled(boolean flag) {
         if (mXSSAuditorEnabled != flag) {
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index c11c7e1..10927a7 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2076,6 +2076,14 @@
                 }
 
                 if (y != mLastY) {
+                    // We may be here after stopping a fling and continuing to scroll.
+                    // If so, we haven't disallowed intercepting touch events yet.
+                    // Make sure that we do so in case we're in a parent that can intercept.
+                    if ((mGroupFlags & FLAG_DISALLOW_INTERCEPT) == 0 &&
+                            Math.abs(deltaY) > mTouchSlop) {
+                        requestDisallowInterceptTouchEvent(true);
+                    }
+
                     deltaY -= mMotionCorrection;
                     int incrementalDeltaY = mLastY != Integer.MIN_VALUE ? y - mLastY : deltaY;
                     
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index f8ab04c..642c313 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -3892,6 +3892,17 @@
                 mHistoryBaseTime = rec.time;
             }
         }
+        
+        long oldnow = SystemClock.elapsedRealtime() - (5*60*100);
+        if (oldnow > 0) {
+            // If the system process has restarted, but not the entire
+            // system, then the mHistoryBaseTime already accounts for
+            // much of the elapsed time.  We thus want to adjust it back,
+            // to avoid large gaps in the data.  We determine we are
+            // in this case by arbitrarily saying it is so if at this
+            // point in boot the elapsed time is already more than 5 seconds.
+            mHistoryBaseTime -= oldnow;
+        }
     }
     
     void writeHistory(Parcel out) {
diff --git a/core/java/com/android/internal/view/RootViewSurfaceTaker.java b/core/java/com/android/internal/view/RootViewSurfaceTaker.java
index 991266a..7ff8d4c 100644
--- a/core/java/com/android/internal/view/RootViewSurfaceTaker.java
+++ b/core/java/com/android/internal/view/RootViewSurfaceTaker.java
@@ -1,6 +1,6 @@
 package com.android.internal.view;
 
-import android.view.InputConsumer;
+import android.view.InputQueue;
 import android.view.SurfaceHolder;
 
 /** hahahah */
@@ -9,5 +9,5 @@
     void setSurfaceType(int type);
     void setSurfaceFormat(int format);
     void setSurfaceKeepScreenOn(boolean keepOn);
-    InputConsumer.Callback willYouTakeTheInputConsumer();
+    InputQueue.Callback willYouTakeTheInputQueue();
 }
diff --git a/core/jni/android_media_AudioTrack.cpp b/core/jni/android_media_AudioTrack.cpp
index 65c0435..ce43e73 100644
--- a/core/jni/android_media_AudioTrack.cpp
+++ b/core/jni/android_media_AudioTrack.cpp
@@ -166,7 +166,7 @@
 static int
 android_media_AudioTrack_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
         jint streamType, jint sampleRateInHertz, jint channels,
-        jint audioFormat, jint buffSizeInBytes, jint memoryMode)
+        jint audioFormat, jint buffSizeInBytes, jint memoryMode, jintArray jSession)
 {
     LOGV("sampleRate=%d, audioFormat(from Java)=%d, channels=%x, buffSize=%d",
         sampleRateInHertz, audioFormat, channels, buffSizeInBytes);
@@ -253,6 +253,20 @@
     
     lpJniStorage->mStreamType = atStreamType;
     
+    jint* nSession = NULL;
+    if (jSession) {
+        nSession = (jint *) env->GetPrimitiveArrayCritical(jSession, NULL);
+        if (nSession == NULL) {
+            LOGE("Error creating AudioTrack: Error retrieving session id pointer");
+            delete lpJniStorage;
+            return AUDIOTRACK_ERROR;
+        }
+    } else {
+        LOGE("Error creating AudioTrack: invalid session ID pointer");
+        delete lpJniStorage;
+        return AUDIOTRACK_ERROR;
+    }
+
     // create the native AudioTrack object
     AudioTrack* lpTrack = new AudioTrack();
     if (lpTrack == NULL) {
@@ -273,7 +287,8 @@
             audioCallback, &(lpJniStorage->mCallbackData),//callback, callback data (user)
             0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack
             0,// shared mem
-            true);// thread can call Java
+            true,// thread can call Java
+            nSession[0]);// audio session ID
             
     } else if (memoryMode == javaAudioTrackFields.MODE_STATIC) {
         // AudioTrack is using shared memory
@@ -293,7 +308,8 @@
             audioCallback, &(lpJniStorage->mCallbackData),//callback, callback data (user));
             0,// notificationFrames == 0 since not using EVENT_MORE_DATA to feed the AudioTrack 
             lpJniStorage->mMemBase,// shared mem
-            true);// thread can call Java 
+            true,// thread can call Java
+            nSession[0]);// audio session ID
     }
 
     if (lpTrack->initCheck() != NO_ERROR) {
@@ -301,6 +317,12 @@
         goto native_init_failure;
     }
 
+    // read the audio session ID back from AudioTrack in case we create a new session
+    nSession[0] = lpTrack->getSessionId();
+
+    env->ReleasePrimitiveArrayCritical(jSession, nSession, 0);
+    nSession = NULL;
+
     // save our newly created C++ AudioTrack in the "nativeTrackInJavaObj" field 
     // of the Java object (in mNativeTrackInJavaObj)
     env->SetIntField(thiz, javaAudioTrackFields.nativeTrackInJavaObj, (int)lpTrack);
@@ -317,6 +339,9 @@
     env->SetIntField(thiz, javaAudioTrackFields.nativeTrackInJavaObj, 0);
     
 native_track_failure:
+    if (nSession != NULL) {
+        env->ReleasePrimitiveArrayCritical(jSession, nSession, 0);
+    }
     env->DeleteGlobalRef(lpJniStorage->mCallbackData.audioTrack_class);
     env->DeleteGlobalRef(lpJniStorage->mCallbackData.audioTrack_ref);
     delete lpJniStorage;
@@ -785,7 +810,7 @@
     {"native_stop",          "()V",      (void *)android_media_AudioTrack_stop},
     {"native_pause",         "()V",      (void *)android_media_AudioTrack_pause},
     {"native_flush",         "()V",      (void *)android_media_AudioTrack_flush},
-    {"native_setup",         "(Ljava/lang/Object;IIIIII)I", 
+    {"native_setup",         "(Ljava/lang/Object;IIIIII[I)I",
                                          (void *)android_media_AudioTrack_native_setup},
     {"native_finalize",      "()V",      (void *)android_media_AudioTrack_native_finalize},
     {"native_release",       "()V",      (void *)android_media_AudioTrack_native_release},
diff --git a/docs/html/guide/topics/data/backup.jd b/docs/html/guide/topics/data/backup.jd
index aad0f92..4e74a83 100644
--- a/docs/html/guide/topics/data/backup.jd
+++ b/docs/html/guide/topics/data/backup.jd
@@ -15,6 +15,8 @@
   <h2>In this document</h2>
   <ol>
     <li><a href="#Basics">The Basics</a></li>
+    <li><a href="#BackupManifest">Declaring the Backup Agent in Your Manifest</a></li>
+    <li><a href="#BackupKey">Registering for Android Backup Service</a></li>
     <li><a href="#BackupAgent">Extending BackupAgent</a>
       <ol>
         <li><a href="#RequiredMethods">Required Methods</a></li>
@@ -45,32 +47,53 @@
 </div>
 
 <p>Android's {@link android.app.backup backup} service allows you to copy your persistent
-application data to a remote "cloud" storage, in order to provide a restore point for the
+application data to remote "cloud" storage, in order to provide a restore point for the
 application data and settings. If a user performs a factory reset or converts to a new
 Android-powered device, the system automatically restores your backup data when the application
-is re-installed. This way, your users are not required to reproduce their previous data or
+is re-installed. This way, your users don't need to reproduce their previous data or
 application settings. This process is completely transparent to the user and does not affect the
 functionality or user experience in your application.</p>
 
-<p>Android-powered devices that support the backup service provide a cloud storage area that
-saves your backup data and a backup transport that delivers your data to
-the storage area and back to the device. During a backup
-operation, Android's Backup Manager requests backup data from your application, then delivers it to
-the cloud storage using the backup transport. During a restore operation, the Backup Manager
-retrieves the backup data from the backup transport and returns it to your application
-so it can restore the data to the device. The backup service is <em>not</em> designed for data
-synchronization (you do not have access the backup data, except during a restore operation on the
-device).</p>
+<p>During a backup operation (which your application can request), Android's Backup Manager ({@link
+android.app.backup.BackupManager}) queries your application for backup data, then hands it to
+a backup transport, which then delivers the data to the cloud storage. During a
+restore operation, the Backup Manager retrieves the backup data from the backup transport and
+returns it to your application so your application can restore the data to the device. It's
+possible for your application to request a restore, but that shouldn't be necessary&mdash;Android
+automatically performs a restore operation when your application is installed and there exists
+backup data associated with the user. The primary scenario in which backup data is restored is when
+a user resets their device or upgrades to a new device and their previously installed
+applications are re-installed.</p>
 
-<p>The cloud storage used for backup won't necessarily be the same on all Android-powered devices.
-The cloud storage and backup transport may differ between devices and service providers.
-Where the backup data is stored is transparent to your application, but you are assured that your
-application data cannot be read by other applications.</p>
+<p class="note"><strong>Note:</strong> The backup service is <em>not</em> designed for
+synchronizing application data with other clients or saving data that you'd like to access during
+the normal application lifecycle. You cannot read or write backup data on demand and cannot access
+it in any way other than through the APIs provided by the Backup Manager.</p>
+
+<p>The backup transport is the client-side component of Android's backup framework, which is
+customizable by
+the device manufacturer and service provider. The backup transport may differ from device to device
+and which backup transport is available on any given device is transparent to your application. The
+Backup Manager APIs isolate your application from the actual backup transport available on a given
+device&mdash;your application communicates with the Backup Manager through a fixed set of APIs,
+regardless of the underlying transport.</p>
+
+<p>Data backup is <em>not</em> guaranteed to be available on all Android-powered
+devices. However, your application is not adversely affected in the event
+that a device does not provide a backup transport. If you believe that users will benefit from data
+backup in your application, then you can implement it as described in this document, test it, then
+publish your application without any concern about which devices actually perform backup. When your
+application runs on a device that does not provide a backup transport, your application operates
+normally, but will not receive callbacks from the Backup Manager to backup data.</p>
+
+<p>Although you cannot know what the current transport is, you are always assured that your
+backup data cannot be read by other applications on the device. Only the Backup Manager and backup
+transport have access to the data you provide during a backup operation.</p>
 
 <p class="caution"><strong>Caution:</strong> Because the cloud storage and transport service can
 differ from device to device, Android makes no guarantees about the security of your data while
-using backup. You should be cautious about using backup to store sensitive data, such as usernames
-and passwords.</p>
+using backup. You should always be cautious about using backup to store sensitive data, such as
+usernames and passwords.</p>
 
 
 <h2 id="Basics">The Basics</h2>
@@ -78,8 +101,8 @@
 <p>To backup your application data, you need to implement a backup agent. Your backup
 agent is called by the Backup Manager to provide the data you want to back up. It is also called
 to restore your backup data when the application is re-installed. The Backup Manager handles all
-your data transactions with the cloud storage and your backup agent handles all your data
-transactions on the device.</p>
+your data transactions with the cloud storage (using the backup transport) and your backup agent
+handles all your data transactions on the device.</p>
 
 <p>To implement a backup agent, you must:</p>
 
@@ -87,6 +110,11 @@
   <li>Declare your backup agent in your manifest file with the <a
 href="{@docRoot}guide/topics/manifest/application-element.html#agent">{@code
 android:backupAgent}</a> attribute.</li>
+  <li>Register your application with a backup service. Google offers <a
+href="http://code.google.com/android/backup/index.html">Android Backup Service</a> as a backup
+service for most Android-powered devices, which requires that you register your application in
+order for it to work. Any other backup services available might also require you to register
+in order to store your data on their servers.</li>
   <li>Define a backup agent by either:</p>
     <ol type="a">
       <li><a href="#backupAgent">Extending BackupAgent</a>
@@ -118,7 +146,6 @@
 
 
 
-
 <h2 id="BackupManifest">Declaring the Backup Agent in Your Manifest</h2>
 
 <p>This is the easiest step, so once you've decided on the class name for your backup agent, declare
@@ -160,6 +187,50 @@
 
 
 
+<h2 id="BackupKey">Registering for Android Backup Service</h2>
+
+<p>Google provides a backup transport with <a
+href="http://code.google.com/android/backup/index.html">Android Backup Service</a> for most
+Android-powered devices running Android 2.2 or greater.</p>
+
+<p>In order for you application to perform backup using Android Backup Service, you must
+register your application with the service to receive a Backup Service Key, then
+declare the Backup Service Key in your Android manifest.</p>
+
+<p>To get your Backup Service Key, <a
+href="http://code.google.com/android/backup/signup.html">register for Android Backup Service</a>.
+When you register, you will be provided a Backup Service Key and the appropriate {@code
+&lt;meta-data&gt;} XML code for your Android manifest file, which you must include as a child of the
+{@code &lt;application&gt;} element. For example:</p>
+
+<pre>
+&lt;application android:label="MyApplication"
+             android:backupAgent="MyBackupAgent"&gt;
+    ...
+    &lt;meta-data android:name="com.google.android.backup.api_key"
+        android:value="AEdPqrEAAAAIDaYEVgU6DJnyJdBmU7KLH3kszDXLv_4DIsEIyQ" /&gt;
+&lt;/application&gt;
+</pre>
+
+<p>The <code>android:name</code> must be <code>"com.google.android.backup.api_key"</code> and
+the <code>android:value</code> must be the Backup Service Key received from the Android Backup
+Service registration.</p>
+
+<p>If you have multiple applications, you must register each one, using the respective package
+name.</p>
+
+<p class="note"><strong>Note:</strong> The backup transport provided by Android Backup Service is
+not guaranteed to be available
+on all Android-powered devices that support backup. Some devices might support backup
+using a different transport, some devices might not support backup at all, and there is no way for
+your application to know what transport is used on the device. However, if you implement backup for
+your application, you should always include a Backup Service Key for Android Backup Service so
+your application can perform backup when the device uses the Android Backup Service transport. If
+the device does not use Android Backup Service, then the {@code &lt;meta-data&gt;} element with the
+Backup Service Key is ignored.</p>
+
+
+
 
 <h2 id="BackupAgent">Extending BackupAgent</h2>
 
diff --git a/include/media/AudioRecord.h b/include/media/AudioRecord.h
index d956882..38e3d44 100644
--- a/include/media/AudioRecord.h
+++ b/include/media/AudioRecord.h
@@ -100,6 +100,19 @@
 
     typedef void (*callback_t)(int event, void* user, void *info);
 
+    /* Returns the minimum frame count required for the successful creation of
+     * an AudioRecord object.
+     * Returned status (from utils/Errors.h) can be:
+     *  - NO_ERROR: successful operation
+     *  - NO_INIT: audio server or audio hardware not initialized
+     *  - BAD_VALUE: unsupported configuration
+     */
+
+     static status_t getMinFrameCount(int* frameCount,
+                                      uint32_t sampleRate,
+                                      int format,
+                                      int channelCount);
+
     /* Constructs an uninitialized AudioRecord. No connection with
      * AudioFlinger takes place.
      */
diff --git a/include/media/IMediaPlayerService.h b/include/media/IMediaPlayerService.h
index 31c0991..e892875 100644
--- a/include/media/IMediaPlayerService.h
+++ b/include/media/IMediaPlayerService.h
@@ -40,8 +40,11 @@
 
     virtual sp<IMediaRecorder>  createMediaRecorder(pid_t pid) = 0;
     virtual sp<IMediaMetadataRetriever> createMetadataRetriever(pid_t pid) = 0;
-    virtual sp<IMediaPlayer>    create(pid_t pid, const sp<IMediaPlayerClient>& client, const char* url, const KeyedVector<String8, String8> *headers = NULL) = 0;
-    virtual sp<IMediaPlayer>    create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length) = 0;
+    virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client,
+            const char* url, const KeyedVector<String8, String8> *headers = NULL,
+            int audioSessionId = 0) = 0;
+    virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client,
+            int fd, int64_t offset, int64_t length, int audioSessionId) = 0;
     virtual sp<IMemory>         decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0;
     virtual sp<IMemory>         decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat) = 0;
     virtual sp<IOMX>            getOMX() = 0;
diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h
index dc783ce..62a4e50 100644
--- a/include/media/mediaplayer.h
+++ b/include/media/mediaplayer.h
@@ -172,6 +172,8 @@
             status_t        getMetadata(bool update_only, bool apply_filter, Parcel *metadata);
             status_t        suspend();
             status_t        resume();
+            status_t        setAudioSessionId(int sessionId);
+            int             getAudioSessionId();
 private:
             void            clear_l();
             status_t        seekTo_l(int msec);
@@ -198,6 +200,7 @@
     float                       mRightVolume;
     int                         mVideoWidth;
     int                         mVideoHeight;
+    int                         mAudioSessionId;
 };
 
 }; // namespace android
diff --git a/include/media/stagefright/MPEG4Writer.h b/include/media/stagefright/MPEG4Writer.h
index d62df46..39d0ea1 100644
--- a/include/media/stagefright/MPEG4Writer.h
+++ b/include/media/stagefright/MPEG4Writer.h
@@ -60,6 +60,7 @@
     class Track;
 
     FILE *mFile;
+    bool mUse32BitOffset;
     bool mPaused;
     bool mStarted;
     off_t mOffset;
diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp
index 2ad3382..b3103a4 100644
--- a/libs/ui/InputDispatcher.cpp
+++ b/libs/ui/InputDispatcher.cpp
@@ -1440,6 +1440,7 @@
     entry->type = type;
     entry->refCount = 1;
     entry->dispatchInProgress = false;
+    entry->eventTime = eventTime;
     entry->injectionResult = INPUT_EVENT_INJECTION_PENDING;
     entry->injectorPid = -1;
     entry->injectorUid = -1;
diff --git a/location/java/android/location/Criteria.java b/location/java/android/location/Criteria.java
index 647a9df..1f3fb7a 100644
--- a/location/java/android/location/Criteria.java
+++ b/location/java/android/location/Criteria.java
@@ -60,68 +60,31 @@
     /**
      * A constant indicating a low location accuracy requirement
      * - may be used for horizontal, altitude, speed or bearing accuracy.
-     * For horizontal and vertical position this corresponds to an accuracy
-     * greater than 500 meters.  For speed and bearing, this corresponds
-     * to greater than 5 meters/second velocity and 10 degrees for bearing.
+     * For horizontal and vertical position this corresponds roughly to
+     * an accuracy of greater than 500 meters.
      */
     public static final int ACCURACY_LOW = 1;
 
     /**
      * A constant indicating a medium accuracy requirement
-     * - may be used for horizontal, altitude, speed or bearing accuracy.
-     * For horizontal position this corresponds to an accuracy of between
-     * 100 and 500 meters, and between 200 and 500 meters for vertical accuracy.
-     * For speed and bearing, this corresponds to 1 meter/second to 5 meters/second
-     * velocity and and between 5 and 10 degrees for bearing.
+     * - currently used only for horizontal accuracy.
+     * For horizontal position this corresponds roughly to to an accuracy
+     * of between 100 and 500 meters.
      */
     public static final int ACCURACY_MEDIUM = 2;
 
     /**
      * a constant indicating a high accuracy requirement
      * - may be used for horizontal, altitude, speed or bearing accuracy.
-     * For horizontal and vertical position this corresponds to an accuracy
-     * less than 100 meters.  For speed and bearing, this corresponds
-     * to less 1 meter/second velocity less than 5 degrees for bearing.
+     * For horizontal and vertical position this corresponds roughly to
+     * an accuracy of less than 100 meters.
      */
     public static final int ACCURACY_HIGH = 3;
 
-    /**
-     * a constant indicating the best accuracy that is available for any
-     * location provider available
-     * - may be used for horizontal, altitude, speed or bearing accuracy.
-     */
-    public static final int ACCURACY_BEST = 4;
-
-    /**
-     * A constant indicating horizontal accuracy has the top priority
-     */
-    public static final int HORIZONTAL_ACCURACY_PRIORITY = 1;
-
-    /**
-     * A constant indicating altitude accuracy has the top priority
-     */
-    public static final int VERTICAL_ACCURACY_PRIORITY = 2;
-
-    /**
-     * A constant indicating speed accuracy has the top priority
-     */
-    public static final int SPEED_ACCURACY_PRIORITY = 3;
-
-    /**
-     * A constant indicating bearing accuracy has the top priority
-     */
-    public static final int BEARING_ACCURACY_PRIORITY = 4;
-
-    /**
-     * A constant indicating power requirement has the top priority
-     */
-    public static final int POWER_REQUIREMENT_PRIORITY = 5;
-
     private int mHorizontalAccuracy    = NO_REQUIREMENT;
     private int mVerticalAccuracy      = NO_REQUIREMENT;
     private int mSpeedAccuracy         = NO_REQUIREMENT;
     private int mBearingAccuracy       = NO_REQUIREMENT;
-    private int mPriority              = HORIZONTAL_ACCURACY_PRIORITY;
     private int mPowerRequirement      = NO_REQUIREMENT;
     private boolean mAltitudeRequired  = false;
     private boolean mBearingRequired   = false;
@@ -144,7 +107,6 @@
         mVerticalAccuracy = criteria.mVerticalAccuracy;
         mSpeedAccuracy = criteria.mSpeedAccuracy;
         mBearingAccuracy = criteria.mBearingAccuracy;
-        mPriority = criteria.mPriority;
         mPowerRequirement = criteria.mPowerRequirement;
         mAltitudeRequired = criteria.mAltitudeRequired;
         mBearingRequired = criteria.mBearingRequired;
@@ -155,13 +117,13 @@
     /**
      * Indicates the desired horizontal accuracy (latitude and longitude).
      * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_MEDIUM},
-     * {@link #ACCURACY_HIGH}, {@link #ACCURACY_BEST},
+     * {@link #ACCURACY_HIGH} or {@link #NO_REQUIREMENT}.
      * More accurate location may consume more power and may take longer.
      *
      * @throws IllegalArgumentException if accuracy is not one of the supported constants
      */
     public void setHorizontalAccuracy(int accuracy) {
-        if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_BEST) {
+        if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_HIGH) {
             throw new IllegalArgumentException("accuracy=" + accuracy);
         }
         mHorizontalAccuracy = accuracy;
@@ -170,7 +132,7 @@
     /**
      * Returns a constant indicating the desired horizontal accuracy (latitude and longitude).
      * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_MEDIUM},
-     * {@link #ACCURACY_HIGH}, {@link #ACCURACY_BEST},
+     * {@link #ACCURACY_HIGH} or {@link #NO_REQUIREMENT}.
      */
     public int getHorizontalAccuracy() {
         return mHorizontalAccuracy;
@@ -179,13 +141,13 @@
     /**
      * Indicates the desired vertical accuracy (altitude).
      * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_MEDIUM},
-     * {@link #ACCURACY_HIGH}, {@link #ACCURACY_BEST},
+     * {@link #ACCURACY_HIGH} or {@link #NO_REQUIREMENT}.
      * More accurate location may consume more power and may take longer.
      *
      * @throws IllegalArgumentException if accuracy is not one of the supported constants
      */
     public void setVerticalAccuracy(int accuracy) {
-        if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_BEST) {
+        if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_HIGH) {
             throw new IllegalArgumentException("accuracy=" + accuracy);
         }
         mVerticalAccuracy = accuracy;
@@ -193,8 +155,8 @@
 
     /**
      * Returns a constant indicating the desired vertical accuracy (altitude).
-     * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_MEDIUM},
-     * {@link #ACCURACY_HIGH}, {@link #ACCURACY_BEST},
+     * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_HIGH},
+     * or {@link #NO_REQUIREMENT}.
      */
     public int getVerticalAccuracy() {
         return mVerticalAccuracy;
@@ -202,14 +164,14 @@
 
     /**
      * Indicates the desired speed accuracy.
-     * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_MEDIUM},
-     * {@link #ACCURACY_HIGH}, {@link #ACCURACY_BEST},
+     * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_HIGH},
+     * or {@link #NO_REQUIREMENT}.
      * More accurate location may consume more power and may take longer.
      *
      * @throws IllegalArgumentException if accuracy is not one of the supported constants
      */
     public void setSpeedAccuracy(int accuracy) {
-        if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_BEST) {
+        if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_HIGH) {
             throw new IllegalArgumentException("accuracy=" + accuracy);
         }
         mSpeedAccuracy = accuracy;
@@ -217,8 +179,8 @@
 
     /**
      * Returns a constant indicating the desired speed accuracy
-     * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_MEDIUM},
-     * {@link #ACCURACY_HIGH}, {@link #ACCURACY_BEST},
+     * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_HIGH},
+     * or {@link #NO_REQUIREMENT}.
      */
     public int getSpeedAccuracy() {
         return mSpeedAccuracy;
@@ -226,14 +188,14 @@
 
     /**
      * Indicates the desired bearing accuracy.
-     * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_MEDIUM},
-     * {@link #ACCURACY_HIGH}, {@link #ACCURACY_BEST},
+     * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_HIGH},
+     * or {@link #NO_REQUIREMENT}.
      * More accurate location may consume more power and may take longer.
      *
      * @throws IllegalArgumentException if accuracy is not one of the supported constants
      */
     public void setBearingAccuracy(int accuracy) {
-        if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_BEST) {
+        if (accuracy < NO_REQUIREMENT || accuracy > ACCURACY_HIGH) {
             throw new IllegalArgumentException("accuracy=" + accuracy);
         }
         mBearingAccuracy = accuracy;
@@ -241,45 +203,14 @@
 
     /**
      * Returns a constant indicating the desired bearing accuracy.
-     * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_MEDIUM},
-     * {@link #ACCURACY_HIGH}, {@link #ACCURACY_BEST},
+     * Accuracy may be {@link #ACCURACY_LOW}, {@link #ACCURACY_HIGH},
+     * or {@link #NO_REQUIREMENT}.
      */
     public int getBearingAccuracy() {
         return mBearingAccuracy;
     }
 
     /**
-     * Indicates the top priority to optimize for if the criteria parameters are
-     * found to be in conflict.
-     * Since a location provider might only be able to optimize for one requirement,
-     * the other requirements are considered good to have, but not guaranteed.
-     * This parameter does not override the priorities communicated through the
-     * preferred accuracy and power consumption parameters.
-     * If this parameter is not specified and conflicts occur, the location manager
-     * will use thefollowing default priority (high priority to low priority):
-     * {@link #HORIZONTAL_ACCURACY_PRIORITY}, {@link #POWER_REQUIREMENT_PRIORITY},
-     * {@link #VERTICAL_ACCURACY_PRIORITY}, {@link #SPEED_ACCURACY_PRIORITY},
-     * {@link #BEARING_ACCURACY_PRIORITY}.
-     */
-    public void setPreferredPriority(int priority) {
-        if (priority < HORIZONTAL_ACCURACY_PRIORITY || priority > POWER_REQUIREMENT_PRIORITY) {
-            throw new IllegalArgumentException("priority=" + priority);
-        }
-        mPriority = priority;
-    }
-
-    /**
-     * Returns a constant indicating the top priority to optimize for if the
-     * criteria parameters are found to be in conflict.
-     * The value can be {@link #HORIZONTAL_ACCURACY_PRIORITY},
-     * {@link #VERTICAL_ACCURACY_PRIORITY}, {@link #SPEED_ACCURACY_PRIORITY},
-     * {@link #BEARING_ACCURACY_PRIORITY} or {@link #POWER_REQUIREMENT_PRIORITY}.
-     */
-    public int getPriority() {
-        return mPriority;
-    }
-
-    /**
      * Indicates the desired accuracy for latitude and longitude. Accuracy
      * may be {@link #ACCURACY_FINE} if desired location
      * is fine, else it can be {@link #ACCURACY_COARSE}.
@@ -292,7 +223,7 @@
             throw new IllegalArgumentException("accuracy=" + accuracy);
         }
         if (accuracy == ACCURACY_FINE) {
-            mHorizontalAccuracy = ACCURACY_BEST;
+            mHorizontalAccuracy = ACCURACY_HIGH;
         } else {
             mHorizontalAccuracy = ACCURACY_LOW;
         }
@@ -401,7 +332,6 @@
             c.mVerticalAccuracy = in.readInt();
             c.mSpeedAccuracy = in.readInt();
             c.mBearingAccuracy = in.readInt();
-            c.mPriority = in.readInt();
             c.mPowerRequirement = in.readInt();
             c.mAltitudeRequired = in.readInt() != 0;
             c.mBearingRequired = in.readInt() != 0;
@@ -424,7 +354,6 @@
         parcel.writeInt(mVerticalAccuracy);
         parcel.writeInt(mSpeedAccuracy);
         parcel.writeInt(mBearingAccuracy);
-        parcel.writeInt(mPriority);
         parcel.writeInt(mPowerRequirement);
         parcel.writeInt(mAltitudeRequired ? 1 : 0);
         parcel.writeInt(mBearingRequired ? 1 : 0);
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index bd78f93..50f0674 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -1627,6 +1627,12 @@
 
                 case MSG_MEDIA_SERVER_STARTED:
                     Log.e(TAG, "Media server started.");
+                    // indicate to audio HAL that we start the reconfiguration phase after a media
+                    // server crash
+                    // Note that MSG_MEDIA_SERVER_STARTED message is only received when the media server
+                    // process restarts after a crash, not the first time it is started.
+                    AudioSystem.setParameters("restarting=true");
+
                     // Restore device connection states
                     Set set = mConnectedDevices.entrySet();
                     Iterator i = set.iterator();
@@ -1660,6 +1666,9 @@
 
                     // Restore ringer mode
                     setRingerModeInt(getRingerMode(), false);
+
+                    // indicate the end of reconfiguration phase to audio HAL
+                    AudioSystem.setParameters("restarting=false");
                     break;
 
                 case MSG_PLAY_SOUND_EFFECT:
diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java
index 1e8d72f..079c41f 100644
--- a/media/java/android/media/AudioTrack.java
+++ b/media/java/android/media/AudioTrack.java
@@ -210,6 +210,10 @@
      * @see AudioFormat#ENCODING_PCM_16BIT
      */
     private int mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
+    /**
+     * Audio session ID
+     */
+    private int mSessionId = 0;
 
 
     //--------------------------------
@@ -258,6 +262,48 @@
     public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat,
             int bufferSizeInBytes, int mode)
     throws IllegalArgumentException {
+        this(streamType, sampleRateInHz, channelConfig, audioFormat,
+                bufferSizeInBytes, mode, 0);
+    }
+
+    /**
+     * Class constructor with audio session. Use this constructor when the AudioTrack must be
+     * attached to a particular audio session. The primary use of the audio session ID is to
+     * associate audio effects to a particular instance of AudioTrack: if an audio session ID
+     * is provided when creating an AudioEffect, this effect will be applied only to audio tracks
+     * and media players in the same session and not to the output mix.
+     * When an AudioTrack is created without specifying a session, it will create its own session
+     * which can be retreived by calling the {@link #getAudioSessionId()} method.
+     * If a session ID is provided, this AudioTrack will share effects attached to this session
+     * with all other media players or audio tracks in the same session.
+     * @param streamType the type of the audio stream. See
+     *   {@link AudioManager#STREAM_VOICE_CALL}, {@link AudioManager#STREAM_SYSTEM},
+     *   {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC} and
+     *   {@link AudioManager#STREAM_ALARM}
+     * @param sampleRateInHz the sample rate expressed in Hertz. Examples of rates are (but
+     *   not limited to) 44100, 22050 and 11025.
+     * @param channelConfig describes the configuration of the audio channels.
+     *   See {@link AudioFormat#CHANNEL_OUT_MONO} and
+     *   {@link AudioFormat#CHANNEL_OUT_STEREO}
+     * @param audioFormat the format in which the audio data is represented.
+     *   See {@link AudioFormat#ENCODING_PCM_16BIT} and
+     *   {@link AudioFormat#ENCODING_PCM_8BIT}
+     * @param bufferSizeInBytes the total size (in bytes) of the buffer where audio data is read
+     *   from for playback. If using the AudioTrack in streaming mode, you can write data into
+     *   this buffer in smaller chunks than this size. If using the AudioTrack in static mode,
+     *   this is the maximum size of the sound that will be played for this instance.
+     *   See {@link #getMinBufferSize(int, int, int)} to determine the minimum required buffer size
+     *   for the successful creation of an AudioTrack instance in streaming mode. Using values
+     *   smaller than getMinBufferSize() will result in an initialization failure.
+     * @param mode streaming or static buffer. See {@link #MODE_STATIC} and {@link #MODE_STREAM}
+     * @param sessionId Id of audio session the AudioTrack must be attached to
+     * @throws java.lang.IllegalArgumentException
+     // FIXME: unhide.
+     * @hide
+     */
+    public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat,
+            int bufferSizeInBytes, int mode, int sessionId)
+    throws IllegalArgumentException {
         mState = STATE_UNINITIALIZED;
         
         // remember which looper is associated with the AudioTrack instanciation
@@ -269,15 +315,23 @@
 
         audioBuffSizeCheck(bufferSizeInBytes);
 
+        if (sessionId < 0) {
+            throw (new IllegalArgumentException("Invalid audio session ID: "+sessionId));
+        }
+
+        int[] session = new int[1];
+        session[0] = sessionId;
         // native initialization
         int initResult = native_setup(new WeakReference<AudioTrack>(this),
                 mStreamType, mSampleRate, mChannels, mAudioFormat,
-                mNativeBufferSizeInBytes, mDataLoadMode);
+                mNativeBufferSizeInBytes, mDataLoadMode, session);
         if (initResult != SUCCESS) {
             loge("Error code "+initResult+" when initializing AudioTrack.");
             return; // with mState == STATE_UNINITIALIZED
         }
 
+        mSessionId = session[0];
+
         if (mDataLoadMode == MODE_STATIC) {
             mState = STATE_NO_STATIC_DATA;
         } else {
@@ -590,6 +644,17 @@
         }
     }
 
+    /**
+     * Returns the audio session ID.
+     *
+     * @return the ID of the audio session this AudioTrack belongs to.
+     // FIXME: unhide.
+     // FIXME: link to AudioEffect class when public.
+     * @hide
+     */
+    public int getAudioSessionId() {
+        return mSessionId;
+    }
 
     //--------------------------------------------------------------------------
     // Initialization / configuration
@@ -1012,7 +1077,7 @@
 
     private native final int native_setup(Object audiotrack_this,
             int streamType, int sampleRate, int nbChannels, int audioFormat,
-            int buffSizeInBytes, int mode);
+            int buffSizeInBytes, int mode, int[] sessionId);
 
     private native final void native_finalize();
 
@@ -1056,6 +1121,7 @@
     static private native final int native_get_min_buff_size(
             int sampleRateInHz, int channelConfig, int audioFormat);
 
+    private native final int native_get_session_id();
 
     //---------------------------------------------------------
     // Utility methods
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index c9d4650..8caa07a 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -423,6 +423,18 @@
  *     <td>Successful invoke of this method in a valid state transfers the
  *         object to the <em>Stopped</em> state. Calling this method in an
  *         invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
+  * <tr><td>setAudioSessionId </p></td>
+ *     <td>{Idle} </p></td>
+ *     <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted,
+ *          Error} </p></td>
+ *     <td>This method must be called in idle state as the audio session ID must be known before
+ *         calling setDataSource. Calling it does not change the object state. </p></td></tr>
+ * <tr><td>getAudioSessionId </p></td>
+ *     <td>any </p></td>
+ *     <td>{} </p></td>
+ *     <td>This method can be called in any state and calling it does not change
+ *         the object state. </p></td></tr>
+ *
  * </table>
  *
  * <a name="Permissions"></a>
@@ -1159,6 +1171,38 @@
     public native Bitmap getFrameAt(int msec) throws IllegalStateException;
 
     /**
+     * Sets the audio session ID.
+     *
+     * @param sessionId: the audio session ID.
+     * The audio session ID is a system wide unique identifier for the audio stream played by
+     * this MediaPlayer instance.
+     * The primary use of the audio session ID  is to associate audio effects to a particular
+     * instance of MediaPlayer: if an audio session ID is provided when creating an audio effect,
+     * this effect will be applied only to the audio content of media players within the same
+     * audio session and not to the output mix.
+     * When created, a MediaPlayer instance automatically generates its own audio session ID.
+     * However, it is possible to force this player to be part of an already existing audio session
+     * by calling this method.
+     * This method must be called before one of the overloaded <code> setDataSource </code> methods.
+     * @throws IllegalStateException if it is called in an invalid state
+     *
+     // FIXME: unhide.
+     // FIXME: link to AudioEffect class when public.
+     * @hide
+     */
+    public native void setAudioSessionId(int sessionId)  throws IllegalArgumentException, IllegalStateException;
+
+    /**
+     * Returns the audio session ID.
+     *
+     * @return the audio session ID. {@see #setAudioSessionId(int)}.
+     * Note that the audio session ID is 0 only if a problem occured when the MediaPlayer was contructed.
+     // FIXME: unhide.
+     * @hide
+     */
+    public native int getAudioSessionId();
+
+    /**
      * @param request Parcel destinated to the media player. The
      *                Interface token must be set to the IMediaPlayer
      *                one to be routed correctly through the system.
diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp
index 60ff264..c5250d7 100644
--- a/media/jni/android_media_MediaPlayer.cpp
+++ b/media/jni/android_media_MediaPlayer.cpp
@@ -292,7 +292,7 @@
     if (surface != NULL) {
         const sp<Surface> native_surface = get_surface(env, surface);
         LOGV("prepare: surface=%p (id=%d)",
-             native_surface.get(), native_surface->ID());
+             native_surface.get(), native_surface->getIdentity());
         mp->setVideoSurface(native_surface);
     }
 }
@@ -332,7 +332,7 @@
     if (surface != NULL) {
         const sp<Surface> native_surface = get_surface(env, surface);
         LOGV("prepareAsync: surface=%p (id=%d)",
-             native_surface.get(), native_surface->ID());
+             native_surface.get(), native_surface->getIdentity());
         mp->setVideoSurface(native_surface);
     }
     process_media_player_call( env, thiz, mp->prepareAsync(), "java/io/IOException", "Prepare Async failed." );
@@ -705,6 +705,27 @@
     return isSuspend ? mp->suspend() : mp->resume();
 }
 
+static void android_media_MediaPlayer_set_audio_session_id(JNIEnv *env,  jobject thiz, jint sessionId) {
+    LOGV("set_session_id(): %d", sessionId);
+    sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
+    if (mp == NULL ) {
+        jniThrowException(env, "java/lang/IllegalStateException", NULL);
+        return;
+    }
+    process_media_player_call( env, thiz, mp->setAudioSessionId(sessionId), NULL, NULL );
+}
+
+static jint android_media_MediaPlayer_get_audio_session_id(JNIEnv *env,  jobject thiz) {
+    LOGV("get_session_id()");
+    sp<MediaPlayer> mp = getMediaPlayer(env, thiz);
+    if (mp == NULL ) {
+        jniThrowException(env, "java/lang/IllegalStateException", NULL);
+        return 0;
+    }
+
+    return mp->getAudioSessionId();
+}
+
 // ----------------------------------------------------------------------------
 
 static JNINativeMethod gMethods[] = {
@@ -738,6 +759,8 @@
     {"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},
+    {"getAudioSessionId",   "()I",                              (void *)android_media_MediaPlayer_get_audio_session_id},
+    {"setAudioSessionId",   "(I)V",                             (void *)android_media_MediaPlayer_set_audio_session_id},
 };
 
 static const char* const kClassPathName = "android/media/MediaPlayer";
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index a2436ab..a6c515c 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -41,6 +41,38 @@
 #define UNLIKELY( exp )     (__builtin_expect( (exp) != 0, false ))
 
 namespace android {
+// ---------------------------------------------------------------------------
+
+// static
+status_t AudioRecord::getMinFrameCount(
+        int* frameCount,
+        uint32_t sampleRate,
+        int format,
+        int channelCount)
+{
+    size_t size = 0;
+    if (AudioSystem::getInputBufferSize(sampleRate, format, channelCount, &size)
+            != NO_ERROR) {
+        LOGE("AudioSystem could not query the input buffer size.");
+        return NO_INIT;
+    }
+
+    if (size == 0) {
+        LOGE("Unsupported configuration: sampleRate %d, format %d, channelCount %d",
+            sampleRate, format, channelCount);
+        return BAD_VALUE;
+    }
+
+    // We double the size of input buffer for ping pong use of record buffer.
+    size <<= 1;
+
+    if (AudioSystem::isLinearPCM(format)) {
+        size /= channelCount * (format == AudioSystem::PCM_16_BIT ? 2 : 1);
+    }
+
+    *frameCount = size;
+    return NO_ERROR;
+}
 
 // ---------------------------------------------------------------------------
 
@@ -132,29 +164,11 @@
     }
 
     // validate framecount
-    size_t inputBuffSizeInBytes = -1;
-    if (AudioSystem::getInputBufferSize(sampleRate, format, channelCount, &inputBuffSizeInBytes)
-            != NO_ERROR) {
-        LOGE("AudioSystem could not query the input buffer size.");
-        return NO_INIT;
+    int minFrameCount = 0;
+    status_t status = getMinFrameCount(&minFrameCount, sampleRate, format, channelCount);
+    if (status != NO_ERROR) {
+        return status;
     }
-
-    if (inputBuffSizeInBytes == 0) {
-        LOGE("Recording parameters are not supported: sampleRate %d, channelCount %d, format %d",
-            sampleRate, channelCount, format);
-        return BAD_VALUE;
-    }
-
-    int frameSizeInBytes = channelCount * (format == AudioSystem::PCM_16_BIT ? 2 : 1);
-    if (AudioSystem::isLinearPCM(format)) {
-        frameSizeInBytes = channelCount * (format == AudioSystem::PCM_16_BIT ? sizeof(int16_t) : sizeof(int8_t));
-    } else {
-        frameSizeInBytes = sizeof(int8_t);
-    }
-
-
-    // We use 2* size of input buffer for ping pong use of record buffer.
-    int minFrameCount = 2 * inputBuffSizeInBytes / frameSizeInBytes;
     LOGV("AudioRecord::set() minFrameCount = %d", minFrameCount);
 
     if (frameCount == 0) {
@@ -170,9 +184,8 @@
     mSessionId = sessionId;
 
     // create the IAudioRecord
-    status_t status = openRecord(sampleRate, format, channelCount,
-                                 frameCount, flags, input);
-
+    status = openRecord(sampleRate, format, channelCount,
+                        frameCount, flags, input);
     if (status != NO_ERROR) {
         return status;
     }
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index 2118f8f..0f2093a 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -92,7 +92,8 @@
     : mStatus(NO_INIT)
 {
     mStatus = set(streamType, sampleRate, format, channels,
-            frameCount, flags, cbf, user, notificationFrames, 0);
+            frameCount, flags, cbf, user, notificationFrames,
+            0, false, sessionId);
 }
 
 AudioTrack::AudioTrack(
@@ -109,7 +110,8 @@
     : mStatus(NO_INIT)
 {
     mStatus = set(streamType, sampleRate, format, channels,
-            0, flags, cbf, user, notificationFrames, sharedBuffer);
+            0, flags, cbf, user, notificationFrames,
+            sharedBuffer, false, sessionId);
 }
 
 AudioTrack::~AudioTrack()
diff --git a/media/libmedia/IMediaPlayerService.cpp b/media/libmedia/IMediaPlayerService.cpp
index 71c5f86..1ae222e 100644
--- a/media/libmedia/IMediaPlayerService.cpp
+++ b/media/libmedia/IMediaPlayerService.cpp
@@ -58,7 +58,7 @@
 
     virtual sp<IMediaPlayer> create(
             pid_t pid, const sp<IMediaPlayerClient>& client,
-            const char* url, const KeyedVector<String8, String8> *headers) {
+            const char* url, const KeyedVector<String8, String8> *headers, int audioSessionId) {
         Parcel data, reply;
         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
         data.writeInt32(pid);
@@ -75,8 +75,10 @@
                 data.writeString8(headers->valueAt(i));
             }
         }
+        data.writeInt32(audioSessionId);
 
         remote()->transact(CREATE_URL, data, &reply);
+
         return interface_cast<IMediaPlayer>(reply.readStrongBinder());
     }
 
@@ -89,7 +91,8 @@
         return interface_cast<IMediaRecorder>(reply.readStrongBinder());
     }
 
-    virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length)
+    virtual sp<IMediaPlayer> create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd,
+            int64_t offset, int64_t length, int audioSessionId)
     {
         Parcel data, reply;
         data.writeInterfaceToken(IMediaPlayerService::getInterfaceDescriptor());
@@ -98,8 +101,11 @@
         data.writeFileDescriptor(fd);
         data.writeInt64(offset);
         data.writeInt64(length);
+        data.writeInt32(audioSessionId);
+
         remote()->transact(CREATE_FD, data, &reply);
-        return interface_cast<IMediaPlayer>(reply.readStrongBinder());
+
+        return interface_cast<IMediaPlayer>(reply.readStrongBinder());;
     }
 
     virtual sp<IMemory> decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat)
@@ -166,9 +172,10 @@
                 String8 value = data.readString8();
                 headers.add(key, value);
             }
+            int audioSessionId = data.readInt32();
 
             sp<IMediaPlayer> player = create(
-                    pid, client, url, numHeaders > 0 ? &headers : NULL);
+                    pid, client, url, numHeaders > 0 ? &headers : NULL, audioSessionId);
 
             reply->writeStrongBinder(player->asBinder());
             return NO_ERROR;
@@ -180,7 +187,9 @@
             int fd = dup(data.readFileDescriptor());
             int64_t offset = data.readInt64();
             int64_t length = data.readInt64();
-            sp<IMediaPlayer> player = create(pid, client, fd, offset, length);
+            int audioSessionId = data.readInt32();
+
+            sp<IMediaPlayer> player = create(pid, client, fd, offset, length, audioSessionId);
             reply->writeStrongBinder(player->asBinder());
             return NO_ERROR;
         } break;
diff --git a/media/libmedia/MediaScanner.cpp b/media/libmedia/MediaScanner.cpp
index b2a6109..24426ff 100644
--- a/media/libmedia/MediaScanner.cpp
+++ b/media/libmedia/MediaScanner.cpp
@@ -14,6 +14,10 @@
  * limitations under the License.
  */
 
+//#define LOG_NDEBUG 0
+#define LOG_TAG "MediaScanner"
+#include <utils/Log.h>
+
 #include <media/mediascanner.h>
 
 #include <sys/stat.h>
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index c6bbbcc..d5a3c13 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -55,6 +55,7 @@
     mLeftVolume = mRightVolume = 1.0;
     mVideoWidth = mVideoHeight = 0;
     mLockThreadId = 0;
+    mAudioSessionId = AudioSystem::newAudioSessionId();
 }
 
 MediaPlayer::~MediaPlayer()
@@ -137,7 +138,7 @@
         const sp<IMediaPlayerService>& service(getMediaPlayerService());
         if (service != 0) {
             sp<IMediaPlayer> player(
-                    service->create(getpid(), this, url, headers));
+                    service->create(getpid(), this, url, headers, mAudioSessionId));
             err = setDataSource(player);
         }
     }
@@ -150,7 +151,7 @@
     status_t err = UNKNOWN_ERROR;
     const sp<IMediaPlayerService>& service(getMediaPlayerService());
     if (service != 0) {
-        sp<IMediaPlayer> player(service->create(getpid(), this, fd, offset, length));
+        sp<IMediaPlayer> player(service->create(getpid(), this, fd, offset, length, mAudioSessionId));
         err = setDataSource(player);
     }
     return err;
@@ -501,6 +502,27 @@
     return OK;
 }
 
+status_t MediaPlayer::setAudioSessionId(int sessionId)
+{
+    LOGV("MediaPlayer::setAudioSessionId(%d)", sessionId);
+    Mutex::Autolock _l(mLock);
+    if (!(mCurrentState & MEDIA_PLAYER_IDLE)) {
+        LOGE("setAudioSessionId called in state %d", mCurrentState);
+        return INVALID_OPERATION;
+    }
+    if (sessionId < 0) {
+        return BAD_VALUE;
+    }
+    mAudioSessionId = sessionId;
+    return NO_ERROR;
+}
+
+int MediaPlayer::getAudioSessionId()
+{
+    Mutex::Autolock _l(mLock);
+    return mAudioSessionId;
+}
+
 void MediaPlayer::notify(int msg, int ext1, int ext2)
 {
     LOGV("message received msg=%d, ext1=%d, ext2=%d", msg, ext1, ext2);
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index d7ca635..d45c17b 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -252,11 +252,12 @@
 
 sp<IMediaPlayer> MediaPlayerService::create(
         pid_t pid, const sp<IMediaPlayerClient>& client, const char* url,
-        const KeyedVector<String8, String8> *headers)
+        const KeyedVector<String8, String8> *headers, int audioSessionId)
 {
     int32_t connId = android_atomic_inc(&mNextConnId);
-    sp<Client> c = new Client(this, pid, connId, client);
-    LOGV("Create new client(%d) from pid %d, url=%s, connId=%d", connId, pid, url, connId);
+    sp<Client> c = new Client(this, pid, connId, client, audioSessionId);
+    LOGV("Create new client(%d) from pid %d, url=%s, connId=%d, audioSessionId=%d",
+            connId, pid, url, connId, audioSessionId);
     if (NO_ERROR != c->setDataSource(url, headers))
     {
         c.clear();
@@ -269,12 +270,12 @@
 }
 
 sp<IMediaPlayer> MediaPlayerService::create(pid_t pid, const sp<IMediaPlayerClient>& client,
-        int fd, int64_t offset, int64_t length)
+        int fd, int64_t offset, int64_t length, int audioSessionId)
 {
     int32_t connId = android_atomic_inc(&mNextConnId);
-    sp<Client> c = new Client(this, pid, connId, client);
-    LOGV("Create new client(%d) from pid %d, fd=%d, offset=%lld, length=%lld",
-            connId, pid, fd, offset, length);
+    sp<Client> c = new Client(this, pid, connId, client, audioSessionId);
+    LOGV("Create new client(%d) from pid %d, fd=%d, offset=%lld, length=%lld, audioSessionId=%d",
+            connId, pid, fd, offset, length, audioSessionId);
     if (NO_ERROR != c->setDataSource(fd, offset, length)) {
         c.clear();
     } else {
@@ -609,7 +610,7 @@
 }
 
 MediaPlayerService::Client::Client(const sp<MediaPlayerService>& service, pid_t pid,
-        int32_t connId, const sp<IMediaPlayerClient>& client)
+        int32_t connId, const sp<IMediaPlayerClient>& client, int audioSessionId)
 {
     LOGV("Client(%d) constructor", connId);
     mPid = pid;
@@ -618,6 +619,8 @@
     mClient = client;
     mLoop = false;
     mStatus = NO_INIT;
+    mAudioSessionId = audioSessionId;
+
 #if CALLBACK_ANTAGONIZER
     LOGD("create Antagonizer");
     mAntagonizer = new Antagonizer(notify, this);
@@ -871,7 +874,7 @@
         if (p == NULL) return NO_INIT;
 
         if (!p->hardwareOutput()) {
-            mAudioOutput = new AudioOutput();
+            mAudioOutput = new AudioOutput(mAudioSessionId);
             static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
         }
 
@@ -921,7 +924,7 @@
     if (p == NULL) return NO_INIT;
 
     if (!p->hardwareOutput()) {
-        mAudioOutput = new AudioOutput();
+        mAudioOutput = new AudioOutput(mAudioSessionId);
         static_cast<MediaPlayerInterface*>(p.get())->setAudioSink(mAudioOutput);
     }
 
@@ -1412,9 +1415,11 @@
 
 #undef LOG_TAG
 #define LOG_TAG "AudioSink"
-MediaPlayerService::AudioOutput::AudioOutput()
+MediaPlayerService::AudioOutput::AudioOutput(int sessionId)
     : mCallback(NULL),
-      mCallbackCookie(NULL) {
+      mCallbackCookie(NULL),
+      mSessionId(sessionId) {
+    LOGV("AudioOutput(%d)", sessionId);
     mTrack = 0;
     mStreamType = AudioSystem::MUSIC;
     mLeftVolume = 1.0;
@@ -1504,7 +1509,7 @@
         bufferCount = mMinBufferCount;
 
     }
-    LOGV("open(%u, %d, %d, %d)", sampleRate, channelCount, format, bufferCount);
+    LOGV("open(%u, %d, %d, %d, %d)", sampleRate, channelCount, format, bufferCount,mSessionId);
     if (mTrack) close();
     int afSampleRate;
     int afFrameCount;
@@ -1529,14 +1534,21 @@
                 frameCount,
                 0 /* flags */,
                 CallbackWrapper,
-                this);
+                this,
+                0,
+                mSessionId);
     } else {
         t = new AudioTrack(
                 mStreamType,
                 sampleRate,
                 format,
                 (channelCount == 2) ? AudioSystem::CHANNEL_OUT_STEREO : AudioSystem::CHANNEL_OUT_MONO,
-                frameCount);
+                frameCount,
+                0,
+                NULL,
+                NULL,
+                0,
+                mSessionId);
     }
 
     if ((t == 0) || (t->initCheck() != NO_ERROR)) {
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 2408c62..60b91c6 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -65,7 +65,7 @@
     class AudioOutput : public MediaPlayerBase::AudioSink
     {
     public:
-                                AudioOutput();
+                                AudioOutput(int sessionId);
         virtual                 ~AudioOutput();
 
         virtual bool            ready() const { return mTrack != NULL; }
@@ -108,6 +108,7 @@
         float                   mRightVolume;
         float                   mMsecsPerFrame;
         uint32_t                mLatency;
+        int                     mSessionId;
 
         static bool             mIsOnEmulator;
         static int              mMinBufferCount;  // 12 for emulator; otherwise 4
@@ -185,9 +186,9 @@
     // House keeping for media player clients
     virtual sp<IMediaPlayer>    create(
             pid_t pid, const sp<IMediaPlayerClient>& client, const char* url,
-            const KeyedVector<String8, String8> *headers);
+            const KeyedVector<String8, String8> *headers, int audioSessionId);
 
-    virtual sp<IMediaPlayer>    create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length);
+    virtual sp<IMediaPlayer>    create(pid_t pid, const sp<IMediaPlayerClient>& client, int fd, int64_t offset, int64_t length, int audioSessionId);
     virtual sp<IMemory>         decode(const char* url, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);
     virtual sp<IMemory>         decode(int fd, int64_t offset, int64_t length, uint32_t *pSampleRate, int* pNumChannels, int* pFormat);
     virtual sp<IMemory>         snoop();
@@ -237,12 +238,15 @@
                 pid_t           pid() const { return mPid; }
         virtual status_t        dump(int fd, const Vector<String16>& args) const;
 
+                int             getAudioSessionId() { return mAudioSessionId; }
+
     private:
         friend class MediaPlayerService;
                                 Client( const sp<MediaPlayerService>& service,
                                         pid_t pid,
                                         int32_t connId,
-                                        const sp<IMediaPlayerClient>& client);
+                                        const sp<IMediaPlayerClient>& client,
+                                        int audioSessionId);
                                 Client();
         virtual                 ~Client();
 
@@ -271,6 +275,7 @@
                     status_t                    mStatus;
                     bool                        mLoop;
                     int32_t                     mConnId;
+                    int                         mAudioSessionId;
 
         // Metadata filters.
         media::Metadata::Filter mMetadataAllow;  // protected by mLock
diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp
index f9251e1..69c3a72 100644
--- a/media/libstagefright/MP3Extractor.cpp
+++ b/media/libstagefright/MP3Extractor.cpp
@@ -634,6 +634,7 @@
     }
 
     size_t frame_size;
+    int bitrate;
     for (;;) {
         ssize_t n = mDataSource->readAt(mCurrentPos, buffer->data(), 4);
         if (n < 4) {
@@ -646,7 +647,7 @@
         uint32_t header = U32_AT((const uint8_t *)buffer->data());
 
         if ((header & kMask) == (mFixedHeader & kMask)
-            && get_mp3_frame_size(header, &frame_size)) {
+            && get_mp3_frame_size(header, &frame_size, NULL, NULL, &bitrate)) {
             break;
         }
 
@@ -683,7 +684,7 @@
     buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs);
 
     mCurrentPos += frame_size;
-    mCurrentTimeUs += 1152 * 1000000 / 44100;
+    mCurrentTimeUs += frame_size * 8000ll / bitrate;
 
     *out = buffer;
 
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index cd20ec7..4242d36 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -48,7 +48,7 @@
 
     int64_t getDurationUs() const;
     int64_t getEstimatedTrackSizeBytes() const;
-    void writeTrackHeader(int32_t trackID);
+    void writeTrackHeader(int32_t trackID, bool use32BitOffset = true);
 
 private:
     MPEG4Writer *mOwner;
@@ -123,6 +123,7 @@
 
 MPEG4Writer::MPEG4Writer(const char *filename)
     : mFile(fopen(filename, "wb")),
+      mUse32BitOffset(true),
       mPaused(false),
       mStarted(false),
       mOffset(0),
@@ -134,6 +135,7 @@
 
 MPEG4Writer::MPEG4Writer(int fd)
     : mFile(fdopen(fd, "wb")),
+      mUse32BitOffset(true),
       mPaused(false),
       mStarted(false),
       mOffset(0),
@@ -218,7 +220,11 @@
     mMdatOffset = mFreeBoxOffset + mEstimatedMoovBoxSize;
     mOffset = mMdatOffset;
     fseeko(mFile, mMdatOffset, SEEK_SET);
-    write("\x00\x00\x00\x01mdat????????", 16);
+    if (mUse32BitOffset) {
+        write("????mdat", 8);
+    } else {
+        write("\x00\x00\x00\x01mdat????????", 16);
+    }
 
     status_t err = startTracks();
     if (err != OK) {
@@ -257,10 +263,16 @@
 
 
     // Fix up the size of the 'mdat' chunk.
-    fseeko(mFile, mMdatOffset + 8, SEEK_SET);
-    int64_t size = mOffset - mMdatOffset;
-    size = hton64(size);
-    fwrite(&size, 1, 8, mFile);
+    if (mUse32BitOffset) {
+        fseeko(mFile, mMdatOffset, SEEK_SET);
+        int32_t size = htonl(static_cast<int32_t>(mOffset - mMdatOffset));
+        fwrite(&size, 1, 4, mFile);
+    } else {
+        fseeko(mFile, mMdatOffset + 8, SEEK_SET);
+        int64_t size = mOffset - mMdatOffset;
+        size = hton64(size);
+        fwrite(&size, 1, 8, mFile);
+    }
     fseeko(mFile, mOffset, SEEK_SET);
 
     time_t now = time(NULL);
@@ -269,6 +281,8 @@
     mMoovBoxBuffer = (uint8_t *) malloc(mEstimatedMoovBoxSize);
     mMoovBoxBufferOffset = 0;
     CHECK(mMoovBoxBuffer != NULL);
+    int32_t timeScale = 1000;
+    int32_t duration = max_duration / timeScale;
 
     beginBox("moov");
 
@@ -276,9 +290,9 @@
         writeInt32(0);             // version=0, flags=0
         writeInt32(now);           // creation time
         writeInt32(now);           // modification time
-        writeInt32(1000);          // timescale
-        writeInt32(max_duration / 1000);
-        writeInt32(0x10000);       // rate
+        writeInt32(timeScale);          // timescale
+        writeInt32(duration);
+        writeInt32(0x10000);       // rate: 1.0
         writeInt16(0x100);         // volume
         writeInt16(0);             // reserved
         writeInt32(0);             // reserved
@@ -304,7 +318,7 @@
       int32_t id = 1;
       for (List<Track *>::iterator it = mTracks.begin();
            it != mTracks.end(); ++it, ++id) {
-          (*it)->writeTrackHeader(id);
+          (*it)->writeTrackHeader(id, mUse32BitOffset);
       }
     endBox();  // moov
 
@@ -415,7 +429,8 @@
 
     const size_t bytes = size * nmemb;
     if (mWriteMoovBoxToMemory) {
-        if (8 + mMoovBoxBufferOffset + bytes > mEstimatedMoovBoxSize) {
+        off_t moovBoxSize = 8 + mMoovBoxBufferOffset + bytes;
+        if (moovBoxSize > mEstimatedMoovBoxSize) {
             for (List<off_t>::iterator it = mBoxes.begin();
                  it != mBoxes.end(); ++it) {
                 (*it) += mOffset;
@@ -1162,24 +1177,29 @@
     return mEstimatedTrackSizeBytes;
 }
 
-void MPEG4Writer::Track::writeTrackHeader(int32_t trackID) {
+void MPEG4Writer::Track::writeTrackHeader(
+        int32_t trackID, bool use32BitOffset) {
     const char *mime;
     bool success = mMeta->findCString(kKeyMIMEType, &mime);
     CHECK(success);
 
     bool is_audio = !strncasecmp(mime, "audio/", 6);
+    int32_t timeScale = 1000;
+    int32_t duration = getDurationUs() / timeScale;
 
     time_t now = time(NULL);
 
     mOwner->beginBox("trak");
 
       mOwner->beginBox("tkhd");
-        mOwner->writeInt32(0);             // version=0, flags=0
+        // Flags = 7 to indicate that the track is enabled, and
+        // part of the presentation
+        mOwner->writeInt32(0x07);          // version=0, flags=7
         mOwner->writeInt32(now);           // creation time
         mOwner->writeInt32(now);           // modification time
         mOwner->writeInt32(trackID);
         mOwner->writeInt32(0);             // reserved
-        mOwner->writeInt32(getDurationUs() / 1000);
+        mOwner->writeInt32(duration);
         mOwner->writeInt32(0);             // reserved
         mOwner->writeInt32(0);             // reserved
         mOwner->writeInt16(0);             // layer
@@ -1214,15 +1234,17 @@
       int64_t moovStartTimeUs = mOwner->getStartTimestampUs();
       if (mStartTimestampUs != moovStartTimeUs) {
         mOwner->beginBox("edts");
-          mOwner->writeInt32(0);             // version=0, flags=0
           mOwner->beginBox("elst");
-            mOwner->writeInt32(0);           // version=0, flags=0
-            mOwner->writeInt32(1);           // a single entry
+            mOwner->writeInt32(0);           // version=0, flags=0: 32-bit time
+            mOwner->writeInt32(2);           // never ends with an empty list
             int64_t durationMs =
                 (mStartTimestampUs - moovStartTimeUs) / 1000;
             mOwner->writeInt32(durationMs);  // edit duration
             mOwner->writeInt32(-1);          // empty edit box to signal starting time offset
-            mOwner->writeInt32(1);           // x1 rate
+            mOwner->writeInt32(1 << 16);     // x1 rate
+            mOwner->writeInt32(duration);
+            mOwner->writeInt32(0);
+            mOwner->writeInt32(1 << 16);
           mOwner->endBox();
         mOwner->endBox();
       }
@@ -1233,9 +1255,14 @@
           mOwner->writeInt32(0);             // version=0, flags=0
           mOwner->writeInt32(now);           // creation time
           mOwner->writeInt32(now);           // modification time
-          mOwner->writeInt32(1000);          // timescale
-          mOwner->writeInt32(getDurationUs() / 1000);
-          mOwner->writeInt16(0);             // language code XXX
+          mOwner->writeInt32(timeScale);     // timescale
+          mOwner->writeInt32(duration);      // duration
+          // Language follows the three letter standard ISO-639-2/T
+          // 'e', 'n', 'g' for "English", for instance.
+          // Each character is packed as the difference between its ASCII value and 0x60.
+          // For "English", these are 00101, 01110, 00111.
+          // XXX: Where is the padding bit located: 0x15C7?
+          mOwner->writeInt16(0);             // language code
           mOwner->writeInt16(0);             // predefined
         mOwner->endBox();
 
@@ -1246,7 +1273,8 @@
           mOwner->writeInt32(0);             // reserved
           mOwner->writeInt32(0);             // reserved
           mOwner->writeInt32(0);             // reserved
-          mOwner->writeCString(is_audio ? "SoundHandler": "");  // name
+          // Removing "r" for the name string just makes the string 4 byte aligned
+          mOwner->writeCString(is_audio ? "SoundHandle": "VideoHandle");  // name
         mOwner->endBox();
 
         mOwner->beginBox("minf");
@@ -1258,7 +1286,7 @@
               mOwner->endBox();
           } else {
               mOwner->beginBox("vmhd");
-              mOwner->writeInt32(0x00000001);  // version=0, flags=1
+              mOwner->writeInt32(0x01);        // version=0, flags=1
               mOwner->writeInt16(0);           // graphics mode
               mOwner->writeInt16(0);           // opcolor
               mOwner->writeInt16(0);
@@ -1269,15 +1297,15 @@
           mOwner->beginBox("dinf");
             mOwner->beginBox("dref");
               mOwner->writeInt32(0);  // version=0, flags=0
-              mOwner->writeInt32(1);
+              mOwner->writeInt32(1);  // entry count (either url or urn)
+              // The table index here refers to the sample description index
+              // in the sample table entries.
               mOwner->beginBox("url ");
-                mOwner->writeInt32(1);  // version=0, flags=1
+                mOwner->writeInt32(1);  // version=0, flags=1 (self-contained)
               mOwner->endBox();  // url
             mOwner->endBox();  // dref
           mOwner->endBox();  // dinf
 
-       mOwner->endBox();  // minf
-
         mOwner->beginBox("stbl");
 
           mOwner->beginBox("stsd");
@@ -1361,7 +1389,7 @@
 
                   mOwner->writeInt32(0);           // reserved
                   mOwner->writeInt16(0);           // reserved
-                  mOwner->writeInt16(0);           // data ref index
+                  mOwner->writeInt16(1);           // data ref index
                   mOwner->writeInt16(0);           // predefined
                   mOwner->writeInt16(0);           // reserved
                   mOwner->writeInt32(0);           // predefined
@@ -1435,6 +1463,11 @@
                       mOwner->endBox();  // avcC
                   }
 
+                  mOwner->beginBox("pasp");
+                    // This is useful if the pixel is not square
+                    mOwner->writeInt32(1 << 16);  // hspacing
+                    mOwner->writeInt32(1 << 16);  // vspacing
+                  mOwner->endBox();  // pasp
                 mOwner->endBox();  // mp4v, s263 or avc1
             }
           mOwner->endBox();  // stsd
@@ -1487,17 +1520,21 @@
                 mOwner->writeInt32(it->sampleDescriptionId);
             }
           mOwner->endBox();  // stsc
-
-          mOwner->beginBox("co64");
+          mOwner->beginBox(use32BitOffset? "stco": "co64");
             mOwner->writeInt32(0);  // version=0, flags=0
             mOwner->writeInt32(mChunkOffsets.size());
             for (List<off_t>::iterator it = mChunkOffsets.begin();
                  it != mChunkOffsets.end(); ++it) {
-                mOwner->writeInt64((*it));
+                if (use32BitOffset) {
+                    mOwner->writeInt32(static_cast<int32_t>(*it));
+                } else {
+                    mOwner->writeInt64((*it));
+                }
             }
           mOwner->endBox();  // co64
 
         mOwner->endBox();  // stbl
+       mOwner->endBox();  // minf
       mOwner->endBox();  // mdia
     mOwner->endBox();  // trak
 }
diff --git a/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp b/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp
index efcb476..f40bd11 100644
--- a/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp
+++ b/media/libstagefright/codecs/mp3dec/MP3Decoder.cpp
@@ -27,13 +27,35 @@
 
 MP3Decoder::MP3Decoder(const sp<MediaSource> &source)
     : mSource(source),
+      mNumChannels(0),
       mStarted(false),
       mBufferGroup(NULL),
       mConfig(new tPVMP3DecoderExternal),
       mDecoderBuf(NULL),
       mAnchorTimeUs(0),
-      mNumSamplesOutput(0),
+      mNumFramesOutput(0),
       mInputBuffer(NULL) {
+    init();
+}
+
+void MP3Decoder::init() {
+    sp<MetaData> srcFormat = mSource->getFormat();
+
+    int32_t sampleRate;
+    CHECK(srcFormat->findInt32(kKeyChannelCount, &mNumChannels));
+    CHECK(srcFormat->findInt32(kKeySampleRate, &sampleRate));
+
+    mMeta = new MetaData;
+    mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
+    mMeta->setInt32(kKeyChannelCount, mNumChannels);
+    mMeta->setInt32(kKeySampleRate, sampleRate);
+
+    int64_t durationUs;
+    if (srcFormat->findInt64(kKeyDuration, &durationUs)) {
+        mMeta->setInt64(kKeyDuration, durationUs);
+    }
+
+    mMeta->setCString(kKeyDecoderComponent, "MP3Decoder");
 }
 
 MP3Decoder::~MP3Decoder() {
@@ -62,7 +84,7 @@
     mSource->start();
 
     mAnchorTimeUs = 0;
-    mNumSamplesOutput = 0;
+    mNumFramesOutput = 0;
     mStarted = true;
 
     return OK;
@@ -90,26 +112,7 @@
 }
 
 sp<MetaData> MP3Decoder::getFormat() {
-    sp<MetaData> srcFormat = mSource->getFormat();
-
-    int32_t numChannels;
-    int32_t sampleRate;
-    CHECK(srcFormat->findInt32(kKeyChannelCount, &numChannels));
-    CHECK(srcFormat->findInt32(kKeySampleRate, &sampleRate));
-
-    sp<MetaData> meta = new MetaData;
-    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
-    meta->setInt32(kKeyChannelCount, numChannels);
-    meta->setInt32(kKeySampleRate, sampleRate);
-
-    int64_t durationUs;
-    if (srcFormat->findInt64(kKeyDuration, &durationUs)) {
-        meta->setInt64(kKeyDuration, durationUs);
-    }
-
-    meta->setCString(kKeyDecoderComponent, "MP3Decoder");
-
-    return meta;
+    return mMeta;
 }
 
 status_t MP3Decoder::read(
@@ -122,7 +125,7 @@
     if (options && options->getSeekTo(&seekTimeUs)) {
         CHECK(seekTimeUs >= 0);
 
-        mNumSamplesOutput = 0;
+        mNumFramesOutput = 0;
 
         if (mInputBuffer) {
             mInputBuffer->release();
@@ -142,7 +145,7 @@
         int64_t timeUs;
         if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
             mAnchorTimeUs = timeUs;
-            mNumSamplesOutput = 0;
+            mNumFramesOutput = 0;
         } else {
             // We must have a new timestamp after seeking.
             CHECK(seekTimeUs < 0);
@@ -179,7 +182,7 @@
 
         // This is recoverable, just ignore the current frame and
         // play silence instead.
-        memset(buffer->data(), 0, mConfig->outputFrameSize);
+        memset(buffer->data(), 0, mConfig->outputFrameSize * sizeof(int16_t));
         mConfig->inputBufferUsedLength = mInputBuffer->range_length();
     }
 
@@ -198,9 +201,9 @@
     buffer->meta_data()->setInt64(
             kKeyTime,
             mAnchorTimeUs
-                + (mNumSamplesOutput * 1000000) / mConfig->samplingRate);
+                + (mNumFramesOutput * 1000000) / mConfig->samplingRate);
 
-    mNumSamplesOutput += mConfig->outputFrameSize / sizeof(int16_t);
+    mNumFramesOutput += mConfig->outputFrameSize / mNumChannels;
 
     *out = buffer;
 
diff --git a/media/libstagefright/include/MP3Decoder.h b/media/libstagefright/include/MP3Decoder.h
index 88aa4c6..4086fb6 100644
--- a/media/libstagefright/include/MP3Decoder.h
+++ b/media/libstagefright/include/MP3Decoder.h
@@ -42,6 +42,9 @@
 
 private:
     sp<MediaSource> mSource;
+    sp<MetaData> mMeta;
+    int32_t mNumChannels;
+
     bool mStarted;
 
     MediaBufferGroup *mBufferGroup;
@@ -49,10 +52,12 @@
     tPVMP3DecoderExternal *mConfig;
     void *mDecoderBuf;
     int64_t mAnchorTimeUs;
-    int64_t mNumSamplesOutput;
+    int64_t mNumFramesOutput;
 
     MediaBuffer *mInputBuffer;
 
+    void init();
+
     MP3Decoder(const MP3Decoder &);
     MP3Decoder &operator=(const MP3Decoder &);
 };
diff --git a/media/libstagefright/omx/OMXMaster.cpp b/media/libstagefright/omx/OMXMaster.cpp
index 9a45bea..56b169a 100644
--- a/media/libstagefright/omx/OMXMaster.cpp
+++ b/media/libstagefright/omx/OMXMaster.cpp
@@ -14,6 +14,10 @@
  * limitations under the License.
  */
 
+//#define LOG_NDEBUG 0
+#define LOG_TAG "OMXMaster"
+#include <utils/Log.h>
+
 #include "OMXMaster.h"
 
 #include <dlfcn.h>
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 5e73b97..e7511e0 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -56,7 +56,7 @@
 import android.view.ActionBarView;
 import android.view.Gravity;
 import android.view.HapticFeedbackConstants;
-import android.view.InputConsumer;
+import android.view.InputQueue;
 import android.view.KeyCharacterMap;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -70,7 +70,6 @@
 import android.view.VolumePanel;
 import android.view.Window;
 import android.view.WindowManager;
-import android.view.InputConsumer.Callback;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.accessibility.AccessibilityManager;
 import android.view.animation.Animation;
@@ -109,7 +108,7 @@
     SurfaceHolder.Callback mTakeSurfaceCallback;
     BaseSurfaceHolder mSurfaceHolder;
     
-    InputConsumer.Callback mTakeInputChannelCallback;
+    InputQueue.Callback mTakeInputQueueCallback;
     
     private boolean mIsFloating;
 
@@ -256,8 +255,8 @@
         mTakeSurfaceCallback = callback;
     }
     
-    public void takeInputChannel(InputConsumer.Callback callback) {
-        mTakeInputChannelCallback = callback;
+    public void takeInputQueue(InputQueue.Callback callback) {
+        mTakeInputQueueCallback = callback;
     }
     
     @Override
@@ -2074,8 +2073,8 @@
             return mFeatureId < 0 ? mTakeSurfaceCallback : null;
         }
         
-        public InputConsumer.Callback willYouTakeTheInputConsumer() {
-            return mFeatureId < 0 ? mTakeInputChannelCallback : null;
+        public InputQueue.Callback willYouTakeTheInputQueue() {
+            return mFeatureId < 0 ? mTakeInputQueueCallback : null;
         }
         
         public void setSurfaceType(int type) {
diff --git a/services/java/com/android/server/AppWidgetService.java b/services/java/com/android/server/AppWidgetService.java
index dc5fd30..3ed6c12 100644
--- a/services/java/com/android/server/AppWidgetService.java
+++ b/services/java/com/android/server/AppWidgetService.java
@@ -1204,6 +1204,7 @@
                             // If it's currently showing, call back with the new AppWidgetProviderInfo.
                             for (int j=0; j<M; j++) {
                                 AppWidgetId id = p.instances.get(j);
+                                id.views = null;
                                 if (id.host != null && id.host.callbacks != null) {
                                     try {
                                         id.host.callbacks.providerChanged(id.appWidgetId, p.info);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 4d18191..d59ecdd 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -8725,6 +8725,35 @@
         }
     }
 
+    public void setImmersive(IBinder token, boolean immersive) {
+        synchronized(this) {
+            int index = (token != null) ? indexOfTokenLocked(token) : -1;
+            if (index < 0) {
+                throw new IllegalArgumentException();
+            }
+            HistoryRecord r = (HistoryRecord)mHistory.get(index);
+            r.immersive = immersive;
+        }
+    }
+
+    public boolean isImmersive(IBinder token) {
+        synchronized (this) {
+            int index = (token != null) ? indexOfTokenLocked(token) : -1;
+            if (index < 0) {
+                throw new IllegalArgumentException();
+            }
+            HistoryRecord r = (HistoryRecord)mHistory.get(index);
+            return r.immersive;
+        }
+    }
+
+    public boolean isTopActivityImmersive() {
+        synchronized (this) {
+            HistoryRecord r = topRunningActivityLocked(null);
+            return (r != null) ? r.immersive : false;
+        }
+    }
+
     public final void enterSafeMode() {
         synchronized(this) {
             // It only makes sense to do this before the system is ready
diff --git a/services/java/com/android/server/am/HistoryRecord.java b/services/java/com/android/server/am/HistoryRecord.java
index dca7a99..fb5c8aa0 100644
--- a/services/java/com/android/server/am/HistoryRecord.java
+++ b/services/java/com/android/server/am/HistoryRecord.java
@@ -101,6 +101,7 @@
     boolean idle;           // has the activity gone idle?
     boolean hasBeenLaunched;// has this activity ever been launched?
     boolean frozenBeforeDestroy;// has been frozen but not yet destroyed.
+    boolean immersive;      // immersive mode (don't interrupt if possible)
 
     String stringName;      // for caching of toString().
     
@@ -153,6 +154,7 @@
         pw.print(prefix); pw.print("keysPaused="); pw.print(keysPaused);
                 pw.print(" inHistory="); pw.print(inHistory);
                 pw.print(" persistent="); pw.print(persistent);
+                pw.print(" immersive="); pw.print(immersive);
                 pw.print(" launchMode="); pw.println(launchMode);
         pw.print(prefix); pw.print("fullscreen="); pw.print(fullscreen);
                 pw.print(" visible="); pw.print(visible);
@@ -278,6 +280,8 @@
             } else {
                 isHomeActivity = false;
             }
+
+            immersive = (aInfo.flags & ActivityInfo.FLAG_IMMERSIVE) != 0;
         } else {
             realActivity = null;
             taskAffinity = null;
@@ -289,6 +293,7 @@
             packageName = null;
             fullscreen = true;
             isHomeActivity = false;
+            immersive = false;
         }
     }
 
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java b/tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java
index 742b1a0..a5870f8 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/CallbackProxy.java
@@ -281,8 +281,7 @@
             break;
 
         case SET_XSS_AUDITOR_ENABLED:
-            mLayoutTestController.setXSSAuditorEnabled(
-                msg.arg1 == 1 ? true : false);
+            mLayoutTestController.setXSSAuditorEnabled(msg.arg1 == 1);
             break;
         }
     }
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
index 44f8640..0a04712 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
@@ -838,6 +838,7 @@
         settings.setDatabasePath(getDir("databases",0).getAbsolutePath());
         settings.setDomStorageEnabled(true);
         settings.setWorkersEnabled(false);
+        settings.setXSSAuditorEnabled(false);
     }
 
     private WebView mWebView;