Merge "turn off some useless messages"
diff --git a/api/current.xml b/api/current.xml
index 644a7b1..953c9f3 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -2103,7 +2103,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843563"
+ value="16843567"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -2125,7 +2125,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843572"
+ value="16843576"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -2136,7 +2136,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843571"
+ value="16843575"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -2147,7 +2147,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843573"
+ value="16843577"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -2191,7 +2191,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843580"
+ value="16843584"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -2213,7 +2213,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843576"
+ value="16843580"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -2235,7 +2235,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843574"
+ value="16843578"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -2246,7 +2246,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843581"
+ value="16843585"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -2257,7 +2257,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843582"
+ value="16843586"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -2466,7 +2466,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843570"
+ value="16843574"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -2807,7 +2807,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843589"
+ value="16843593"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -2818,7 +2818,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843588"
+ value="16843592"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -4497,6 +4497,28 @@
  visibility="public"
 >
 </field>
+<field name="fragmentNextEnterAnimation"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843563"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="fragmentNextExitAnimation"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843564"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="fragmentOpenEnterAnimation"
  type="int"
  transient="false"
@@ -4519,6 +4541,28 @@
  visibility="public"
 >
 </field>
+<field name="fragmentPrevEnterAnimation"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843565"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="fragmentPrevExitAnimation"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843566"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="freezesText"
  type="int"
  transient="false"
@@ -4996,7 +5040,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843579"
+ value="16843583"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -5117,7 +5161,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843566"
+ value="16843570"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -5128,7 +5172,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843564"
+ value="16843568"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -5139,7 +5183,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843565"
+ value="16843569"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -5502,7 +5546,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843575"
+ value="16843579"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -6778,7 +6822,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843568"
+ value="16843572"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -6822,7 +6866,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843590"
+ value="16843594"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -6833,7 +6877,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843584"
+ value="16843588"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -6921,7 +6965,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843592"
+ value="16843596"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -7735,7 +7779,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843585"
+ value="16843589"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -9044,7 +9088,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843569"
+ value="16843573"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -9066,7 +9110,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843567"
+ value="16843571"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -9165,7 +9209,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843583"
+ value="16843587"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -9396,7 +9440,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843578"
+ value="16843582"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -9781,7 +9825,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843586"
+ value="16843590"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -9858,7 +9902,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843587"
+ value="16843591"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -9902,7 +9946,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843591"
+ value="16843595"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -10320,7 +10364,7 @@
  type="int"
  transient="false"
  volatile="false"
- value="16843577"
+ value="16843581"
  static="true"
  final="true"
  deprecated="not deprecated"
@@ -30872,6 +30916,17 @@
  visibility="public"
 >
 </field>
+<field name="TRANSIT_FRAGMENT_NEXT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4099"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="TRANSIT_FRAGMENT_OPEN"
  type="int"
  transient="false"
@@ -30883,6 +30938,17 @@
  visibility="public"
 >
 </field>
+<field name="TRANSIT_FRAGMENT_PREV"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="8196"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="TRANSIT_NONE"
  type="int"
  transient="false"
@@ -55076,6 +55142,17 @@
  visibility="public"
 >
 </field>
+<field name="SCREEN_ORIENTATION_FULL_SENSOR"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="10"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="SCREEN_ORIENTATION_LANDSCAPE"
  type="int"
  transient="false"
@@ -55109,6 +55186,28 @@
  visibility="public"
 >
 </field>
+<field name="SCREEN_ORIENTATION_REVERSE_LANDSCAPE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="8"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCREEN_ORIENTATION_REVERSE_PORTRAIT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="9"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="SCREEN_ORIENTATION_SENSOR"
  type="int"
  transient="false"
@@ -55120,6 +55219,28 @@
  visibility="public"
 >
 </field>
+<field name="SCREEN_ORIENTATION_SENSOR_LANDSCAPE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="6"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SCREEN_ORIENTATION_SENSOR_PORTRAIT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="7"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="SCREEN_ORIENTATION_UNSPECIFIED"
  type="int"
  transient="false"
@@ -143207,6 +143328,8 @@
 </parameter>
 <parameter name="args" type="android.os.Bundle">
 </parameter>
+<parameter name="next" type="boolean">
+</parameter>
 </method>
 <field name="EXTRA_NO_HEADERS"
  type="java.lang.String"
@@ -189909,6 +190032,16 @@
  deprecated="not deprecated"
  visibility="public"
 >
+<parameter name="action" type="int">
+</parameter>
+<parameter name="x" type="float">
+</parameter>
+<parameter name="y" type="float">
+</parameter>
+<parameter name="description" type="android.content.ClipDescription">
+</parameter>
+<parameter name="data" type="android.content.ClipData">
+</parameter>
 </method>
 <method name="obtain"
  return="android.view.DragEvent"
@@ -189920,15 +190053,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="action" type="int">
-</parameter>
-<parameter name="x" type="float">
-</parameter>
-<parameter name="y" type="float">
-</parameter>
-<parameter name="description" type="android.content.ClipDescription">
-</parameter>
-<parameter name="data" type="android.content.ClipData">
+<parameter name="source" type="android.view.DragEvent">
 </parameter>
 </method>
 <method name="recycle"
@@ -203415,6 +203540,53 @@
 >
 </field>
 </class>
+<class name="View.DragThumbnailBuilder"
+ extends="java.lang.Object"
+ abstract="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="View.DragThumbnailBuilder"
+ type="android.view.View.DragThumbnailBuilder"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="view" type="android.view.View">
+</parameter>
+</constructor>
+<method name="onDrawThumbnail"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="canvas" type="android.graphics.Canvas">
+</parameter>
+</method>
+<method name="onProvideThumbnailMetrics"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="thumbnailSize" type="android.graphics.Point">
+</parameter>
+<parameter name="thumbnailTouchPoint" type="android.graphics.Point">
+</parameter>
+</method>
+</class>
 <class name="View.MeasureSpec"
  extends="java.lang.Object"
  abstract="false"
@@ -223734,7 +223906,7 @@
 >
 </method>
 <method name="getInAnimation"
- return="android.view.animation.Animation"
+ return="android.animation.ObjectAnimator&lt;?&gt;"
  abstract="false"
  native="false"
  synchronized="false"
@@ -223745,7 +223917,7 @@
 >
 </method>
 <method name="getOutAnimation"
- return="android.view.animation.Animation"
+ return="android.animation.ObjectAnimator&lt;?&gt;"
  abstract="false"
  native="false"
  synchronized="false"
@@ -223861,7 +224033,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="inAnimation" type="android.view.animation.Animation">
+<parameter name="inAnimation" type="android.animation.ObjectAnimator&lt;?&gt;">
 </parameter>
 </method>
 <method name="setInAnimation"
@@ -223889,7 +224061,7 @@
  deprecated="not deprecated"
  visibility="public"
 >
-<parameter name="outAnimation" type="android.view.animation.Animation">
+<parameter name="outAnimation" type="android.animation.ObjectAnimator&lt;?&gt;">
 </parameter>
 </method>
 <method name="setOutAnimation"
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index da7ba6f..37e7253 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -1380,6 +1380,12 @@
             case FragmentTransaction.TRANSIT_FRAGMENT_CLOSE:
                 rev = FragmentTransaction.TRANSIT_FRAGMENT_OPEN;
                 break;
+            case FragmentTransaction.TRANSIT_FRAGMENT_NEXT:
+                rev = FragmentTransaction.TRANSIT_FRAGMENT_PREV;
+                break;
+            case FragmentTransaction.TRANSIT_FRAGMENT_PREV:
+                rev = FragmentTransaction.TRANSIT_FRAGMENT_NEXT;
+                break;
         }
         return rev;
         
@@ -1398,6 +1404,16 @@
                     ? com.android.internal.R.styleable.FragmentAnimation_fragmentCloseEnterAnimation
                     : com.android.internal.R.styleable.FragmentAnimation_fragmentCloseExitAnimation;
                 break;
+            case FragmentTransaction.TRANSIT_FRAGMENT_NEXT:
+                animAttr = enter
+                    ? com.android.internal.R.styleable.FragmentAnimation_fragmentNextEnterAnimation
+                    : com.android.internal.R.styleable.FragmentAnimation_fragmentNextExitAnimation;
+                break;
+            case FragmentTransaction.TRANSIT_FRAGMENT_PREV:
+                animAttr = enter
+                    ? com.android.internal.R.styleable.FragmentAnimation_fragmentPrevEnterAnimation
+                    : com.android.internal.R.styleable.FragmentAnimation_fragmentPrevExitAnimation;
+                break;
         }
         return animAttr;
     }
diff --git a/core/java/android/app/FragmentTransaction.java b/core/java/android/app/FragmentTransaction.java
index 09d8d26..b00476bb 100644
--- a/core/java/android/app/FragmentTransaction.java
+++ b/core/java/android/app/FragmentTransaction.java
@@ -106,10 +106,14 @@
     public final int TRANSIT_UNSET = -1;
     /** No animation for transition. */
     public final int TRANSIT_NONE = 0;
-    /** Fragment is being added */
+    /** Fragment is being added onto the stack */
     public final int TRANSIT_FRAGMENT_OPEN = 1 | TRANSIT_ENTER_MASK;
-    /** Fragment is being removed */
+    /** Fragment is being removed from the stack */
     public final int TRANSIT_FRAGMENT_CLOSE = 2 | TRANSIT_EXIT_MASK;
+    /** Fragment is being added in a 'next' operation*/
+    public final int TRANSIT_FRAGMENT_NEXT = 3 | TRANSIT_ENTER_MASK;
+    /** Fragment is being removed in a 'previous' operation */
+    public final int TRANSIT_FRAGMENT_PREV = 4 | TRANSIT_EXIT_MASK;
 
     /**
      * Set specific animation resources to run for the fragments that are
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index e21cb97..e688c86 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -216,10 +216,41 @@
     public static final int SCREEN_ORIENTATION_SENSOR = 4;
   
     /**
-     * Constant corresponding to <code>sensor</code> in
+     * Constant corresponding to <code>nosensor</code> in
      * the {@link android.R.attr#screenOrientation} attribute.
      */
     public static final int SCREEN_ORIENTATION_NOSENSOR = 5;
+
+    /**
+     * Constant corresponding to <code>sensorLandscape</code> in
+     * the {@link android.R.attr#screenOrientation} attribute.
+     */
+    public static final int SCREEN_ORIENTATION_SENSOR_LANDSCAPE = 6;
+
+    /**
+     * Constant corresponding to <code>sensorPortrait</code> in
+     * the {@link android.R.attr#screenOrientation} attribute.
+     */
+    public static final int SCREEN_ORIENTATION_SENSOR_PORTRAIT = 7;
+
+    /**
+     * Constant corresponding to <code>reverseLandscape</code> in
+     * the {@link android.R.attr#screenOrientation} attribute.
+     */
+    public static final int SCREEN_ORIENTATION_REVERSE_LANDSCAPE = 8;
+
+    /**
+     * Constant corresponding to <code>reversePortrait</code> in
+     * the {@link android.R.attr#screenOrientation} attribute.
+     */
+    public static final int SCREEN_ORIENTATION_REVERSE_PORTRAIT = 9;
+
+    /**
+     * Constant corresponding to <code>fullSensor</code> in
+     * the {@link android.R.attr#screenOrientation} attribute.
+     */
+    public static final int SCREEN_ORIENTATION_FULL_SENSOR = 10;
+
     /**
      * The preferred screen orientation this activity would like to run in.
      * From the {@link android.R.attr#screenOrientation} attribute, one of
@@ -229,7 +260,12 @@
      * {@link #SCREEN_ORIENTATION_USER},
      * {@link #SCREEN_ORIENTATION_BEHIND},
      * {@link #SCREEN_ORIENTATION_SENSOR},
-     * {@link #SCREEN_ORIENTATION_NOSENSOR}.
+     * {@link #SCREEN_ORIENTATION_NOSENSOR},
+     * {@link #SCREEN_ORIENTATION_SENSOR_LANDSCAPE},
+     * {@link #SCREEN_ORIENTATION_SENSOR_PORTRAIT},
+     * {@link #SCREEN_ORIENTATION_REVERSE_LANDSCAPE},
+     * {@link #SCREEN_ORIENTATION_REVERSE_PORTRAIT},
+     * {@link #SCREEN_ORIENTATION_FULL_SENSOR}.
      */
     public int screenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
     
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index a6c7d9e..a59b2f8 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -893,11 +893,15 @@
         }
     }
 
-    public void switchToHeaderInner(String fragmentName, Bundle args) {
+    public void switchToHeaderInner(String fragmentName, Bundle args, boolean next) {
         getFragmentManager().popBackStack(BACK_STACK_PREFS, POP_BACK_STACK_INCLUSIVE);
         Fragment f = Fragment.instantiate(this, fragmentName, args);
-        getFragmentManager().openTransaction().replace(
-                com.android.internal.R.id.prefs, f).commit();
+        FragmentTransaction transaction = getFragmentManager().openTransaction();
+        transaction.setTransition(next ?
+                FragmentTransaction.TRANSIT_FRAGMENT_NEXT :
+                FragmentTransaction.TRANSIT_FRAGMENT_PREV);
+        transaction.replace(com.android.internal.R.id.prefs, f);
+        transaction.commit();
     }
 
     /**
@@ -909,7 +913,7 @@
      */
     public void switchToHeader(String fragmentName, Bundle args) {
         setSelectedHeader(null);
-        switchToHeaderInner(fragmentName, args);
+        switchToHeaderInner(fragmentName, args, true);
     }
 
     /**
@@ -919,7 +923,8 @@
      * @param header The new header to display.
      */
     public void switchToHeader(Header header) {
-        switchToHeaderInner(header.fragment, header.fragmentArguments);
+        switchToHeaderInner(header.fragment, header.fragmentArguments,
+                mHeaders.indexOf(header) > mHeaders.indexOf(mCurHeader));
         setSelectedHeader(header);
     }
 
@@ -979,7 +984,10 @@
         FragmentTransaction transaction = getFragmentManager().openTransaction();
         startPreferenceFragment(fragment, transaction);
         if (push) {
+            transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
             transaction.addToBackStack(BACK_STACK_PREFS);
+        } else {
+            transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_NEXT);
         }
         transaction.commit();
     }
@@ -1001,6 +1009,7 @@
         FragmentTransaction transaction = getFragmentManager().openTransaction();
         startPreferenceFragment(f, transaction);
         transaction.setBreadCrumbTitle(pref.getTitle());
+        transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
         transaction.addToBackStack(BACK_STACK_PREFS);
         transaction.commit();
         return true;
diff --git a/core/java/android/view/DragEvent.java b/core/java/android/view/DragEvent.java
index 47c6d3c..93598cd 100644
--- a/core/java/android/view/DragEvent.java
+++ b/core/java/android/view/DragEvent.java
@@ -50,10 +50,10 @@
     public static final int ACTION_DRAG_EXITED = 6;
 
     /* hide the constructor behind package scope */
-    DragEvent() {
+    private DragEvent() {
     }
 
-    public static DragEvent obtain() {
+    static DragEvent obtain() {
         return DragEvent.obtain(0, 0f, 0f, null, null);
     }
 
@@ -81,6 +81,11 @@
         return ev;
     }
 
+    public static DragEvent obtain(DragEvent source) {
+        return obtain(source.mAction, source.mX, source.mY,
+                source.mClipDescription, source.mClipData);
+    }
+
     public int getAction() {
         return mAction;
     }
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index 6b9cda0..85a8c1a 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -17,8 +17,6 @@
 
 package android.view;
 
-import android.content.ClipData;
-import android.content.ClipDescription;
 import android.content.res.Configuration;
 import android.graphics.Rect;
 import android.os.Bundle;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1dfd2bf..2afbe81 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -66,6 +66,7 @@
 import com.android.internal.R;
 import com.android.internal.view.menu.MenuBuilder;
 
+import java.lang.ref.WeakReference;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
@@ -615,7 +616,6 @@
  */
 public class View implements Drawable.Callback, KeyEvent.Callback, AccessibilityEventSource {
     private static final boolean DBG = false;
-    static final boolean DEBUG_DRAG = true;
 
     /**
      * The logging tag used by this class with android.util.Log.
@@ -3957,6 +3957,12 @@
         return true;
     }
 
+    /** Gets the ViewRoot, or null if not attached. */
+    /*package*/ ViewRoot getViewRoot() {
+        View root = getRootView();
+        return root != null ? (ViewRoot)root.getParent() : null;
+    }
+
     /**
      * Call this to try to give focus to a specific view or to one of its descendants. This is a
      * special variant of {@link #requestFocus() } that will allow views that are not focuable in
@@ -3970,12 +3976,9 @@
     public final boolean requestFocusFromTouch() {
         // Leave touch mode if we need to
         if (isInTouchMode()) {
-            View root = getRootView();
-            if (root != null) {
-               ViewRoot viewRoot = (ViewRoot)root.getParent();
-               if (viewRoot != null) {
-                   viewRoot.ensureTouchMode(false);
-               }
+            ViewRoot viewRoot = getViewRoot();
+            if (viewRoot != null) {
+                viewRoot.ensureTouchMode(false);
             }
         }
         return requestFocus(View.FOCUS_DOWN);
@@ -5150,7 +5153,7 @@
     /**
      * Recomputes the transform matrix if necessary.
      */
-    private final void updateMatrix() {
+    private void updateMatrix() {
         if (mMatrixDirty) {
             // transform-related properties have changed since the last time someone
             // asked for the matrix; recalculate it with the current values
@@ -6205,7 +6208,8 @@
             ViewDebug.trace(this, ViewDebug.HierarchyTraceType.INVALIDATE);
         }
 
-        if ((mPrivateFlags & (DRAWN | HAS_BOUNDS)) == (DRAWN | HAS_BOUNDS)) {
+        if ((mPrivateFlags & (DRAWN | HAS_BOUNDS)) == (DRAWN | HAS_BOUNDS) ||
+                (mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID) {
             mPrivateFlags &= ~DRAWING_CACHE_VALID;
             final ViewParent p = mParent;
             final AttachInfo ai = mAttachInfo;
@@ -6236,7 +6240,8 @@
             ViewDebug.trace(this, ViewDebug.HierarchyTraceType.INVALIDATE);
         }
 
-        if ((mPrivateFlags & (DRAWN | HAS_BOUNDS)) == (DRAWN | HAS_BOUNDS)) {
+        if ((mPrivateFlags & (DRAWN | HAS_BOUNDS)) == (DRAWN | HAS_BOUNDS) ||
+                (mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID) {
             mPrivateFlags &= ~DRAWING_CACHE_VALID;
             final ViewParent p = mParent;
             final AttachInfo ai = mAttachInfo;
@@ -6275,7 +6280,8 @@
             ViewDebug.trace(this, ViewDebug.HierarchyTraceType.INVALIDATE);
         }
 
-        if ((mPrivateFlags & (DRAWN | HAS_BOUNDS)) == (DRAWN | HAS_BOUNDS)) {
+        if ((mPrivateFlags & (DRAWN | HAS_BOUNDS)) == (DRAWN | HAS_BOUNDS) ||
+                (invalidateCache && (mPrivateFlags & DRAWING_CACHE_VALID) == DRAWING_CACHE_VALID)) {
             mPrivateFlags &= ~DRAWN;
             if (invalidateCache) {
                 mPrivateFlags &= ~DRAWING_CACHE_VALID;
@@ -7425,8 +7431,7 @@
 
                 final int restoreCount = canvas.save();
 
-                mPrivateFlags |= DRAWN;
-                mPrivateFlags |= DRAWING_CACHE_VALID;
+                mPrivateFlags |= DRAWN | DRAWING_CACHE_VALID;
     
                 // Fast path for layouts with no backgrounds
                 if ((mPrivateFlags & SKIP_DRAW) == SKIP_DRAW) {
@@ -9833,40 +9838,109 @@
     }
 
     /**
+     * !!! TODO: real docs
+     *
+     * The base class implementation makes the thumbnail the same size and appearance
+     * as the view itself, and positions it with its center at the touch point.
+     */
+    public static class DragThumbnailBuilder {
+        private final WeakReference<View> mView;
+
+        /**
+         * Construct a thumbnail builder object for use with the given view.
+         * @param view
+         */
+        public DragThumbnailBuilder(View view) {
+            mView = new WeakReference<View>(view);
+        }
+
+        /**
+         * Provide the draggable-thumbnail metrics for the operation: the dimensions of
+         * the thumbnail image itself, and the point within that thumbnail that should
+         * be centered under the touch location while dragging.
+         * <p>
+         * The default implementation sets the dimensions of the thumbnail to be the
+         * same as the dimensions of the View itself and centers the thumbnail under
+         * the touch point.
+         *
+         * @param thumbnailSize The application should set the {@code x} member of this
+         *        parameter to the desired thumbnail width, and the {@code y} member to
+         *        the desired height.
+         * @param thumbnailTouchPoint The application should set this point to be the
+         *        location within the thumbnail that should track directly underneath
+         *        the touch point on the screen during a drag.
+         */
+        public void onProvideThumbnailMetrics(Point thumbnailSize, Point thumbnailTouchPoint) {
+            final View view = mView.get();
+            if (view != null) {
+                thumbnailSize.set(view.getWidth(), view.getHeight());
+                thumbnailTouchPoint.set(thumbnailSize.x / 2, thumbnailSize.y / 2);
+            } else {
+                Log.e(View.VIEW_LOG_TAG, "Asked for drag thumb metrics but no view");
+            }
+        }
+
+        /**
+         * Draw the thumbnail image for the upcoming drag.  The thumbnail canvas was
+         * created with the dimensions supplied by the onProvideThumbnailMetrics()
+         * callback.
+         *
+         * @param canvas
+         */
+        public void onDrawThumbnail(Canvas canvas) {
+            final View view = mView.get();
+            if (view != null) {
+                view.draw(canvas);
+            } else {
+                Log.e(View.VIEW_LOG_TAG, "Asked to draw drag thumb but no view");
+            }
+        }
+    }
+
+    /**
      * Drag and drop.  App calls startDrag(), then callbacks to onMeasureDragThumbnail()
      * and onDrawDragThumbnail() happen, then the drag operation is handed over to the
      * OS.
      * !!! TODO: real docs
      * @hide
      */
-    public final boolean startDrag(ClipData data, float touchX, float touchY,
-            float thumbnailTouchX, float thumbnailTouchY, boolean myWindowOnly) {
-        if (DEBUG_DRAG) {
-            Log.d(VIEW_LOG_TAG, "startDrag: touch=(" + touchX + "," + touchY
-                    + ") thumb=(" + thumbnailTouchX + "," + thumbnailTouchY
-                    + ") data=" + data + " local=" + myWindowOnly);
+    public final boolean startDrag(ClipData data, DragThumbnailBuilder thumbBuilder,
+            boolean myWindowOnly) {
+        if (ViewDebug.DEBUG_DRAG) {
+            Log.d(VIEW_LOG_TAG, "startDrag: data=" + data + " local=" + myWindowOnly);
         }
         boolean okay = false;
 
-        measureThumbnail();     // throws if the view fails to specify dimensions
+        Point thumbSize = new Point();
+        Point thumbTouchPoint = new Point();
+        thumbBuilder.onProvideThumbnailMetrics(thumbSize, thumbTouchPoint);
+
+        if ((thumbSize.x < 0) || (thumbSize.y < 0) ||
+                (thumbTouchPoint.x < 0) || (thumbTouchPoint.y < 0)) {
+            throw new IllegalStateException("Drag thumb dimensions must not be negative");
+        }
 
         Surface surface = new Surface();
         try {
             IBinder token = mAttachInfo.mSession.prepareDrag(mAttachInfo.mWindow,
                     myWindowOnly, mThumbnailWidth, mThumbnailHeight, surface);
-            if (DEBUG_DRAG) Log.d(VIEW_LOG_TAG, "prepareDrag returned token=" + token
+            if (ViewDebug.DEBUG_DRAG) Log.d(VIEW_LOG_TAG, "prepareDrag returned token=" + token
                     + " surface=" + surface);
             if (token != null) {
                 Canvas canvas = surface.lockCanvas(null);
                 try {
-                    onDrawDragThumbnail(canvas);
+                    thumbBuilder.onDrawThumbnail(canvas);
                 } finally {
                     surface.unlockCanvasAndPost(canvas);
                 }
 
+                // repurpose 'thumbSize' for the last touch point
+                getViewRoot().getLastTouchPoint(thumbSize);
+
                 okay = mAttachInfo.mSession.performDrag(mAttachInfo.mWindow, token,
-                        touchX, touchY, thumbnailTouchX, thumbnailTouchY, data);
-                if (DEBUG_DRAG) Log.d(VIEW_LOG_TAG, "performDrag returned " + okay);
+                        (float) thumbSize.x, (float) thumbSize.y,
+                        (float) thumbTouchPoint.x, (float) thumbTouchPoint.y, data);
+                if (ViewDebug.DEBUG_DRAG) Log.d(VIEW_LOG_TAG, "performDrag returned " + okay);
             }
         } catch (Exception e) {
             Log.e(VIEW_LOG_TAG, "Unable to initiate drag", e);
@@ -9888,7 +9962,7 @@
                     + " measured dimension by calling setDragThumbnailDimension()");
         }
 
-        if (DEBUG_DRAG) {
+        if (ViewDebug.DEBUG_DRAG) {
             Log.d(VIEW_LOG_TAG, "Drag thumb measured: w=" + mThumbnailWidth
                     + " h=" + mThumbnailHeight);
         }
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index b1d5272..727cf17 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -136,6 +136,12 @@
     public static final boolean DEBUG_SHOW_FPS = false;
 
     /**
+     * Enables detailed logging of drag/drop operations.
+     * @hide
+     */
+    public static final boolean DEBUG_DRAG = true;
+
+    /**
      * <p>Enables or disables views consistency check. Even when this property is enabled,
      * view consistency checks happen only if {@link android.util.Config#DEBUG} is set
      * to true. The value of this property can be configured externally in one of the
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 6c57e1e..5ebc981 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -19,8 +19,6 @@
 import android.animation.LayoutTransition;
 import com.android.internal.R;
 
-import android.content.ClipData;
-import android.content.ClipDescription;
 import android.content.Context;
 import android.content.res.Configuration;
 import android.content.res.TypedArray;
@@ -36,7 +34,6 @@
 import android.os.SystemClock;
 import android.util.AttributeSet;
 import android.util.Log;
-import android.util.Slog;
 import android.util.SparseArray;
 import android.view.accessibility.AccessibilityEvent;
 import android.view.animation.Animation;
@@ -72,7 +69,6 @@
 public abstract class ViewGroup extends View implements ViewParent, ViewManager {
 
     private static final boolean DBG = false;
-    private static final String TAG = "ViewGroup";
 
     /**
      * Views which have been hidden or removed which need to be animated on
@@ -868,9 +864,7 @@
         final float tx = event.mX;
         final float ty = event.mY;
 
-        // !!! BUGCHECK: If we have a ViewGroup, we must necessarily have a ViewRoot,
-        // so we don't need to check getRootView() for null here?
-        ViewRoot root = (ViewRoot)(getRootView().getParent());
+        ViewRoot root = getViewRoot();
 
         // Dispatch down the view hierarchy
         switch (event.mAction) {
@@ -883,10 +877,13 @@
             final int count = mChildrenCount;
             final View[] children = mChildren;
             for (int i = 0; i < count; i++) {
-                final boolean handled = children[i].dispatchDragEvent(event);
-                children[i].mCanAcceptDrop = handled;
-                if (handled) {
-                    mChildAcceptsDrag = true;
+                final View child = children[i];
+                if (child.getVisibility() == VISIBLE) {
+                    final boolean handled = children[i].dispatchDragEvent(event);
+                    children[i].mCanAcceptDrop = handled;
+                    if (handled) {
+                        mChildAcceptsDrag = true;
+                    }
                 }
             }
 
@@ -901,7 +898,10 @@
             final int count = mChildrenCount;
             final View[] children = mChildren;
             for (int i = 0; i < count; i++) {
-                children[i].dispatchDragEvent(event);
+                final View child = children[i];
+                if (child.getVisibility() == VISIBLE) {
+                    child.dispatchDragEvent(event);
+                }
             }
             // We consider drag-ended to have been handled if one of our children
             // had offered to handle the drag.
@@ -921,7 +921,7 @@
                 root.setDragFocus(event, target);
                 mCurrentDragView = target;
             }
-            
+
             // Dispatch the actual drag location notice, localized into its coordinates
             if (target != null) {
                 event.mX = mLocalPoint.x;
@@ -935,7 +935,7 @@
         } break;
 
         case DragEvent.ACTION_DROP: {
-            if (View.DEBUG_DRAG) Slog.d(TAG, "Drop event: " + event);
+            if (ViewDebug.DEBUG_DRAG) Log.d(View.VIEW_LOG_TAG, "Drop event: " + event);
             View target = findFrontmostDroppableChildAt(event.mX, event.mY, mLocalPoint);
             if (target != null) {
                 event.mX = mLocalPoint.x;
@@ -957,30 +957,15 @@
     // Find the frontmost child view that lies under the given point, and calculate
     // the position within its own local coordinate system.
     View findFrontmostDroppableChildAt(float x, float y, PointF outLocalPoint) {
-        final float scrolledX = x + mScrollX;
-        final float scrolledY = y + mScrollY;
         final int count = mChildrenCount;
         final View[] children = mChildren;
         for (int i = count - 1; i >= 0; i--) {
             final View child = children[i];
-            if (child.mCanAcceptDrop == false) {
+            if (!child.mCanAcceptDrop) {
                 continue;
             }
 
-            float localX = scrolledX - child.mLeft;
-            float localY = scrolledY - child.mTop;
-            if (!child.hasIdentityMatrix() && mAttachInfo != null) {
-                // non-identity matrix: transform the point into the view's coordinates
-                final float[] localXY = mAttachInfo.mTmpTransformLocation;
-                localXY[0] = localX;
-                localXY[1] = localY;
-                child.getInverseMatrix().mapPoints(localXY);
-                localX = localXY[0];
-                localY = localXY[1];
-            }
-            if (localX >= 0 && localY >= 0 && localX < (child.mRight - child.mLeft) &&
-                    localY < (child.mBottom - child.mTop)) {
-                outLocalPoint.set(localX, localY);
+            if (isTransformedTouchPointInView(x, y, child, outLocalPoint)) {
                 return child;
             }
         }
@@ -1108,7 +1093,7 @@
                             continue;
                         }
 
-                        if (!isTransformedTouchPointInView(x, y, child)) {
+                        if (!isTransformedTouchPointInView(x, y, child, null)) {
                             // New pointer is out of child's bounds.
                             continue;
                         }
@@ -1192,16 +1177,20 @@
         return handled;
     }
 
-    /* Resets all touch state in preparation for a new cycle. */
-    private final void resetTouchState() {
+    /**
+     * Resets all touch state in preparation for a new cycle.
+     */
+    private void resetTouchState() {
         clearTouchTargets();
         resetCancelNextUpFlag(this);
         mGroupFlags &= ~FLAG_DISALLOW_INTERCEPT;
     }
 
-    /* Resets the cancel next up flag.
-     * Returns true if the flag was previously set. */
-    private final boolean resetCancelNextUpFlag(View view) {
+    /**
+     * Resets the cancel next up flag.
+     * Returns true if the flag was previously set.
+     */
+    private boolean resetCancelNextUpFlag(View view) {
         if ((view.mPrivateFlags & CANCEL_NEXT_UP_EVENT) != 0) {
             view.mPrivateFlags &= ~CANCEL_NEXT_UP_EVENT;
             return true;
@@ -1209,8 +1198,10 @@
         return false;
     }
 
-    /* Clears all touch targets. */
-    private final void clearTouchTargets() {
+    /**
+     * Clears all touch targets.
+     */
+    private void clearTouchTargets() {
         TouchTarget target = mFirstTouchTarget;
         if (target != null) {
             do {
@@ -1222,8 +1213,10 @@
         }
     }
 
-    /* Cancels and clears all touch targets. */
-    private final void cancelAndClearTouchTargets(MotionEvent event) {
+    /**
+     * Cancels and clears all touch targets.
+     */
+    private void cancelAndClearTouchTargets(MotionEvent event) {
         if (mFirstTouchTarget != null) {
             boolean syntheticEvent = false;
             if (event == null) {
@@ -1245,9 +1238,11 @@
         }
     }
 
-    /* Gets the touch target for specified child view.
-     * Returns null if not found. */
-    private final TouchTarget getTouchTarget(View child) {
+    /**
+     * Gets the touch target for specified child view.
+     * Returns null if not found.
+     */
+    private TouchTarget getTouchTarget(View child) {
         for (TouchTarget target = mFirstTouchTarget; target != null; target = target.next) {
             if (target.child == child) {
                 return target;
@@ -1256,17 +1251,21 @@
         return null;
     }
 
-    /* Adds a touch target for specified child to the beginning of the list.
-     * Assumes the target child is not already present. */
-    private final TouchTarget addTouchTarget(View child, int pointerIdBits) {
+    /**
+     * Adds a touch target for specified child to the beginning of the list.
+     * Assumes the target child is not already present.
+     */
+    private TouchTarget addTouchTarget(View child, int pointerIdBits) {
         TouchTarget target = TouchTarget.obtain(child, pointerIdBits);
         target.next = mFirstTouchTarget;
         mFirstTouchTarget = target;
         return target;
     }
 
-    /* Removes the pointer ids from consideration. */
-    private final void removePointersFromTouchTargets(int pointerIdBits) {
+    /**
+     * Removes the pointer ids from consideration.
+     */
+    private void removePointersFromTouchTargets(int pointerIdBits) {
         TouchTarget predecessor = null;
         TouchTarget target = mFirstTouchTarget;
         while (target != null) {
@@ -1289,10 +1288,13 @@
         }
     }
 
-    /* Returns true if a child view contains the specified point when transformed
+    /**
+     * Returns true if a child view contains the specified point when transformed
      * into its coordinate space.
-     * Child must not be null. */
-    private final boolean isTransformedTouchPointInView(float x, float y, View child) {
+     * Child must not be null.
+     */
+    private boolean isTransformedTouchPointInView(float x, float y, View child,
+            PointF outLocalPoint) {
         float localX = x + mScrollX - child.mLeft;
         float localY = y + mScrollY - child.mTop;
         if (! child.hasIdentityMatrix() && mAttachInfo != null) {
@@ -1303,13 +1305,19 @@
             localX = localXY[0];
             localY = localXY[1];
         }
-        return child.pointInView(localX, localY);
+        final boolean isInView = child.pointInView(localX, localY);
+        if (isInView && outLocalPoint != null) {
+            outLocalPoint.set(localX, localY);
+        }
+        return isInView;
     }
 
-    /* Transforms a motion event into the coordinate space of a particular child view,
+    /**
+     * Transforms a motion event into the coordinate space of a particular child view,
      * filters out irrelevant pointer ids, and overrides its action if necessary.
-     * If child is null, assumes the MotionEvent will be sent to this ViewGroup instead. */
-    private final boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel,
+     * If child is null, assumes the MotionEvent will be sent to this ViewGroup instead.
+     */
+    private boolean dispatchTransformedTouchEvent(MotionEvent event, boolean cancel,
             View child, int desiredPointerIdBits) {
         final boolean handled;
 
@@ -1484,9 +1492,11 @@
         return handled;
     }
 
-    /* Enlarge the temporary pointer arrays for splitting pointers.
-     * May discard contents (but keeps PointerCoords objects to avoid reallocating them). */
-    private final void growTmpPointerArrays(int desiredCapacity) {
+    /**
+     * Enlarge the temporary pointer arrays for splitting pointers.
+     * May discard contents (but keeps PointerCoords objects to avoid reallocating them).
+     */
+    private void growTmpPointerArrays(int desiredCapacity) {
         final MotionEvent.PointerCoords[] oldTmpPointerCoords = mTmpPointerCoords;
         int capacity;
         if (oldTmpPointerCoords != null) {
@@ -2182,7 +2192,8 @@
             if (!canvas.isHardwareAccelerated()) {
                 cache = child.getDrawingCache(true);
             } else {
-                displayList = child.getDisplayList();
+                // TODO: bring back
+                // displayList = child.getDisplayList();
             }
         }
 
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index c63f7d6..155122f 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -24,6 +24,7 @@
 import android.graphics.Canvas;
 import android.graphics.PixelFormat;
 import android.graphics.PorterDuff;
+import android.graphics.Point;
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.Region;
@@ -205,6 +206,7 @@
     ClipDescription mDragDescription;
     View mCurrentDragView;
     final PointF mDragPoint = new PointF();
+    final PointF mLastTouchPoint = new PointF();
 
     /**
      * see {@link #playSoundEffect(int)}
@@ -2024,6 +2026,9 @@
             if (MEASURE_LATENCY) {
                 lt.sample("A Dispatching TouchEvents", System.nanoTime() - event.getEventTimeNano());
             }
+            // cache for possible drag-initiation
+            mLastTouchPoint.x = event.getRawX();
+            mLastTouchPoint.y = event.getRawY();
             handled = mView.dispatchTouchEvent(event);
             if (MEASURE_LATENCY) {
                 lt.sample("B Dispatched TouchEvents ", System.nanoTime() - event.getEventTimeNano());
@@ -2509,6 +2514,11 @@
         event.recycle();
     }
 
+    public void getLastTouchPoint(Point outLocation) {
+        outLocation.x = (int) mLastTouchPoint.x;
+        outLocation.y = (int) mLastTouchPoint.y;
+    }
+
     public void setDragFocus(DragEvent event, View newDragTarget) {
         final int action = event.mAction;
         // If we've dragged off of a view, send it the EXITED message
diff --git a/core/java/android/view/WindowOrientationListener.java b/core/java/android/view/WindowOrientationListener.java
index 8ffa158..3e2e92b 100755
--- a/core/java/android/view/WindowOrientationListener.java
+++ b/core/java/android/view/WindowOrientationListener.java
@@ -28,6 +28,11 @@
  * A special helper class used by the WindowManager
  *  for receiving notifications from the SensorManager when
  * the orientation of the device has changed.
+ *
+ * NOTE: If changing anything here, please run the API demo
+ * "App/Activity/Screen Orientation" to ensure that all orientation
+ * modes still work correctly.
+ *
  * @hide
  */
 public abstract class WindowOrientationListener {
@@ -103,6 +108,10 @@
         }
     }
 
+    public void setAllow180Rotation(boolean allowed) {
+        mSensorEventListener.setAllow180Rotation(allowed);
+    }
+
     public int getCurrentRotation(int lastRotation) {
         if (mEnabled) {
             return mSensorEventListener.getCurrentRotation(lastRotation);
@@ -151,19 +160,20 @@
         private static final int ROTATION_0 = 0;
         private static final int ROTATION_90 = 1;
         private static final int ROTATION_270 = 2;
+        private static final int ROTATION_180 = 3;
 
         // Mapping our internal aliases into actual Surface rotation values
         private static final int[] INTERNAL_TO_SURFACE_ROTATION = new int[] {
-            Surface.ROTATION_0, Surface.ROTATION_90, Surface.ROTATION_270};
+            Surface.ROTATION_0, Surface.ROTATION_90, Surface.ROTATION_270,
+            Surface.ROTATION_180};
 
         // Mapping Surface rotation values to internal aliases.
-        // We have no constant for Surface.ROTATION_180.  That should never happen, but if it
-        // does, we'll arbitrarily choose a mapping.
         private static final int[] SURFACE_TO_INTERNAL_ROTATION = new int[] {
-            ROTATION_0, ROTATION_90, ROTATION_90, ROTATION_270};
+            ROTATION_0, ROTATION_90, ROTATION_180, ROTATION_270};
 
         // Threshold ranges of orientation angle to transition into other orientation states.
-        // The first list is for transitions from ROTATION_0, the next for ROTATION_90, etc.
+        // The first list is for transitions from ROTATION_0, ROTATION_90, ROTATION_270,
+        // and then ROTATION_180.
         // ROTATE_TO defines the orientation each threshold range transitions to, and must be kept
         // in sync with this.
         // We generally transition about the halfway point between two states with a swing of 30
@@ -172,13 +182,32 @@
                 {{60, 180}, {180, 300}},
                 {{0, 30}, {195, 315}, {315, 360}},
                 {{0, 45}, {45, 165}, {330, 360}},
-        };
 
+                // Handle situation where we are currently doing 180 rotation
+                // but that is no longer allowed.
+                {{0, 45}, {45, 135}, {135, 225}, {225, 315}, {315, 360}},
+        };
         // See THRESHOLDS
         private static final int[][] ROTATE_TO = new int[][] {
                 {ROTATION_90, ROTATION_270},
                 {ROTATION_0, ROTATION_270, ROTATION_0},
                 {ROTATION_0, ROTATION_90, ROTATION_0},
+                {ROTATION_0, ROTATION_90, ROTATION_0, ROTATION_270, ROTATION_0},
+        };
+
+        // Thresholds that allow all 4 orientations.
+        private static final int[][][] THRESHOLDS_WITH_180 = new int[][][] {
+            {{60, 165}, {165, 195}, {195, 300}},
+            {{0, 30}, {165, 195}, {195, 315}, {315, 360}},
+            {{0, 45}, {45, 165}, {165, 195}, {330, 360}},
+            {{0, 45}, {45, 135}, {225, 315}, {315, 360}},
+        };
+        // See THRESHOLDS_WITH_180
+        private static final int[][] ROTATE_TO_WITH_180 = new int[][] {
+            {ROTATION_90, ROTATION_180, ROTATION_270},
+            {ROTATION_0, ROTATION_180, ROTATION_90, ROTATION_0},
+            {ROTATION_0, ROTATION_270, ROTATION_180, ROTATION_0},
+            {ROTATION_0, ROTATION_90, ROTATION_270, ROTATION_0},
         };
 
         // Maximum absolute tilt angle at which to consider orientation data.  Beyond this (i.e.
@@ -188,7 +217,7 @@
         // Additional limits on tilt angle to transition to each new orientation.  We ignore all
         // data with tilt beyond MAX_TILT, but we can set stricter limits on transitions to a
         // particular orientation here.
-        private static final int[] MAX_TRANSITION_TILT = new int[] {MAX_TILT, 65, 65};
+        private static final int[] MAX_TRANSITION_TILT = new int[] {MAX_TILT, 65, 65, 40};
 
         // Between this tilt angle and MAX_TILT, we'll allow orientation changes, but we'll filter
         // with a higher time constant, making us less sensitive to change.  This primarily helps
@@ -228,6 +257,8 @@
         private static final float ACCELERATING_LOWPASS_ALPHA =
             computeLowpassAlpha(ACCELERATING_TIME_CONSTANT_MS);
 
+        private boolean mAllow180Rotation = false;
+
         private WindowOrientationListener mOrientationListener;
         private int mRotation = ROTATION_0; // Current orientation state
         private float mTiltAngle = 0; // low-pass filtered
@@ -249,6 +280,10 @@
             return (float) SAMPLING_PERIOD_MS / (timeConstantMs + SAMPLING_PERIOD_MS);
         }
 
+        void setAllow180Rotation(boolean allowed) {
+            mAllow180Rotation = allowed;
+        }
+
         int getCurrentRotation(int lastRotation) {
             if (mTiltDistrust > 0) {
                 // we really don't know the current orientation, so trust what's currently displayed
@@ -259,7 +294,9 @@
 
         private void calculateNewRotation(float orientation, float tiltAngle) {
             if (localLOGV) Log.i(TAG, orientation + ", " + tiltAngle + ", " + mRotation);
-            int thresholdRanges[][] = THRESHOLDS[mRotation];
+            final boolean allow180Rotation = mAllow180Rotation;
+            int thresholdRanges[][] = allow180Rotation
+                    ? THRESHOLDS_WITH_180[mRotation] : THRESHOLDS[mRotation];
             int row = -1;
             for (int i = 0; i < thresholdRanges.length; i++) {
                 if (orientation >= thresholdRanges[i][0] && orientation < thresholdRanges[i][1]) {
@@ -269,13 +306,15 @@
             }
             if (row == -1) return; // no matching transition
 
-            int rotation = ROTATE_TO[mRotation][row];
+            int rotation = allow180Rotation
+                    ? ROTATE_TO_WITH_180[mRotation][row] : ROTATE_TO[mRotation][row];
             if (tiltAngle > MAX_TRANSITION_TILT[rotation]) {
                 // tilted too far flat to go to this rotation
                 return;
             }
 
-            if (localLOGV) Log.i(TAG, " new rotation = " + rotation);
+            if (localLOGV) Log.i(TAG, "orientation " + orientation + " gives new rotation = "
+                    + rotation);
             mRotation = rotation;
             mOrientationListener.onOrientationChanged(INTERNAL_TO_SURFACE_ROTATION[mRotation]);
         }
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 20aafbd..7b9af5b 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -1081,6 +1081,7 @@
         if (mBlockNetworkLoads != flag) {
             mBlockNetworkLoads = flag;
             verifyNetworkAccess();
+            postSync();
         }
     }
 
diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java
index 9983d54..1d1e601 100644
--- a/core/java/android/widget/AdapterViewAnimator.java
+++ b/core/java/android/widget/AdapterViewAnimator.java
@@ -19,6 +19,7 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 
+import android.animation.AnimatorInflater;
 import android.animation.ObjectAnimator;
 import android.content.Context;
 import android.content.Intent;
@@ -135,12 +136,15 @@
     int mReferenceChildHeight = -1;
 
     /**
-     * TODO: Animation stuff is still in flux, waiting on the new framework to settle a bit.
+     * In and out animations.
      */
-    Animation mInAnimation;
-    Animation mOutAnimation;
+    ObjectAnimator<?> mInAnimation;
+    ObjectAnimator<?> mOutAnimation;
+
     private  ArrayList<View> mViewsToBringToFront;
 
+    private static final int DEFAULT_ANIMATION_DURATION = 200;
+
     public AdapterViewAnimator(Context context) {
         super(context);
         initViewAnimator();
@@ -155,11 +159,15 @@
                 com.android.internal.R.styleable.AdapterViewAnimator_inAnimation, 0);
         if (resource > 0) {
             setInAnimation(context, resource);
+        } else {
+            setInAnimation(getDefaultInAnimation());
         }
 
         resource = a.getResourceId(com.android.internal.R.styleable.AdapterViewAnimator_outAnimation, 0);
         if (resource > 0) {
             setOutAnimation(context, resource);
+        } else {
+            setOutAnimation(getDefaultOutAnimation());
         }
 
         boolean flag = a.getBoolean(
@@ -229,17 +237,23 @@
      * @param view The view that is being animated
      */
     void animateViewForTransition(int fromIndex, int toIndex, View view) {
-        ObjectAnimator pa;
         if (fromIndex == -1) {
-            view.setAlpha(0.0f);
-            pa = new ObjectAnimator(400, view, "alpha", 0.0f, 1.0f);
-            pa.start();
+            mInAnimation.setTarget(view);
+            mInAnimation.start();
         } else if (toIndex == -1) {
-            pa = new ObjectAnimator(400, view, "alpha", 1.0f, 0.0f);
-            pa.start();
+            mOutAnimation.setTarget(view);
+            mOutAnimation.start();
         }
     }
 
+    ObjectAnimator<?> getDefaultInAnimation() {
+        return new ObjectAnimator<Float>(DEFAULT_ANIMATION_DURATION, null, "alpha", 0.0f, 1.0f);
+    }
+
+    ObjectAnimator<?> getDefaultOutAnimation() {
+        return new ObjectAnimator<Float>(DEFAULT_ANIMATION_DURATION, null, "alpha", 1.0f, 0.0f);
+    }
+
     /**
      * Sets which child view will be displayed.
      *
@@ -265,20 +279,6 @@
     }
 
     /**
-     * Return default inAnimation. To be overriden by subclasses.
-     */
-    Animation getDefaultInAnimation() {
-        return null;
-    }
-
-    /**
-     * Return default outAnimation. To be overridden by subclasses.
-     */
-    Animation getDefaultOutAnimation() {
-        return null;
-    }
-
-    /**
      * To be overridden by subclasses. This method applies a view / index specific
      * transform to the child view.
      *
@@ -690,7 +690,7 @@
      * @see #setInAnimation(android.view.animation.Animation)
      * @see #setInAnimation(android.content.Context, int)
      */
-    public Animation getInAnimation() {
+    public ObjectAnimator<?> getInAnimation() {
         return mInAnimation;
     }
 
@@ -702,7 +702,7 @@
      * @see #getInAnimation()
      * @see #setInAnimation(android.content.Context, int)
      */
-    public void setInAnimation(Animation inAnimation) {
+    public void setInAnimation(ObjectAnimator<?> inAnimation) {
         mInAnimation = inAnimation;
     }
 
@@ -714,7 +714,7 @@
      * @see #setOutAnimation(android.view.animation.Animation)
      * @see #setOutAnimation(android.content.Context, int)
      */
-    public Animation getOutAnimation() {
+    public ObjectAnimator<?> getOutAnimation() {
         return mOutAnimation;
     }
 
@@ -726,7 +726,7 @@
      * @see #getOutAnimation()
      * @see #setOutAnimation(android.content.Context, int)
      */
-    public void setOutAnimation(Animation outAnimation) {
+    public void setOutAnimation(ObjectAnimator<?> outAnimation) {
         mOutAnimation = outAnimation;
     }
 
@@ -740,7 +740,7 @@
      * @see #setInAnimation(android.view.animation.Animation)
      */
     public void setInAnimation(Context context, int resourceID) {
-        setInAnimation(AnimationUtils.loadAnimation(context, resourceID));
+        setInAnimation((ObjectAnimator<?>) AnimatorInflater.loadAnimator(context, resourceID));
     }
 
     /**
@@ -753,7 +753,7 @@
      * @see #setOutAnimation(android.view.animation.Animation)
      */
     public void setOutAnimation(Context context, int resourceID) {
-        setOutAnimation(AnimationUtils.loadAnimation(context, resourceID));
+        setOutAnimation((ObjectAnimator<?>) AnimatorInflater.loadAnimator(context, resourceID));
     }
 
     /**
diff --git a/core/java/android/widget/AdapterViewFlipper.java b/core/java/android/widget/AdapterViewFlipper.java
index 95ebdd3..b09ade7 100644
--- a/core/java/android/widget/AdapterViewFlipper.java
+++ b/core/java/android/widget/AdapterViewFlipper.java
@@ -16,6 +16,7 @@
 
 package android.widget;
 
+import android.animation.ObjectAnimator;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
@@ -43,10 +44,8 @@
     private static final boolean LOGD = false;
 
     private static final int DEFAULT_INTERVAL = 10000;
-    private static final int DEFAULT_ANIMATION_DURATION = 200;
 
     private int mFlipInterval = DEFAULT_INTERVAL;
-    private int mAnimationDuration = DEFAULT_ANIMATION_DURATION;
     private boolean mAutoStart = false;
 
     private boolean mRunning = false;
@@ -56,7 +55,6 @@
 
     public AdapterViewFlipper(Context context) {
         super(context);
-        initDefaultAnimations();
     }
 
     public AdapterViewFlipper(Context context, AttributeSet attrs) {
@@ -74,19 +72,6 @@
                 com.android.internal.R.styleable.AdapterViewAnimator_loopViews, true);
 
         a.recycle();
-        initDefaultAnimations();
-    }
-
-    private void initDefaultAnimations() {
-        // Set the default animations to be fade in/out
-        if (mInAnimation == null) {
-            mInAnimation = new AlphaAnimation(0.0f, 1.0f);
-            mInAnimation.setDuration(mAnimationDuration);
-        }
-        if (mOutAnimation == null) {
-            mOutAnimation = new AlphaAnimation(1.0f, 0.0f);
-            mOutAnimation.setDuration(mAnimationDuration);
-        }
     }
 
     private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java
index 4a0617c..fefdcea 100644
--- a/core/java/com/android/internal/app/AlertController.java
+++ b/core/java/com/android/internal/app/AlertController.java
@@ -17,6 +17,9 @@
 package com.android.internal.app;
 
 import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+
+import com.android.internal.R;
+
 import android.app.AlertDialog;
 import android.content.Context;
 import android.content.DialogInterface;
@@ -32,10 +35,11 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
 import android.view.Window;
 import android.view.WindowManager;
-import android.view.ViewGroup.LayoutParams;
 import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
 import android.widget.ArrayAdapter;
 import android.widget.Button;
 import android.widget.CheckedTextView;
@@ -48,9 +52,6 @@
 import android.widget.ScrollView;
 import android.widget.SimpleCursorAdapter;
 import android.widget.TextView;
-import android.widget.AdapterView.OnItemClickListener;
-
-import com.android.internal.R;
 
 import java.lang.ref.WeakReference;
 
@@ -403,12 +404,10 @@
             
             mIconView = (ImageView) mWindow.findViewById(R.id.icon);
             if (hasTextTitle) {
-                
                 /* Display the title if a title is supplied, else hide it */
                 mTitleView = (TextView) mWindow.findViewById(R.id.alertTitle);
 
                 mTitleView.setText(mTitle);
-                mIconView.setImageResource(R.drawable.ic_dialog_menu_generic);
                 
                 /* Do this last so that if the user has supplied any
                  * icons we use them instead of the default ones. If the
@@ -689,7 +688,7 @@
         public final Context mContext;
         public final LayoutInflater mInflater;
         
-        public int mIconId = -1;
+        public int mIconId = 0;
         public Drawable mIcon;
         public CharSequence mTitle;
         public View mCustomTitleView;
diff --git a/core/res/res/anim/fragment_close_enter.xml b/core/res/res/anim/fragment_close_enter.xml
index 53afa2a..7a9a3b9 100644
--- a/core/res/res/anim/fragment_close_enter.xml
+++ b/core/res/res/anim/fragment_close_enter.xml
@@ -19,20 +19,6 @@
 <set xmlns:android="http://schemas.android.com/apk/res/android">
     <objectAnimator
         android:interpolator="@anim/decelerate_interpolator"
-        android:valueFrom="2"
-        android:valueTo="1"
-        android:valueType="floatType"
-        android:propertyName="scaleX"
-        android:duration="@android:integer/config_mediumAnimTime"/>
-    <objectAnimator
-        android:interpolator="@anim/decelerate_interpolator"
-        android:valueFrom="2"
-        android:valueTo="1"
-        android:valueType="floatType"
-        android:propertyName="scaleY"
-        android:duration="@android:integer/config_mediumAnimTime"/>
-    <objectAnimator
-        android:interpolator="@anim/decelerate_interpolator"
         android:valueFrom="0"
         android:valueTo="1"
         android:valueType="floatType"
diff --git a/core/res/res/anim/fragment_close_exit.xml b/core/res/res/anim/fragment_close_exit.xml
index 1554a4e..0743577 100644
--- a/core/res/res/anim/fragment_close_exit.xml
+++ b/core/res/res/anim/fragment_close_exit.xml
@@ -20,20 +20,6 @@
     <objectAnimator
         android:interpolator="@anim/accelerate_interpolator"
         android:valueFrom="1"
-        android:valueTo=".5"
-        android:valueType="floatType"
-        android:propertyName="scaleX"
-        android:duration="@android:integer/config_mediumAnimTime"/>
-    <objectAnimator
-        android:interpolator="@anim/accelerate_interpolator"
-        android:valueFrom="1"
-        android:valueTo=".5"
-        android:valueType="floatType"
-        android:propertyName="scaleY"
-        android:duration="@android:integer/config_mediumAnimTime"/>
-    <objectAnimator
-        android:interpolator="@anim/accelerate_interpolator"
-        android:valueFrom="1"
         android:valueTo="0"
         android:valueType="floatType"
         android:propertyName="alpha"
diff --git a/core/res/res/anim/fragment_next_enter.xml b/core/res/res/anim/fragment_next_enter.xml
new file mode 100644
index 0000000..d2d6ec9
--- /dev/null
+++ b/core/res/res/anim/fragment_next_enter.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <objectAnimator
+        android:valueFrom="0"
+        android:valueTo="1"
+        android:valueType="floatType"
+        android:propertyName="alpha"
+        android:duration="@android:integer/config_longAnimTime"/>
+    <objectAnimator
+        android:valueFrom="50"
+        android:valueTo="0"
+        android:valueType="floatType"
+        android:propertyName="translationY"
+        android:duration="@android:integer/config_longAnimTime"/>
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/fragment_next_exit.xml b/core/res/res/anim/fragment_next_exit.xml
new file mode 100644
index 0000000..fbb82d9
--- /dev/null
+++ b/core/res/res/anim/fragment_next_exit.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <objectAnimator
+        android:valueFrom="1"
+        android:valueTo="0"
+        android:valueType="floatType"
+        android:propertyName="alpha"
+        android:duration="@android:integer/config_mediumAnimTime"/>
+    <objectAnimator
+        android:valueFrom="0"
+        android:valueTo="-50"
+        android:valueType="floatType"
+        android:propertyName="translationY"
+        android:duration="@android:integer/config_mediumAnimTime"/>
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/fragment_open_enter.xml b/core/res/res/anim/fragment_open_enter.xml
index 142f60c..ac60494 100644
--- a/core/res/res/anim/fragment_open_enter.xml
+++ b/core/res/res/anim/fragment_open_enter.xml
@@ -18,20 +18,6 @@
 -->
 <set xmlns:android="http://schemas.android.com/apk/res/android">
     <objectAnimator
-        android:interpolator="@anim/decelerate_interpolator"
-        android:valueFrom="2"
-        android:valueTo="1"
-        android:valueType="floatType"
-        android:propertyName="scaleX"
-        android:duration="@android:integer/config_mediumAnimTime"/>
-    <objectAnimator
-        android:interpolator="@anim/decelerate_interpolator"
-        android:valueFrom="2"
-        android:valueTo="1"
-        android:valueType="floatType"
-        android:propertyName="scaleY"
-        android:duration="@android:integer/config_mediumAnimTime"/>
-    <objectAnimator
         android:valueFrom="0"
         android:valueTo="1"
         android:valueType="floatType"
diff --git a/core/res/res/anim/fragment_open_exit.xml b/core/res/res/anim/fragment_open_exit.xml
index 21260b9..3bf1ad4 100644
--- a/core/res/res/anim/fragment_open_exit.xml
+++ b/core/res/res/anim/fragment_open_exit.xml
@@ -18,20 +18,6 @@
 -->
 <set xmlns:android="http://schemas.android.com/apk/res/android">
     <objectAnimator
-        android:interpolator="@anim/accelerate_interpolator"
-        android:valueFrom="1"
-        android:valueTo="2"
-        android:valueType="floatType"
-        android:propertyName="scaleX"
-        android:duration="@android:integer/config_mediumAnimTime"/>
-    <objectAnimator
-        android:interpolator="@anim/accelerate_interpolator"
-        android:valueFrom="1"
-        android:valueTo="2"
-        android:valueType="floatType"
-        android:propertyName="scaleY"
-        android:duration="@android:integer/config_mediumAnimTime"/>
-    <objectAnimator
         android:valueFrom="1"
         android:valueTo="0"
         android:valueType="floatType"
diff --git a/core/res/res/anim/fragment_prev_enter.xml b/core/res/res/anim/fragment_prev_enter.xml
new file mode 100644
index 0000000..d37afd0
--- /dev/null
+++ b/core/res/res/anim/fragment_prev_enter.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <objectAnimator
+        android:valueFrom="0"
+        android:valueTo="1"
+        android:valueType="floatType"
+        android:propertyName="alpha"
+        android:duration="@android:integer/config_longAnimTime"/>
+    <objectAnimator
+        android:valueFrom="-50"
+        android:valueTo="0"
+        android:valueType="floatType"
+        android:propertyName="translationY"
+        android:duration="@android:integer/config_longAnimTime"/>
+</set>
\ No newline at end of file
diff --git a/core/res/res/anim/fragment_prev_exit.xml b/core/res/res/anim/fragment_prev_exit.xml
new file mode 100644
index 0000000..a445a4d
--- /dev/null
+++ b/core/res/res/anim/fragment_prev_exit.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 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.
+*/
+-->
+<set xmlns:android="http://schemas.android.com/apk/res/android">
+    <objectAnimator
+        android:valueFrom="1"
+        android:valueTo="0"
+        android:valueType="floatType"
+        android:propertyName="alpha"
+        android:duration="@android:integer/config_mediumAnimTime"/>
+    <objectAnimator
+        android:valueFrom="0"
+        android:valueTo="50"
+        android:valueType="floatType"
+        android:propertyName="translationY"
+        android:duration="@android:integer/config_mediumAnimTime"/>
+</set>
\ No newline at end of file
diff --git a/core/res/res/drawable-hdpi/ic_dialog_menu_generic.png b/core/res/res/drawable-hdpi/ic_dialog_menu_generic.png
deleted file mode 100644
index ef8a877..0000000
--- a/core/res/res/drawable-hdpi/ic_dialog_menu_generic.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_100.png b/core/res/res/drawable-hdpi/stat_sys_battery_100.png
index e85f524..e49448d 100644
--- a/core/res/res/drawable-hdpi/stat_sys_battery_100.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_100.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_40.png b/core/res/res/drawable-hdpi/stat_sys_battery_40.png
index ca70784..441bbfb 100644
--- a/core/res/res/drawable-hdpi/stat_sys_battery_40.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_40.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_60.png b/core/res/res/drawable-hdpi/stat_sys_battery_60.png
index fee28db..d9467ed 100644
--- a/core/res/res/drawable-hdpi/stat_sys_battery_60.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_60.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_80.png b/core/res/res/drawable-hdpi/stat_sys_battery_80.png
index 7f4a38f..e3f4805 100644
--- a/core/res/res/drawable-hdpi/stat_sys_battery_80.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_80.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim2.png b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim2.png
index 2277096..426a66b 100644
--- a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim2.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim2.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim3.png b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim3.png
index 7a3b19e..21582ca 100644
--- a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim3.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim3.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim4.png b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim4.png
index 5c23c13..8a94763 100644
--- a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim4.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim4.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim5.png b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim5.png
index 321545f..fad0d65 100644
--- a/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim5.png
+++ b/core/res/res/drawable-hdpi/stat_sys_battery_charge_anim5.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_download_anim1.png b/core/res/res/drawable-hdpi/stat_sys_download_anim1.png
index 4f47db0..851eff9 100755
--- a/core/res/res/drawable-hdpi/stat_sys_download_anim1.png
+++ b/core/res/res/drawable-hdpi/stat_sys_download_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_download_anim2.png b/core/res/res/drawable-hdpi/stat_sys_download_anim2.png
index e50d3c3..2d06bb1 100755
--- a/core/res/res/drawable-hdpi/stat_sys_download_anim2.png
+++ b/core/res/res/drawable-hdpi/stat_sys_download_anim2.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_download_anim3.png b/core/res/res/drawable-hdpi/stat_sys_download_anim3.png
index 6c1029c..5c0ae7a 100755
--- a/core/res/res/drawable-hdpi/stat_sys_download_anim3.png
+++ b/core/res/res/drawable-hdpi/stat_sys_download_anim3.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_download_anim4.png b/core/res/res/drawable-hdpi/stat_sys_download_anim4.png
index 693f085..f8d5c8a 100755
--- a/core/res/res/drawable-hdpi/stat_sys_download_anim4.png
+++ b/core/res/res/drawable-hdpi/stat_sys_download_anim4.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_download_anim5.png b/core/res/res/drawable-hdpi/stat_sys_download_anim5.png
index eabe0ef..32b1425 100755
--- a/core/res/res/drawable-hdpi/stat_sys_download_anim5.png
+++ b/core/res/res/drawable-hdpi/stat_sys_download_anim5.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_upload_anim0.png b/core/res/res/drawable-hdpi/stat_sys_upload_anim0.png
index d72afbe..32b5077 100755
--- a/core/res/res/drawable-hdpi/stat_sys_upload_anim0.png
+++ b/core/res/res/drawable-hdpi/stat_sys_upload_anim0.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_upload_anim1.png b/core/res/res/drawable-hdpi/stat_sys_upload_anim1.png
index 5de2873..8387b45 100755
--- a/core/res/res/drawable-hdpi/stat_sys_upload_anim1.png
+++ b/core/res/res/drawable-hdpi/stat_sys_upload_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_upload_anim2.png b/core/res/res/drawable-hdpi/stat_sys_upload_anim2.png
index dd0b49f..c9a56a0 100755
--- a/core/res/res/drawable-hdpi/stat_sys_upload_anim2.png
+++ b/core/res/res/drawable-hdpi/stat_sys_upload_anim2.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_upload_anim3.png b/core/res/res/drawable-hdpi/stat_sys_upload_anim3.png
index 8ac29b3..972808a 100755
--- a/core/res/res/drawable-hdpi/stat_sys_upload_anim3.png
+++ b/core/res/res/drawable-hdpi/stat_sys_upload_anim3.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_upload_anim4.png b/core/res/res/drawable-hdpi/stat_sys_upload_anim4.png
index 26c3e714..d47c761 100755
--- a/core/res/res/drawable-hdpi/stat_sys_upload_anim4.png
+++ b/core/res/res/drawable-hdpi/stat_sys_upload_anim4.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_upload_anim5.png b/core/res/res/drawable-hdpi/stat_sys_upload_anim5.png
index 431ac6b..7aeafbe 100755
--- a/core/res/res/drawable-hdpi/stat_sys_upload_anim5.png
+++ b/core/res/res/drawable-hdpi/stat_sys_upload_anim5.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/ic_dialog_menu_generic.png b/core/res/res/drawable-mdpi/ic_dialog_menu_generic.png
deleted file mode 100755
index de07bda..0000000
--- a/core/res/res/drawable-mdpi/ic_dialog_menu_generic.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 8e2b762..33d3eeb 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1088,6 +1088,10 @@
         <attr name="fragmentOpenExitAnimation" format="reference" />
         <attr name="fragmentCloseEnterAnimation" format="reference" />
         <attr name="fragmentCloseExitAnimation" format="reference" />
+        <attr name="fragmentNextEnterAnimation" format="reference" />
+        <attr name="fragmentNextExitAnimation" format="reference" />
+        <attr name="fragmentPrevEnterAnimation" format="reference" />
+        <attr name="fragmentPrevExitAnimation" format="reference" />
     </declare-styleable>
 
     <!-- Window animation class attributes. -->
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 8cf65ae..949d960 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -497,10 +497,10 @@
              orientation will changed based on how the user rotates the device -->
         <enum name="unspecified" value="-1" />
         <!-- Would like to have the screen in a landscape orientation: that
-             is, with the display wider than it is tall. -->
+             is, with the display wider than it is tall, ignoring sensor data. -->
         <enum name="landscape" value="0" />
         <!-- Would like to have the screen in a portrait orientation: that
-             is, with the display taller than it is wide. -->
+             is, with the display taller than it is wide, ignoring sensor data. -->
         <enum name="portrait" value="1" />
         <!-- Use the user's current preferred orientation of the handset. -->
         <enum name="user" value="2" />
@@ -513,6 +513,24 @@
         <!-- Always ignore orientation determined by orientation sensor:
              the display will not rotate when the user moves the device. -->
         <enum name="nosensor" value="5" />
+        <!-- Would like to have the screen in landscape orientation, but can
+             use the sensor to change which direction the screen is facing. -->
+        <enum name="sensorLandscape" value="6" />
+        <!-- Would like to have the screen in portrait orientation, but can
+             use the sensor to change which direction the screen is facing. -->
+        <enum name="sensorPortait" value="7" />
+        <!-- Would like to have the screen in landscape orientation, turned in
+             the opposite direction from normal landscape. -->
+        <enum name="reverseLandscape" value="8" />
+        <!-- Would like to have the screen in portrait orientation, turned in
+             the opposite direction from normal portrait. -->
+        <enum name="reversePortait" value="9" />
+        <!-- Orientation is determined by a physical orientation sensor:
+             the display will rotate based on how the user moves the device.
+             This allows any of the 4 possible rotations, regardless of what
+             the device will normally do (for example some devices won't
+             normally use 180 degree rotation). -->
+        <enum name="fullSensor" value="10" />
     </attr>
     
     <!-- Specify one or more configuration changes that the activity will
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 35f8df5..2c3c4fc 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1332,6 +1332,10 @@
   <public type="attr" name="fragmentOpenExitAnimation" />
   <public type="attr" name="fragmentCloseEnterAnimation" />
   <public type="attr" name="fragmentCloseExitAnimation" />
+  <public type="attr" name="fragmentNextEnterAnimation" />
+  <public type="attr" name="fragmentNextExitAnimation" />
+  <public type="attr" name="fragmentPrevEnterAnimation" />
+  <public type="attr" name="fragmentPrevExitAnimation" />
   <public type="attr" name="actionBarSize" />
   <public type="attr" name="imeSubtypeLocale" />
   <public type="attr" name="imeSubtypeMode" />
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 3dfaf7f..4b5047e 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -78,6 +78,10 @@
         <item name="fragmentOpenExitAnimation">@anim/fragment_open_exit</item>
         <item name="fragmentCloseEnterAnimation">@anim/fragment_close_enter</item>
         <item name="fragmentCloseExitAnimation">@anim/fragment_close_exit</item>
+        <item name="fragmentNextEnterAnimation">@anim/fragment_next_enter</item>
+        <item name="fragmentNextExitAnimation">@anim/fragment_next_exit</item>
+        <item name="fragmentPrevEnterAnimation">@anim/fragment_prev_enter</item>
+        <item name="fragmentPrevExitAnimation">@anim/fragment_prev_exit</item>
     </style>
 
     <!-- Standard animations for a non-full-screen window or activity. -->
diff --git a/docs/html/guide/appendix/market-filters.jd b/docs/html/guide/appendix/market-filters.jd
index 0797892..e74cefb 100644
--- a/docs/html/guide/appendix/market-filters.jd
+++ b/docs/html/guide/appendix/market-filters.jd
@@ -4,7 +4,7 @@
 <div id="qv-wrapper">

 <div id="qv">

 

-<h2 align="left">Market filters quickview</h2>

+<h2>Quickview</h2>

 <ul> <li>Android Market applies filters to that let you control whether your app is shown to a

 user who is browing or searching for apps.</li> 

 <li>Filtering is determined by elements in an app's manifest file,

diff --git a/docs/html/guide/practices/design/performance.jd b/docs/html/guide/practices/design/performance.jd
index 56872a7..f5588ac 100644
--- a/docs/html/guide/practices/design/performance.jd
+++ b/docs/html/guide/practices/design/performance.jd
@@ -1,6 +1,30 @@
 page.title=Designing for Performance
 @jd:body
 
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>In this document</h2>
+<ol>
+  <li><a href="#intro">Introduction</a></li>
+  <li><a href="#optimize_judiciously">Optimize Judiciously</a></li>
+  <li><a href="#object_creation">Avoid Creating Objects</a></li>
+  <li><a href="#myths">Performance Myths</a></li>
+  <li><a href="#prefer_static">Prefer Static Over Virtual</a></li>
+  <li><a href="#internal_get_set">Avoid Internal Getters/Setters</a></li>
+  <li><a href="#use_final">Use Static Final For Constants</a></li>
+  <li><a href="#foreach">Use Enhanced For Loop Syntax</a></li>
+  <li><a href="#avoid_enums">Avoid Enums Where You Only Need Ints</a></li>
+  <li><a href="#package_inner">Use Package Scope with Inner Classes</a></li>
+  <li><a href="#avoidfloat">Use Floating-Point Judiciously</a> </li>
+  <li><a href="#library">Know And Use The Libraries</a></li>
+  <li><a href="#native_methods">Use Native Methods Judiciously</a></li>
+  <li><a href="#closing_notes">Closing Notes</a></li>
+</ol>
+
+</div>
+</div>
+
 <p>An Android application will run on a mobile device with limited computing
 power and storage, and constrained battery life. Because of
 this, it should be <em>efficient</em>. Battery life is one reason you might
@@ -8,24 +32,6 @@
 Battery life is important to users, and Android's battery usage breakdown
 means users will know if your app is responsible draining their battery.</p>
 
-<p>This document covers these topics: </p>
-<ul>
-    <li><a href="#intro">Introduction</a></li>
-    <li><a href="#optimize_judiciously">Optimize Judiciously</a></li>
-    <li><a href="#object_creation">Avoid Creating Objects</a></li>
-    <li><a href="#myths">Performance Myths</a></li>
-    <li><a href="#prefer_static">Prefer Static Over Virtual</a></li>
-    <li><a href="#internal_get_set">Avoid Internal Getters/Setters</a></li>
-    <li><a href="#use_final">Use Static Final For Constants</a></li>
-    <li><a href="#foreach">Use Enhanced For Loop Syntax</a></li>
-    <li><a href="#avoid_enums">Avoid Enums Where You Only Need Ints</a></li>
-    <li><a href="#package_inner">Use Package Scope with Inner Classes</a></li>
-    <li><a href="#avoidfloat">Use Floating-Point Judiciously</a> </li>
-    <li><a href="#library">Know And Use The Libraries</a></li>
-    <li><a href="#native_methods">Use Native Methods Judiciously</a></li>
-    <li><a href="#closing_notes">Closing Notes</a></li>
-</ul>
-
 <p>Note that although this document primarily covers micro-optimizations,
 these will almost never make or break your software. Choosing the right
 algorithms and data structures should always be your priority, but is
diff --git a/docs/html/guide/practices/design/responsiveness.jd b/docs/html/guide/practices/design/responsiveness.jd
index 9858e36..b811d1b 100644
--- a/docs/html/guide/practices/design/responsiveness.jd
+++ b/docs/html/guide/practices/design/responsiveness.jd
@@ -1,6 +1,19 @@
 page.title=Designing for Responsiveness
 @jd:body
 
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>In this document</h2>
+<ol>
+  <li><a href="#anr">What Triggers ANR?</a></li>
+  <li><a href="#avoiding">How to Avoid ANR</a></li>
+  <li><a href="#reinforcing">Reinforcing Responsiveness</a></li>
+</ol>
+
+</div>
+</div>
+
 <div class="figure">
 <img src="{@docRoot}images/anr.png" alt="Screenshot of ANR dialog box" width="240" height="320"/>
 <p><strong>Figure 1.</strong> An ANR dialog displayed to the user.</p>
diff --git a/docs/html/guide/practices/design/seamlessness.jd b/docs/html/guide/practices/design/seamlessness.jd
index a6c1641..dedc16f 100644
--- a/docs/html/guide/practices/design/seamlessness.jd
+++ b/docs/html/guide/practices/design/seamlessness.jd
@@ -1,6 +1,26 @@
 page.title=Designing for Seamlessness
 @jd:body
 
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>In this document</h2>
+<ol>
+  <li><a href="#drop">Don't Drop Data</a></li>
+  <li><a href="#expose">Don't Expose Raw Data</a></li>
+  <li><a href="#interrupt">Don't Interrupt the User</a></li>
+  <li><a href="#threads">Got a Lot to Do? Do it in a Thread</a></li>
+  <li><a href="#multiple-activities">Don't Overload a Single Activity Screen</a></li>
+  <li><a href="#themes">Extend System Themes</a></li>
+  <li><a href="#flexui">Design Your UI to Work with Multiple Screen Resolutions</a></li>
+  <li><a href="#network">Assume the Network is Slow</a></li>
+  <li><a href="#keyboard">Don't Assume Touchscreen or Keyboard</a></li>
+  <li><a href="#battery">Do Conserve the Device Battery</a></li>
+</ol>
+
+</div>
+</div>
+
 <p>Even if your application is fast and responsive, certain design decisions can
 still cause problems for users &mdash; because of unplanned interactions with
 other applications or dialogs, inadvertent loss of data, unintended blocking,
@@ -42,20 +62,7 @@
 by allowing you to integrate cleanly and seamlessly with other applications, and
 so you should design your own code to return the favor.</p>
 
-<p>This document discusses common seamlessness problems and how to avoid them.
-It covers these topics: </p>
-<ul>
-    <li><a href="#drop">Don't Drop Data</a></li>
-    <li><a href="#expose">Don't Expose Raw Data</a></li>
-    <li><a href="#interrupt">Don't Interrupt the User</a></li>
-    <li><a href="#threads">Got a Lot to Do? Do it in a Thread</a></li>
-    <li><a href="#multiple-activities">Don't Overload a Single Activity Screen</a></li>
-    <li><a href="#themes">Extend System Themes</a></li>
-    <li><a href="#flexui">Design Your UI to Work with Multiple Screen Resolutions</a></li>
-    <li><a href="#network">Assume the Network is Slow</a></li>
-    <li><a href="#keyboard">Don't Assume Touchscreen or Keyboard</a></li>
-    <li><a href="#battery">Do Conserve the Device Battery</a></li>
-</ul>
+<p>This document discusses common seamlessness problems and how to avoid them.</p>
 
 <h2 id="drop">Don't Drop Data</h2>
 
diff --git a/docs/html/guide/practices/screens_support.jd b/docs/html/guide/practices/screens_support.jd
index 11ad1b8..13b5e3a 100644
--- a/docs/html/guide/practices/screens_support.jd
+++ b/docs/html/guide/practices/screens_support.jd
@@ -5,7 +5,7 @@
 <div id="qv-wrapper">
 <div id="qv">
 
-  <h2>Multiple screens quickview: </h2>
+  <h2>Quickview</h2>
   <ul>
     <li>Android runs on devices that have different screen sizes and resolutions.</li>
     <li>The screen on which your application is displayed can affect its user interface.</li>
diff --git a/docs/html/guide/practices/ui_guidelines/activity_task_design.jd b/docs/html/guide/practices/ui_guidelines/activity_task_design.jd
index c8d241c..6cb98e6 100644
--- a/docs/html/guide/practices/ui_guidelines/activity_task_design.jd
+++ b/docs/html/guide/practices/ui_guidelines/activity_task_design.jd
@@ -4,7 +4,7 @@
 <div id="qv-wrapper">
 <div id="qv">
 
-<h2>Activity and task design quickview</h2>
+<h2>Quickview</h2>
 
 <ul>
 <li>Activities are the main building blocks of Android applications. </li>
diff --git a/docs/html/guide/practices/ui_guidelines/icon_design.jd b/docs/html/guide/practices/ui_guidelines/icon_design.jd
index 51ccfaf..389d5fa 100644
--- a/docs/html/guide/practices/ui_guidelines/icon_design.jd
+++ b/docs/html/guide/practices/ui_guidelines/icon_design.jd
@@ -4,7 +4,7 @@
 <div id="qv-wrapper">
 <div id="qv">
 
-<h2>Icon design quickview</h2>
+<h2>Quickview</h2>
 
 <ul>
 <li>You can use several types of icons in an Android application.</li>
@@ -35,25 +35,30 @@
 
 </ol>
 
-<h2>See also</h2>
-
-<ol>
-<li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
-Screens</a></li>
-<li><a href="{@docRoot}shareables/icon_templates-v2.0.zip">Android Icon
-Templates Pack, v2.0 &raquo;</a></li>
-</ol>
-
 <h2>Older versions</h2>
 
 <ol>
 <li style="margin-top:4px;"><a
 href="{@docRoot}guide/practices/ui_guidelines/icon_design_1.html">Icon Design
 Guidelines, Android 1.0</a></li>
+</ol>
+
+<h2>Downloads</h2>
+
+<ol>
+<li><a href="{@docRoot}shareables/icon_templates-v2.0.zip">Android Icon
+Templates Pack, v2.0 &raquo;</a></li>
 <li><a href="{@docRoot}shareables/icon_templates-v1.0.zip">Android Icon
 Templates Pack, v1.0 &raquo;</a></li>
 </ol>
 
+<h2>See also</h2>
+
+<ol>
+<li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
+Screens</a></li>
+</ol>
+
 
 </div>
 </div>
diff --git a/docs/html/guide/practices/ui_guidelines/icon_design_1.jd b/docs/html/guide/practices/ui_guidelines/icon_design_1.jd
index 1c75843..995cfea 100644
--- a/docs/html/guide/practices/ui_guidelines/icon_design_1.jd
+++ b/docs/html/guide/practices/ui_guidelines/icon_design_1.jd
@@ -4,7 +4,7 @@
 <div id="qv-wrapper">
 <div id="qv">
 
-<h2>Icon design quickview</h2>
+<h2>Quickview</h2>
 
 <ul>
 <li>You can use several types of icons in an Android application.</li>
@@ -35,12 +35,17 @@
 
 </ol>
 
+<h2>Downloads</h2>
+
+<ol>
+<li><a href="{@docRoot}shareables/icon_templates-v1.0.zip">Android Icon
+Templates Pack, v1.0 &raquo;</a></li>
+</ol>
+
 <h2>See also</h2>
 
 <ol>
 <li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a></li>
-<li><a href="{@docRoot}shareables/icon_templates-v1.0.zip">Android Icon
-Templates Pack, v1.0 &raquo;</a></li>
 </ol>
 
 
diff --git a/docs/html/guide/practices/ui_guidelines/menu_design.jd b/docs/html/guide/practices/ui_guidelines/menu_design.jd
index ebf8a4b..840ee66 100644
--- a/docs/html/guide/practices/ui_guidelines/menu_design.jd
+++ b/docs/html/guide/practices/ui_guidelines/menu_design.jd
@@ -4,7 +4,7 @@
 <div id="qv-wrapper">
 <div id="qv">
 			
-<h2>Menu design quickview</h2>
+<h2>Quickview</h2>
 
 <ul>
   <li>An Options menu is for any commands that are global to the current activity. </li>
diff --git a/docs/html/guide/practices/ui_guidelines/widget_design.jd b/docs/html/guide/practices/ui_guidelines/widget_design.jd
index fc62fe6..e978069 100644
--- a/docs/html/guide/practices/ui_guidelines/widget_design.jd
+++ b/docs/html/guide/practices/ui_guidelines/widget_design.jd
@@ -4,7 +4,7 @@
 <div id="qv-wrapper">
 <div id="qv">
 
-<h2>Widget design quickview</h2>
+<h2>Quickview</h2>
 
 <ul>
 <li>Widgets have six standard sizes on the Home screen</li>
@@ -27,7 +27,7 @@
 <h2>See also</h2>
 
 <ol>
-<li><a href="{@docRoot}guide/topics/appwidgets/index.html">AppWidgets</a> topic in the <em>Dev Guide</em></li>
+<li><a href="{@docRoot}guide/topics/appwidgets/index.html">App Widgets</a></li>
 <li><a href="http://android-developers.blogspot.com/2009/04/introducing-home-screen-widgets-and.html">AppWidgets blog post</a></li>
 </ol>
 
diff --git a/docs/html/guide/publishing/app-signing.jd b/docs/html/guide/publishing/app-signing.jd
index 34d9419..6758054 100644
--- a/docs/html/guide/publishing/app-signing.jd
+++ b/docs/html/guide/publishing/app-signing.jd
@@ -4,7 +4,7 @@
 <div id="qv-wrapper">
 <div id="qv">
 
-<h2>Signing quickview</h2>
+<h2>Quickview</h2>
 
 <ul>
 <li>All Android apps <em>must</em> be signed</a></li>
diff --git a/docs/html/guide/publishing/licensing.jd b/docs/html/guide/publishing/licensing.jd
index 07af68d..fc83ec0 100644
--- a/docs/html/guide/publishing/licensing.jd
+++ b/docs/html/guide/publishing/licensing.jd
@@ -4,7 +4,7 @@
 <div id="qv-wrapper">
 <div id="qv">
 
-  <h2>Market Licensing quickview: </h2>
+  <h2>Quickview</h2>
   <ul>
     <li>Licensing lets you protect your application on any device that includes Android Market.</li>
     <li>Your app maintains control of how it enforces its licensing status. </li>
diff --git a/docs/html/guide/publishing/preparing.jd b/docs/html/guide/publishing/preparing.jd
index 442c12a..45a5b77 100644
--- a/docs/html/guide/publishing/preparing.jd
+++ b/docs/html/guide/publishing/preparing.jd
@@ -1,20 +1,6 @@
 page.title=Preparing to Publish: A Checklist
 @jd:body
 
-<!--
-<div id="qv-wrapper">
-<div id="qv">
-
-<h2>In this document</h2>
-
-<ol>
-<li><a href=""></a></li>
-</ol>
-
-</div>
-</div>
--->
-
 <p>Publishing an application means testing it, packaging it appropriately, and 
 making it available to users of Android-powered mobile devices.</p>
 
@@ -34,7 +20,7 @@
 
 <div class="special">
 
-<p>Before you consider your application ready for release:</p>
+<p><a href="#releaseready">Before you consider your application ready for release</a>:</p>
 
 <ol>
 <li>Test your application extensively on an actual device </li>
@@ -44,7 +30,7 @@
 <li>Turn off logging and debugging and clean up data/files</li>
 </ol>
 
-<p>Before you do the final compile of your application:</p>
+<p><a href="#finalcompile">Before you do the final compile of your application</a>:</p>
 
 <ol start="6">
 <li>Version your application</li>
@@ -52,8 +38,9 @@
 <li>Register for a Maps API Key, if your application is using MapView elements</li>
 </ol>
 
-<p><em>Compile your application...</em></p>
-<p>After compiling your application:</p>
+<p><a href="#compile">Compile your application</a></p>
+
+<p><a href="#post-compile">After you compile your application</a>:</p>
 <ol start="9">
 <li>Sign your application</li>
 <li>Test your compiled application</li>
@@ -242,7 +229,7 @@
 you can compile your application for release.</p>
 
 
-<h2 id="post-compile">After compiling your application</h2>
+<h2 id="post-compile">After you compile your application</h2>
 
 <h3 id="signapp">9. Sign your application</h3>
 
diff --git a/docs/html/guide/publishing/publishing.jd b/docs/html/guide/publishing/publishing.jd
index 9b470c8..af1ea74 100644
--- a/docs/html/guide/publishing/publishing.jd
+++ b/docs/html/guide/publishing/publishing.jd
@@ -4,7 +4,7 @@
 <div id="qv-wrapper">
 <div id="qv">
 
-<h2>Publishing quickview</h2>
+<h2>Quickview</h2>
 
 <ul>
 <li>You can publish your application using a hosted service such as Android Market or through a web server.</li>
diff --git a/docs/html/guide/publishing/versioning.jd b/docs/html/guide/publishing/versioning.jd
index 1d55f8a..b646247 100644
--- a/docs/html/guide/publishing/versioning.jd
+++ b/docs/html/guide/publishing/versioning.jd
@@ -4,7 +4,7 @@
 <div id="qv-wrapper">
 <div id="qv">
 
-<h2>Versioning quickview</h2>
+<h2>Quickview</h2>
 
 <ul>
 <li>Your application <em>must</em> be versioned</a></li>
diff --git a/docs/html/guide/topics/appwidgets/index.jd b/docs/html/guide/topics/appwidgets/index.jd
index 7a8dd59..3de5627 100644
--- a/docs/html/guide/topics/appwidgets/index.jd
+++ b/docs/html/guide/topics/appwidgets/index.jd
@@ -3,12 +3,14 @@
 
 <div id="qv-wrapper">
   <div id="qv">
-    <h2>Key classes</h2>
-    <ol>
-      <li>{@link android.appwidget.AppWidgetProvider}</li>
-      <li>{@link android.appwidget.AppWidgetProviderInfo}</li>
-      <li>{@link android.appwidget.AppWidgetManager}</li>
-    </ol>
+    <h2>Quickview</h2>
+    <ul>
+      <li>App Widgets provide users access to some of your application features
+directly from the Home screen (without the need to launch an activity)</li>
+      <li>App Widgets are backed by a special kind of broadcast receiver that handles the App
+Widget lifecycle</li>
+    </ul>
+    
     <h2>In this document</h2>
     <ol>
       <li><a href="#Basics">The Basics</a></li>
@@ -28,6 +30,13 @@
       </li>
     </ol>
 
+    <h2>Key classes</h2>
+    <ol>
+      <li>{@link android.appwidget.AppWidgetProvider}</li>
+      <li>{@link android.appwidget.AppWidgetProviderInfo}</li>
+      <li>{@link android.appwidget.AppWidgetManager}</li>
+    </ol>
+    
     <h2>See also</h2>
     <ol>
       <li><a href="{@docRoot}guide/practices/ui_guidelines/widget_design.html">App Widget Design 
diff --git a/docs/html/guide/topics/fundamentals.jd b/docs/html/guide/topics/fundamentals.jd
index db06efc..84c2ed2 100644
--- a/docs/html/guide/topics/fundamentals.jd
+++ b/docs/html/guide/topics/fundamentals.jd
@@ -3,14 +3,6 @@
 
 <div id="qv-wrapper">
 <div id="qv">
-<h2>Key classes</h2>
-<ol>
-<li>{@link android.app.Activity}</li>
-<li>{@link android.app.Service}</li>
-<li>{@link android.content.BroadcastReceiver}</li>
-<li>{@link android.content.ContentProvider}</li>
-<li>{@link android.content.Intent}</li>
-</ol>
 
 <h2>In this document</h2>
 <ol>
@@ -43,6 +35,16 @@
     <li><a href="#proclife">Processes and lifecycles</a></li>
   </ol></li>
 </ol>
+
+<h2>Key classes</h2>
+<ol>
+<li>{@link android.app.Activity}</li>
+<li>{@link android.app.Service}</li>
+<li>{@link android.content.BroadcastReceiver}</li>
+<li>{@link android.content.ContentProvider}</li>
+<li>{@link android.content.Intent}</li>
+</ol>
+
 </div>
 </div>
 
diff --git a/docs/html/guide/topics/fundamentals/activities.jd b/docs/html/guide/topics/fundamentals/activities.jd
new file mode 100644
index 0000000..b616ab8
--- /dev/null
+++ b/docs/html/guide/topics/fundamentals/activities.jd
@@ -0,0 +1,762 @@
+page.title=Activities
+parent.title=Application Fundamentals
+parent.link=index.html
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+<h2>Quickview</h2>
+<ul>
+  <li>An activity provides a user interface for a single screen in your application</li>
+  <li>Activities can move into the background and then be resumed with their state restored</li>
+</ul>
+
+<h2>In this document</h2>
+<ol>
+  <li><a href="#Creating">Creating an Activity</a>
+    <ol>
+      <li><a href="#UI">Implementing a user interface</a></li>
+      <li><a href="#Declaring">Declaring the activity in the manifest</a></li>
+    </ol>
+  </li>
+  <li><a href="#StartingAnActivity">Starting an Activity</a>
+    <ol>
+      <li><a href="#StartingAnActivityForResult">Starting an Activity for a Result</a></li>
+    </ol>
+  </li>
+  <li><a href="#Lifecycle">Managing the Activity Lifecycle</a>
+    <ol>
+      <li><a href="#ImplementingLifecycleCallbacks">Implementing the lifecycle callbacks</a></li>
+      <li><a href="#SavingActivityState">Saving activity state</a></li>
+      <li><a href="#ConfigurationChanges">Handling configuration changes</a></li>
+      <li><a href="#CoordinatingActivities">Coordinating activities</a></li>
+    </ol>
+  </li>
+</ol>
+
+<h2>Key classes</h2>
+<ol>
+  <li>{@link android.app.Activity}</li>
+</ol>
+
+<h2>See also</h2>
+<ol>
+  <li><a href="{@docRoot}resources/tutorials/hello-world.html">Hello World Tutorial</a></li>
+  <li><a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack">Tasks and Back
+Stack</a></li>
+</ol>
+
+</div>
+</div>
+
+
+
+<p>An {@link android.app.Activity} is an application component that provides a screen with which
+users can interact in order to do something, such as dial the phone, take a photo, send an email, or
+view a map. Each activity is given a window in which to draw its user interface. The window
+typically fills the screen, but may be smaller than the screen and float on top of other
+windows.</p>
+
+<p> An application usually consists of multiple activities that are loosely bound
+to each other. Typically, one activity in an application is specified as the "main" activity, which
+is presented to the user when launching the application for the first time. Each
+activity can then start another activity in order to perform different actions. Each time a new
+activity starts, the previous activity is stopped, but the system preserves the activity
+in a stack (the "back stack"). When a new activity starts, it is pushed onto the back stack and
+takes user focus. The back stack abides to the basic "last in, first out" queue mechanism,
+so, when the user is done with the current activity and presses the BACK key, it
+is popped from the stack (and destroyed) and the previous activity resumes. (The back stack is
+discussed more in the <a href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks
+and Back Stack</a> document.)</p>
+
+<p>When an activity is stopped because a new activity starts, it is notified of this change in state
+through the activity's lifecycle callback methods.
+There are several callback methods that an activity might receive, due to a change in its
+state&mdash;whether the system is creating it, stopping it, resuming it, or destroying it&mdash;and
+each callback provides you the opportunity to perform specific work that's
+appropriate to that state change. For instance, when stopped, your activity should release any
+large objects, such as network or database connections. When the activity resumes, you can
+reacquire the necessary resources and resume actions that were interrupted. These state transitions
+are all part of the activity lifecycle.</p>
+
+<p>The rest of this document discusses the basics of how to build and use an activity,
+including a complete discussion of how the activity lifecycle works, so you can properly manage
+the transition between various activity states.</p>
+
+
+
+<h2 id="Creating">Creating an Activity</h2>
+
+<p>To create an activity, you must create a subclass of {@link android.app.Activity} (or
+an existing subclass of it). In your subclass, you need to implement callback methods that the
+system calls when the activity transitions between various states of its lifecycle, such as when
+the activity is being created, stopped, resumed, or destroyed. The two most important callback
+methods are:</p>
+
+<dl>
+  <dt>{@link android.app.Activity#onCreate onCreate()}</dt>
+  <dd>You must implement this method. The system calls this when creating your
+    activity. Within your implementation, you should initialize the essential components of your
+activity.
+    Most importantly, this is where you must call {@link android.app.Activity#setContentView
+    setContentView()} to define the layout for the activity's user interface.</dd>
+  <dt>{@link android.app.Activity#onPause onPause()}</dt>
+  <dd>The system calls this method as the first indication that the user is leaving your
+activity (though it does not always mean the activity is being destroyed). This is usually where you
+should commit any changes that should be persisted beyond the current user session (because
+the user might not come back).</dd>
+</dl>
+
+<p>There are several other lifecycle callback methods that you should use in order to provide a
+fluid user experience between activities and handle unexpected interuptions that cause your activity
+to be stopped and even destroyed. All of the lifecycle callback methods are discussed later, in
+the section about <a href="#Lifecycle">Managing the Activity Lifecycle</a>.</p>
+
+
+
+<h3 id="UI">Implementing a user interface</h3>
+
+<p> The user interface for an activity is provided by a hierarchy of views&mdash;objects derived
+from the {@link android.view.View} class.  Each view controls a particular rectangular space
+within the activity's window and can respond to user interaction. For example, a view might be a
+button that initiates an action when the user touches it.</p>
+
+<p>Android provides a number of ready-made views that you can use to design and organize your
+layout. "Widgets" are views that provide a visual (and interactive) elements for the screen, such
+as a button, text field, checkbox, or just an image. "Layouts" are views derived from {@link
+android.view.ViewGroup} that provide a unique layout model for its child views, such as a linear
+layout, a grid layout, or relative layout. You can also subclass the {@link android.view.View} and
+{@link android.view.ViewGroup} classes (or existing subclasses) to create your own widgets and
+layouts and apply them to your activity layout.</p>
+
+<p>The most common way to define a layout using views is with an XML layout file saved in your
+application resources. This way, you can maintain the design of your user interface separately from
+the source code that defines the activity's behavior. You can set the layout as the UI for your
+activity with {@link android.app.Activity#setContentView(int) setContentView()}, passing the
+resource ID for the layout. However, you can also create new {@link android.view.View}s in your
+activity code and build a view hierarchy by inserting new {@link
+android.view.View}s into a {@link android.view.ViewGroup}, then use that layout by passing the root
+{@link android.view.ViewGroup} to {@link android.app.Activity#setContentView(View)
+setContentView()}.</p>
+
+<p>For information about creating a user interface, see the <a
+href="{@docRoot}guide/topics/ui/index.html">User Interface</a> documentation.</p>
+
+
+
+<h3 id="Declaring">Declaring the activity in the manifest</h3>
+
+<p>You must declare your activity in the manifest file in order for it to
+be accessible to the system. To decalare your activity, open your manifest file and add an <a
+href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a> element
+as a child of the <a
+href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application&gt;}</a>
+element. For example:</p>
+
+<pre>
+&lt;manifest ... &gt;
+  &lt;application ... &gt;
+      &lt;activity android:name=".ExampleActivity" /&gt;
+      ...
+  &lt;/application ... &gt;
+  ...
+&lt;/manifest &gt;
+</pre>
+
+<p>There are several other attributes that you can include in this element, to define properties
+such as the label for the activity, an icon for the activity, or a theme to style the activity's
+UI. See the <a
+href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a> element
+reference for more information about available attributes.</p>
+
+
+<h4>Using intent filters</h4>
+
+<p>An <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
+&lt;activity&gt;}</a> element can also specify various intent filters&mdash;using the <a
+href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
+&lt;intent-filter&gt;}</a> element&mdash;in order to declare how other application components may
+activate it.</p>
+
+<p>When you create a new application using the Android SDK tools, the stub activity
+that's created for you automatically includes an intent filter that declares the activity
+responds to the "main" action and should be placed in the "launcher" category. The intent filter
+looks like this:</p>
+
+<pre>
+&lt;activity android:name=".ExampleActivity" android:icon="@drawable/app_icon"&gt;
+    &lt;intent-filter&gt;
+        &lt;action android:name="android.intent.action.MAIN" /&gt;
+        &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
+    &lt;/intent-filter&gt;
+&lt;/activity&gt;
+</pre>
+
+<p>The <a href="{@docRoot}guide/topics/manifest/action-element.html">{@code
+&lt;action&gt;}</a> element specifies that this is the "main" entry point to the application. The <a
+href="{@docRoot}guide/topics/manifest/category-element.html">{@code
+&lt;category&gt;}</a> element specifies that this activity should be listed in the
+system's application launcher (to allow users to launch this activity).</p>
+
+<p>If you intend for your application to be self-contained and not allow other applications to
+activate its activities, then you don't need any other intent filters. Only one activity should
+have the "main" action and "launcher" category, as in the previous example. Activities that
+you don't want to make available to other applications should have no intent filters and you can
+start them yourself using explicit intents (as discussed in the following section).</p>
+
+<p>However, if you want your activity to respond to implicit intents that are delivered from
+other applications (and your own), then you must define additional intent filters for your
+activity. For each type of intent to which you want to respond, you must include an <a
+href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
+&lt;intent-filter&gt;}</a> that includes an
+<a href="{@docRoot}guide/topics/manifest/action-element.html">{@code
+&lt;action&gt;}</a> element and, optionally, a <a
+href="{@docRoot}guide/topics/manifest/category-element.html">{@code
+&lt;category&gt;}</a> element and/or a <a
+href="{@docRoot}guide/topics/manifest/data-element.html">{@code
+&lt;data&gt;}</a> element. These elements specify the type of intent to which your activity can
+respond.</p>
+
+<p>For more information about how your activities can respond to intents, see the <a
+href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent Filters</a>
+document.</p>
+
+
+
+<h2 id="StartingAnActivity">Starting an Activity</h2>
+
+<p>You can start another activity by calling {@link android.app.Activity#startActivity
+  startActivity()}, passing it an {@link android.content.Intent} that describes the activity you
+  want to start. The intent specifies either the exact activity you want to start or describes the
+  type of action you want to perform (and the system selects the appropriate activity for you,
+which
+  can even be from a different application). An intent can also carry small amounts of data to be
+  used by the activity that is started.</p>
+
+<p>When working within your own application, you'll often need to simply launch a known activity.
+ You can do so by creating an intent that explicitly defines the activity you want to start,
+using the class name. For example, here's how one activity starts another activity named {@code
+SignInActivity}:</p>
+
+<pre>
+Intent intent = new Intent(this, SignInActivity.class);
+startActivity(intent);
+</pre>
+
+<p>However, your application might also want to perform some action, such as send an email, text
+  message, or status update, using data from your activity. In this case, your application might
+ not have its own activities to perform such actions, so you can instead leverage the activities
+  provided by other applications on the device, which can perform the actions for you. This is where
+intents are really valuable&mdash;you can create an intent that describes an action you want to
+perform and the system
+  launches the appropriate activity from another application. If there are
+  multiple activities that can handle the intent, then the user can select which one to use. For
+  example, if you want to allow the user to send an email message, you can create the
+  following intent:</p>
+
+<pre>
+Intent intent = new Intent(Intent.ACTION_SEND);
+intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
+startActivity(intent);
+</pre>
+
+<p>The {@link android.content.Intent#EXTRA_EMAIL} extra added to the intent is a string array of
+  email addresses to which the email should be sent. When an email application responds to this
+  intent, it reads the string array provided in the extra and places them in the "to" field of the
+  email composition form. In this situation, the email application's activity starts and when the
+  user is done, your activity resumes.</p>
+
+
+
+
+<h3 id="StartingAnActivityForResult">Starting an activity for a result</h3>
+
+<p>Sometimes, you might want to receive a result from the activity that you start. In that case,
+  start the activity by calling {@link android.app.Activity#startActivityForResult
+  startActivityForResult()} (instead of {@link android.app.Activity#startActivity
+  startActivity()}). To then receive the result from the subsequent
+activity, implement the {@link android.app.Activity#onActivityResult onActivityResult()} callback
+  method. When the subsequent activity is done, it returns a result in an {@link
+android.content.Intent} to your {@link android.app.Activity#onActivityResult onActivityResult()}
+method.</p>
+
+<p>For example, perhaps you want the user to pick one of their contacts, so your activity can
+do something with the information in that contact. Here's how you can create such an intent and
+handle the result:</p>
+
+<pre>
+private void pickContact() {
+    // Create an intent to "pick" a contact, as defined by the content provider URI
+    Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);
+    startActivityForResult(intent, PICK_CONTACT_REQUEST);
+}
+
+&#64;Override
+protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+    // If the request went well (OK) and the request was PICK_CONTACT_REQUEST
+    if (resultCode == Activity.RESULT_OK &amp;&amp; requestCode == PICK_CONTACT_REQUEST) {
+        // Perform a query to the contact's content provider for the contact's name
+        Cursor cursor = getContentResolver().query(data.getData(),
+        new String[] {Contacts.DISPLAY_NAME}, null, null, null);
+        if (cursor.moveToFirst()) { // True if the cursor is not empty
+            int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME);
+            String name = cursor.getString(columnIndex);
+            // Do something with the selected contact's name...
+        }
+    }
+}
+</pre>
+
+<p>This example shows the basic logic you should use in your {@link
+android.app.Activity#onActivityResult onActivityResult()} method in order to handle an
+activity result. The first condition checks whether the request was successful&mdash;if it was, then
+the {@code resultCode} will be {@link android.app.Activity#RESULT_OK}&mdash;and whether the request
+to which this result is responding is known&mdash;in this case, the {@code requestCode} matches the
+second parameter sent with {@link android.app.Activity#startActivityForResult
+startActivityForResult()}. From there, the code handles the activity result by querying the
+data returned in an {@link android.content.Intent} (the {@code data} parameter).</p>
+
+<p>What happens is, a {@link
+android.content.ContentResolver} performs a query against a content provider, which returns a
+{@link android.database.Cursor} that allows the queried data to be read. For more information, see
+the <a
+href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a> document.</p>
+
+<p>For more information about using intents, see the <a
+href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent
+Filters</a> document.</p>
+
+
+<h2 id="ShuttingDown">Shutting Down an Activity</h2>
+
+<p>You can shut down an activity by calling its {@link android.app.Activity#finish
+finish()} method. You can also shut down a separate activity that you previously started by calling
+{@link android.app.Activity#finishActivity finishActivity()}.</p>
+
+<p class="note"><strong>Note:</strong> In most cases, you should not explicitly finish an activity
+using these methods. As discussed in the following section about the activity lifecycle, the
+Android system manages the life of an activity for you, so you do not need to finish your own
+activities. Calling these methods could adversely affect the expected user
+experience and should only be used when you absolutely do not want the user to return to this
+instance of the activity.</p>
+
+
+<h2 id="Lifecycle">Managing the Activity Lifecycle</h2>
+
+<p>Managing the lifecycle of your activities by implementing callback methods is
+crucial to developing a strong
+and flexible application. The lifecycle of an activity is directly affected by its association with
+other activities, its task and back stack.</p>
+
+<p>An activity can exist in essentially three states:</p>
+
+<dl>
+  <dt><i>Resumed</i></dt>
+    <dd>The activity is in the foreground of the screen and has user focus. (This state is
+also sometimes referred to as "running".)</dd>
+
+  <dt><i>Paused</i></dt>
+    <dd>Another activity is in the foreground and has focus, but this one is still visible. That is,
+another activity is visible on top of this one and that activity is partially transparent or doesn't
+cover the entire screen. A paused activity is completely alive (the {@link android.app.Activity}
+object is retained in memory, it maintains all state and member information, and remains attached to
+the window manager), but can be killed by the system in extremely low memory situations.</dd>
+
+  <dt><i>Stopped</i></dt>
+    <dd>The activity is completely obscured by another activity (the activity is now in the
+"background"). A stopped activity is also still alive (the {@link android.app.Activity}
+object is retained in memory, it maintains all state and member information, but is <em>not</em>
+attached to the window manager). However, it is no longer visible to the user and it
+can be killed by the system when memory is needed elsewhere.</dd>
+</dl>
+
+<p>If an activity is paused or stopped, the system can drop it from memory either by asking it to
+finish (calling its {@link android.app.Activity#finish finish()} method), or simply killing its
+process.  When the activity is opened again (after being finished or killed), it must be created all
+over.</p>
+
+
+
+<h3 id="ImplementingLifecycleCallbacks">Implementing the lifecycle callbacks</h3>
+
+<p>When an activity transitions into and out of the different states described above, it is notified
+through various callback methods. All of the callback methods are hooks that you
+can override to do appropriate work when the state of your activity changes. The following skeleton
+activity includes each of the fundamental lifecycle methods:</p>
+
+
+<pre>
+public class ExampleActivity extends Activity {
+    &#64;Override
+    public void {@link android.app.Activity#onCreate onCreate}(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        // The activity is being created.
+    }
+    &#64;Override
+    protected void {@link android.app.Activity#onStart onStart()} {
+        super.onStart();
+        // The activity is about to become visible.
+    }
+    &#64;Override
+    protected void {@link android.app.Activity#onResume onResume()} {
+        super.onResume();
+        // The activity has become visible (it is now "resumed").
+    }
+    &#64;Override
+    protected void {@link android.app.Activity#onPause onPause()} {
+        super.onPause();
+        // Another activity is taking focus (this activity is about to be "paused").
+    }
+    &#64;Override
+    protected void {@link android.app.Activity#onStop onStop()} {
+        super.onStop();
+        // The activity is no longer visible (it is now "stopped")
+    }
+    &#64;Override
+    protected void {@link android.app.Activity#onDestroy onDestroy()} {
+        super.onDestroy();
+        // The activity is about to be destroyed.
+    }
+}
+</pre>
+
+<p class="note"><strong>Note:</strong> Your implementation of these lifecycle methods must
+always call the superclass implementation before doing any work, as shown in the examples above.</p>
+
+<p>Taken together, these methods define the entire lifecycle of an activity. By implementing these
+methods, you can monitor three nested loops in the activity lifecycle: </p>
+
+<ul>
+<li>The <b>entire lifetime</b> of an activity happens between the call to {@link
+android.app.Activity#onCreate onCreate()} and the call to {@link
+android.app.Activity#onDestroy}. Your activity should perform setup of
+"global" state (such as defining layout) in {@link android.app.Activity#onCreate onCreate()}, and
+release all remaining resources in {@link android.app.Activity#onDestroy}. For example, if your
+activity has a thread running in the background to download data from the network, it might create
+that thread in {@link android.app.Activity#onCreate onCreate()} and then stop the thread in {@link
+android.app.Activity#onDestroy}.</li>
+
+<li><p>The <b>visible lifetime</b> of an activity happens between the call to {@link
+android.app.Activity#onStart onStart()} and the call to {@link
+android.app.Activity#onStop onStop()}. During this time, the user can see the activity
+on-screen and interact with it. For example, {@link android.app.Activity#onStop onStop()} is called
+when a new activity starts and this one is no longer visible. Between these two methods, you can
+maintain resources that are needed to show the activity to the user. For example, you can register a
+{@link android.content.BroadcastReceiver} in {@link
+android.app.Activity#onStart onStart()} to monitor changes that impact your UI, and unregister
+it in {@link android.app.Activity#onStop onStop()} when the user can no longer see what you are
+displaying. The system might call {@link android.app.Activity#onStart onStart()} and {@link
+android.app.Activity#onStop onStop()} multiple times during the entire lifetime of the activity, as
+the activity alternates between being visible and hidden to the user.</p></li>
+
+<li><p>The <b>foreground lifetime</b> of an activity happens between the call to {@link
+android.app.Activity#onResume onResume()} and the call to {@link android.app.Activity#onPause
+onPause()}. During this time, the activity is in front of all other activities on screen and has
+user input focus.  An activity can frequently transition in and out of the foreground&mdash;for
+example, {@link android.app.Activity#onPause onPause()} is called when the device goes to sleep or
+when a dialog appears. Because this state can transition often, the code in these two methods should
+be fairly lightweight in order to avoid slow transitions that make the user wait.</p></li>
+</ul>
+
+<p>Figure 1 illustrates these loops and the paths an activity might take between states.
+The rectangles represent the callback methods you can implement to perform operations when
+the activity transitions between states. <p>
+
+<img src="{@docRoot}images/activity_lifecycle.png" alt="" />
+<p class="img-caption"><strong>Figure 1.</strong> The activity lifecycle.</p>
+
+<p>The same lifecycle callback methods are listed in table 1, which describes each of the callback
+methods in more detail and locates each one within the
+activity's overall lifecycle, including whether the system can kill the activity after the
+callback method completes.</p>
+
+<p class="table-caption"><strong>Table 1.</strong> A summary of the activity lifecycle's
+callback methods.</p>
+
+<table border="2" width="85%" frame="hsides" rules="rows">
+<colgroup align="left" span="3"></colgroup>
+<colgroup align="left"></colgroup>
+<colgroup align="center"></colgroup>
+<colgroup align="center"></colgroup>
+
+<thead>
+<tr><th colspan="3">Method</th> <th>Description</th> <th>Killable after?</th> <th>Next</th></tr>
+</thead>
+
+<tbody>
+<tr>
+  <td colspan="3" align="left"><code>{@link android.app.Activity#onCreate onCreate()}</code></td>
+  <td>Called when the activity is first created.
+      This is where you should do all of your normal static set up &mdash;
+      create views, bind data to lists, and so on.  This method is passed
+      a Bundle object containing the activity's previous state, if that
+      state was captured (see <a href="#actstate">Saving Activity State</a>,
+      later).
+      <p>Always followed by {@code onStart()}.</p></td>
+  <td align="center">No</td>
+      <td align="center">{@code onStart()}</td>
+</tr>
+
+<tr>
+   <td rowspan="5" style="border-left: none; border-right: none;">&nbsp;&nbsp;&nbsp;&nbsp;</td>
+   <td colspan="2" align="left"><code>{@link android.app.Activity#onRestart
+onRestart()}</code></td>
+   <td>Called after the activity has been stopped, just prior to it being
+       started again.
+       <p>Always followed by {@code onStart()}</p></td>
+   <td align="center">No</td>
+   <td align="center">{@code onStart()}</td>
+</tr>
+
+<tr>
+   <td colspan="2" align="left"><code>{@link android.app.Activity#onStart onStart()}</code></td>
+   <td>Called just before the activity becomes visible to the user.
+       <p>Followed by {@code onResume()} if the activity comes
+       to the foreground, or {@code onStop()} if it becomes hidden.</p></td>
+    <td align="center">No</td>
+    <td align="center">{@code onResume()} <br/>or<br/> {@code onStop()}</td>
+</tr>
+
+<tr>
+   <td rowspan="2" style="border-left: none;">&nbsp;&nbsp;&nbsp;&nbsp;</td>
+   <td align="left"><code>{@link android.app.Activity#onResume onResume()}</code></td>
+   <td>Called just before the activity starts
+       interacting with the user.  At this point the activity is at
+       the top of the activity stack, with user input going to it.
+       <p>Always followed by {@code onPause()}.</p></td>
+   <td align="center">No</td>
+   <td align="center">{@code onPause()}</td>
+</tr>
+
+<tr>
+   <td align="left"><code>{@link android.app.Activity#onPause onPause()}</code></td>
+   <td>Called when the system is about to start resuming another
+       activity.  This method is typically used to commit unsaved changes to
+       persistent data, stop animations and other things that may be consuming
+       CPU, and so on.  It should do whatever it does very quickly, because
+       the next activity will not be resumed until it returns.
+       <p>Followed either by {@code onResume()} if the activity
+       returns back to the front, or by {@code onStop()} if it becomes
+       invisible to the user.</td>
+   <td align="center"><strong style="color:#800000">Yes</strong></td>
+   <td align="center">{@code onResume()} <br/>or<br/> {@code onStop()}</td>
+</tr>
+
+<tr>
+   <td colspan="2" align="left"><code>{@link android.app.Activity#onStop onStop()}</code></td>
+   <td>Called when the activity is no longer visible to the user.  This
+       may happen because it is being destroyed, or because another activity
+       (either an existing one or a new one) has been resumed and is covering it.
+       <p>Followed either by {@code onRestart()} if
+       the activity is coming back to interact with the user, or by
+       {@code onDestroy()} if this activity is going away.</p></td>
+   <td align="center"><strong style="color:#800000">Yes</strong></td>
+   <td align="center">{@code onRestart()} <br/>or<br/> {@code onDestroy()}</td>
+</tr>
+
+<tr>
+   <td colspan="3" align="left"><code>{@link android.app.Activity#onDestroy
+onDestroy()}</code></td>
+   <td>Called before the activity is destroyed.  This is the final call
+       that the activity will receive.  It could be called either because the
+       activity is finishing (someone called <code>{@link android.app.Activity#finish
+       finish()}</code> on it), or because the system is temporarily destroying this
+       instance of the activity to save space.  You can distinguish
+       between these two scenarios with the <code>{@link
+       android.app.Activity#isFinishing isFinishing()}</code> method.</td>
+   <td align="center"><strong style="color:#800000">Yes</strong></td>
+   <td align="center"><em>nothing</em></td>
+</tr>
+</tbody>
+</table>
+
+<p>The column labeled "Killable after?" indicates whether or not the system can
+kill the process hosting the activity at any time <em>after the method returns</em>, without
+executing another line of the activity's code.  Three methods are marked "yes": ({@link
+android.app.Activity#onPause
+onPause()}, {@link android.app.Activity#onStop onStop()}, and {@link android.app.Activity#onDestroy
+onDestroy()}). Because {@link android.app.Activity#onPause onPause()} is the first
+of the three, once the activity is created, {@link android.app.Activity#onPause onPause()} is the
+last method that's guaranteed to be called before the process <em>can</em> be killed&mdash;if
+the system must recover memory in an emergency, then {@link
+android.app.Activity#onStop onStop()} and {@link android.app.Activity#onDestroy onDestroy()} might
+not be called. Therefore, you should use {@link android.app.Activity#onPause onPause()} to write
+crucial persistent data (such as user edits) to storage. However, you should be selective about
+what information must be retained during {@link android.app.Activity#onPause onPause()}, because any
+blocking procedures in this method block the transition to the next activity and slow the user
+experience.</p>
+
+<p> Methods that are marked "No" in the <b>Killable</b> column protect the process hosting the
+activity from being killed from the moment they are called.  Thus, an activity is killable
+from the time {@link android.app.Activity#onPause onPause()} returns to the time
+{@link android.app.Activity#onResume onResume()} is called. It will not again be killable until
+{@link android.app.Activity#onPause onPause()} is again called and returns. </p>
+
+<p class="note"><strong>Note:</strong> An activity that's not technically "killable" by this
+definition in table 1 might still be killed by the system&mdash;but that would happen only in
+extreme circumstances when there is no other recourse. When an activity might be killed is
+discussed more in the <a
+href="{@docRoot}guide/topics/fundamentals/processes-and-threading.html">Processes and
+Threading</a> document.</p>
+
+
+<h3 id="SavingActivityState">Saving activity state</h3>
+
+<p>The introduction to <a href="Lifecycle">Managing the Activity Lifecycle</a> briefly mentions that
+when an activity is paused or stopped, the state of the activity is retained. This is true because
+the {@link android.app.Activity} object is still held in memory when it is paused or
+stopped&mdash;all information about its members and current state is still alive. Thus, any changes
+the user made within the activity are retained in memory, so that when the activity returns to the
+foreground (when it "resumes"), those changes are still there.</p>
+
+<div class="figure" style="width:615px">
+<img src="{@docRoot}images/fundamentals/restore_instance.png" alt="" />
+<p class="img-caption"><strong>Figure 2.</strong> The two ways in which an activity returns to user
+focus with its state intact: either the activity is stopped, then resumed and the activity state
+remains intact (left), or the activity is destroyed, then recreated and the activity must restore
+the previous activity state (right).</p>
+</div>
+
+<p>However, when the system destroys an activity in order to recover memory, the {@link
+android.app.Activity} object is destroyed, so the system cannot simply resume it with its state
+intact. Instead, the system must recreate the {@link android.app.Activity} object if the user
+navigates back to it. Yet, the user is unaware
+that the system destroyed the activity and recreated it and, thus, probably
+expects the activity to be exactly as it was. In this situation, you can ensure that
+important information about the activity state is preserved by implementing an additional
+callback method that allows you to save information about the state of your activity and then
+restore it when the the system recreates the activity.</p>
+
+<p>The callback method in which you can save information about the current state of your activity is
+{@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}. The system calls this method
+before making the activity vulnerable to being destroyed and passes it
+a {@link android.os.Bundle} object. The {@link android.os.Bundle} is where you can store 
+state information about the activity as name-value pairs, using methods such as {@link
+android.os.Bundle#putString putString()}. Then, if the system kills your activity's
+process and the user navigates back to your activity, the system passes the {@link
+android.os.Bundle} to {@link android.app.Activity#onCreate onCreate()} so you can restore the
+activity state you saved during {@link android.app.Activity#onSaveInstanceState
+onSaveInstanceState()}. If there is no state information to restore, then the {@link
+android.os.Bundle} passed to {@link android.app.Activity#onCreate onCreate()} is null.</p>
+
+<p class="note"><strong>Note:</strong> There's no guarantee that {@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()} will be called before your
+activity is destroyed, because there are cases in which it won't be necessary to save the state
+(such as when the user leaves your activity using the BACK key, because the user is explicitly
+closing the activity). If the method is called, it is always called before {@link
+android.app.Activity#onStop onStop()} and possibly before {@link android.app.Activity#onPause
+onPause()}.</p>
+
+<p>However, even if you do nothing and do not implement {@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()}, some of the activity state is
+restored by the {@link android.app.Activity} class's default implementation of {@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()}. Specifically, the default
+implementation calls {@link
+android.view.View#onSaveInstanceState onSaveInstanceState()} for every {@link android.view.View}
+in the layout, which allows each view to provide information about itself
+that should be saved. Almost every widget in the Android framework implements this method as
+appropriate, such that any visible changes to the UI are automatically saved and restored when your
+activity is recreated. For example, the {@link android.widget.EditText} widget saves any text
+entered by the user and the {@link android.widget.CheckBox} widget saves whether it's checked or
+not. The only work required by you is to provide a unique ID (with the <a
+href="{@docRoot}guide/topics/resources/layout-resource.html#idvalue">{@code android:id}</a>
+attribute) for each widget you want to save its state. If a widget does not have an ID, then it
+cannot save its state.</p>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+<p>You can also explicitly stop a view in your layout from saving its state by setting the
+{@link android.R.attr#saveEnabled android:saveEnabled} attribute to {@code "false"} or by calling
+the {@link android.view.View#setSaveEnabled setSaveEnabled()} method. Usually, you should not
+disable this, but you might if you want to restore the state of the activity UI differently.</p>
+</div>
+</div>
+
+<p>Although the default implementation of {@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()} saves useful information about
+your activity's UI, you still might need to override it to save additional information.
+For example, you might need to save member values that changed during the activity's life (which
+might correlate to values restored in the UI, but the members that hold those UI values are not
+restored, by default).</p>
+
+<p>Because the default implementation of {@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()} helps save the state of the UI, if
+you override the method in order to save additional state information, you should always call the
+superclass implementation of {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}
+before doing any work.</p>
+
+<p class="note"><strong>Note:</strong> Because {@link android.app.Activity#onSaveInstanceState
+onSaveInstanceState()} is not guaranteed
+to be called, you should use it only to record the transient state of the activity (the state of
+the UI)&mdash;you should never use it to store persistent data.  Instead, you should use  {@link
+android.app.Activity#onPause onPause()} to store persistent data (such as data that should be saved
+to a database) when the user leaves the activity.</p>
+
+<p>A good way to test your application's ability to restore its state is to simply rotate the
+device so that the screen orientation changes. When the screen orientation changes, the system
+destroys and recreates the activity in order to apply alternative resources that might be available
+for the new orientation. For this reason alone, it's very important that your activity
+completely restores its state when it is recreated, because users regularly rotate the screen while
+using applications.</p>
+
+
+<h3 id="ConfigurationChanges">Handling configuration changes</h3>
+
+<p>Some device configurations can change during runtime (such as screen orientation, keyboard
+availability, and language). When such a change occurs, Android restarts the running Activity
+({@link android.app.Activity#onDestroy} is called, followed immediately by {@link
+android.app.Activity#onCreate onCreate()}). The restart behavior is
+designed to help your application adapt to new configurations by automatically reloading your
+application with alternative resources that you've provided. If you design your activity to
+properly handle this event, it will be more resilient to unexpected events in the activity
+lifecycle.</p>
+
+<p>The best way to handle a configuration change, such as a change in the screen orientation, is
+  to simply preserve the state of your application using {@link
+  android.app.Activity#onSaveInstanceState onSaveInstanceState()} and {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} (or {@link
+android.app.Activity#onCreate onCreate()}), as discussed in the previous section.</p>
+
+<p>For a detailed discussion about configuration changes that happen at runtime and how you should
+handle them, read <a href="{@docRoot}guide/topics/resources/runtime-changes.html">Handling
+Runtime Changes</a>.</p>
+
+
+
+<h3 id="CoordinatingActivities">Coordinating activities</h3>
+
+ <p>When one activity starts another, they both experience lifecycle transitions. The first activity
+pauses and stops (though, it won't stop if it's still visible in the background), while the other
+activity is created. In case these activities share data saved to disc or elsewhere, it's important
+to understand that the first activity is not completely stopped before the second one is created.
+Rather, the process of starting the second one overlaps with the process of stopping the first
+one.</p>
+
+<p>The order of lifecycle callbacks is well defined, particularly when the two activities are in the
+same process and one is starting the other. Here's the order of operations that occur when Activity
+A starts Acivity B: </p>
+
+<ol>
+<li>Activity A's {@link android.app.Activity#onPause onPause()} method executes.</li>
+
+<li>Activity B's {@link android.app.Activity#onCreate onCreate()}, {@link
+android.app.Activity#onStart onStart()}, and {@link android.app.Activity#onResume onResume()}
+methods execute in sequence. (Activity B now has user focus.)</li>
+
+<li>Then, if Activity A is no longer visible on screen, its {@link
+android.app.Activity#onStop onStop()} method executes.</li>
+</ol>
+
+ <p>This predictable sequence of lifecycle callbacks allows you to manage the transition of
+information from one activity to another. For example, if you must write to a database when the
+first activity stops so that the following activity can read it, then you should write to the
+database during {@link android.app.Activity#onPause onPause()} instead of during {@link
+android.app.Activity#onStop onStop()}.</p>
+
+
+<h2>Beginner's Path</h2>
+
+<p>For more information about how Android maintains a history of activities and
+enables user multitasking, continue with the <b><a
+href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back
+Stack</a></b> document.</p>
diff --git a/docs/html/guide/topics/fundamentals/tasks-and-back-stack.jd b/docs/html/guide/topics/fundamentals/tasks-and-back-stack.jd
new file mode 100644
index 0000000..47dc5471
--- /dev/null
+++ b/docs/html/guide/topics/fundamentals/tasks-and-back-stack.jd
@@ -0,0 +1,568 @@
+page.title=Tasks and Back Stack
+parent.title=Application Fundamentals
+parent.link=index.html
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+<h2>Quickview</h2>
+<ul>
+  <li>All activities belong to a task</li>
+  <li>A task contains a collection of activities in the order in which the user interacts with
+them</li>
+  <li>Tasks can move to the background and retain the state of each activity in order for the user
+to perform other tasks without loosing their work</li>
+</ul>
+
+<h2>In this document</h2>
+<ol>
+<li><a href="#ActivityState">Saving Activity State</a></li></li>
+<li><a href="#ManagingTasks">Managing Tasks</a>
+  <ol>
+    <li><a href="#TaskLaunchModes">Defining launch modes</a></li>
+    <li><a href="#Affinities">Handling affinities</a></li>
+    <li><a href="#Clearing">Clearing the back stack</a></li>
+    <li><a href="#Starting">Starting a task</a></li>
+  </ol>
+</li>
+</ol>
+
+<h2>See also</h2>
+<ol>
+  <li><a><a href="{@docRoot}videos/index.html#v=fL6gSd4ugSI">Application Lifecycle video</a></li>
+  <li><a
+href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;} manifest
+element</a></li>
+</ol>
+</div>
+</div>
+
+
+<p>An application usually contains multiple <a
+href="{@docRoot}guide/topics/fundamentals/activities.html">activities</a>. Each activity
+should be designed around a specific kind of action the user can perform and can start other
+activities. For example, an email application might have one activity to show a list of new email.
+When the user selects an email, a new activity opens to view that email.</p>
+
+<p>An activity can even start activities that exist in other applications on the device. For
+example, if your application wants to send an email, you can define an intent to perform a "send"
+action and include some data, such as an email address and a message. An activity from another
+application that declares itself to handle this kind of intent then opens. In this case, the intent
+is to send an email, so an email application's "compose" activity starts (if multiple activities
+support the same intent, then the system lets the user select which one to use). When the email is
+sent, your activity resumes and it seems as if the email activity was part of your application. Even
+though the activities may be from different applications, Android maintains this seamless user
+experience by keeping both activities in the same <em>task</em>.</p>
+
+<p>A task is a collection of activities that users interact with
+when performing a certain job. The activities are arranged in a stack (the "back stack"), in the
+order in which each activity is opened.</p>
+
+<!-- SAVE FOR WHEN THE FRAGMENT DOC IS ADDED
+<div class="sidebox-wrapper">
+<div class="sidebox">
+<h3>Adding fragments to a task's back stack</h3>
+
+<p>Your activity can also include {@link android.app.Fragment}s to the back stack. For example,
+suppose you have a two-pane layout using fragments, one of which is a list view (fragment A) and the
+other being a layout to display an item from the list (fragment B). When the user selects an item
+from the list, fragment B is replaced by a new fragment (fragment C). In this case, it might be
+desireable for the user to navigate back to reveal fragment B, using the BACK key.</p>
+<p>In order to add fragment B to the back stack so that this is possible, you must call {@link
+android.app.FragmentTransaction#addToBackStack addToBackStack()} before you {@link
+android.app.FragmentTransaction#commit()} the transaction that replaces fragment B with fragment
+C.</p>
+<p>For more information about using fragments and adding them to the back stack, see the {@link
+android.app.Fragment} class documentation.</p>
+
+</div>
+</div>
+-->
+
+<p>The device Home screen is the starting place for most tasks. When the user touches an icon in the
+application
+launcher (or a shortcut on the Home screen), that application's task comes to the foreground. If no
+task exists for the application (the application has not been used recently), then a new task
+is created and the "main" activity for that application opens as the root activity in the stack.</p>
+
+<p>When the current activity starts another, the new activity is pushed on the top of the stack and
+takes focus. The previous activity remains in the stack, but is stopped. When an activity
+stops, the system retains the current state of its user interface. When the user presses the BACK
+key, the current activity is popped from the top of the stack (the activity is destroyed) and the
+previous activity resumes (the previous state of its UI is restored). Activities in the stack are
+never rearranged, only pushed and popped from the stack&mdash;pushed onto the stack when started by
+the current activity and popped off when the user leaves it using the BACK key. As such, the back
+stack operates as a "last in, first out" object structure. Figure 1 visualizes
+this behavior with a timeline showing the progress between activities along with the current back
+stack at each point in time.</p>
+
+<img src="{@docRoot}images/fundamentals/diagram_backstack.png" alt="" />
+<p class="img-caption"><strong>Figure 1.</strong> A representation of how each new activity in a
+task adds an item to the back stack. When the user presses the BACK key, the current activity is
+destroyed and the previous activity resumes.</p>
+
+
+<p>If the user continues to press BACK, then each activity in the stack is popped off to reveal the
+previous one, until the user returns to the Home screen (or to whichever activity was running when
+the task began). When all activities are removed from the stack, the task no longer exists.</p>
+
+<div class="figure" style="width:369px">
+<img src="{@docRoot}images/fundamentals/diagram_multitasking.png" alt="" /> <p
+class="img-caption"><strong>Figure 2.</strong> Two tasks: Task A is in the background, waiting
+to be resumed, while Task B receives user interaction in the foreground.</p>
+</div>
+<div class="figure" style="width:178px">
+  <img src="{@docRoot}images/fundamentals/diagram_multiple_instances.png" alt="" /> <p
+class="img-caption"><strong>Figure 3.</strong> A single activity is instantiated multiple times.</p>
+</div>
+
+<p>A task is a cohesive unit that can move to the "background" when users begin a new task or go
+to the Home screen, via the HOME key. While in the background, all the activities in the task are
+stopped, but the back stack for the task remains intact&mdash;the task has simply lost focus while
+another task takes place, as shown in figure 2. A task can then return to the "foreground" so users
+can pick up where they left off. Suppose, for example, that the current task (Task A) has three
+activities in its stack&mdash;two under the current activity. The user presses the HOME key, then
+starts a new application from the application launcher. When the Home screen appears, Task A goes
+into the background. When the new application starts, the system starts a task for that application
+(Task B) with its own stack of activities. After interacting with
+that application, the user returns Home again and selects the application that originally
+started Task A. Now, Task A comes to the
+foreground&mdash;all three activities in its stack are intact and the activity at the top of the
+stack resumes. At
+this point, the user can also switch back to Task B by going Home and selecting the application icon
+that started that task (or by touching and holding the HOME key to reveal recent tasks and selecting
+one). This is an example of multitasking on Android.</p>
+
+<p class="note"><strong>Note:</strong> Multiple tasks can be held in the background at once.
+However, if the user is running many background tasks at the same time, the system might begin
+destroying background activities in order to recover memory, causing the activity states to be lost.
+See the following section about <a href="#ActivityState">Activity state</a>.</p>
+
+<p>Because the activities in the back stack are never rearranged, if your application allows
+users to start a particular activity from more than one activity, a new instance of
+that activity is created and popped onto the stack (rather than bringing any previous instance of
+the activity to the top). As such, one activity in your application might be instantiated multiple
+times (even from different tasks), as shown in figure 3. As such, if the user navigates backward
+using the BACK key, each instance of the activity is revealed in the order they were opened (each
+with their own UI state). However, you can modify this behavior if you do not want an activity to be
+instantiated more than once. How to do so is discussed in the later section about <a
+href="#ManagingTasks">Managing Tasks</a>.</p>
+
+
+<p>To summarize the default behavior for activities and tasks:</p>
+
+<ul>
+  <li>When Activity A starts Activity B, Activity A is stopped, but the system retains its state
+(such as scroll position and text entered into forms).
+If the user presses the BACK key while in Activity B, Activity A resumes with its state
+restored.</li>
+  <li>When the user leaves a task by pressing the HOME key, the current activity is stopped and
+its task goes into the background. The system retains the state of every activity in the task. If
+the user later resumes the task by selecting the launcher icon that began the task, the task comes
+to the foreground and resumes the activity at the top of the stack.</li>
+  <li>If the user presses the BACK key, the current activity is popped from the stack and
+destroyed. The previous activity in the stack is resumed. When an activity is destroyed, the system
+<em>does not</em> retain the activity's state.</li>
+  <li>Activities can be instantiated multiple times, even from other tasks.</li>
+</ul>
+
+
+<h2 id="ActivityState">Saving Activity State</h2>
+
+<p>As discussed above, the system's default behavior preserves the state of an activity when it is
+stopped. This way, when users navigate back to a previous activity, its user interface appears
+the way they left it. However, you can&mdash;and <strong>should</strong>&mdash;proactively retain
+the state of your activities using callback methods, in case the activity is destroyed and must
+be recreated.</p>
+
+<p>When the system stops one of your activities (such as when a new activity starts or the task
+moves to the background), the system might destroy that activity completely if it needs to recover
+system memory. When this happens, information about the activity state is lost. If this happens, the
+system still
+knows that the activity has a place in the back stack, but when the activity is brought to the
+top of the stack the system must recreate it (rather than resume it). In order to
+avoid loosing the user's work, you should proactively retain it by implementing the {@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()} callback
+methods in your activity.</p>
+
+<p>For more information about how to save your activity state, see the <a
+href="{@docRoot}guide/topics/fundamentals/activities.html#SavingActivityState">Activities</a>
+document.</p>
+
+
+
+<h2 id="ManagingTasks">Managing Tasks</h2>
+
+<p>The way Android manages tasks and the back stack, as described above&mdash;by placing all
+activities started in succession in the same task and in a "last in, first out" stack&mdash;works
+great for most applications and you shouldn't have to worry about how your activities are associated
+with tasks or how they exist in the back stack. However, you might decide that you want to interrupt
+the normal behavior. Perhaps you want an activity in your application to begin a new task when it is
+started (instead of being placed within the current task); or, when you start an activity, you want
+to bring forward an existing instance of it (instead of creating a new
+instance on top of the back stack); or, you want your back stack to be cleared of all
+activitiesstart an activity except for the root activity when the user leaves the task.</p>
+
+<p>You can do these things and more, with attributes in the
+<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
+&lt;activity&gt;}</a> manifest element and with flags in the intent that you pass to {@link
+android.app.Activity#startActivity startActivity()}.</p>
+
+<p>In this regard, the the principal <a
+href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a>
+attributes you can use are:</p>
+
+<ul class="nolist">
+  <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code
+taskAffinity}</a></li>
+  <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code
+launchMode}</a></li>
+  <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#reparent">{@code
+allowTaskReparenting}</a></li>
+  <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#clear">{@code
+clearTaskOnLaunch}</a></li>
+  <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#always">{@code
+alwaysRetainTaskState}</a></li>
+  <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#finish">{@code
+finishOnTaskLaunch}</a></li>
+</ul>
+
+<p>And the principal intent flags you can use are:</p>
+
+<ul class="nolist">
+  <li>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</li>
+  <li>{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}</li>
+  <li>{@link android.content.Intent#FLAG_ACTIVITY_SINGLE_TOP}</li>
+</ul>
+
+<p>In the following sections, you'll see how you can use these manifest attributes and intent
+flags to define how activities are associated with tasks and how the behave in the back stack.</p>
+
+
+<p class="caution"><strong>Caution:</strong> Most applications should not interrupt the default
+behavior for activities and tasks. If you determine that it's necessary for your activity to modify
+the default behaviors, use caution and be sure to test the usability of the activity during
+launch and when navigating back to it from other activities and tasks with the BACK key. Be sure 
+to test for navigation behaviors that might conflict with the user's expected behavior.</p>
+
+
+<h3 id="TaskLaunchModes">Defining launch modes</h3>
+
+<p>Launch modes allow you to define how a new instance of an activity is associated with the
+current task. You can define different launch modes in two ways:</p>
+<ul class="nolist">
+  <li><a href="#ManifestForTasks">Using the manifest file</a>
+    <p>When you declare an activity in your manifest file, you can specify how the activity
+should associate with tasks when it starts.</li>
+  <li><a href="#IntentFlagsForTasks">Using Intent flags</a>
+    <p>When you call {@link android.app.Activity#startActivity startActivity()},
+you can include a flag in the {@link android.content.Intent} that declares how (or
+whether) the new activity should associate with the current task.</p></li>
+</ul>
+
+<p>As such, if Activity A starts Activity B, Activity B can define in its manifest how it
+should associate with the current task (if at all) and Activity A can also request how Activity
+B should associate with current task. If both activities define how Activity B
+should associate with a task, then Activity A's request (as defined in the intent) is honored
+over Activity B's request (as defined in its manifest).</p>
+
+<p class="note"><strong>Note:</strong> Some the launch modes available in the manifest
+are not available as flags for an intent and, likewise, some launch modes available as flags
+for an intent cannot be defined in the manifest.</p>
+
+
+<h4 id="ManifestForTasks">Using the manifest file</h4>
+
+<p>When declaring an activity in your manifest file, you can specify how the activity should
+associate with a task using the <a
+href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a>
+element's <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code
+launchMode}</a> attribute.</p>
+
+<p>The <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code
+launchMode}</a> attribute specifies an instruction on how the activity should be launched into a
+task. There are four different launch modes you can assign to the
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">launchMode</a></code>
+attribute:</p>
+
+<dl>
+<dt>{@code "standard"} (the default mode)</dt>
+  <dd>Default. The system creates a new instance of the activity in the task from
+which it was started and routes the intent to it. The activity can be instantiated multiple times,
+each instance can belong to different tasks, and one task can have multiple instances.</dd>
+<dt>{@code "singleTop"}</dt>
+  <dd>If an instance of the activity already exists at the top of the current task, the system
+routes the intent to that instance through a call to its {@link
+android.app.Activity#onNewIntent onNewIntent()} method, rather than creating a new instance of the
+activity. The activity can be instantiated multiple times, each instance can
+belong to different tasks, and one task can have multiple instances (but only if the the
+activity at the top of the back stack is <em>not</em> an existing instance of the activity).
+  <p>For example, suppose a task's back stack consists of root activity A with activities B, C,
+and D on top (the stack is A-B-C-D; D is on top). An intent arrives for an activity of type D.
+If D has the default {@code "standard"} launch mode, a new instance of the class is launched and the
+stack becomes A-B-C-D-D. However, if D's launch mode is {@code "singleTop"}, the existing instance
+of D is deliverd the intent through {@link
+android.app.Activity#onNewIntent onNewIntent()}, because it's at the top of the stack&mdash;the
+stack remains A-B-C-D. However, if an intent arrives for an activity of type B, then a new
+instance of B is added to the stack, even if its launch mode is {@code "singleTop"}.</p>
+  <p class="note"><strong>Note:</strong> When a new instance of an activity is created,
+the user can press the BACK key to return to the previous activity. But when an existing instance of
+an activity handles a new intent, the user cannot press the BACK key to return to the state of
+the activity before the new intent arrived in {@link android.app.Activity#onNewIntent
+onNewIntent()}.</p>
+</dd>
+
+<dt>{@code "singleTask"}</dt>
+  <dd>The system creates a new task and instantiates the activity at the root of the new task.
+However, if an instance of the activity already exists in a separate task, the system routes the
+intent to the existing instance through a call to its {@link
+android.app.Activity#onNewIntent onNewIntent()} method, rather than creating a new instance. Only
+one instance of the activity can exist at a time.
+  <p class="note"><strong>Note:</strong> Although the activity starts in a new task, the
+BACK key still returns the user to the previous activity.</p></dd>
+<dt>{@code "singleInstance"}.</dt>
+  <dd>Same as {@code "singleTask"}, except that the system doesn't launch any other activities into
+the task holding the instance. The activity is always the single and only member of its task;
+any activities started by this one open in a separate task.</dd>
+</dl>
+
+
+<p>As another example, the Android Browser application declares that the web browser activity should
+always open in its own task&mdash;by specifying the {@code singleTask} launch mode in the <a
+href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a> element.
+This means that if your application issues an
+intent to open the Android Browser, its activity is <em>not</em> placed in the same
+task as your application. Instead, either a new task starts for the Browser or, if the Browser
+already has a task running in the background, that task is brought forward to handle the new
+intent.</p>
+
+<p>Regardless of whether an activity starts in a new task or in the same task as the activity that
+started it, the BACK key always takes the user to the previous activity. However, if you
+start an activity from your task (Task A) that specifies the {@code singleTask} launch mode, then
+that activity might have an instance in the background that belongs to a task with its own back
+stack (Task B). In this
+case, when Task B is brought forward to handle a new intent, the BACK key first navigates
+backward through the activities in Task B before returning to
+the top-most activity in Task A. Figure 4 visualizes this type of scenario.</p>
+
+<img src="{@docRoot}images/fundamentals/diagram_backstack_singletask_multiactivity.png" alt="" />
+<p class="img-caption"><strong>Figure 4.</strong> A representation of how an activity with
+launch mode "singleTask" is added to the back stack. If the activity is already a part of a
+background task with its own back stack (Task B), then the entire back stack also comes
+forward, on top of the current task (Task A).</p>
+
+<p>For more information about using launch modes in the manifest file, see the
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+element documentation, where the {@code launchMode} attribute and the accepted values are
+discussed more.</p>
+
+<p class="note"><strong>Note:</strong> The behaviors that you specify for your activity with the <a
+href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> attribute
+can be overriden by flags included with the intent that start your activity, as discussed in the
+next section.</p>
+
+
+
+<h4 id="#IntentFlagsForTasks">Using Intent flags</h4>
+
+<p>When starting an activity, you can modify the default association of an activity to its task
+by including flags in the intent that you deliver to {@link
+android.app.Activity#startActivity startActivity()}. The flags you can use to modify the
+default behavior are:</p>
+
+<p>
+  <dt>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</dt>
+    <dd>Start the activity in a new task. If a task is already running for the activity you are now
+starting, that task is brought to the foreground with its last state restored and the activity
+receives the new intent in {@link android.app.Activity#onNewIntent onNewIntent()}. 
+    <p>This produces the same behavior as the {@code "singleTask"} <a
+href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> value,
+discussed in the previous section.</p></dd>
+  <dt>{@link android.content.Intent#FLAG_ACTIVITY_SINGLE_TOP}</dt>
+    <dd>If the activity being started is the current activity (at the top of the back stack), then
+the existing instance receives a call to {@link android.app.Activity#onNewIntent onNewIntent()},
+instead of creating a new instance of the activity.
+    <p>This produces the same behavior as the {@code "singleTop"} <a
+href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> value,
+discussed in the previous section.</p></dd>
+  <dt>{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}</dt>
+    <dd>If the activity being started is already running in the current task, then instead
+of launching a new instance of that activity, all of the other activities on top of it are
+destroyed and this intent is delivered to the resumed instance of the activity (now on top),
+through {@link android.app.Activity#onNewIntent onNewIntent()}).
+    <p>There is no value for the <a
+href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a>
+attribute that produces this behavior.</p>
+    <p>{@code FLAG_ACTIVITY_CLEAR_TOP} is most often used in conjunction with {@code
+FLAG_ACTIVITY_NEW_TASK}.  When used together, these flags are a way of locating an existing activity
+in another task and putting it in a position where it can respond to the intent. </p>
+    <p class="note"><strong>Note:</strong> If the launch mode of the designated activity is {@code
+"standard"}, it too is removed from the stack and a new instance is launched in its place to handle
+the incoming intent.  That's because a new instance is always created for a new intent when the
+launch mode is {@code "standard"}. </p>
+</dd>
+</dl>
+
+
+
+
+
+<h3 id="Affinities">Handling affinities</h3>
+
+<p>The <em>affinity</em> indicates which task an activity prefers to belong to. By default, all the
+activities from the same application have an affinity for each other. So, by default, all
+activities in the same application prefer to be in the same task. However, you can modify
+the default affinity for an activity. Activities defined in
+different applications can share an affinity, or activities defined in the same application can be
+assigned different task affinities.</p>
+
+<p>You can modify the affinity for any given activity with the <a
+href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a> attribute
+of the <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a>
+element.</p>
+
+<p>The <a
+href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a>
+attribute takes a string value, which must be unique from the default package name
+declared in the <a href="{@docRoot}guide/topics/manifest/manifest-element.html">{@code
+&lt;manifest&gt;}</a> element, because the system uses that name to identify the default task
+affinity for the application.</p>
+
+<p>The affinity comes into play in two circumstances:</p>
+<ul>
+  <li>When the intent that launches an activity contains the {@link
+android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag.
+
+<p>A new activity is, by default, launched into the task of the activity
+that called {@link android.app.Activity#startActivity startActivity()}. It's pushed onto the same
+back stack as the caller.  However, if the intent passed to {@link
+android.app.Activity#startActivity startActivity()} contains the {@link
+android.content.Intent#FLAG_ACTIVITY_NEW_TASK}
+flag, the system looks for a different task to house the new activity. Often, it's a new task. 
+However, it doesn't have to be.  If there's already an existing task with the same affinity as the
+new activity, the activity is launched into that task.  If not, it begins a new task.</p>
+
+<p>If this flag causes an activity to begin a new task and the user presses the HOME key to leave
+it, there must be some way for the user to navigate back to the task. Some entities (such as the
+notification manager) always start activities in an external task, never as part of their own, so
+they always put {@code FLAG_ACTIVITY_NEW_TASK} in the intents they pass to {@link
+android.app.Activity#startActivity startActivity()}.  If you have an activity that can be invoked by
+an external entity that might use this flag, take care that the user has a independent way to get
+back to the task that's started, such as with a launcher icon (the root activity of the task
+has a {@link android.content.Intent#CATEGORY_LAUNCHER} intent filter; see the <a
+href="#Starting">Starting a task</a> section below).</p>
+</li>
+
+  <li>When an activity has its <a
+href="{@docRoot}guide/topics/manifest/activity-element.html#reparent">{@code
+allowTaskReparenting}</a> attribute set to {@code "true"}.
+  <p>In this case, the activity can move from the task it starts to the task it has an affinity
+for, when that task comes to the foreground.</p>
+  <p>For example, suppose that an activity that reports weather conditions in selected cities is
+defined as part of a travel application.  It has the same affinity as other activities in the same
+application (the default application affinity) and it allows re-parenting with this attribute.
+When one of your activities starts the weather reporter activity, it initially belongs to the same
+task as your activity. However, when the travel application's task comes to the foreground, the
+weather reporter activity is reassigned to that task and displayed within it.</p>
+</li>
+</ul>
+
+<p class="note"><strong>Tip:</strong> If an {@code .apk} file contains more than one "application"
+from the user's point of view, you probably want to use the <a
+href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a>
+attribute to assign different affinities to the activities associated with each "application".</p>
+
+
+
+<h3 id="Clearing">Clearing the back stack</h3>
+
+<p>If the user leaves a task for a long time, the system clears the task of all activities except
+the root activity.  When the user returns to the task again, only the root activity is restored.
+The system behaves this way, because, after an extended amount of time, users likely have abandoned
+what they were doing before and are returning to the task to begin something new. </p>
+
+<p>There are some activity attributes that you can use to modify this behavior: </p>
+
+<dl>
+<dt><code><a
+href="{@docRoot}guide/topics/manifest/activity-element.html#always">alwaysRetainTaskState</a></code>
+</dt>
+<dd>If this attribute is set to {@code "true"} in the root activity of a task,
+the default behavior just described does not happen.
+The task retains all activities in its stack even after a long period.</dd>
+
+<dt><code><a
+href="{@docRoot}guide/topics/manifest/activity-element.html#clear">clearTaskOnLaunch</a></code></dt>
+<dd>If this attribute is set to {@code "true"} in the root activity of a task,
+the stack is cleared down to the root activity whenever the user leaves the task
+and returns to it.  In other words, it's the opposite of <a
+href="{@docRoot}guide/topics/manifest/activity-element.html#always">{@code
+alwaysRetainTaskState}</a>.  The user always returns to the task in its
+initial state, even after a leaving the task for only a moment.</dd>
+
+<dt><code><a
+href="{@docRoot}guide/topics/manifest/activity-element.html#finish">finishOnTaskLaunch</a></code>
+</dt>
+<dd>This attribute is like <a
+href="{@docRoot}guide/topics/manifest/activity-element.html#clear">{@code clearTaskOnLaunch}</a>,
+but it operates on a
+single activity, not an entire task.  It can also cause any activity to go
+away, including the root activity.  When it's set to {@code "true"}, the
+activity remains part of the task only for the current session.  If the user
+leaves and then returns to the task, it is no longer present.</dd>
+</dl>
+
+
+
+
+<h3 id="Starting">Starting a task</h3>
+
+<p>You can set up an activity as the entry point for a task by giving it an intent filter with
+{@code "android.intent.action.MAIN"} as the specified action and {@code
+"android.intent.category.LAUNCHER"} as the specified category. For example:</p>
+
+<pre>
+&lt;activity ... &gt;
+    &lt;intent-filter ... &gt;
+        &lt;action android:name="android.intent.action.MAIN" /&gt;
+        &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
+    &lt;/intent-filter&gt;
+    ...
+&lt;/activity&gt;
+</pre>
+
+<p>An intent filter of this kind causes an icon and label for the
+activity to be displayed in the application launcher, giving users a way to launch the activity and
+to return to the task that it creates any time after it has been launched.
+</p>
+
+<p>This second ability is important: Users must be able to leave a task and then come back to it
+later using this activity launcher.  For this reason, the two <a href="#LaunchModes">launch
+modes</a> that mark activities as always initiating a task, {@code "singleTask"} and "{@code
+"singleInstance"}, should be used only when the activity has an {@link
+android.content.Intent#ACTION_MAIN}
+and a {@link android.content.Intent#CATEGORY_LAUNCHER}
+filter. Imagine, for example, what could happen if the filter is missing: An intent launches a
+{@code "singleTask"} activity, initiating a new task, and the user spends some time working in
+that task.  The user then presses the HOME key. The task is now sent to the background and not
+visible. Because it is not represented in the application launcher, the user has no way to return to
+the task.
+</p>
+
+<p>For those cases where you don't want the user to be able to return to an activity, set the
+  <code><a
+href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code> element's
+<a href="{@docRoot}guide/topics/manifest/activity-element.html#finish">{@code
+finishOnTaskLaunch}</a> to {@code "true"} (see <a
+href="#Clearing">Clearing the stack</a>).</p>
+
+
+
+
+<h2>Beginner's Path</h2>
+
+<p>For more information about how to use intents to
+activate other application components and publish the intents to which your components
+respond, continue with the <b><a
+href="{@docRoot}guide/topics/intents/intents-filters.html">Intents and Intent
+Filters</a></b> document.</p>
diff --git a/docs/html/guide/topics/intents/intents-filters.jd b/docs/html/guide/topics/intents/intents-filters.jd
index bd1d694..5905214 100644
--- a/docs/html/guide/topics/intents/intents-filters.jd
+++ b/docs/html/guide/topics/intents/intents-filters.jd
@@ -3,15 +3,6 @@
 
 <div id="qv-wrapper">
 <div id="qv">
-<h2>Key classes</h2>
-<ol>
-<li>{@link android.content.Intent}</li>
-<li>{@link android.content.IntentFilter}</li>
-<li>{@link android.app.Activity}</li>
-<li>{@link android.app.Service}</li>
-<li>{@link android.content.BroadcastReceiver}</li>
-<li>{@link android.content.pm.PackageManager}</li>
-</ol>
 
 <h2>In this document</h2>
 <ol>
@@ -22,6 +13,15 @@
 <li style="margin-left: 2em"><a href="#imatch">Using intent matching</a></li>
 <li><a href="#npex">Note Pad Example</a></li>
 </ol>
+
+<h2>Key classes</h2>
+<ol>
+<li>{@link android.content.Intent}</li>
+<li>{@link android.content.IntentFilter}</li>
+<li>{@link android.content.BroadcastReceiver}</li>
+<li>{@link android.content.pm.PackageManager}</li>
+</ol>
+
 </div>
 </div>
 
diff --git a/docs/html/guide/topics/media/index.jd b/docs/html/guide/topics/media/index.jd
index 96c500c..558d453 100644
--- a/docs/html/guide/topics/media/index.jd
+++ b/docs/html/guide/topics/media/index.jd
@@ -4,7 +4,7 @@
     <div id="qv-wrapper">
     <div id="qv">
 
-<h2>Audio/Video quickview</h2>
+<h2>Quickview</h2>
 <ul>
 <li>Audio playback and record</li>
 <li>Video playback</li>
@@ -12,14 +12,6 @@
 <li>Built-in codecs for a variety of media. See <a href="{@docRoot}guide/appendix/media-formats.html">Android Supported Media Formats</a></li>
 </ul>
 
-<h2>Key classes</h2>
-<ol>
-<li>{@link android.media.MediaPlayer MediaPlayer} (all available formats)</li>
-<li>{@link android.media.MediaRecorder MediaRecorder} (all available formats)</li>
-<li>{@link android.media.JetPlayer JetPlayer} (playback, JET content)</li>
-<li>{@link android.media.SoundPool SoundPool} (sound management)</li>
-</ol>
-
 <h2>In this document</h2>
 <ol>
 <li><a href="#playback.html">Audio and Video Playback</a>
@@ -32,6 +24,14 @@
 <li><a href="#capture">Audio Capture</a></li>
 </ol>
 
+<h2>Key classes</h2>
+<ol>
+<li>{@link android.media.MediaPlayer MediaPlayer}</li>
+<li>{@link android.media.MediaRecorder MediaRecorder}</li>
+<li>{@link android.media.JetPlayer JetPlayer}</li>
+<li>{@link android.media.SoundPool SoundPool}</li>
+</ol>
+
 <h2>See also</h2>
 <ol>
 <li><a href="{@docRoot}guide/topics/data/data-storage.html">Data Storage</a></li>
diff --git a/docs/html/guide/topics/providers/content-providers.jd b/docs/html/guide/topics/providers/content-providers.jd
index da4e7a1..2aed5e1 100644
--- a/docs/html/guide/topics/providers/content-providers.jd
+++ b/docs/html/guide/topics/providers/content-providers.jd
@@ -3,12 +3,6 @@
 
 <div id="qv-wrapper">
 <div id="qv">
-<h2>Key classes</h2>
-<ol>
-<li>{@link android.content.ContentProvider}</li>
-<li>{@link android.content.ContentResolver}</li>
-<li>{@link android.database.Cursor}</li>
-</ol>
 
 <h2>In this document</h2>
 <ol>
@@ -18,6 +12,13 @@
 <li><a href="#creating">Creating a content provider</a></li>
 <li><a href="#urisum">Content URI summary</a></li>
 </ol>
+
+<h2>Key classes</h2>
+<ol>
+<li>{@link android.content.ContentProvider}</li>
+<li>{@link android.content.ContentResolver}</li>
+<li>{@link android.database.Cursor}</li>
+</ol>
 </div>
 </div>
 
diff --git a/docs/html/guide/topics/search/adding-custom-suggestions.jd b/docs/html/guide/topics/search/adding-custom-suggestions.jd
index ce0c619..c8f06b9 100644
--- a/docs/html/guide/topics/search/adding-custom-suggestions.jd
+++ b/docs/html/guide/topics/search/adding-custom-suggestions.jd
@@ -33,7 +33,7 @@
 <li>{@link android.content.ContentProvider}</li>
 </ol>
 
-<h2>Related Samples</h2>
+<h2>Related samples</h2>
 <ol>
 <li><a href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable
 Dictionary</a></li>
diff --git a/docs/html/guide/topics/search/index.jd b/docs/html/guide/topics/search/index.jd
index 78e0be2..f563715 100644
--- a/docs/html/guide/topics/search/index.jd
+++ b/docs/html/guide/topics/search/index.jd
@@ -13,7 +13,7 @@
 <ol>
 <li><a href="searchable-config.html">Searchable Configuration</a></li>
 </ol>
-<h2>Related Samples</h2>
+<h2>Related samples</h2>
 <ol>
 <li><a href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable
 Dictionary</a></li>
diff --git a/docs/html/guide/topics/search/search-dialog.jd b/docs/html/guide/topics/search/search-dialog.jd
index 49c6627..49938b4 100644
--- a/docs/html/guide/topics/search/search-dialog.jd
+++ b/docs/html/guide/topics/search/search-dialog.jd
@@ -29,7 +29,7 @@
 <li>{@link android.app.SearchManager}</li>
 </ol>
 
-<h2>Related Samples</h2>
+<h2>Related samples</h2>
 <ol>
 <li><a href="{@docRoot}resources/samples/SearchableDictionary/index.html">Searchable
 Dictionary</a></li>
diff --git a/docs/html/guide/topics/testing/testing_android.jd b/docs/html/guide/topics/testing/testing_android.jd
index 513e472..1d5f911 100755
--- a/docs/html/guide/topics/testing/testing_android.jd
+++ b/docs/html/guide/topics/testing/testing_android.jd
@@ -50,14 +50,14 @@
         <a href="#NextSteps">Next Steps</a>
     </li>
   </ol>
-  <h2>Key Classes and Packages</h2>
+  <h2>Key classes</h2>
     <ol>
       <li>{@link android.test.InstrumentationTestRunner}</li>
       <li>{@link android.test}</li>
       <li>{@link android.test.mock}</li>
       <li>{@link junit.framework}</li>
     </ol>
-  <h2>Related Tutorials</h2>
+  <h2>Related tutorials</h2>
     <ol>
         <li>
             <a href="{@docRoot}resources/tutorials/testing/helloandroid_test.html">
@@ -67,7 +67,7 @@
             <a href="{@docRoot}resources/tutorials/testing/activity_test.html">Activity Testing</a>
         </li>
     </ol>
-  <h2>See Also</h2>
+  <h2>See also</h2>
       <ol>
         <li>
           <a href="{@docRoot}guide/developing/testing/testing_eclipse.html">
diff --git a/docs/html/guide/topics/ui/binding.jd b/docs/html/guide/topics/ui/binding.jd
index 6ac0bb0..26364ee 100644
--- a/docs/html/guide/topics/ui/binding.jd
+++ b/docs/html/guide/topics/ui/binding.jd
@@ -11,11 +11,11 @@
     <li><a href="#HandlingUserSelections">Handling User Selections</a></li>
   </ol>
   
-  <h2>See also</h2>
+  <h2>Related tutorials</h2>
   <ol>
-    <li><a href="{@docRoot}resources/tutorials/views/hello-spinner.html">Hello Spinner tutorial</a></li>
-    <li><a href="{@docRoot}resources/tutorials/views/hello-listview.html">Hello ListView tutorial</a></li>
-    <li><a href="{@docRoot}resources/tutorials/views/hello-gridview.html">Hello GridView tutorial</a></li>
+    <li><a href="{@docRoot}resources/tutorials/views/hello-spinner.html">Spinner</a></li>
+    <li><a href="{@docRoot}resources/tutorials/views/hello-listview.html">List View</a></li>
+    <li><a href="{@docRoot}resources/tutorials/views/hello-gridview.html">Grid View</a></li>
   </ol>
 </div>
 </div>
diff --git a/docs/html/guide/topics/ui/declaring-layout.jd b/docs/html/guide/topics/ui/declaring-layout.jd
index 5c12db9..fe641a2 100644
--- a/docs/html/guide/topics/ui/declaring-layout.jd
+++ b/docs/html/guide/topics/ui/declaring-layout.jd
@@ -5,12 +5,6 @@
 
 <div id="qv-wrapper">
 <div id="qv">
-  <h2>Key classes</h2>
-  <ol>
-    <li>{@link android.view.View}</li>
-    <li>{@link android.view.ViewGroup}</li>
-    <li>{@link android.view.ViewGroup.LayoutParams}</li>
-  </ol>
   <h2>In this document</h2>
   <ol>
     <li><a href="#write">Write the XML</a></li>
@@ -26,6 +20,12 @@
     <li><a href="#example">Example Layout</a></li>
   </ol>
 
+  <h2>Key classes</h2>
+  <ol>
+    <li>{@link android.view.View}</li>
+    <li>{@link android.view.ViewGroup}</li>
+    <li>{@link android.view.ViewGroup.LayoutParams}</li>
+  </ol>
 </div>
 </div>
 
diff --git a/docs/html/guide/topics/ui/dialogs.jd b/docs/html/guide/topics/ui/dialogs.jd
index f47a709..879eb8b 100644
--- a/docs/html/guide/topics/ui/dialogs.jd
+++ b/docs/html/guide/topics/ui/dialogs.jd
@@ -5,10 +5,6 @@
 
 <div id="qv-wrapper">
   <div id="qv">
-    <h2>Key classes</h2>
-    <ol>
-      <li>{@link android.app.Dialog}</li>
-    </ol>
     <h2>In this document</h2>
     <ol>
       <li><a href="#ShowingADialog">Showing a Dialog</a></li>
@@ -26,6 +22,11 @@
       </li>
       <li><a href="#CustomDialog">Creating a Custom Dialog</a></li>
     </ol>
+    
+    <h2>Key classes</h2>
+    <ol>
+      <li>{@link android.app.Dialog}</li>
+    </ol>
   </div>
 </div>
 
diff --git a/docs/html/guide/topics/ui/index.jd b/docs/html/guide/topics/ui/index.jd
index abcf6be..375c9fe 100644
--- a/docs/html/guide/topics/ui/index.jd
+++ b/docs/html/guide/topics/ui/index.jd
@@ -4,13 +4,6 @@
 <div id="qv-wrapper">
 <div id="qv">
 
-  <h2>Key classes</h2>
-  <ol>
-    <li>{@link android.view.View}</li>
-    <li>{@link android.view.ViewGroup}</li>
-    <li>{@link android.widget Widget classes}</li>
-  </ol>
-
   <h2>In this document</h2>
   <ol>
     <li><a href="#ViewHierarchy">View Hierarchy</a></li>
@@ -25,6 +18,13 @@
       </ol>
     </li>
   </ol>
+
+  <h2>Key classes</h2>
+  <ol>
+    <li>{@link android.view.View}</li>
+    <li>{@link android.view.ViewGroup}</li>
+    <li>{@link android.widget Widget classes}</li>
+  </ol>
 </div>
 </div>
 
diff --git a/docs/html/guide/topics/ui/notifiers/index.jd b/docs/html/guide/topics/ui/notifiers/index.jd
index f7ccce7..d29324c 100644
--- a/docs/html/guide/topics/ui/notifiers/index.jd
+++ b/docs/html/guide/topics/ui/notifiers/index.jd
@@ -3,13 +3,7 @@
 
 <div id="qv-wrapper">
   <div id="qv">
-    <h2>In this document</h2>
-    <ol>
-      <li><a href="#Toast">Toast Notification</a></li>
-      <li><a href="#StatusBarNotification">Status Bar Notification</a></li>
-      <li><a href="#Dialog">Dialog Notification</a></li>
-    </ol>
-    <h2>More about</h2>
+    <h2>Topics</h2>
     <ol>
       <li><a href="toasts.html">Creating Toast Notifications</a></li>
       <li><a href="notifications.html">Creating Status Bar Notifications</a></li>
diff --git a/docs/html/guide/topics/ui/notifiers/notifications.jd b/docs/html/guide/topics/ui/notifiers/notifications.jd
index a0dd9f1..abc945a 100644
--- a/docs/html/guide/topics/ui/notifiers/notifications.jd
+++ b/docs/html/guide/topics/ui/notifiers/notifications.jd
@@ -5,18 +5,21 @@
 
 <div id="qv-wrapper">
   <div id="qv">
-    <h2>Key classes</h2>
-    <ol>
-      <li>{@link android.app.Notification}</li>
-      <li>{@link android.app.NotificationManager}</li>
-    </ol>
+    <h2>Quickview</h2>
+    <ul>
+      <li>A status bar notification allows your application to notify the user of an event
+without interupting their current activity</li>
+      <li>You can attach an intent to your notification that the system will initiate when the
+user clicks it</li>
+    </ul>
+    
     <h2>In this document</h2>
     <ol>
       <li><a href="#Basics">The Basics</a></li>
       <li><a href="#ManageYourNotifications">Managing your Notifications</a></li>
       <li><a href="#CreateANotification">Creating a Notification</a>
         <ol>
-          <li><a href="#Update">Updating the notification</a></li>
+          <li><a href="#Updating">Updating the notification</a></li>
           <li><a href="#Sound">Adding a sound</a></li>
           <li><a href="#Vibration">Adding vibration</a></li>
           <li><a href="#Lights">Adding flashing lights</a></li>
@@ -25,6 +28,11 @@
       </li>
       <li><a href="#CustomExpandedView">Creating a Custom Expanded View</a></li>
     </ol>
+    <h2>Key classes</h2>
+    <ol>
+      <li>{@link android.app.Notification}</li>
+      <li>{@link android.app.NotificationManager}</li>
+    </ol>
   </div>
 </div>
 
diff --git a/docs/html/guide/topics/ui/notifiers/toasts.jd b/docs/html/guide/topics/ui/notifiers/toasts.jd
index 5b324d2..0d3e10c 100644
--- a/docs/html/guide/topics/ui/notifiers/toasts.jd
+++ b/docs/html/guide/topics/ui/notifiers/toasts.jd
@@ -5,16 +5,24 @@
 
 <div id="qv-wrapper">
   <div id="qv">
-    <h2>Key classes</h2>
+    <h2>Quickview</h2>
     <ol>
-      <li>{@link android.widget.Toast}</li>
+      <li>A toast is a message that appears on the surface of the screen for a moment, but it
+does not take focus (or pause the current activity), so it cannot accept user input</li>
+      <li>You can customize the toast layout to include images</li>
     </ol>
+    
     <h2>In this document</h2>
     <ol>
       <li><a href="#Basics">The Basics</a></li>
-      <li><a href="#Position">Positioning your Toast</a></li>
+      <li><a href="#Positioning">Positioning your Toast</a></li>
       <li><a href="#CustomToastView">Creating a Custom Toast View</a></li>
     </ol>
+    
+    <h2>Key classes</h2>
+    <ol>
+      <li>{@link android.widget.Toast}</li>
+    </ol>
   </div>
 </div>
 
diff --git a/docs/html/guide/topics/ui/ui-events.jd b/docs/html/guide/topics/ui/ui-events.jd
index ccef64f..7d7bfaf 100644
--- a/docs/html/guide/topics/ui/ui-events.jd
+++ b/docs/html/guide/topics/ui/ui-events.jd
@@ -13,9 +13,9 @@
     <li><a href="#HandlingFocus">Handling Focus</a></li>
   </ol>
 
-  <h2>See also</h2>
+  <h2>Related tutorials</h2>
   <ol>
-    <li><a href="{@docRoot}resources/tutorials/views/hello-formstuff.html">Hello Form Stuff tutorial</a></li>
+    <li><a href="{@docRoot}resources/tutorials/views/hello-formstuff.html">Form Stuff</a></li>
   </ol>
 </div>
 </div>
diff --git a/docs/html/guide/topics/wireless/bluetooth.jd b/docs/html/guide/topics/wireless/bluetooth.jd
index a8ff007..fa2875b 100644
--- a/docs/html/guide/topics/wireless/bluetooth.jd
+++ b/docs/html/guide/topics/wireless/bluetooth.jd
@@ -3,14 +3,13 @@
 
 <div id="qv-wrapper">
 <div id="qv">
-  <h2>Key Classes</h2>
-  <ol>
-    <li>{@link android.bluetooth.BluetoothAdapter}</li>
-    <li>{@link android.bluetooth.BluetoothDevice}</li>
-    <li>{@link android.bluetooth.BluetoothSocket}</li>
-    <li>{@link android.bluetooth.BluetoothServerSocket}</li>
-  </ol>
 
+  <h2>Quickview</h2>
+  <ul>
+    <li>Android's bluetooth APIs allow your application to perform wireless data transactions with
+other devices</li>
+  </ul>
+  
   <h2>In this document</h2>
   <ol>
     <li><a href="#TheBasics">The Basics</a></li>
@@ -33,11 +32,18 @@
     </li>
     <li><a href="#ManagingAConnection">Managing a Connection</a></li>
   </ol>
-
-  <h2>See also</h2>
+  
+  <h2>Key classes</h2>
   <ol>
-    <li><a href="{@docRoot}resources/samples/BluetoothChat/index.html">Bluetooth Chat sample
-      app</a></li>
+    <li>{@link android.bluetooth.BluetoothAdapter}</li>
+    <li>{@link android.bluetooth.BluetoothDevice}</li>
+    <li>{@link android.bluetooth.BluetoothSocket}</li>
+    <li>{@link android.bluetooth.BluetoothServerSocket}</li>
+  </ol>
+
+  <h2>Related samples</h2>
+  <ol>
+    <li><a href="{@docRoot}resources/samples/BluetoothChat/index.html">Bluetooth Chat</a></li>
   </ol>
 
 </div>
diff --git a/docs/html/images/fundamentals/diagram_backstack.png b/docs/html/images/fundamentals/diagram_backstack.png
new file mode 100644
index 0000000..2c6e33f
--- /dev/null
+++ b/docs/html/images/fundamentals/diagram_backstack.png
Binary files differ
diff --git a/docs/html/images/fundamentals/diagram_backstack_singletask_multiactivity.png b/docs/html/images/fundamentals/diagram_backstack_singletask_multiactivity.png
new file mode 100644
index 0000000..d6a21d7
--- /dev/null
+++ b/docs/html/images/fundamentals/diagram_backstack_singletask_multiactivity.png
Binary files differ
diff --git a/docs/html/images/fundamentals/diagram_multiple_instances.png b/docs/html/images/fundamentals/diagram_multiple_instances.png
new file mode 100644
index 0000000..380e7788
--- /dev/null
+++ b/docs/html/images/fundamentals/diagram_multiple_instances.png
Binary files differ
diff --git a/docs/html/images/fundamentals/diagram_multitasking.png b/docs/html/images/fundamentals/diagram_multitasking.png
new file mode 100644
index 0000000..b8c7b45
--- /dev/null
+++ b/docs/html/images/fundamentals/diagram_multitasking.png
Binary files differ
diff --git a/docs/html/images/fundamentals/restore_instance.png b/docs/html/images/fundamentals/restore_instance.png
new file mode 100644
index 0000000..fa428a7
--- /dev/null
+++ b/docs/html/images/fundamentals/restore_instance.png
Binary files differ
diff --git a/docs/html/images/home/market-intl.png b/docs/html/images/home/market-intl.png
new file mode 100644
index 0000000..2bb22f1
--- /dev/null
+++ b/docs/html/images/home/market-intl.png
Binary files differ
diff --git a/docs/html/index.jd b/docs/html/index.jd
index f37a122..049df62 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -11,12 +11,14 @@
                             </div><!-- end homeTitle -->
                             <div id="announcement-block">
                             <!-- total max width is 520px -->
-                                  <img src="{@docRoot}images/home/io-logo.png" alt="Google IO
-2010" width="200" height="41" style="padding:22px 12px;"/>
+                                  <img src="{@docRoot}images/home/market-intl.png" alt="Android
+Market" width="104" height="120" style="padding:10px 60px 5px" />
                                   <div id="announcement" style="width:295px">
-<p>Thanks to everyone who visited us at Google I/O in San Francisco! Stay tuned for
-videos and slides from the Android sessions, which will be posted at the Google I/O web site.</p><p><a
-href="http://code.google.com/events/io/2010/sessions.html#Android">Learn more &raquo;</a></p>
+<p>We're pleased to announce that paid apps are available in more locations of the world! Developers
+from 20 more locations can now sell paid apps on Android Market. Users in more locations will also
+soon be able to purchase apps.</p><p><a
+href="http://android-developers.blogspot.com/2010/09/more-countries-more-sellers-more-buyers.html">
+Learn more &raquo;</a></p>
                                 </div> <!-- end annoucement -->
                             </div> <!-- end annoucement-block -->
                         </div><!-- end topAnnouncement -->
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 985d700..2c076b3 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -182,6 +182,24 @@
         mRS.nAllocationRead(mID, d);
     }
 
+    public void resize(int dimX) {
+        if ((mType.getY() > 0)|| (mType.getZ() > 0) || mType.getFaces() || mType.getLOD()) {
+            throw new IllegalStateException("Resize only support for 1D allocations at this time.");
+        }
+        mRS.nAllocationResize1D(mID, dimX);
+    }
+
+    /*
+    public void resize(int dimX, int dimY) {
+        if ((mType.getZ() > 0) || mType.getFaces() || mType.getLOD()) {
+            throw new IllegalStateException("Resize only support for 2D allocations at this time.");
+        }
+        if (mType.getY() == 0) {
+            throw new IllegalStateException("Resize only support for 2D allocations at this time.");
+        }
+        mRS.nAllocationResize2D(mID, dimX, dimY);
+    }
+    */
 
     public class Adapter1D extends BaseObj {
         Adapter1D(int id, RenderScript rs) {
diff --git a/graphics/java/android/renderscript/RenderScript.java b/graphics/java/android/renderscript/RenderScript.java
index 3c0b4e5..0088373 100644
--- a/graphics/java/android/renderscript/RenderScript.java
+++ b/graphics/java/android/renderscript/RenderScript.java
@@ -254,6 +254,15 @@
         return rsnAllocationGetType(mContext, id);
     }
 
+    native void rsnAllocationResize1D(int con, int id, int dimX);
+    synchronized void nAllocationResize1D(int id, int dimX) {
+        rsnAllocationResize1D(mContext, id, dimX);
+    }
+    native void rsnAllocationResize2D(int con, int id, int dimX, int dimY);
+    synchronized void nAllocationResize2D(int id, int dimX, int dimY) {
+        rsnAllocationResize2D(mContext, id, dimX, dimY);
+    }
+
     native int  rsnFileA3DCreateFromAssetStream(int con, int assetStream);
     synchronized int nFileA3DCreateFromAssetStream(int assetStream) {
         return rsnFileA3DCreateFromAssetStream(mContext, assetStream);
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 67a2b63..8f1e93c 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -587,6 +587,20 @@
     return (jint) rsAllocationGetType(con, (RsAllocation)a);
 }
 
+static void
+nAllocationResize1D(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint dimX)
+{
+    LOG_API("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i)", con, (RsAllocation)alloc, dimX);
+    rsAllocationResize1D(con, (RsAllocation)alloc, dimX);
+}
+
+static void
+nAllocationResize2D(JNIEnv *_env, jobject _this, RsContext con, jint alloc, jint dimX, jint dimY)
+{
+    LOG_API("nAllocationResize1D, con(%p), alloc(%p), sizeX(%i), sizeY(%i)", con, (RsAllocation)alloc, dimX, dimY);
+    rsAllocationResize2D(con, (RsAllocation)alloc, dimX, dimY);
+}
+
 // -----------------------------------
 
 static int
@@ -1252,6 +1266,8 @@
 {"rsnAllocationRead",                "(II[I)V",                               (void*)nAllocationRead_i },
 {"rsnAllocationRead",                "(II[F)V",                               (void*)nAllocationRead_f },
 {"rsnAllocationGetType",             "(II)I",                                 (void*)nAllocationGetType},
+{"rsnAllocationResize1D",            "(III)V",                                (void*)nAllocationResize1D },
+{"rsnAllocationResize2D",            "(IIII)V",                               (void*)nAllocationResize2D },
 
 {"rsnAdapter1DBindAllocation",       "(III)V",                                (void*)nAdapter1DBindAllocation },
 {"rsnAdapter1DSetConstraint",        "(IIII)V",                               (void*)nAdapter1DSetConstraint },
diff --git a/libs/hwui/TextureCache.cpp b/libs/hwui/TextureCache.cpp
index adf6ee2..701df83 100644
--- a/libs/hwui/TextureCache.cpp
+++ b/libs/hwui/TextureCache.cpp
@@ -18,6 +18,8 @@
 
 #include <GLES2/gl2.h>
 
+#include <SkCanvas.h>
+
 #include <utils/threads.h>
 
 #include "TextureCache.h"
@@ -192,8 +194,12 @@
         // decoding happened
         texture->blend = !bitmap->isOpaque();
         break;
+    case SkBitmap::kIndex8_Config:
+        uploadPalettedTexture(resize, bitmap, texture->width, texture->height);
+        texture->blend = false;
+        break;
     default:
-        LOGW("Unsupported bitmap config");
+        LOGW("Unsupported bitmap config: %d", bitmap->getConfig());
         break;
     }
 
@@ -204,6 +210,20 @@
     glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
 }
 
+void TextureCache::uploadPalettedTexture(bool resize, SkBitmap* bitmap,
+        uint32_t width, uint32_t height) {
+    SkBitmap rgbaBitmap;
+    rgbaBitmap.setConfig(SkBitmap::kARGB_8888_Config, width, height);
+    rgbaBitmap.allocPixels();
+    rgbaBitmap.eraseColor(0);
+
+    SkCanvas canvas(rgbaBitmap);
+    canvas.drawBitmap(*bitmap, 0.0f, 0.0f, NULL);
+
+    uploadToTexture(resize, GL_RGBA, rgbaBitmap.rowBytesAsPixels(), height,
+            GL_UNSIGNED_BYTE, rgbaBitmap.getPixels());
+}
+
 void TextureCache::uploadToTexture(bool resize, GLenum format, GLsizei width, GLsizei height,
         GLenum type, const GLvoid * data) {
     if (resize) {
diff --git a/libs/hwui/TextureCache.h b/libs/hwui/TextureCache.h
index 7cf66d9..34c5455 100644
--- a/libs/hwui/TextureCache.h
+++ b/libs/hwui/TextureCache.h
@@ -79,6 +79,7 @@
      */
     void generateTexture(SkBitmap* bitmap, Texture* texture, bool regenerate = false);
 
+    void uploadPalettedTexture(bool resize, SkBitmap* bitmap, uint32_t width, uint32_t height);
     void uploadToTexture(bool resize, GLenum format, GLsizei width, GLsizei height,
             GLenum type, const GLvoid * data);
 
diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk
index 37c418b..05c1a48 100644
--- a/libs/rs/Android.mk
+++ b/libs/rs/Android.mk
@@ -83,7 +83,6 @@
 	rsElement.cpp \
 	rsFileA3D.cpp \
 	rsFont.cpp \
-	rsLight.cpp \
 	rsLocklessFifo.cpp \
 	rsObjectBase.cpp \
 	rsMatrix.cpp \
diff --git a/libs/rs/RenderScript.h b/libs/rs/RenderScript.h
index 13ae1fb..66e27f3 100644
--- a/libs/rs/RenderScript.h
+++ b/libs/rs/RenderScript.h
@@ -40,7 +40,6 @@
 typedef void * RsScript;
 typedef void * RsMesh;
 typedef void * RsType;
-typedef void * RsLight;
 typedef void * RsObjectBase;
 
 typedef void * RsProgram;
@@ -242,7 +241,6 @@
     RS_A3D_CLASS_ID_PROGRAM_STORE,
     RS_A3D_CLASS_ID_SAMPLER,
     RS_A3D_CLASS_ID_ANIMATION,
-    RS_A3D_CLASS_ID_LIGHT,
     RS_A3D_CLASS_ID_ADAPTER_1D,
     RS_A3D_CLASS_ID_ADAPTER_2D,
     RS_A3D_CLASS_ID_SCRIPT_C
diff --git a/libs/rs/RenderScriptEnv.h b/libs/rs/RenderScriptEnv.h
index c83ece4..b82eaf1 100644
--- a/libs/rs/RenderScriptEnv.h
+++ b/libs/rs/RenderScriptEnv.h
@@ -13,8 +13,6 @@
 typedef void * RsType;
 typedef void * RsProgramFragment;
 typedef void * RsProgramStore;
-typedef void * RsLight;
-
 
 typedef struct {
     float m[16];
diff --git a/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java b/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java
index a15c4a1..0990da3 100644
--- a/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java
+++ b/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java
@@ -84,8 +84,6 @@
     private Allocation mTexTransparent;
     private Allocation mTexChecker;
 
-    private Allocation mAllocPV;
-
     private Mesh mMbyNMesh;
     private Mesh mTorus;
 
@@ -95,7 +93,6 @@
     Font mFontSerifItalic;
     Font mFontSerifBoldItalic;
     Font mFontMono;
-
     private Allocation mTextAlloc;
 
     private ScriptC_rsrenderstates mScript;
@@ -267,12 +264,15 @@
         mFontSerifBoldItalic = Font.createFromFamily(mRS, mRes, "serif", Font.Style.BOLD_ITALIC, 8);
         mFontMono = Font.createFromFamily(mRS, mRes, "mono", Font.Style.NORMAL, 8);
 
+        mTextAlloc = Allocation.createFromString(mRS, "String from allocation");
+
         mScript.set_gFontSans(mFontSans);
         mScript.set_gFontSerif(mFontSerif);
         mScript.set_gFontSerifBold(mFontSerifBold);
         mScript.set_gFontSerifItalic(mFontSerifItalic);
         mScript.set_gFontSerifBoldItalic(mFontSerifBoldItalic);
         mScript.set_gFontMono(mFontMono);
+        mScript.set_gTextAlloc(mTextAlloc);
     }
 
     private void initMesh() {
diff --git a/libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs b/libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs
index b471504..77384ef 100644
--- a/libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs
+++ b/libs/rs/java/Samples/src/com/android/samples/rsrenderstates.rs
@@ -42,6 +42,7 @@
 rs_font gFontSerifItalic;
 rs_font gFontSerifBoldItalic;
 rs_font gFontMono;
+rs_allocation gTextAlloc;
 
 int gDisplayMode;
 
@@ -70,7 +71,7 @@
 #pragma rs export_var(gProgStoreBlendNoneDepth, gProgStoreBlendNone, gProgStoreBlendAlpha, gProgStoreBlendAdd)
 #pragma rs export_var(gTexOpaque, gTexTorus, gTexTransparent, gTexChecker)
 #pragma rs export_var(gMbyNMesh, gTorusMesh)
-#pragma rs export_var(gFontSans, gFontSerif, gFontSerifBold, gFontSerifItalic, gFontSerifBoldItalic, gFontMono)
+#pragma rs export_var(gFontSans, gFontSerif, gFontSerifBold, gFontSerifItalic, gFontSerifBoldItalic, gFontMono, gTextAlloc)
 #pragma rs export_var(gLinearClamp, gLinearWrap, gMipLinearWrap, gMipLinearAniso8, gMipLinearAniso15, gNearestClamp)
 #pragma rs export_var(gCullBack, gCullFront, gCullNone)
 #pragma rs export_var(gVSConstants, gFSConstants, gVSInputs, gProgVertexCustom, gProgFragmentCustom, gProgFragmentMultitex)
@@ -85,7 +86,7 @@
 
 void displayFontSamples() {
     rsgFontColor(1.0f, 1.0f, 1.0f, 1.0f);
-    int yPos = 30;
+    int yPos = 100;
     rsgBindFont(gFontSans);
     rsgDrawText("Sans font sample", 30, yPos);
     yPos += 30;
@@ -107,6 +108,47 @@
     yPos += 30;
     rsgBindFont(gFontMono);
     rsgDrawText("Monospace font sample", 30, yPos);
+    yPos += 50;
+
+    // Now use text metrics to center the text
+    uint width = rsgGetWidth();
+    uint height = rsgGetHeight();
+    int left = 0, right = 0, top = 0, bottom = 0;
+
+    rsgFontColor(0.9f, 0.9f, 0.95f, 1.0f);
+    rsgBindFont(gFontSerifBoldItalic);
+
+    rsgMeasureText(gTextAlloc, &left, &right, &top, &bottom);
+    int centeredPos = width / 2 - (right - left) / 2;
+    rsgDrawText(gTextAlloc, centeredPos, yPos);
+    yPos += 30;
+
+    const char* text = "Centered Text Sample";
+    rsgMeasureText(text, &left, &right, &top, &bottom);
+    centeredPos = width / 2 - (right - left) / 2;
+    rsgDrawText(text, centeredPos, yPos);
+    yPos += 30;
+
+    rsgBindFont(gFontSans);
+    text = "More Centered Text Samples";
+    rsgMeasureText(text, &left, &right, &top, &bottom);
+    centeredPos = width / 2 - (right - left) / 2;
+    rsgDrawText(text, centeredPos, yPos);
+    yPos += 30;
+
+    // Now draw bottom and top right aligned text
+    text = "Top-right aligned text";
+    rsgMeasureText(text, &left, &right, &top, &bottom);
+    rsgDrawText(text, width - right, top);
+
+    text = "Top-left";
+    rsgMeasureText(text, &left, &right, &top, &bottom);
+    rsgDrawText(text, -left, top);
+
+    text = "Bottom-right aligned text";
+    rsgMeasureText(text, &left, &right, &top, &bottom);
+    rsgDrawText(text, width - right, height + bottom);
+
 }
 
 void bindProgramVertexOrtho() {
diff --git a/libs/rs/rs.spec b/libs/rs/rs.spec
index a4752f4..0da637e 100644
--- a/libs/rs/rs.spec
+++ b/libs/rs/rs.spec
@@ -280,6 +280,17 @@
 	ret const void*
 	}
 
+AllocationResize1D {
+	param RsAllocation va
+	param uint32_t dimX
+	}
+
+AllocationResize2D {
+	param RsAllocation va
+	param uint32_t dimX
+	param uint32_t dimY
+	}
+
 SamplerBegin {
 	}
 
diff --git a/libs/rs/rsAllocation.cpp b/libs/rs/rsAllocation.cpp
index 0356e4d..2e9e0b3 100644
--- a/libs/rs/rsAllocation.cpp
+++ b/libs/rs/rsAllocation.cpp
@@ -488,12 +488,13 @@
     }
 }
 
-void Allocation::incRefs(const void *ptr, size_t ct) const
+void Allocation::incRefs(const void *ptr, size_t ct, size_t startOff) const
 {
     const uint8_t *p = static_cast<const uint8_t *>(ptr);
     const Element *e = mType->getElement();
     uint32_t stride = e->getSizeBytes();
 
+    p += stride * startOff;
     while (ct > 0) {
         e->incRefs(p);
         ct --;
@@ -501,12 +502,13 @@
     }
 }
 
-void Allocation::decRefs(const void *ptr, size_t ct) const
+void Allocation::decRefs(const void *ptr, size_t ct, size_t startOff) const
 {
     const uint8_t *p = static_cast<const uint8_t *>(ptr);
     const Element *e = mType->getElement();
     uint32_t stride = e->getSizeBytes();
 
+    p += stride * startOff;
     while (ct > 0) {
         e->decRefs(p);
         ct --;
@@ -514,6 +516,37 @@
     }
 }
 
+void Allocation::copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff, int32_t destOff, int32_t len)
+{
+}
+
+void Allocation::resize1D(Context *rsc, uint32_t dimX)
+{
+    Type *t = mType->cloneAndResize1D(rsc, dimX);
+
+    uint32_t oldDimX = mType->getDimX();
+    if (dimX == oldDimX) {
+        return;
+    }
+
+    if (dimX < oldDimX) {
+        decRefs(mPtr, oldDimX - dimX, dimX);
+    }
+    mPtr = realloc(mPtr, t->getSizeBytes());
+
+    if (dimX > oldDimX) {
+        const Element *e = mType->getElement();
+        uint32_t stride = e->getSizeBytes();
+        memset(((uint8_t *)mPtr) + stride * oldDimX, 0, stride * (dimX - oldDimX));
+    }
+    mType.set(t);
+}
+
+void Allocation::resize2D(Context *rsc, uint32_t dimX, uint32_t dimY)
+{
+    LOGE("not implemented");
+}
+
 /////////////////
 //
 
@@ -822,6 +855,18 @@
     a->read(data);
 }
 
+void rsi_AllocationResize1D(Context *rsc, RsAllocation va, uint32_t dimX)
+{
+    Allocation *a = static_cast<Allocation *>(va);
+    a->resize1D(rsc, dimX);
+}
+
+void rsi_AllocationResize2D(Context *rsc, RsAllocation va, uint32_t dimX, uint32_t dimY)
+{
+    Allocation *a = static_cast<Allocation *>(va);
+    a->resize2D(rsc, dimX, dimY);
+}
+
 const void* rsi_AllocationGetType(Context *rsc, RsAllocation va)
 {
     Allocation *a = static_cast<Allocation *>(va);
diff --git a/libs/rs/rsAllocation.h b/libs/rs/rsAllocation.h
index ce5372f..24e245f 100644
--- a/libs/rs/rsAllocation.h
+++ b/libs/rs/rsAllocation.h
@@ -55,6 +55,10 @@
     void uploadToBufferObject(const Context *rsc);
     uint32_t getBufferObjectID() const {return mBufferID;}
 
+    void copyRange1D(Context *rsc, const Allocation *src, int32_t srcOff, int32_t destOff, int32_t len);
+
+    void resize1D(Context *rsc, uint32_t dimX);
+    void resize2D(Context *rsc, uint32_t dimX, uint32_t dimY);
 
     void data(Context *rsc, const void *data, uint32_t sizeBytes);
     void subData(Context *rsc, uint32_t xoff, uint32_t count, const void *data, uint32_t sizeBytes);
@@ -86,8 +90,8 @@
     bool getIsTexture() const {return mIsTexture;}
     bool getIsBufferObject() const {return mIsVertexBuffer;}
 
-    void incRefs(const void *ptr, size_t ct) const;
-    void decRefs(const void *ptr, size_t ct) const;
+    void incRefs(const void *ptr, size_t ct, size_t startOff = 0) const;
+    void decRefs(const void *ptr, size_t ct, size_t startOff = 0) const;
 
     void sendDirty() const;
     bool getHasGraphicsMipmaps() const {return mTextureGenMipmap;}
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 6940033..30add62 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -188,6 +188,9 @@
     mTimeFrame = mTimeLast;
     mTimeLastFrame = mTimeLast;
     mTimerActive = RS_TIMER_INTERNAL;
+    mAverageFPSFrameCount = 0;
+    mAverageFPSStartTime = mTimeLast;
+    mAverageFPS = 0;
     timerReset();
 }
 
@@ -195,6 +198,16 @@
 {
     mTimeLastFrame = mTimeFrame;
     mTimeFrame = getTime();
+    // Update average fps
+    const uint64_t averageFramerateInterval = 1000 * 1000000;
+    mAverageFPSFrameCount ++;
+    uint64_t inverval = mTimeFrame - mAverageFPSStartTime;
+    if(inverval >= averageFramerateInterval) {
+        inverval = inverval / 1000000;
+        mAverageFPS = (mAverageFPSFrameCount * 1000) / inverval;
+        mAverageFPSFrameCount = 0;
+        mAverageFPSStartTime = mTimeFrame;
+    }
 }
 
 void Context::timerSet(Timers tm)
@@ -218,12 +231,13 @@
 
 
     if (props.mLogTimes) {
-        LOGV("RS: Frame (%i),   Script %2.1f (%i),  Clear & Swap %2.1f (%i),  Idle %2.1f (%lli),  Internal %2.1f (%lli)",
+        LOGV("RS: Frame (%i),   Script %2.1f (%i),  Clear & Swap %2.1f (%i),  Idle %2.1f (%lli),  Internal %2.1f (%lli), Avg fps: %u",
              mTimeMSLastFrame,
              100.0 * mTimers[RS_TIMER_SCRIPT] / total, mTimeMSLastScript,
              100.0 * mTimers[RS_TIMER_CLEAR_SWAP] / total, mTimeMSLastSwap,
              100.0 * mTimers[RS_TIMER_IDLE] / total, mTimers[RS_TIMER_IDLE] / 1000000,
-             100.0 * mTimers[RS_TIMER_INTERNAL] / total, mTimers[RS_TIMER_INTERNAL] / 1000000);
+             100.0 * mTimers[RS_TIMER_INTERNAL] / total, mTimers[RS_TIMER_INTERNAL] / 1000000,
+             mAverageFPS);
     }
 }
 
@@ -255,17 +269,17 @@
 void Context::displayDebugStats()
 {
     char buffer[128];
-    sprintf(buffer, "Frame %i ms, Script %i ms", mTimeMSLastFrame, mTimeMSLastScript);
+    sprintf(buffer, "Avg fps %u, Frame %i ms, Script %i ms", mAverageFPS, mTimeMSLastFrame, mTimeMSLastScript);
     float oldR, oldG, oldB, oldA;
     mStateFont.getFontColor(&oldR, &oldG, &oldB, &oldA);
+    uint32_t bufferLen = strlen(buffer);
 
-    float shadowCol = 0.2f;
+    float shadowCol = 0.1f;
     mStateFont.setFontColor(shadowCol, shadowCol, shadowCol, 1.0f);
-    mStateFont.renderText(buffer, 5, getHeight() - 5);
+    mStateFont.renderText(buffer, bufferLen, 5, getHeight() - 6);
 
-    float textCol = 0.9f;
-    mStateFont.setFontColor(textCol, textCol, textCol, 1.0f);
-    mStateFont.renderText(buffer, 4, getHeight() - 6);
+    mStateFont.setFontColor(1.0f, 0.7f, 0.0f, 1.0f);
+    mStateFont.renderText(buffer, bufferLen, 4, getHeight() - 7);
 
     mStateFont.setFontColor(oldR, oldG, oldB, oldA);
 }
diff --git a/libs/rs/rsContext.h b/libs/rs/rsContext.h
index dabe196..8a8b8a8 100644
--- a/libs/rs/rsContext.h
+++ b/libs/rs/rsContext.h
@@ -30,7 +30,6 @@
 #include "rsAllocation.h"
 #include "rsAdapter.h"
 #include "rsSampler.h"
-#include "rsLight.h"
 #include "rsFont.h"
 #include "rsProgramFragment.h"
 #include "rsProgramStore.h"
@@ -94,7 +93,6 @@
     ProgramStoreState mStateFragmentStore;
     ProgramRasterState mStateRaster;
     ProgramVertexState mStateVertex;
-    LightState mStateLight;
     VertexArrayState mStateVertexArray;
     FontState mStateFont;
 
@@ -296,6 +294,9 @@
     uint32_t mTimeMSLastFrame;
     uint32_t mTimeMSLastScript;
     uint32_t mTimeMSLastSwap;
+    uint32_t mAverageFPSFrameCount;
+    uint64_t mAverageFPSStartTime;
+    uint32_t mAverageFPS;
 };
 
 }
diff --git a/libs/rs/rsContextHostStub.h b/libs/rs/rsContextHostStub.h
index 06298e8..aa0205d 100644
--- a/libs/rs/rsContextHostStub.h
+++ b/libs/rs/rsContextHostStub.h
@@ -30,7 +30,6 @@
 #include "rsAllocation.h"
 #include "rsAdapter.h"
 #include "rsSampler.h"
-#include "rsLight.h"
 #include "rsProgramFragment.h"
 #include "rsProgramStore.h"
 #include "rsProgramRaster.h"
@@ -68,7 +67,6 @@
     ProgramStoreState mStateFragmentStore;
     //ProgramRasterState mStateRaster;
     //ProgramVertexState mStateVertex;
-    LightState mStateLight;
     VertexArrayState mStateVertexArray;
 
     //ScriptCState mScriptC;
diff --git a/libs/rs/rsFileA3D.cpp b/libs/rs/rsFileA3D.cpp
index 893598f..c90edc2 100644
--- a/libs/rs/rsFileA3D.cpp
+++ b/libs/rs/rsFileA3D.cpp
@@ -278,9 +278,6 @@
         case RS_A3D_CLASS_ID_ANIMATION:
             entry->mRsObj = Animation::createFromStream(mRSC, mReadStream);
             break;
-        case RS_A3D_CLASS_ID_LIGHT:
-            entry->mRsObj = Light::createFromStream(mRSC, mReadStream);
-            break;
         case RS_A3D_CLASS_ID_ADAPTER_1D:
             entry->mRsObj = Adapter1D::createFromStream(mRSC, mReadStream);
             break;
diff --git a/libs/rs/rsFont.cpp b/libs/rs/rsFont.cpp
index c516ea9..b9de7e1 100644
--- a/libs/rs/rsFont.cpp
+++ b/libs/rs/rsFont.cpp
@@ -84,34 +84,95 @@
     }
 }
 
-void Font::drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y)
+void Font::drawCachedGlyph(CachedGlyphInfo *glyph, int32_t x, int32_t y)
 {
     FontState *state = &mRSC->mStateFont;
 
-    int nPenX = x + glyph->mBitmapLeft;
-    int nPenY = y - glyph->mBitmapTop + glyph->mBitmapHeight;
+    int32_t nPenX = x + glyph->mBitmapLeft;
+    int32_t nPenY = y - glyph->mBitmapTop + glyph->mBitmapHeight;
 
-    state->appendMeshQuad(nPenX, nPenY, 0,
-                            glyph->mBitmapMinU, glyph->mBitmapMaxV,
+    float u1 = glyph->mBitmapMinU;
+    float u2 = glyph->mBitmapMaxU;
+    float v1 = glyph->mBitmapMinV;
+    float v2 = glyph->mBitmapMaxV;
 
-                            nPenX + (int)glyph->mBitmapWidth, nPenY, 0,
-                            glyph->mBitmapMaxU, glyph->mBitmapMaxV,
+    int32_t width = (int32_t) glyph->mBitmapWidth;
+    int32_t height = (int32_t) glyph->mBitmapHeight;
 
-                            nPenX + (int)glyph->mBitmapWidth, nPenY - (int)glyph->mBitmapHeight, 0,
-                            glyph->mBitmapMaxU, glyph->mBitmapMinV,
-
-                            nPenX, nPenY - (int)glyph->mBitmapHeight, 0,
-                            glyph->mBitmapMinU, glyph->mBitmapMinV);
+    state->appendMeshQuad(nPenX, nPenY, 0, u1, v2,
+                          nPenX + width, nPenY, 0, u2, v2,
+                          nPenX + width, nPenY - height, 0, u2, v1,
+                          nPenX, nPenY - height, 0, u1, v1);
 }
 
-void Font::renderUTF(const char *text, uint32_t len, uint32_t start, int numGlyphs, int x, int y)
+void Font::drawCachedGlyph(CachedGlyphInfo* glyph, int32_t x, int32_t y,
+                           uint8_t* bitmap, uint32_t bitmapW, uint32_t bitmapH) {
+    int32_t nPenX = x + glyph->mBitmapLeft;
+    int32_t nPenY = y + glyph->mBitmapTop;
+
+    uint32_t endX = glyph->mBitmapMinX + glyph->mBitmapWidth;
+    uint32_t endY = glyph->mBitmapMinY + glyph->mBitmapHeight;
+
+    FontState *state = &mRSC->mStateFont;
+    uint32_t cacheWidth = state->getCacheTextureType()->getDimX();
+    const uint8_t* cacheBuffer = state->getTextTextureData();
+
+    uint32_t cacheX = 0, cacheY = 0;
+    int32_t bX = 0, bY = 0;
+    for (cacheX = glyph->mBitmapMinX, bX = nPenX; cacheX < endX; cacheX++, bX++) {
+        for (cacheY = glyph->mBitmapMinY, bY = nPenY; cacheY < endY; cacheY++, bY++) {
+            if (bX < 0 || bY < 0 || bX >= (int32_t) bitmapW || bY >= (int32_t) bitmapH) {
+                LOGE("Skipping invalid index");
+                continue;
+            }
+            uint8_t tempCol = cacheBuffer[cacheY * cacheWidth + cacheX];
+            bitmap[bY * bitmapW + bX] = tempCol;
+        }
+    }
+
+}
+
+void Font::measureCachedGlyph(CachedGlyphInfo *glyph, int32_t x, int32_t y, Rect *bounds) {
+    int32_t nPenX = x + glyph->mBitmapLeft;
+    int32_t nPenY = y - glyph->mBitmapTop + glyph->mBitmapHeight;
+
+    int32_t width = (int32_t) glyph->mBitmapWidth;
+    int32_t height = (int32_t) glyph->mBitmapHeight;
+
+    if (bounds->bottom > nPenY) {
+        bounds->bottom = nPenY;
+    }
+    if (bounds->left > nPenX) {
+        bounds->left = nPenX;
+    }
+    if (bounds->right < nPenX + width) {
+        bounds->right = nPenX + width;
+    }
+    if (bounds->top < nPenY + height) {
+        bounds->top = nPenY + height;
+    }
+}
+
+void Font::renderUTF(const char *text, uint32_t len, int32_t x, int32_t y,
+                     uint32_t start, int32_t numGlyphs,
+                     RenderMode mode, Rect *bounds,
+                     uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH)
 {
     if(!mInitialized || numGlyphs == 0 || text == NULL || len == 0) {
         return;
     }
 
-    int penX = x, penY = y;
-    int glyphsLeft = 1;
+    if(mode == Font::MEASURE) {
+        if (bounds == NULL) {
+            LOGE("No return rectangle provided to measure text");
+            return;
+        }
+        // Reset min and max of the bounding box to something large
+        bounds->set(1e6, -1e6, -1e6, 1e6);
+    }
+
+    int32_t penX = x, penY = y;
+    int32_t glyphsLeft = 1;
     if(numGlyphs > 0) {
         glyphsLeft = numGlyphs;
     }
@@ -135,7 +196,17 @@
 
         // If it's still not valid, we couldn't cache it, so we shouldn't draw garbage
         if(cachedGlyph->mIsValid) {
-            drawCachedGlyph(cachedGlyph, penX, penY);
+            switch(mode) {
+            case FRAMEBUFFER:
+                drawCachedGlyph(cachedGlyph, penX, penY);
+                break;
+            case BITMAP:
+                drawCachedGlyph(cachedGlyph, penX, penY, bitmap, bitmapW, bitmapH);
+                break;
+            case MEASURE:
+                measureCachedGlyph(cachedGlyph, penX, penY, bounds);
+                break;
+            }
         }
 
         penX += (cachedGlyph->mAdvance.x >> 6);
@@ -283,7 +354,7 @@
     }
 
     // Get the black gamma threshold
-    int blackThreshold = DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD;
+    int32_t blackThreshold = DEFAULT_TEXT_BLACK_GAMMA_THRESHOLD;
     if (property_get(PROPERTY_TEXT_BLACK_GAMMA_THRESHOLD, property, NULL) > 0) {
         LOGD("  Setting text black gamma threshold to %s", property);
         blackThreshold = atoi(property);
@@ -294,7 +365,7 @@
     mBlackThreshold = (float)(blackThreshold) / 255.0f;
 
     // Get the white gamma threshold
-    int whiteThreshold = DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD;
+    int32_t whiteThreshold = DEFAULT_TEXT_WHITE_GAMMA_THRESHOLD;
     if (property_get(PROPERTY_TEXT_WHITE_GAMMA_THRESHOLD, property, NULL) > 0) {
         LOGD("  Setting text white gamma threshold to %s", property);
         whiteThreshold = atoi(property);
@@ -397,13 +468,13 @@
 
     uint32_t cacheWidth = getCacheTextureType()->getDimX();
 
-    unsigned char *cacheBuffer = (unsigned char*)mTextTexture->getPtr();
-    unsigned char *bitmapBuffer = bitmap->buffer;
+    uint8_t *cacheBuffer = (uint8_t*)mTextTexture->getPtr();
+    uint8_t *bitmapBuffer = bitmap->buffer;
 
     uint32_t cacheX = 0, bX = 0, cacheY = 0, bY = 0;
     for(cacheX = startX, bX = 0; cacheX < endX; cacheX ++, bX ++) {
         for(cacheY = startY, bY = 0; cacheY < endY; cacheY ++, bY ++) {
-            unsigned char tempCol = bitmapBuffer[bY * bitmap->width + bX];
+            uint8_t tempCol = bitmapBuffer[bY * bitmap->width + bX];
             cacheBuffer[cacheY*cacheWidth + cacheX] = tempCol;
         }
     }
@@ -487,7 +558,7 @@
     mTextTexture->deferedUploadToTexture(mRSC, false, 0);
 
     // Split up our cache texture into lines of certain widths
-    int nextLine = 0;
+    int32_t nextLine = 0;
     mCacheLines.push(new CacheTextureLine(16, texType->getDimX(), nextLine, 0));
     nextLine += mCacheLines.top()->mMaxHeight;
     mCacheLines.push(new CacheTextureLine(24, texType->getDimX(), nextLine, 0));
@@ -519,8 +590,8 @@
 
     // Four verts, two triangles , six indices per quad
     for(uint32_t i = 0; i < mMaxNumberOfQuads; i ++) {
-        int i6 = i * 6;
-        int i4 = i * 4;
+        int32_t i6 = i * 6;
+        int32_t i4 = i * 4;
 
         indexPtr[i6 + 0] = i4 + 0;
         indexPtr[i6 + 1] = i4 + 1;
@@ -713,7 +784,11 @@
 }
 
 
-void FontState::renderText(const char *text, uint32_t len, uint32_t startIndex, int numGlyphs, int x, int y)
+void FontState::renderText(const char *text, uint32_t len, int32_t x, int32_t y,
+                           uint32_t startIndex, int32_t numGlyphs,
+                           Font::RenderMode mode,
+                           Font::Rect *bounds,
+                           uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH)
 {
     checkInit();
 
@@ -730,7 +805,8 @@
         return;
     }
 
-    currentFont->renderUTF(text, len, startIndex, numGlyphs, x, y);
+    currentFont->renderUTF(text, len, x, y, startIndex, numGlyphs,
+                           mode, bounds, bitmap, bitmapW, bitmapH);
 
     if(mCurrentQuadIndex != 0) {
         issueDrawCommand();
@@ -738,32 +814,8 @@
     }
 }
 
-void FontState::renderText(const char *text, int x, int y)
-{
-    size_t textLen = strlen(text);
-    renderText(text, textLen, 0, -1, x, y);
-}
-
-void FontState::renderText(Allocation *alloc, int x, int y)
-{
-    if(!alloc) {
-        return;
-    }
-
-    const char *text = (const char *)alloc->getPtr();
-    size_t allocSize = alloc->getType()->getSizeBytes();
-    renderText(text, allocSize, 0, -1, x, y);
-}
-
-void FontState::renderText(Allocation *alloc, uint32_t start, int len, int x, int y)
-{
-    if(!alloc) {
-        return;
-    }
-
-    const char *text = (const char *)alloc->getPtr();
-    size_t allocSize = alloc->getType()->getSizeBytes();
-    renderText(text, allocSize, start, len, x, y);
+void FontState::measureText(const char *text, uint32_t len, Font::Rect *bounds) {
+    renderText(text, len, 0, 0, 0, -1, Font::MEASURE, bounds);
 }
 
 void FontState::setFontColor(float r, float g, float b, float a) {
@@ -773,7 +825,7 @@
     mConstants.mFontColor[3] = a;
 
     mConstants.mGamma = 1.0f;
-    const int luminance = (r * 2.0f + g * 5.0f + b) / 8.0f;
+    const float luminance = (r * 2.0f + g * 5.0f + b) / 8.0f;
     if (luminance <= mBlackThreshold) {
         mConstants.mGamma = mBlackGamma;
     } else if (luminance >= mWhiteThreshold) {
diff --git a/libs/rs/rsFont.h b/libs/rs/rsFont.h
index 16009ef..0012b84 100644
--- a/libs/rs/rsFont.h
+++ b/libs/rs/rsFont.h
@@ -45,12 +45,26 @@
 class Font : public ObjectBase
 {
 public:
-    ~Font();
+    enum RenderMode {
+        FRAMEBUFFER,
+        BITMAP,
+        MEASURE,
+    };
 
-    // Pointer to the utf data, length of data, where to start, number of glyphs ot read
-    // (each glyph may be longer than a char because we are dealing with utf data)
-    // Last two variables are the initial pen position
-    void renderUTF(const char *text, uint32_t len, uint32_t start, int numGlyphs, int x, int y);
+    struct Rect {
+        int32_t left;
+        int32_t top;
+        int32_t right;
+        int32_t bottom;
+        void set(int32_t l, int32_t r, int32_t t, int32_t b) {
+            left = l;
+            right = r;
+            top = t;
+            bottom = b;
+        }
+    };
+
+    ~Font();
 
     // Currently files do not get serialized,
     // but we need to inherit from ObjectBase for ref tracking
@@ -66,6 +80,14 @@
 
     friend class FontState;
 
+    // Pointer to the utf data, length of data, where to start, number of glyphs ot read
+    // (each glyph may be longer than a char because we are dealing with utf data)
+    // Last two variables are the initial pen position
+    void renderUTF(const char *text, uint32_t len, int32_t x, int32_t y,
+                   uint32_t start, int32_t numGlyphs,
+                   RenderMode mode = FRAMEBUFFER, Rect *bounds = NULL,
+                   uint8_t *bitmap = NULL, uint32_t bitmapW = 0, uint32_t bitmapH = 0);
+
     void invalidateTextureCache();
     struct CachedGlyphInfo
     {
@@ -106,7 +128,10 @@
 
     CachedGlyphInfo *cacheGlyph(uint32_t glyph);
     void updateGlyphCache(CachedGlyphInfo *glyph);
-    void drawCachedGlyph(CachedGlyphInfo *glyph, int x, int y);
+    void measureCachedGlyph(CachedGlyphInfo *glyph, int32_t x, int32_t y, Rect *bounds);
+    void drawCachedGlyph(CachedGlyphInfo *glyph, int32_t x, int32_t y);
+    void drawCachedGlyph(CachedGlyphInfo *glyph, int32_t x, int32_t y,
+                         uint8_t *bitmap, uint32_t bitmapW, uint32_t bitmapH);
 };
 
 class FontState
@@ -121,10 +146,13 @@
     ObjectBaseRef<Font> mDefault;
     ObjectBaseRef<Font> mLast;
 
-    void renderText(const char *text, uint32_t len, uint32_t startIndex, int numGlyphs, int x, int y);
-    void renderText(const char *text, int x, int y);
-    void renderText(Allocation *alloc, int x, int y);
-    void renderText(Allocation *alloc, uint32_t start, int len, int x, int y);
+    void renderText(const char *text, uint32_t len, int32_t x, int32_t y,
+                    uint32_t startIndex = 0, int numGlyphs = -1,
+                    Font::RenderMode mode = Font::FRAMEBUFFER,
+                    Font::Rect *bounds = NULL,
+                    uint8_t *bitmap = NULL, uint32_t bitmapW = 0, uint32_t bitmapH = 0);
+
+    void measureText(const char *text, uint32_t len, Font::Rect *bounds);
 
     void setFontColor(float r, float g, float b, float a);
     void getFontColor(float *r, float *g, float *b, float *a) const;
@@ -198,6 +226,9 @@
     // Texture to cache glyph bitmaps
     ObjectBaseRef<Allocation> mTextTexture;
     void initTextTexture();
+    const uint8_t* getTextTextureData() const {
+        return (uint8_t*)mTextTexture->getPtr();
+    }
 
     bool cacheBitmap(FT_Bitmap *bitmap, uint32_t *retOriginX, uint32_t *retOriginY);
     const Type* getCacheTextureType() {
diff --git a/libs/rs/rsLight.cpp b/libs/rs/rsLight.cpp
deleted file mode 100644
index eab9a07..0000000
--- a/libs/rs/rsLight.cpp
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_RS_BUILD_FOR_HOST
-#include "rsContext.h"
-#include <GLES/gl.h>
-#else
-#include "rsContextHostStub.h"
-#include <OpenGL/gl.h>
-#endif //ANDROID_RS_BUILD_FOR_HOST
-
-using namespace android;
-using namespace android::renderscript;
-
-
-Light::Light(Context *rsc, bool isLocal, bool isMono) : ObjectBase(rsc)
-{
-    mAllocFile = __FILE__;
-    mAllocLine = __LINE__;
-    mIsLocal = isLocal;
-    mIsMono = isMono;
-
-    mPosition[0] = 0;
-    mPosition[1] = 0;
-    mPosition[2] = 1;
-    mPosition[3] = 0;
-
-    mColor[0] = 1.f;
-    mColor[1] = 1.f;
-    mColor[2] = 1.f;
-    mColor[3] = 1.f;
-}
-
-Light::~Light()
-{
-}
-
-void Light::setPosition(float x, float y, float z)
-{
-    mPosition[0] = x;
-    mPosition[1] = y;
-    mPosition[2] = z;
-}
-
-void Light::setColor(float r, float g, float b)
-{
-    mColor[0] = r;
-    mColor[1] = g;
-    mColor[2] = b;
-}
-
-void Light::setupGL(uint32_t num) const
-{
-    glLightfv(GL_LIGHT0 + num, GL_DIFFUSE, mColor);
-    glLightfv(GL_LIGHT0 + num, GL_SPECULAR, mColor);
-    glLightfv(GL_LIGHT0 + num, GL_POSITION, mPosition);
-}
-
-void Light::serialize(OStream *stream) const
-{
-    
-}
-
-Light *Light::createFromStream(Context *rsc, IStream *stream)
-{
-    return NULL;
-}
-
-////////////////////////////////////////////
-
-LightState::LightState()
-{
-    clear();
-}
-
-LightState::~LightState()
-{
-}
-
-void LightState::clear()
-{
-    mIsLocal = false;
-    mIsMono = false;
-}
-
-
-////////////////////////////////////////////////////
-//
-
-namespace android {
-namespace renderscript {
-
-void rsi_LightBegin(Context *rsc)
-{
-    rsc->mStateLight.clear();
-}
-
-void rsi_LightSetLocal(Context *rsc, bool isLocal)
-{
-    rsc->mStateLight.mIsLocal = isLocal;
-}
-
-void rsi_LightSetMonochromatic(Context *rsc, bool isMono)
-{
-    rsc->mStateLight.mIsMono = isMono;
-}
-
-RsLight rsi_LightCreate(Context *rsc)
-{
-    Light *l = new Light(rsc, rsc->mStateLight.mIsLocal,
-                         rsc->mStateLight.mIsMono);
-    l->incUserRef();
-    return l;
-}
-
-void rsi_LightSetColor(Context *rsc, RsLight vl, float r, float g, float b)
-{
-    Light *l = static_cast<Light *>(vl);
-    l->setColor(r, g, b);
-}
-
-void rsi_LightSetPosition(Context *rsc, RsLight vl, float x, float y, float z)
-{
-    Light *l = static_cast<Light *>(vl);
-    l->setPosition(x, y, z);
-}
-
-
-
-}
-}
diff --git a/libs/rs/rsLight.h b/libs/rs/rsLight.h
deleted file mode 100644
index bd58979..0000000
--- a/libs/rs/rsLight.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_LIGHT_H
-#define ANDROID_LIGHT_H
-
-
-#include "rsObjectBase.h"
-
-// ---------------------------------------------------------------------------
-namespace android {
-namespace renderscript {
-
-
-// An element is a group of Components that occupies one cell in a structure.
-class Light : public ObjectBase
-{
-public:
-    Light(Context *, bool isLocal, bool isMono);
-    virtual ~Light();
-
-    // Values, mutable after creation.
-    void setPosition(float x, float y, float z);
-    void setColor(float r, float g, float b);
-
-    void setupGL(uint32_t num) const;
-    virtual void serialize(OStream *stream) const;
-    virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_LIGHT; }
-    static Light *createFromStream(Context *rsc, IStream *stream);
-
-protected:
-    float mColor[4];
-    float mPosition[4];
-    bool mIsLocal;
-    bool mIsMono;
-};
-
-
-class LightState {
-public:
-    LightState();
-    ~LightState();
-
-    void clear();
-
-    bool mIsMono;
-    bool mIsLocal;
-};
-
-
-}
-}
-#endif //ANDROID_LIGHT_H
-
diff --git a/libs/rs/rsScriptC_LibGL.cpp b/libs/rs/rsScriptC_LibGL.cpp
index 88db761..b991cab 100644
--- a/libs/rs/rsScriptC_LibGL.cpp
+++ b/libs/rs/rsScriptC_LibGL.cpp
@@ -351,13 +351,59 @@
     CHECK_OBJ(va);
     GET_TLS();
     Allocation *alloc = static_cast<Allocation *>(va);
-    rsc->mStateFont.renderText(alloc, x, y);
+    const char *text = (const char *)alloc->getPtr();
+    size_t allocSize = alloc->getType()->getSizeBytes();
+    rsc->mStateFont.renderText(text, allocSize, x, y);
 }
 
 static void SC_DrawText(const char *text, int x, int y)
 {
     GET_TLS();
-    rsc->mStateFont.renderText(text, x, y);
+    size_t textLen = strlen(text);
+    rsc->mStateFont.renderText(text, textLen, x, y);
+}
+
+static void SC_setMetrics(Font::Rect *metrics,
+                          int32_t *left, int32_t *right,
+                          int32_t *top, int32_t *bottom)
+{
+    if(left) {
+        *left = metrics->left;
+    }
+    if(right) {
+        *right = metrics->right;
+    }
+    if(top) {
+        *top = metrics->top;
+    }
+    if(bottom) {
+        *bottom = metrics->bottom;
+    }
+}
+
+static void SC_MeasureTextAlloc(RsAllocation va,
+                                int32_t *left, int32_t *right,
+                                int32_t *top, int32_t *bottom)
+{
+    CHECK_OBJ(va);
+    GET_TLS();
+    Allocation *alloc = static_cast<Allocation *>(va);
+    const char *text = (const char *)alloc->getPtr();
+    size_t textLen = alloc->getType()->getSizeBytes();
+    Font::Rect metrics;
+    rsc->mStateFont.measureText(text, textLen, &metrics);
+    SC_setMetrics(&metrics, left, right, top, bottom);
+}
+
+static void SC_MeasureText(const char *text,
+                           int32_t *left, int32_t *right,
+                           int32_t *top, int32_t *bottom)
+{
+    GET_TLS();
+    size_t textLen = strlen(text);
+    Font::Rect metrics;
+    rsc->mStateFont.measureText(text, textLen, &metrics);
+    SC_setMetrics(&metrics, left, right, top, bottom);
 }
 
 static void SC_BindFont(RsFont font)
@@ -432,6 +478,8 @@
 
     { "_Z11rsgDrawTextPKcii", (void *)&SC_DrawText },
     { "_Z11rsgDrawText13rs_allocationii", (void *)&SC_DrawTextAlloc },
+    { "_Z14rsgMeasureTextPKcPiS1_S1_S1_", (void *)&SC_MeasureText },
+    { "_Z14rsgMeasureText13rs_allocationPiS0_S0_S0_", (void *)&SC_MeasureTextAlloc },
 
     { "_Z11rsgBindFont7rs_font", (void *)&SC_BindFont },
     { "_Z12rsgFontColorffff", (void *)&SC_FontColor },
diff --git a/libs/rs/rsType.cpp b/libs/rs/rsType.cpp
index fc037a3..8cdb48a 100644
--- a/libs/rs/rsType.cpp
+++ b/libs/rs/rsType.cpp
@@ -274,6 +274,59 @@
     return false;
 }
 
+Type * Type::cloneAndResize1D(Context *rsc, uint32_t dimX) const
+{
+    TypeState * stc = &rsc->mStateType;
+    for (uint32_t ct=0; ct < stc->mTypes.size(); ct++) {
+        Type *t = stc->mTypes[ct];
+        if (t->getElement() != mElement.get()) continue;
+        if (t->getDimX() != dimX) continue;
+        if (t->getDimY() != mDimY) continue;
+        if (t->getDimZ() != mDimZ) continue;
+        if (t->getDimLOD() != mDimLOD) continue;
+        if (t->getDimFaces() != mFaces) continue;
+        t->incUserRef();
+        return t;
+    }
+
+    Type *nt = new Type(rsc);
+    nt->mElement.set(mElement);
+    nt->mDimX = dimX;
+    nt->mDimY = mDimY;
+    nt->mDimZ = mDimZ;
+    nt->mDimLOD = mDimLOD;
+    nt->mFaces = mFaces;
+    nt->compute();
+    return nt;
+}
+
+Type * Type::cloneAndResize2D(Context *rsc, uint32_t dimX, uint32_t dimY) const
+{
+    TypeState * stc = &rsc->mStateType;
+    for (uint32_t ct=0; ct < stc->mTypes.size(); ct++) {
+        Type *t = stc->mTypes[ct];
+        if (t->getElement() != mElement.get()) continue;
+        if (t->getDimX() != dimX) continue;
+        if (t->getDimY() != dimY) continue;
+        if (t->getDimZ() != mDimZ) continue;
+        if (t->getDimLOD() != mDimLOD) continue;
+        if (t->getDimFaces() != mFaces) continue;
+        t->incUserRef();
+        return t;
+    }
+
+    Type *nt = new Type(rsc);
+    nt->mElement.set(mElement);
+    nt->mDimX = dimX;
+    nt->mDimY = dimY;
+    nt->mDimZ = mDimZ;
+    nt->mDimLOD = mDimLOD;
+    nt->mFaces = mFaces;
+    nt->compute();
+    return nt;
+}
+
+
 //////////////////////////////////////////////////
 //
 namespace android {
diff --git a/libs/rs/rsType.h b/libs/rs/rsType.h
index 33faa87..b5548c0 100644
--- a/libs/rs/rsType.h
+++ b/libs/rs/rsType.h
@@ -79,6 +79,9 @@
 
     bool isEqual(const Type *other) const;
 
+    Type * cloneAndResize1D(Context *rsc, uint32_t dimX) const;
+    Type * cloneAndResize2D(Context *rsc, uint32_t dimX, uint32_t dimY) const;
+
 protected:
     struct LOD {
         size_t mX;
diff --git a/libs/rs/rsVertexArray.h b/libs/rs/rsVertexArray.h
index bd76d87..dea7d41 100644
--- a/libs/rs/rsVertexArray.h
+++ b/libs/rs/rsVertexArray.h
@@ -62,7 +62,6 @@
     }
 
     void add(const Attrib &, uint32_t stride);
-    //void addLegacy(uint32_t type, uint32_t size, uint32_t stride, bool normalized, uint32_t offset);
     void add(uint32_t type, uint32_t size, uint32_t stride, bool normalized, uint32_t offset, const char *name);
 
     void setupGL2(const Context *rsc, class VertexArrayState *, ShaderCache *) const;
@@ -89,7 +88,7 @@
 
 }
 }
-#endif //ANDROID_LIGHT_H
+#endif //ANDROID_VERTEX_ARRAY_H
 
 
 
diff --git a/libs/rs/scriptc/rs_graphics.rsh b/libs/rs/scriptc/rs_graphics.rsh
index c0b2d2d..ac6f8cc 100644
--- a/libs/rs/scriptc/rs_graphics.rsh
+++ b/libs/rs/scriptc/rs_graphics.rsh
@@ -79,6 +79,12 @@
     rsgBindFont(rs_font);
 extern void __attribute__((overloadable))
     rsgFontColor(float, float, float, float);
+// Returns the bounding box of the text relative to (0, 0)
+// Any of left, right, top, bottom could be NULL
+extern void __attribute__((overloadable))
+    rsgMeasureText(const char *, int *left, int *right, int *top, int *bottom);
+extern void __attribute__((overloadable))
+    rsgMeasureText(rs_allocation, int *left, int *right, int *top, int *bottom);
 
 extern void __attribute__((overloadable))
     rsgMeshComputeBoundingBox(rs_mesh mesh, float *minX, float *minY, float *minZ,
diff --git a/media/java/android/media/videoeditor/AudioTrack.java b/media/java/android/media/videoeditor/AudioTrack.java
index 3b800f2..8da7eaa 100755
--- a/media/java/android/media/videoeditor/AudioTrack.java
+++ b/media/java/android/media/videoeditor/AudioTrack.java
@@ -32,14 +32,15 @@
     // Instance variables

     private final String mUniqueId;

     private final String mFilename;

-    private final long mDurationMs;

     private long mStartTimeMs;

     private long mTimelineDurationMs;

     private int mVolumePercent;

     private long mBeginBoundaryTimeMs;

     private long mEndBoundaryTimeMs;

     private boolean mLoop;

+    private boolean mMuted;

 

+    private final long mDurationMs;

     private final int mAudioChannels;

     private final int mAudioType;

     private final int mAudioBitrate;

@@ -217,6 +218,9 @@
         // By default loop is disabled

         mLoop = false;

 

+        // By default the audio track is not muted

+        mMuted = false;

+

         // Ducking is enabled by default

         mDuckingThreshold = 0;

         mDuckingLowVolume = 0;

@@ -239,12 +243,13 @@
      *            beginning of the audio track)

      * @param loop true to loop the audio track

      * @param volume The volume in percentage

+     * @param muted true if the audio track is muted

      * @param audioWaveformFilename The name of the waveform file

      *

      * @throws IOException if file is not found

      */

     AudioTrack(String audioTrackId, String filename, long startTimeMs, long beginMs, long endMs,

-            boolean loop, int volume, String audioWaveformFilename) throws IOException {

+            boolean loop, int volume, boolean muted, String audioWaveformFilename) throws IOException {

         mUniqueId = audioTrackId;

         mFilename = filename;

         mStartTimeMs = startTimeMs;

@@ -266,6 +271,7 @@
         mEndBoundaryTimeMs = endMs;

 

         mLoop = loop;

+        mMuted = muted;

 

         mAudioWaveformFilename = audioWaveformFilename;

     }

@@ -341,6 +347,20 @@
     }

 

     /**

+     * @param muted true to mute the audio track

+     */

+    public void setMute(boolean muted) {

+        mMuted = muted;

+    }

+

+    /**

+     * @return true if the audio track is muted

+     */

+    public boolean isMuted() {

+        return mMuted;

+    }

+

+    /**

      * Set the start time of this audio track relative to the storyboard

      * timeline. Default value is 0.

      *

diff --git a/media/java/android/media/videoeditor/MediaVideoItem.java b/media/java/android/media/videoeditor/MediaVideoItem.java
index 13014a7..cc0a155 100755
--- a/media/java/android/media/videoeditor/MediaVideoItem.java
+++ b/media/java/android/media/videoeditor/MediaVideoItem.java
@@ -49,6 +49,7 @@
     private long mBeginBoundaryTimeMs;

     private long mEndBoundaryTimeMs;

     private int mVolumePercentage;

+    private boolean mMuted;

     private String mAudioWaveformFilename;

     private PlaybackThread mPlaybackThread;

 

@@ -206,7 +207,7 @@
      */

     public MediaVideoItem(String mediaItemId, String filename, int renderingMode)

         throws IOException {

-        this(mediaItemId, filename, renderingMode, null);

+        this(mediaItemId, filename, renderingMode, 0, END_OF_FILE, 100, false, null);

     }

 

     /**

@@ -215,11 +216,19 @@
      * @param mediaItemId The MediaItem id

      * @param filename The image file name

      * @param renderingMode The rendering mode

+     * @param beginMs Start time in milliseconds. Set to 0 to extract from the

+     *           beginning

+     * @param endMs End time in milliseconds. Set to {@link #END_OF_FILE} to

+     *           extract until the end

+     * @param volumePercent in %/. 100% means no change; 50% means half value, 200%

+     *            means double, 0% means silent.

+     * @param muted true if the audio is muted

      * @param audioWaveformFilename The name of the audio waveform file

      *

      * @throws IOException if the file cannot be opened for reading

      */

     MediaVideoItem(String mediaItemId, String filename, int renderingMode,

+            long beginMs, long endMs, int volumePercent, boolean muted,

             String audioWaveformFilename)  throws IOException {

         super(mediaItemId, filename, renderingMode);

         // TODO: Set these variables correctly

@@ -239,9 +248,10 @@
         mAudioChannels = 2;

         mAudioSamplingFrequency = 16000;

 

-        mBeginBoundaryTimeMs = 0;

-        mEndBoundaryTimeMs = mDurationMs;

-        mVolumePercentage = 100;

+        mBeginBoundaryTimeMs = beginMs;

+        mEndBoundaryTimeMs = endMs == END_OF_FILE ? mDurationMs : endMs;

+        mVolumePercentage = volumePercent;

+        mMuted = muted;

         mAudioWaveformFilename = audioWaveformFilename;

     }

 

@@ -539,6 +549,20 @@
     }

 

     /**

+     * @param muted true to mute the media item

+     */

+    public void setMute(boolean muted) {

+        mMuted = muted;

+    }

+

+    /**

+     * @return true if the media item is muted

+     */

+    public boolean isMuted() {

+        return mMuted;

+    }

+

+    /**

      * @return The video type

      */

     public int getVideoType() {

diff --git a/media/java/android/media/videoeditor/VideoEditorTestImpl.java b/media/java/android/media/videoeditor/VideoEditorTestImpl.java
index de962e89..b39d9d8 100644
--- a/media/java/android/media/videoeditor/VideoEditorTestImpl.java
+++ b/media/java/android/media/videoeditor/VideoEditorTestImpl.java
@@ -89,6 +89,7 @@
     private static final String ATTR_END_RECT_R = "end_r";
     private static final String ATTR_END_RECT_B = "end_b";
     private static final String ATTR_LOOP = "loop";
+    private static final String ATTR_MUTED = "muted";
 
     // Instance variables
     private long mDurationMs;
@@ -582,6 +583,7 @@
                         .attribute("", ATTR_BEGIN_TIME, Long.toString(mvi.getBoundaryBeginTime()));
                 serializer.attribute("", ATTR_END_TIME, Long.toString(mvi.getBoundaryEndTime()));
                 serializer.attribute("", ATTR_VOLUME, Integer.toString(mvi.getVolume()));
+                serializer.attribute("", ATTR_MUTED, Boolean.toString(mvi.isMuted()));
                 if (mvi.getAudioWaveformFilename() != null) {
                     serializer.attribute("", ATTR_AUDIO_WAVEFORM_FILENAME,
                             mvi.getAudioWaveformFilename());
@@ -713,6 +715,7 @@
             serializer.attribute("", ATTR_BEGIN_TIME, Long.toString(at.getBoundaryBeginTime()));
             serializer.attribute("", ATTR_END_TIME, Long.toString(at.getBoundaryEndTime()));
             serializer.attribute("", ATTR_VOLUME, Integer.toString(at.getVolume()));
+            serializer.attribute("", ATTR_MUTED, Boolean.toString(at.isMuted()));
             serializer.attribute("", ATTR_LOOP, Boolean.toString(at.isLooping()));
             if (at.getAudioWaveformFilename() != null) {
                 serializer.attribute("", ATTR_AUDIO_WAVEFORM_FILENAME,
@@ -765,10 +768,19 @@
                             currentMediaItem = new MediaImageItem(mediaItemId, filename,
                                     durationMs, renderingMode);
                         } else if (MediaVideoItem.class.getSimpleName().equals(type)) {
+                            final long beginMs = Long.parseLong(parser.getAttributeValue("",
+                                    ATTR_BEGIN_TIME));
+                            final long endMs = Long.parseLong(parser.getAttributeValue("",
+                                    ATTR_END_TIME));
+                            final int volume = Integer.parseInt(parser.getAttributeValue("",
+                                    ATTR_VOLUME));
+                            final boolean muted = Boolean.parseBoolean(parser.getAttributeValue("",
+                                    ATTR_MUTED));
                             final String audioWaveformFilename = parser.getAttributeValue("",
                                     ATTR_AUDIO_WAVEFORM_FILENAME);
                             currentMediaItem = new MediaVideoItem(mediaItemId, filename,
-                                    renderingMode, audioWaveformFilename);
+                                    renderingMode, beginMs, endMs, volume, muted,
+                                    audioWaveformFilename);
 
                             final long beginTimeMs = Long.parseLong(parser.getAttributeValue("",
                                     ATTR_BEGIN_TIME));
@@ -1001,11 +1013,12 @@
         final long beginMs = Long.parseLong(parser.getAttributeValue("", ATTR_BEGIN_TIME));
         final long endMs = Long.parseLong(parser.getAttributeValue("", ATTR_END_TIME));
         final int volume = Integer.parseInt(parser.getAttributeValue("", ATTR_VOLUME));
+        final boolean muted = Boolean.parseBoolean(parser.getAttributeValue("", ATTR_MUTED));
         final boolean loop = Boolean.parseBoolean(parser.getAttributeValue("", ATTR_LOOP));
         final String waveformFilename = parser.getAttributeValue("", ATTR_AUDIO_WAVEFORM_FILENAME);
         try {
             final AudioTrack audioTrack = new AudioTrack(audioTrackId, filename, startTimeMs,
-                    beginMs, endMs, loop, volume, waveformFilename);
+                    beginMs, endMs, loop, volume, muted, waveformFilename);
 
             return audioTrack;
         } catch (IOException ex) {
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 546df47..90b1aab 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -40,6 +40,7 @@
 static const int64_t kMax32BitFileSize = 0x007fffffffLL;
 static const uint8_t kNalUnitTypeSeqParamSet = 0x07;
 static const uint8_t kNalUnitTypePicParamSet = 0x08;
+static const int64_t kVideoMediaTimeAdjustPeriodTimeUs = 10000000LL;  // 10s
 
 class MPEG4Writer::Track {
 public:
@@ -148,6 +149,28 @@
     int64_t mPreviousTrackTimeUs;
     int64_t mTrackEveryTimeDurationUs;
 
+    // Has the media time adjustment for video started?
+    bool    mIsMediaTimeAdjustmentOn;
+    // The time stamp when previous media time adjustment period starts
+    int64_t mPrevMediaTimeAdjustTimestampUs;
+    // Number of vidoe frames whose time stamp may be adjusted
+    int64_t mMediaTimeAdjustNumFrames;
+    // The sample number when previous meida time adjustmnet period starts
+    int64_t mPrevMediaTimeAdjustSample;
+    // The total accumulated drift time within a period of
+    // kVideoMediaTimeAdjustPeriodTimeUs.
+    int64_t mTotalDriftTimeToAdjustUs;
+    // The total accumalated drift time since the start of the recording
+    // excluding the current time adjustment period
+    int64_t mPrevTotalAccumDriftTimeUs;
+
+    // Update the audio track's drift information.
+    void updateDriftTime(const sp<MetaData>& meta);
+
+    // Adjust the time stamp of the video track according to
+    // the drift time information from the audio track.
+    void adjustMediaTime(int64_t *timestampUs);
+
     static void *ThreadWrapper(void *me);
     status_t threadEntry();
 
@@ -319,7 +342,7 @@
         size = MAX_MOOV_BOX_SIZE;
     }
 
-    LOGI("limits: %lld/%lld bytes/us, bit rate: %d bps and the estimated"
+    LOGV("limits: %lld/%lld bytes/us, bit rate: %d bps and the estimated"
          " moov size %lld bytes",
          mMaxFileSizeLimitBytes, mMaxFileDurationLimitUs, bitRate, size);
     return factor * size;
@@ -346,7 +369,7 @@
         // If file size is set to be larger than the 32 bit file
         // size limit, treat it as an error.
         if (mMaxFileSizeLimitBytes > kMax32BitFileSize) {
-            LOGW("32-bi file size limit (%lld bytes) too big. "
+            LOGW("32-bit file size limit (%lld bytes) too big. "
                  "It is changed to %lld bytes",
                 mMaxFileSizeLimitBytes, kMax32BitFileSize);
             mMaxFileSizeLimitBytes = kMax32BitFileSize;
@@ -1149,6 +1172,12 @@
     mNumStscTableEntries = 0;
     mNumSttsTableEntries = 0;
     mMdatSizeBytes = 0;
+    mIsMediaTimeAdjustmentOn = false;
+    mPrevMediaTimeAdjustTimestampUs = 0;
+    mMediaTimeAdjustNumFrames = 0;
+    mPrevMediaTimeAdjustSample = 0;
+    mTotalDriftTimeToAdjustUs = 0;
+    mPrevTotalAccumDriftTimeUs = 0;
 
     pthread_create(&mThread, &attr, ThreadWrapper, this);
     pthread_attr_destroy(&attr);
@@ -1437,6 +1466,145 @@
     return OK;
 }
 
+/*
+* The video track's media time adjustment for real-time applications
+* is described as follows:
+*
+* First, the media time adjustment is done for every period of
+* kVideoMediaTimeAdjustPeriodTimeUs. kVideoMediaTimeAdjustPeriodTimeUs
+* is currently a fixed value chosen heuristically. The value of
+* kVideoMediaTimeAdjustPeriodTimeUs should not be very large or very small
+* for two considerations: on one hand, a relatively large value
+* helps reduce large fluctuation of drift time in the audio encoding
+* path; while on the other hand, a relatively small value helps keep
+* restoring synchronization in audio/video more frequently. Note for the
+* very first period of kVideoMediaTimeAdjustPeriodTimeUs, there is
+* no media time adjustment for the video track.
+*
+* Second, the total accumulated audio track time drift found
+* in a period of kVideoMediaTimeAdjustPeriodTimeUs is distributed
+* over a stream of incoming video frames. The number of video frames
+* affected is determined based on the number of recorded video frames
+* within the past kVideoMediaTimeAdjustPeriodTimeUs period.
+* We choose to distribute the drift time over only a portion
+* (rather than all) of the total number of recorded video frames
+* in order to make sure that the video track media time adjustment is
+* completed for the current period before the next video track media
+* time adjustment period starts. Currently, the portion chosen is a
+* half (0.5).
+*
+* Last, various additional checks are performed to ensure that
+* the actual audio encoding path does not have too much drift.
+* In particular, 1) we want to limit the average incremental time
+* adjustment for each video frame to be less than a threshold
+* for a single period of kVideoMediaTimeAdjustPeriodTimeUs.
+* Currently, the threshold is set to 5 ms. If the average incremental
+* media time adjustment for a video frame is larger than the
+* threshold, the audio encoding path has too much time drift.
+* 2) We also want to limit the total time drift in the audio
+* encoding path to be less than a threshold for a period of
+* kVideoMediaTimeAdjustPeriodTimeUs. Currently, the threshold
+* is 0.5% of kVideoMediaTimeAdjustPeriodTimeUs. If the time drift of
+* the audio encoding path is larger than the threshold, the audio
+* encoding path has too much time drift. We treat the large time
+* drift of the audio encoding path as errors, since there is no
+* way to keep audio/video in synchronization for real-time
+* applications if the time drift is too large unless we drop some
+* video frames, which has its own problems that we don't want
+* to get into for the time being.
+*/
+void MPEG4Writer::Track::adjustMediaTime(int64_t *timestampUs) {
+    if (*timestampUs - mPrevMediaTimeAdjustTimestampUs >=
+        kVideoMediaTimeAdjustPeriodTimeUs) {
+
+        LOGV("New media time adjustment period at %lld us", *timestampUs);
+        mIsMediaTimeAdjustmentOn = true;
+        mMediaTimeAdjustNumFrames =
+                (mNumSamples - mPrevMediaTimeAdjustSample) >> 1;
+
+        mPrevMediaTimeAdjustTimestampUs = *timestampUs;
+        mPrevMediaTimeAdjustSample = mNumSamples;
+        int64_t totalAccumDriftTimeUs = mOwner->getDriftTimeUs();
+        mTotalDriftTimeToAdjustUs =
+                totalAccumDriftTimeUs - mPrevTotalAccumDriftTimeUs;
+
+        mPrevTotalAccumDriftTimeUs = totalAccumDriftTimeUs;
+
+        // Check on incremental adjusted time per frame
+        int64_t adjustTimePerFrameUs =
+                mTotalDriftTimeToAdjustUs / mMediaTimeAdjustNumFrames;
+
+        if (adjustTimePerFrameUs < 0) {
+            adjustTimePerFrameUs = -adjustTimePerFrameUs;
+        }
+        if (adjustTimePerFrameUs >= 5000) {
+            LOGE("Adjusted time per video frame is %lld us",
+                adjustTimePerFrameUs);
+            CHECK(!"Video frame time adjustment is too large!");
+        }
+
+        // Check on total accumulated time drift within a period of
+        // kVideoMediaTimeAdjustPeriodTimeUs.
+        int64_t driftPercentage = (mTotalDriftTimeToAdjustUs * 1000)
+                / kVideoMediaTimeAdjustPeriodTimeUs;
+
+        if (driftPercentage < 0) {
+            driftPercentage = -driftPercentage;
+        }
+        if (driftPercentage > 5) {
+            LOGE("Audio track has time drift %lld us over %lld us",
+                mTotalDriftTimeToAdjustUs,
+                kVideoMediaTimeAdjustPeriodTimeUs);
+
+            CHECK(!"The audio track media time drifts too much!");
+        }
+
+    }
+
+    if (mIsMediaTimeAdjustmentOn) {
+        if (mNumSamples - mPrevMediaTimeAdjustSample <=
+            mMediaTimeAdjustNumFrames) {
+
+            // Do media time incremental adjustment
+            int64_t incrementalAdjustTimeUs =
+                        (mTotalDriftTimeToAdjustUs *
+                            (mNumSamples - mPrevMediaTimeAdjustSample))
+                                / mMediaTimeAdjustNumFrames;
+
+            *timestampUs +=
+                (incrementalAdjustTimeUs + mPrevTotalAccumDriftTimeUs);
+
+            LOGV("Incremental video frame media time adjustment: %lld us",
+                (incrementalAdjustTimeUs + mPrevTotalAccumDriftTimeUs));
+        } else {
+            // Within the remaining adjustment period,
+            // no incremental adjustment is needed.
+            *timestampUs +=
+                (mTotalDriftTimeToAdjustUs + mPrevTotalAccumDriftTimeUs);
+
+            LOGV("Fixed video frame media time adjustment: %lld us",
+                (mTotalDriftTimeToAdjustUs + mPrevTotalAccumDriftTimeUs));
+        }
+    }
+}
+
+/*
+ * Updates the drift time from the audio track so that
+ * the video track can get the updated drift time information
+ * from the file writer. The fluctuation of the drift time of the audio
+ * encoding path is smoothed out with a simple filter by giving a larger
+ * weight to more recently drift time. The filter coefficients, 0.5 and 0.5,
+ * are heuristically determined.
+ */
+void MPEG4Writer::Track::updateDriftTime(const sp<MetaData>& meta) {
+    int64_t driftTimeUs = 0;
+    if (meta->findInt64(kKeyDriftTime, &driftTimeUs)) {
+        int64_t prevDriftTimeUs = mOwner->getDriftTimeUs();
+        int64_t timeUs = (driftTimeUs + prevDriftTimeUs) >> 1;
+        mOwner->setDriftTimeUs(timeUs);
+    }
+}
+
 status_t MPEG4Writer::Track::threadEntry() {
     int32_t count = 0;
     const int64_t interleaveDurationUs = mOwner->interleaveDuration();
@@ -1587,24 +1755,16 @@
 
         timestampUs -= previousPausedDurationUs;
         CHECK(timestampUs >= 0);
-        if (mIsRealTimeRecording && !mIsAudio) {
-            // The minor adjustment on the timestamp is heuristic/experimental
-            // We are adjusting the timestamp to reduce the fluctuation of the duration
-            // of neighboring samples. This in turn helps reduce the track header size,
-            // especially, the number of entries in the "stts" box.
-            if (mNumSamples > 1) {
-                int64_t currDriftTimeUs = mOwner->getDriftTimeUs();
-                int64_t durationUs = timestampUs + currDriftTimeUs - lastTimestampUs;
-                int64_t diffUs = (durationUs > lastDurationUs)
-                            ? durationUs - lastDurationUs
-                            : lastDurationUs - durationUs;
-                if (diffUs <= 5000) {  // XXX: Magic number 5ms
-                    timestampUs = lastTimestampUs + lastDurationUs;
-                } else {
-                    timestampUs += currDriftTimeUs;
-                }
+
+        // Media time adjustment for real-time applications
+        if (mIsRealTimeRecording) {
+            if (mIsAudio) {
+                updateDriftTime(meta_data);
+            } else {
+                adjustMediaTime(&timestampUs);
             }
         }
+
         CHECK(timestampUs >= 0);
         if (mNumSamples > 1) {
             if (timestampUs <= lastTimestampUs) {
@@ -1656,12 +1816,6 @@
         lastDurationUs = timestampUs - lastTimestampUs;
         lastDurationTicks = currDurationTicks;
         lastTimestampUs = timestampUs;
-        if (mIsRealTimeRecording && mIsAudio) {
-            int64_t driftTimeUs = 0;
-            if (meta_data->findInt64(kKeyDriftTime, &driftTimeUs)) {
-                mOwner->setDriftTimeUs(driftTimeUs);
-            }
-        }
 
         if (isSync != 0) {
             addOneStssTableEntry(mNumSamples);
@@ -1735,6 +1889,9 @@
     mReachedEOS = true;
     LOGI("Received total/0-length (%d/%d) buffers and encoded %d frames. - %s",
             count, nZeroLengthFrames, mNumSamples, mIsAudio? "audio": "video");
+    if (mIsAudio) {
+        LOGI("Audio track drift time: %lld us", mOwner->getDriftTimeUs());
+    }
 
     if (err == ERROR_END_OF_STREAM) {
         return OK;
diff --git a/packages/SystemUI/res/drawable-hdpi/battery_low_battery.png b/packages/SystemUI/res/drawable-hdpi/battery_low_battery.png
index d894f7b..e74c22f 100644
--- a/packages/SystemUI/res/drawable-hdpi/battery_low_battery.png
+++ b/packages/SystemUI/res/drawable-hdpi/battery_low_battery.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_notification_overlay.9.png b/packages/SystemUI/res/drawable-hdpi/ic_notification_overlay.9.png
index 744178f..d6c8a21 100644
--- a/packages/SystemUI/res/drawable-hdpi/ic_notification_overlay.9.png
+++ b/packages/SystemUI/res/drawable-hdpi/ic_notification_overlay.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_0.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_0.png
index 3e317dd..b16e436 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_0.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_0.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_0_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_0_fully.png
index 2f66b1d..b16e436 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_0_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_0_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1.png
index 72329f8..1b6ed74 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1_fully.png
index 72329f8..43e35d3 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_1_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2.png
index 558c49c..498adbb 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2_fully.png
index 558c49c..b7e42a0 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_2_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3.png
index 6440bdd..959fc5c 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3_fully.png
index 6440bdd..f905979 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_3_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4.png
index fe20423..6e8e73c 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4_fully.png
index fe20423..b5799c8 100644
--- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4_fully.png
+++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_4_fully.png
Binary files differ
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
new file mode 100644
index 0000000..a0def6b
--- /dev/null
+++ b/packages/SystemUI/res/values/colors.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+ * Copyright 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.
+ */
+-->
+<resources>
+    <drawable name="notification_number_text_color">#ffffffff</drawable>
+</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/IconMerger.java b/packages/SystemUI/src/com/android/systemui/statusbar/IconMerger.java
index 027bed4a..e87d003 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/IconMerger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/IconMerger.java
@@ -23,28 +23,34 @@
 import android.view.View;
 import android.widget.LinearLayout;
 
+import com.android.internal.statusbar.StatusBarIcon;
+
 import com.android.systemui.R;
 
 
 public class IconMerger extends LinearLayout {
     private static final String TAG = "IconMerger";
 
+    private int mIconSize;
     private StatusBarIconView mMoreView;
+    private StatusBarIcon mMoreIcon = new StatusBarIcon(null, R.drawable.stat_notify_more, 0);
 
     public IconMerger(Context context, AttributeSet attrs) {
         super(context, attrs);
+
+        mIconSize = context.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.status_bar_icon_size);
+
+        mMoreView = new StatusBarIconView(context, "more");
+        mMoreView.set(mMoreIcon);
+        addView(mMoreView, 0, new LinearLayout.LayoutParams(mIconSize, mIconSize));
     }
 
-    public void addMoreView(StatusBarIconView v, LinearLayout.LayoutParams lp) {
-        super.addView(v, lp);
-        mMoreView = v;
-    }
-
-    public void addView(StatusBarIconView v, int index, LinearLayout.LayoutParams lp) {
+    public void addView(StatusBarIconView v, int index) {
         if (index == 0) {
             throw new RuntimeException("Attempt to put view before the more view: " + v);
         }
-        super.addView(v, index, lp);
+        addView(v, index, new LinearLayout.LayoutParams(mIconSize, mIconSize));
     }
 
     @Override
@@ -127,28 +133,8 @@
                 }
             }
         }
-        
-        // BUG: Updating the text during the layout here doesn't seem to cause
-        // the view to be redrawn fully.  The text view gets resized correctly, but the
-        // text contents aren't drawn properly.  To work around this, we post a message
-        // and provide the value later.  We're the only one changing this value show it
-        // should be ordered correctly.
-        if (false) {
-            // TODO this.moreIcon.update(number);
-        } else {
-            mBugWorkaroundNumber = number;
-            mBugWorkaroundHandler.post(mBugWorkaroundRunnable);
-        }
-    }
 
-    private int mBugWorkaroundNumber;
-    private Handler mBugWorkaroundHandler = new Handler();
-    private Runnable mBugWorkaroundRunnable = new Runnable() {
-        public void run() {
-            /* TODO
-            IconMerger.this.moreIcon.update(mBugWorkaroundNumber);
-            IconMerger.this.moreIcon.view.invalidate();
-            */
-        }
-    };
+        mMoreIcon.number = number;
+        mMoreView.set(mMoreIcon);
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
index e945981..57ebd27 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java
@@ -274,12 +274,6 @@
 
         mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore);
 
-        // the more notifications icon
-        StatusBarIconView moreView = new StatusBarIconView(this, "more");
-        moreView.set(new StatusBarIcon(null, R.drawable.stat_notify_more, 0));
-        mNotificationIcons.addMoreView(moreView,
-                new LinearLayout.LayoutParams(mIconSize, mIconSize));
-
         // set the inital view visibility
         setAreThereNotifications();
         mDateView.setVisibility(View.INVISIBLE);
@@ -579,8 +573,7 @@
         parent.addView(row, viewIndex);
         // Add the icon.
         final int iconIndex = chooseIconIndex(isOngoing, viewIndex);
-        mNotificationIcons.addView(iconView, iconIndex,
-                new LinearLayout.LayoutParams(mIconSize, mIconSize));
+        mNotificationIcons.addView(iconView, iconIndex);
         return iconView;
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 0ca0572..8419e56 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -21,22 +21,37 @@
 import android.content.res.Resources;
 import android.graphics.drawable.Drawable;
 import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
 import android.util.Slog;
 import android.util.Log;
+import android.view.View;
 import android.view.ViewDebug;
 import android.widget.FrameLayout;
 
 import com.android.internal.statusbar.StatusBarIcon;
 
+import com.android.systemui.R;
+
 public class StatusBarIconView extends AnimatedImageView {
     private static final String TAG = "StatusBarIconView";
 
     private StatusBarIcon mIcon;
     @ViewDebug.ExportedProperty private String mSlot;
+    private Drawable mNumberBackground;
+    private Paint mNumberPain;
+    private int mNumberX;
+    private int mNumberY;
+    private String mNumberText;
 
     public StatusBarIconView(Context context, String slot) {
         super(context);
+        final Resources res = context.getResources();
         mSlot = slot;
+        mNumberPain = new Paint();
+        mNumberPain.setTextAlign(Paint.Align.CENTER);
+        mNumberPain.setColor(res.getColor(R.drawable.notification_number_text_color));
+        mNumberPain.setAntiAlias(true);
     }
 
     private static boolean streq(String a, String b) {
@@ -63,6 +78,9 @@
                 && mIcon.iconLevel == icon.iconLevel;
         final boolean visibilityEquals = mIcon != null
                 && mIcon.visible == icon.visible;
+        final boolean numberEquals = mIcon != null
+                && mIcon.number == icon.number;
+        mIcon = icon.clone();
         if (!iconEquals) {
             Drawable drawable = getIcon(icon);
             if (drawable == null) {
@@ -74,10 +92,22 @@
         if (!levelEquals) {
             setImageLevel(icon.iconLevel);
         }
+        if (!numberEquals) {
+            if (icon.number > 0) {
+                if (mNumberBackground == null) {
+                    mNumberBackground = getContext().getResources().getDrawable(
+                            R.drawable.ic_notification_overlay);
+                }
+                placeNumber();
+            } else {
+                mNumberBackground = null;
+                mNumberText = null;
+            }
+            invalidate();
+        }
         if (!visibilityEquals) {
             setVisibility(icon.visible ? VISIBLE : GONE);
         }
-        mIcon = icon.clone();
         return true;
     }
 
@@ -126,9 +156,47 @@
         return mIcon;
     }
 
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        super.onSizeChanged(w, h, oldw, oldh);
+        if (mNumberBackground != null) {
+            placeNumber();
+        }
+    }
+
+    protected void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+
+        if (mNumberBackground != null) {
+            mNumberBackground.draw(canvas);
+            canvas.drawText(mNumberText, mNumberX, mNumberY, mNumberPain);
+        }
+    }
+
     protected void debug(int depth) {
         super.debug(depth);
         Log.d("View", debugIndent(depth) + "slot=" + mSlot);
         Log.d("View", debugIndent(depth) + "icon=" + mIcon);
     }
+
+    void placeNumber() {
+        final String str = mNumberText = Integer.toString(mIcon.number);
+        final int w = getWidth();
+        final int h = getHeight();
+        final Rect r = new Rect();
+        mNumberPain.getTextBounds(str, 0, str.length(), r);
+        final int tw = r.right - r.left;
+        final int th = r.bottom - r.top;
+        mNumberBackground.getPadding(r);
+        int dw = r.left + tw + r.right;
+        if (dw < mNumberBackground.getMinimumWidth()) {
+            dw = mNumberBackground.getMinimumWidth();
+        }
+        mNumberX = w-r.right-((dw-r.right-r.left)/2);
+        int dh = r.top + th + r.bottom;
+        if (dh < mNumberBackground.getMinimumWidth()) {
+            dh = mNumberBackground.getMinimumWidth();
+        }
+        mNumberY = h-r.bottom-((dh-r.top-th-r.bottom)/2);
+        mNumberBackground.setBounds(w-dw, h-dh, w, h);
+    }
 }
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index c70f5d4..33685ba 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -296,7 +296,8 @@
 
     int mLandscapeRotation = -1; // default landscape rotation
     int mSeascapeRotation = -1; // "other" landscape rotation, 180 degrees from mLandscapeRotation
-    int mPortraitRotation = -1;
+    int mPortraitRotation = -1; // default portrait rotation
+    int mUpsideDownRotation = -1; // "other" portrait rotation
 
     // Nothing to see here, move along...
     int mFancyRotationAnimation;
@@ -364,26 +365,25 @@
 
     boolean useSensorForOrientationLp(int appOrientation) {
         // The app says use the sensor.
-        if (appOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR) {
+        if (appOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR
+                || appOrientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
+                || appOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
+                || appOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT) {
             return true;
         }
         // The user preference says we can rotate, and the app is willing to rotate.
-        // Note we include SCREEN_ORIENTATION_LANDSCAPE since we can use the sensor to choose
-        // between the two possible landscape rotations.
         if (mAccelerometerDefault != 0 &&
                 (appOrientation == ActivityInfo.SCREEN_ORIENTATION_USER
-                 || appOrientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
-                 || appOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)) {
+                 || appOrientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED)) {
             return true;
         }
-        // We're in a dock that has a rotation affinity, an the app is willing to rotate.
+        // We're in a dock that has a rotation affinity, and the app is willing to rotate.
         if ((mCarDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_CAR)
                 || (mDeskDockEnablesAccelerometer && mDockMode == Intent.EXTRA_DOCK_STATE_DESK)) {
             // Note we override the nosensor flag here.
             if (appOrientation == ActivityInfo.SCREEN_ORIENTATION_USER
                     || appOrientation == ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
-                    || appOrientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR
-                    || appOrientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
+                    || appOrientation == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR) {
                 return true;
             }
         }
@@ -397,7 +397,10 @@
      * screen is switched off.
      */
     boolean needSensorRunningLp() {
-        if (mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR) {
+        if (mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR
+                || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR
+                || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT
+                || mCurrentAppOrientation == ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE) {
             // If the application has explicitly requested to follow the
             // orientation, then we need to turn the sensor or.
             return true;
@@ -2133,21 +2136,42 @@
             if (d.getWidth() > d.getHeight()) {
                 mPortraitRotation = Surface.ROTATION_90;
                 mLandscapeRotation = Surface.ROTATION_0;
+                mUpsideDownRotation = Surface.ROTATION_270;
                 mSeascapeRotation = Surface.ROTATION_180;
             } else {
                 mPortraitRotation = Surface.ROTATION_0;
                 mLandscapeRotation = Surface.ROTATION_90;
+                mUpsideDownRotation = Surface.ROTATION_180;
                 mSeascapeRotation = Surface.ROTATION_270;
             }
         }
 
         synchronized (mLock) {
-            if (orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
-                //always return portrait if orientation set to portrait
-                return mPortraitRotation;
-            } else if (orientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
-                return getCurrentLandscapeRotation(lastRotation);
+            switch (orientation) {
+                case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
+                    //always return portrait if orientation set to portrait
+                    return mPortraitRotation;
+                case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
+                    //always return landscape if orientation set to landscape
+                    return mLandscapeRotation;
+                case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT:
+                    //always return portrait if orientation set to portrait
+                    return mUpsideDownRotation;
+                case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE:
+                    //always return seascape if orientation set to reverse landscape
+                    return mSeascapeRotation;
+                case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE:
+                    //return either landscape rotation based on the sensor
+                    mOrientationListener.setAllow180Rotation(false);
+                    return getCurrentLandscapeRotation(lastRotation);
+                case ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT:
+                    mOrientationListener.setAllow180Rotation(true);
+                    return getCurrentPortraitRotation(lastRotation);
             }
+
+            mOrientationListener.setAllow180Rotation(
+                    orientation == ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
+
             // case for nosensor meaning ignore sensor and consider only lid
             // or orientation sensor disabled
             //or case.unspecified
@@ -2167,18 +2191,15 @@
     }
 
     private int getCurrentLandscapeRotation(int lastRotation) {
-        // landscape-only apps can take either landscape rotation
-        if (useSensorForOrientationLp(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)) {
-            int sensorRotation = mOrientationListener.getCurrentRotation(lastRotation);
-            if (isLandscapeOrSeascape(sensorRotation)) {
-                return sensorRotation;
-            }
+        int sensorRotation = mOrientationListener.getCurrentRotation(lastRotation);
+        if (isLandscapeOrSeascape(sensorRotation)) {
+            return sensorRotation;
         }
         // try to preserve the old rotation if it was landscape
         if (isLandscapeOrSeascape(lastRotation)) {
             return lastRotation;
         }
-        // default to one of the two landscape rotations
+        // default to one of the primary landscape rotation
         return mLandscapeRotation;
     }
 
@@ -2186,6 +2207,23 @@
         return sensorRotation == mLandscapeRotation || sensorRotation == mSeascapeRotation;
     }
 
+    private int getCurrentPortraitRotation(int lastRotation) {
+        int sensorRotation = mOrientationListener.getCurrentRotation(lastRotation);
+        if (isAnyPortrait(sensorRotation)) {
+            return sensorRotation;
+        }
+        // try to preserve the old rotation if it was portrait
+        if (isAnyPortrait(lastRotation)) {
+            return lastRotation;
+        }
+        // default to one of the primary portrait rotations
+        return mPortraitRotation;
+    }
+
+    private boolean isAnyPortrait(int sensorRotation) {
+        return sensorRotation == mPortraitRotation || sensorRotation == mUpsideDownRotation;
+    }
+
     public boolean detectSafeMode() {
         try {
             int menuState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_MENU);
diff --git a/services/java/com/android/server/InputManager.java b/services/java/com/android/server/InputManager.java
index a960097..fe306b3 100644
--- a/services/java/com/android/server/InputManager.java
+++ b/services/java/com/android/server/InputManager.java
@@ -342,7 +342,6 @@
         if (toChannel == null) {
             throw new IllegalArgumentException("toChannel must not be null.");
         }
-        Slog.d(TAG, "transferring touch focus");
         return nativeTransferTouchFocus(fromChannel, toChannel);
     }
     
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index de28375..9a5423c 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -117,6 +117,7 @@
 
     final Context mContext;
     final Handler mHandler;
+    final InputMethodSettings mSettings;
     final SettingsObserver mSettingsObserver;
     final StatusBarManagerService mStatusBar;
     final IWindowManager mIWindowManager;
@@ -126,13 +127,8 @@
 
     // All known input methods.  mMethodMap also serves as the global
     // lock for this class.
-    final ArrayList<InputMethodInfo> mMethodList
-            = new ArrayList<InputMethodInfo>();
-    final HashMap<String, InputMethodInfo> mMethodMap
-            = new HashMap<String, InputMethodInfo>();
-
-    final TextUtils.SimpleStringSplitter mStringColonSplitter
-            = new TextUtils.SimpleStringSplitter(':');
+    final ArrayList<InputMethodInfo> mMethodList = new ArrayList<InputMethodInfo>();
+    final HashMap<String, InputMethodInfo> mMethodMap = new HashMap<String, InputMethodInfo>();
 
     class SessionState {
         final ClientState client;
@@ -483,27 +479,18 @@
         mStatusBar = statusBar;
         statusBar.setIconVisibility("ime", false);
 
+        // mSettings should be created before buildInputMethodListLocked
+        mSettings = new InputMethodSettings(context.getContentResolver(), mMethodMap, mMethodList);
         buildInputMethodListLocked(mMethodList, mMethodMap);
+        mSettings.enableAllIMEsIfThereIsNoEnabledIME();
 
-        final String enabledStr = Settings.Secure.getString(
-                mContext.getContentResolver(),
-                Settings.Secure.ENABLED_INPUT_METHODS);
-        Slog.i(TAG, "Enabled input methods: " + enabledStr);
-        final String defaultIme = Settings.Secure.getString(mContext
-                .getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
-        if (enabledStr == null || TextUtils.isEmpty(defaultIme)) {
-            Slog.i(TAG, "Enabled input methods or default IME has not been set, enabling all");
+        if (TextUtils.isEmpty(Settings.Secure.getString(
+                mContext.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD))) {
             InputMethodInfo defIm = null;
-            StringBuilder sb = new StringBuilder(256);
-            final int N = mMethodList.size();
-            for (int i=0; i<N; i++) {
-                InputMethodInfo imi = mMethodList.get(i);
-                Slog.i(TAG, "Adding: " + imi.getId());
-                if (i > 0) sb.append(':');
-                sb.append(imi.getId());
+            for (InputMethodInfo imi: mMethodList) {
                 if (defIm == null && imi.getIsDefaultResourceId() != 0) {
                     try {
-                        Resources res = mContext.createPackageContext(
+                        Resources res = context.createPackageContext(
                                 imi.getPackageName(), 0).getResources();
                         if (res.getBoolean(imi.getIsDefaultResourceId())) {
                             defIm = imi;
@@ -514,12 +501,10 @@
                     }
                 }
             }
-            if (defIm == null && N > 0) {
+            if (defIm == null && mMethodList.size() > 0) {
                 defIm = mMethodList.get(0);
                 Slog.i(TAG, "No default found, using " + defIm.getId());
             }
-            Settings.Secure.putString(mContext.getContentResolver(),
-                    Settings.Secure.ENABLED_INPUT_METHODS, sb.toString());
             if (defIm != null) {
                 Settings.Secure.putString(mContext.getContentResolver(),
                         Settings.Secure.DEFAULT_INPUT_METHOD, defIm.getId());
@@ -567,31 +552,10 @@
 
     public List<InputMethodInfo> getEnabledInputMethodList() {
         synchronized (mMethodMap) {
-            return getEnabledInputMethodListLocked();
+            return mSettings.getEnabledInputMethodListLocked();
         }
     }
 
-    List<InputMethodInfo> getEnabledInputMethodListLocked() {
-        final ArrayList<InputMethodInfo> res = new ArrayList<InputMethodInfo>();
-
-        final String enabledStr = Settings.Secure.getString(
-                mContext.getContentResolver(),
-                Settings.Secure.ENABLED_INPUT_METHODS);
-        if (enabledStr != null) {
-            final TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
-            splitter.setString(enabledStr);
-
-            while (splitter.hasNext()) {
-                InputMethodInfo info = mMethodMap.get(splitter.next());
-                if (info != null) {
-                    res.add(info);
-                }
-            }
-        }
-
-        return res;
-    }
-
     public void addClient(IInputMethodClient client,
             IInputContext inputContext, int uid, int pid) {
         synchronized (mMethodMap) {
@@ -1471,7 +1435,7 @@
     }
 
     private boolean chooseNewDefaultIMELocked() {
-        List<InputMethodInfo> enabled = getEnabledInputMethodListLocked();
+        List<InputMethodInfo> enabled = mSettings.getEnabledInputMethodListLocked();
         if (enabled != null && enabled.size() > 0) {
             // We'd prefer to fall back on a system IME, since that is safer.
             int i=enabled.size();
@@ -1650,7 +1614,7 @@
                     hideInputMethodMenu();
                 }
             };
-    
+
             TypedArray a = context.obtainStyledAttributes(null,
                     com.android.internal.R.styleable.DialogPreference,
                     com.android.internal.R.attr.alertDialogStyle, 0);
@@ -1664,7 +1628,7 @@
                     .setIcon(a.getDrawable(
                             com.android.internal.R.styleable.DialogPreference_dialogTitle));
             a.recycle();
-    
+
             mDialogBuilder.setSingleChoiceItems(mItems, checkedItem,
                     new AlertDialog.OnClickListener() {
                         public void onClick(DialogInterface dialog, int which) {
@@ -1738,81 +1702,45 @@
         // Make sure this is a valid input method.
         InputMethodInfo imm = mMethodMap.get(id);
         if (imm == null) {
-            if (imm == null) {
-                throw new IllegalArgumentException("Unknown id: " + mCurMethodId);
-            }
+            throw new IllegalArgumentException("Unknown id: " + mCurMethodId);
         }
 
-        StringBuilder builder = new StringBuilder(256);
+        List<Pair<String, ArrayList<String>>> enabledInputMethodsList = mSettings
+                .getEnabledInputMethodsAndSubtypeListLocked();
 
-        boolean removed = false;
-        String firstId = null;
-
-        // Look through the currently enabled input methods.
-        String enabledStr = Settings.Secure.getString(mContext.getContentResolver(),
-                Settings.Secure.ENABLED_INPUT_METHODS);
-        if (enabledStr != null) {
-            final TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;
-            splitter.setString(enabledStr);
-            while (splitter.hasNext()) {
-                String curId = splitter.next();
-                if (curId.equals(id)) {
-                    if (enabled) {
-                        // We are enabling this input method, but it is
-                        // already enabled.  Nothing to do.  The previous
-                        // state was enabled.
-                        return true;
-                    }
-                    // We are disabling this input method, and it is
-                    // currently enabled.  Skip it to remove from the
-                    // new list.
-                    removed = true;
-                } else if (!enabled) {
-                    // We are building a new list of input methods that
-                    // doesn't contain the given one.
-                    if (firstId == null) firstId = curId;
-                    if (builder.length() > 0) builder.append(':');
-                    builder.append(curId);
+        if (enabled) {
+            for (Pair<String, ArrayList<String>> pair: enabledInputMethodsList) {
+                if (pair.first.equals(id)) {
+                    // We are enabling this input method, but it is already enabled.
+                    // Nothing to do. The previous state was enabled.
+                    return true;
                 }
             }
-        }
-
-        if (!enabled) {
-            if (!removed) {
-                // We are disabling the input method but it is already
-                // disabled.  Nothing to do.  The previous state was
-                // disabled.
+            mSettings.appendAndPutEnabledInputMethodLocked(id, false);
+            // Previous state was disabled.
+            return false;
+        } else {
+            StringBuilder builder = new StringBuilder();
+            if (mSettings.buildAndPutEnabledInputMethodsStrRemovingIdLocked(
+                    builder, enabledInputMethodsList, id)) {
+                // Disabled input method is currently selected, switch to another one.
+                String selId = Settings.Secure.getString(mContext.getContentResolver(),
+                        Settings.Secure.DEFAULT_INPUT_METHOD);
+                if (id.equals(selId)) {
+                    Settings.Secure.putString(
+                            mContext.getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD,
+                            enabledInputMethodsList.size() > 0
+                                    ? enabledInputMethodsList.get(0).first : "");
+                    resetSelectedInputMethodSubtype();
+                }
+                // Previous state was enabled.
+                return true;
+            } else {
+                // We are disabling the input method but it is already disabled.
+                // Nothing to do.  The previous state was disabled.
                 return false;
             }
-            // Update the setting with the new list of input methods.
-            Settings.Secure.putString(mContext.getContentResolver(),
-                    Settings.Secure.ENABLED_INPUT_METHODS, builder.toString());
-            // We the disabled input method is currently selected, switch
-            // to another one.
-            String selId = Settings.Secure.getString(mContext.getContentResolver(),
-                    Settings.Secure.DEFAULT_INPUT_METHOD);
-            if (id.equals(selId)) {
-                Settings.Secure.putString(mContext.getContentResolver(),
-                        Settings.Secure.DEFAULT_INPUT_METHOD,
-                        firstId != null ? firstId : "");
-                resetSelectedInputMethodSubtype();
-            }
-            // Previous state was enabled.
-            return true;
         }
-
-        // Add in the newly enabled input method.
-        if (enabledStr == null || enabledStr.length() == 0) {
-            enabledStr = id;
-        } else {
-            enabledStr = enabledStr + ':' + id;
-        }
-
-        Settings.Secure.putString(mContext.getContentResolver(),
-                Settings.Secure.ENABLED_INPUT_METHODS, enabledStr);
-
-        // Previous state was disabled.
-        return false;
     }
 
     private void resetSelectedInputMethodSubtype() {
@@ -1862,6 +1790,161 @@
         return mCurrentSubtype;
     }
 
+    /**
+     * Utility class for putting and getting settings for InputMethod
+     * TODO: Move all putters and getters of settings to this class.
+     */
+    private static class InputMethodSettings {
+        // The string for enabled input method is saved as follows:
+        // example: ("ime0;subtype0;subtype1;subtype2:ime1:ime2;subtype0")
+        private static final char INPUT_METHOD_SEPARATER = ':';
+        private static final char INPUT_METHOD_SUBTYPE_SEPARATER = ';';
+        private final TextUtils.SimpleStringSplitter mStringColonSplitter =
+                new TextUtils.SimpleStringSplitter(INPUT_METHOD_SEPARATER);
+
+        private final TextUtils.SimpleStringSplitter mStringSemiColonSplitter =
+                new TextUtils.SimpleStringSplitter(INPUT_METHOD_SUBTYPE_SEPARATER);
+
+        private final ContentResolver mResolver;
+        private final HashMap<String, InputMethodInfo> mMethodMap;
+        private final ArrayList<InputMethodInfo> mMethodList;
+
+        private String mEnabledInputMethodsStrCache;
+
+        private static void buildEnabledInputMethodsSettingString(
+                StringBuilder builder, Pair<String, ArrayList<String>> pair) {
+            String id = pair.first;
+            ArrayList<String> subtypes = pair.second;
+            builder.append(id);
+            if (subtypes.size() > 0) {
+                builder.append(subtypes.get(0));
+                for (int i = 1; i < subtypes.size(); ++i) {
+                    builder.append(INPUT_METHOD_SUBTYPE_SEPARATER).append(subtypes.get(i));
+                }
+            }
+        }
+
+        public InputMethodSettings(
+                ContentResolver resolver, HashMap<String, InputMethodInfo> methodMap,
+                ArrayList<InputMethodInfo> methodList) {
+            mResolver = resolver;
+            mMethodMap = methodMap;
+            mMethodList = methodList;
+        }
+
+        public List<InputMethodInfo> getEnabledInputMethodListLocked() {
+            return createEnabledInputMethodListLocked(
+                    getEnabledInputMethodsAndSubtypeListLocked());
+        }
+
+        // At the initial boot, the settings for input methods are not set,
+        // so we need to enable IME in that case.
+        public void enableAllIMEsIfThereIsNoEnabledIME() {
+            if (TextUtils.isEmpty(getEnabledInputMethodsStr())) {
+                StringBuilder sb = new StringBuilder();
+                final int N = mMethodList.size();
+                for (int i = 0; i < N; i++) {
+                    InputMethodInfo imi = mMethodList.get(i);
+                    Slog.i(TAG, "Adding: " + imi.getId());
+                    if (i > 0) sb.append(':');
+                    sb.append(imi.getId());
+                }
+                putEnabledInputMethodsStr(sb.toString());
+            }
+        }
+
+        public List<Pair<String, ArrayList<String>>> getEnabledInputMethodsAndSubtypeListLocked() {
+            ArrayList<Pair<String, ArrayList<String>>> imsList
+                    = new ArrayList<Pair<String, ArrayList<String>>>();
+            final String enabledInputMethodsStr = getEnabledInputMethodsStr();
+            if (TextUtils.isEmpty(enabledInputMethodsStr)) {
+                return imsList;
+            }
+            mStringColonSplitter.setString(enabledInputMethodsStr);
+            while (mStringColonSplitter.hasNext()) {
+                String nextImsStr = mStringColonSplitter.next();
+                mStringSemiColonSplitter.setString(nextImsStr);
+                if (mStringSemiColonSplitter.hasNext()) {
+                    ArrayList<String> subtypeHashes = new ArrayList<String>();
+                    // The first element is ime id.
+                    String imeId = mStringSemiColonSplitter.next();
+                    while (mStringSemiColonSplitter.hasNext()) {
+                        subtypeHashes.add(mStringSemiColonSplitter.next());
+                    }
+                    imsList.add(new Pair<String, ArrayList<String>>(imeId, subtypeHashes));
+                }
+            }
+            return imsList;
+        }
+
+        public void appendAndPutEnabledInputMethodLocked(String id, boolean reloadInputMethodStr) {
+            if (reloadInputMethodStr) {
+                getEnabledInputMethodsStr();
+            }
+            if (TextUtils.isEmpty(mEnabledInputMethodsStrCache)) {
+                // Add in the newly enabled input method.
+                putEnabledInputMethodsStr(id);
+            } else {
+                putEnabledInputMethodsStr(
+                        mEnabledInputMethodsStrCache + INPUT_METHOD_SEPARATER + id);
+            }
+        }
+
+        /**
+         * Build and put a string of EnabledInputMethods with removing specified Id.
+         * @return the specified id was removed or not.
+         */
+        public boolean buildAndPutEnabledInputMethodsStrRemovingIdLocked(
+                StringBuilder builder, List<Pair<String, ArrayList<String>>> imsList, String id) {
+            boolean isRemoved = false;
+            boolean needsAppendSeparator = false;
+            for (Pair<String, ArrayList<String>> ims: imsList) {
+                String curId = ims.first;
+                if (curId.equals(id)) {
+                    // We are disabling this input method, and it is
+                    // currently enabled.  Skip it to remove from the
+                    // new list.
+                    isRemoved = true;
+                } else {
+                    if (needsAppendSeparator) {
+                        builder.append(INPUT_METHOD_SEPARATER);
+                    } else {
+                        needsAppendSeparator = true;
+                    }
+                    buildEnabledInputMethodsSettingString(builder, ims);
+                }
+            }
+            if (isRemoved) {
+                // Update the setting with the new list of input methods.
+                putEnabledInputMethodsStr(builder.toString());
+            }
+            return isRemoved;
+        }
+
+        private List<InputMethodInfo> createEnabledInputMethodListLocked(
+                List<Pair<String, ArrayList<String>>> imsList) {
+            final ArrayList<InputMethodInfo> res = new ArrayList<InputMethodInfo>();
+            for (Pair<String, ArrayList<String>> ims: imsList) {
+                InputMethodInfo info = mMethodMap.get(ims.first);
+                if (info != null) {
+                    res.add(info);
+                }
+            }
+            return res;
+        }
+
+        private void putEnabledInputMethodsStr(String str) {
+            Settings.Secure.putString(mResolver, Settings.Secure.ENABLED_INPUT_METHODS, str);
+            mEnabledInputMethodsStrCache = str;
+        }
+
+        private String getEnabledInputMethodsStr() {
+            mEnabledInputMethodsStrCache = Settings.Secure.getString(
+                    mResolver, Settings.Secure.ENABLED_INPUT_METHODS);
+            return mEnabledInputMethodsStrCache;
+        }
+    }
+
     // ----------------------------------------------------------------------
 
     @Override
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index 19f56a8..540c7fe 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -881,7 +881,6 @@
                  * the already-set timer.
                  */
                 int pluggedType = intent.getIntExtra("plugged", 0);
-                Slog.d(TAG, "ACTION_BATTERY_CHANGED pluggedType: " + pluggedType);
                 if (mScreenOff && shouldWifiStayAwake(stayAwakeConditions, mPluggedType) &&
                         !shouldWifiStayAwake(stayAwakeConditions, pluggedType)) {
                     long triggerTime = System.currentTimeMillis() + idleMillis;
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 0727a79..30aed69 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -569,8 +569,10 @@
 
             DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_STARTED, 0, 0,
                     mDataDescription, null);
-            for (WindowState ws : mWindows) {
-                sendDragStartedLw(ws, evt);
+            final int N = mWindows.size();
+            for (int i = 0; i < N; i++) {
+                // sendDragStartedLw() clones evt for local-process dispatch
+                sendDragStartedLw(mWindows.get(i), evt);
             }
             evt.recycle();
         }
@@ -579,10 +581,17 @@
          * designated window is potentially a drop recipient.  There are race situations
          * around DRAG_ENDED broadcast, so we make sure that once we've declared that
          * the drag has ended, we never send out another DRAG_STARTED for this drag action.
+         *
+         * This method clones the 'event' parameter if it's being delivered to the same
+         * process, so it's safe for the caller to call recycle() on the event afterwards.
          */
-        private void sendDragStartedLw(WindowState newWin, final DragEvent event) {
+        private void sendDragStartedLw(WindowState newWin, DragEvent event) {
             if (!mDragEnded && newWin.isPotentialDragTarget()) {
                 try {
+                    // clone for local callees since dispatch will recycle the event
+                    if (Process.myPid() == newWin.mSession.mPid) {
+                        event = DragEvent.obtain(event);
+                    }
                     newWin.mClient.dispatchDragEvent(event);
                     // track each window that we've notified that the drag is starting
                     mNotifiedWindows.add(newWin);
@@ -608,6 +617,7 @@
             }
             DragEvent event = DragEvent.obtain(DragEvent.ACTION_DRAG_STARTED, 0, 0,
                     mDataDescription, null);
+            // sendDragStartedLw() clones 'event' if the window is process-local
             sendDragStartedLw(newWin, event);
             event.recycle();
         }
@@ -632,6 +642,14 @@
         }
 
         void notifyMoveLw(float x, float y) {
+            final int myPid = Process.myPid();
+
+            // Move the surface to the given touch
+            mSurface.openTransaction();
+            mSurface.setPosition((int)(x - mThumbOffsetX), (int)(y - mThumbOffsetY));
+            mSurface.closeTransaction();
+
+            // Tell the affected window
             WindowState touchedWin = getTouchedWinAtPointLw(x, y);
             try {
                 // have we dragged over a new window?
@@ -643,7 +661,9 @@
                     DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_EXITED,
                             0, 0, null, null);
                     mTargetWindow.mClient.dispatchDragEvent(evt);
-                    evt.recycle();
+                    if (myPid != mTargetWindow.mSession.mPid) {
+                        evt.recycle();
+                    }
                 }
                 if (touchedWin != null) {
                     if (DEBUG_DRAG) {
@@ -652,7 +672,9 @@
                     DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DRAG_LOCATION,
                             x, y, null, null);
                     touchedWin.mClient.dispatchDragEvent(evt);
-                    evt.recycle();
+                    if (myPid != touchedWin.mSession.mPid) {
+                        evt.recycle();
+                    }
                 }
             } catch (RemoteException e) {
                 Slog.w(TAG, "can't send drag notification to windows");
@@ -667,13 +689,16 @@
                 if (DEBUG_DRAG) {
                     Slog.d(TAG, "sending DROP to " + touchedWin);
                 }
+                final int myPid = Process.myPid();
                 DragEvent evt = DragEvent.obtain(DragEvent.ACTION_DROP, x, y, null, mData);
                 try {
                     touchedWin.mClient.dispatchDragEvent(evt);
                 } catch (RemoteException e) {
                     Slog.w(TAG, "can't send drop notification to win " + touchedWin);
                 }
-                evt.recycle();
+                if (myPid != touchedWin.mSession.mPid) {
+                    evt.recycle();
+                }
             }
         }
 
@@ -749,13 +774,7 @@
 
                     case MotionEvent.ACTION_MOVE: {
                         synchronized (mWindowMap) {
-                            // move the surface to the latest touch point
-                            mDragState.mSurface.openTransaction();
-                            mDragState.mSurface.setPosition((int)(newX - mDragState.mThumbOffsetX),
-                                    (int)(newY - mDragState.mThumbOffsetY));
-                            mDragState.mSurface.closeTransaction();
-
-                            // tell the involved window(s) where we are
+                            // move the surface and tell the involved window(s) where we are
                             mDragState.notifyMoveLw(newX, newY);
                         }
                     } break;
@@ -3368,11 +3387,8 @@
             }
             // If this application has requested an explicit orientation,
             // then use it.
-            if (or == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE ||
-                    or == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT ||
-                    or == ActivityInfo.SCREEN_ORIENTATION_SENSOR ||
-                    or == ActivityInfo.SCREEN_ORIENTATION_NOSENSOR ||
-                    or == ActivityInfo.SCREEN_ORIENTATION_USER) {
+            if (or != ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
+                    && or != ActivityInfo.SCREEN_ORIENTATION_BEHIND) {
                 return or;
             }
             findingBehind |= (or == ActivityInfo.SCREEN_ORIENTATION_BEHIND);
@@ -5403,7 +5419,6 @@
                         mDragState.reset();
                         mDragState = null;
                     }
-                    
                 }
             }
         } finally {
@@ -5535,7 +5550,7 @@
             inputWindow.frameTop = 0;
             inputWindow.frameRight = mDisplay.getWidth();
             inputWindow.frameBottom = mDisplay.getHeight();
-            
+
             inputWindow.visibleFrameLeft = inputWindow.frameLeft;
             inputWindow.visibleFrameTop = inputWindow.frameTop;
             inputWindow.visibleFrameRight = inputWindow.frameRight;
@@ -6195,9 +6210,8 @@
 
                 mH.removeMessages(H.DRAG_START_TIMEOUT, window.asBinder());
 
-                // !!! TODO: call into the input monitor to sever the current touch event flow
-                // and redirect to the drag "window"; also extract the current touch (x, y)
-                // in screen coordinates
+                // !!! TODO: extract the current touch (x, y) in screen coordinates.  That
+                // will let us eliminate the (touchX,touchY) parameters from the API.
 
                 mDragState.register();
                 mInputMonitor.updateInputWindowsLw();
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/LinesActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/LinesActivity.java
index 4430533..0dc836d 100644
--- a/tests/HwAccelerationTest/src/com/android/test/hwui/LinesActivity.java
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/LinesActivity.java
@@ -101,6 +101,8 @@
             mSmallPaint.setAntiAlias(false);
             canvas.drawLine(0.0f, 0.0f, 400.0f, 0.0f, mSmallPaint);
             mSmallPaint.setAntiAlias(true);
+            canvas.drawLine(0.0f, 0.0f, 0.0f, 400.0f, mSmallPaint);
+            canvas.drawLine(0.0f, 400.0f, 400.0f, 400.0f, mSmallPaint);
             
             canvas.translate(120.0f, 0.0f);
             mAlphaPaint.setShader(mShader);            
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index 2d7ee13..e30cf4a 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -727,7 +727,7 @@
             }
         },
 
-        new Test("Persistent with numbers 222") {
+        new Test("Persistent with numbers 22") {
             public void run() {
                 mNM.notify(1, notificationWithNumbers(22));
             }