Merge "add a self instrumentation into framework perf app" into ics-mr1
diff --git a/Android.mk b/Android.mk
index 586eb4a..a748b7b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -412,6 +412,8 @@
 		            resources/samples/BackupRestore "Backup and Restore" \
 		-samplecode $(sample_dir)/BluetoothChat \
 		            resources/samples/BluetoothChat "Bluetooth Chat" \
+		-samplecode $(sample_dir)/BluetoothHDP \
+		            resources/samples/BluetoothHDP "Bluetooth HDP Demo" \
 		-samplecode $(sample_dir)/BusinessCard \
 		            resources/samples/BusinessCard "Business Card" \
 		-samplecode $(sample_dir)/ContactManager \
diff --git a/api/current.txt b/api/current.txt
index cbb8b44..b302cf3 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -83,6 +83,7 @@
     field public static final java.lang.String READ_PHONE_STATE = "android.permission.READ_PHONE_STATE";
     field public static final java.lang.String READ_PROFILE = "android.permission.READ_PROFILE";
     field public static final java.lang.String READ_SMS = "android.permission.READ_SMS";
+    field public static final java.lang.String READ_SOCIAL_STREAM = "android.permission.READ_SOCIAL_STREAM";
     field public static final java.lang.String READ_SYNC_SETTINGS = "android.permission.READ_SYNC_SETTINGS";
     field public static final java.lang.String READ_SYNC_STATS = "android.permission.READ_SYNC_STATS";
     field public static final java.lang.String REBOOT = "android.permission.REBOOT";
@@ -127,6 +128,7 @@
     field public static final java.lang.String WRITE_SECURE_SETTINGS = "android.permission.WRITE_SECURE_SETTINGS";
     field public static final java.lang.String WRITE_SETTINGS = "android.permission.WRITE_SETTINGS";
     field public static final java.lang.String WRITE_SMS = "android.permission.WRITE_SMS";
+    field public static final java.lang.String WRITE_SOCIAL_STREAM = "android.permission.WRITE_SOCIAL_STREAM";
     field public static final java.lang.String WRITE_SYNC_SETTINGS = "android.permission.WRITE_SYNC_SETTINGS";
   }
 
@@ -13631,16 +13633,19 @@
     field public static final int GL_RENDERBUFFER_RED_SIZE_OES = 36176; // 0x8d50
     field public static final int GL_RENDERBUFFER_STENCIL_SIZE_OES = 36181; // 0x8d55
     field public static final int GL_RENDERBUFFER_WIDTH_OES = 36162; // 0x8d42
+    field public static final int GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES = 36200; // 0x8d68
     field public static final int GL_RGB565_OES = 36194; // 0x8d62
     field public static final int GL_RGB5_A1_OES = 32855; // 0x8057
     field public static final int GL_RGB8_OES = 32849; // 0x8051
     field public static final int GL_RGBA4_OES = 32854; // 0x8056
     field public static final int GL_RGBA8_OES = 32856; // 0x8058
+    field public static final int GL_SAMPLER_EXTERNAL_OES = 36198; // 0x8d66
     field public static final int GL_STENCIL_ATTACHMENT_OES = 36128; // 0x8d20
     field public static final int GL_STENCIL_INDEX1_OES = 36166; // 0x8d46
     field public static final int GL_STENCIL_INDEX4_OES = 36167; // 0x8d47
     field public static final int GL_STENCIL_INDEX8_OES = 36168; // 0x8d48
     field public static final int GL_TEXTURE_BINDING_CUBE_MAP_OES = 34068; // 0x8514
+    field public static final int GL_TEXTURE_BINDING_EXTERNAL_OES = 36199; // 0x8d67
     field public static final int GL_TEXTURE_CROP_RECT_OES = 35741; // 0x8b9d
     field public static final int GL_TEXTURE_CUBE_MAP_NEGATIVE_X_OES = 34070; // 0x8516
     field public static final int GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_OES = 34072; // 0x8518
@@ -13649,6 +13654,7 @@
     field public static final int GL_TEXTURE_CUBE_MAP_POSITIVE_X_OES = 34069; // 0x8515
     field public static final int GL_TEXTURE_CUBE_MAP_POSITIVE_Y_OES = 34071; // 0x8517
     field public static final int GL_TEXTURE_CUBE_MAP_POSITIVE_Z_OES = 34073; // 0x8519
+    field public static final int GL_TEXTURE_EXTERNAL_OES = 36197; // 0x8d65
     field public static final int GL_TEXTURE_GEN_MODE_OES = 9472; // 0x2500
     field public static final int GL_TEXTURE_GEN_STR_OES = 36192; // 0x8d60
     field public static final int GL_TEXTURE_MATRIX_FLOAT_AS_INT_BITS_OES = 35215; // 0x898f
@@ -25152,7 +25158,7 @@
     method public synchronized java.lang.String getFixedFontFamily();
     method public synchronized boolean getJavaScriptCanOpenWindowsAutomatically();
     method public synchronized boolean getJavaScriptEnabled();
-    method public deprecated synchronized android.webkit.WebSettings.LayoutAlgorithm getLayoutAlgorithm();
+    method public synchronized android.webkit.WebSettings.LayoutAlgorithm getLayoutAlgorithm();
     method public boolean getLightTouchEnabled();
     method public boolean getLoadWithOverviewMode();
     method public synchronized boolean getLoadsImagesAutomatically();
@@ -25199,7 +25205,7 @@
     method public synchronized void setGeolocationEnabled(boolean);
     method public synchronized void setJavaScriptCanOpenWindowsAutomatically(boolean);
     method public synchronized void setJavaScriptEnabled(boolean);
-    method public deprecated synchronized void setLayoutAlgorithm(android.webkit.WebSettings.LayoutAlgorithm);
+    method public synchronized void setLayoutAlgorithm(android.webkit.WebSettings.LayoutAlgorithm);
     method public void setLightTouchEnabled(boolean);
     method public void setLoadWithOverviewMode(boolean);
     method public synchronized void setLoadsImagesAutomatically(boolean);
@@ -25234,12 +25240,12 @@
     field public static final int LOAD_NO_CACHE = 2; // 0x2
   }
 
-  public static final deprecated class WebSettings.LayoutAlgorithm extends java.lang.Enum {
+  public static final class WebSettings.LayoutAlgorithm extends java.lang.Enum {
     method public static android.webkit.WebSettings.LayoutAlgorithm valueOf(java.lang.String);
     method public static final android.webkit.WebSettings.LayoutAlgorithm[] values();
     enum_constant public static final android.webkit.WebSettings.LayoutAlgorithm NARROW_COLUMNS;
     enum_constant public static final android.webkit.WebSettings.LayoutAlgorithm NORMAL;
-    enum_constant public static final android.webkit.WebSettings.LayoutAlgorithm SINGLE_COLUMN;
+    enum_constant public static final deprecated android.webkit.WebSettings.LayoutAlgorithm SINGLE_COLUMN;
   }
 
   public static final class WebSettings.PluginState extends java.lang.Enum {
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index ca66a4e..fe81d2b 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -145,8 +145,7 @@
             "su", "root", "wlutil", "counters", NULL);
 #endif
 
-#ifdef BROKEN_VRIL_IS_FIXED_B_4442803
-   char ril_dumpstate_timeout[PROPERTY_VALUE_MAX] = {0};
+    char ril_dumpstate_timeout[PROPERTY_VALUE_MAX] = {0};
     property_get("ril.dumpstate.timeout", ril_dumpstate_timeout, "30");
     if (strnlen(ril_dumpstate_timeout, PROPERTY_VALUE_MAX - 1) > 0) {
         if (0 == strncmp(build_type, "user", PROPERTY_VALUE_MAX - 1)) {
@@ -160,7 +159,6 @@
                     "su", "root", "vril-dump", NULL);
         }
     }
-#endif
 
     print_properties();
 
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index ea5c3db..d971652 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -533,6 +533,7 @@
      * @hide
      */
     public ParcelUuid[] getUuids() {
+        if (getState() != STATE_ON) return null;
         try {
             return mService.getUuids();
         } catch (RemoteException e) {Log.e(TAG, "", e);}
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index a9f1685..2857ac5 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -360,6 +360,10 @@
         /* use getSystemService() instead of just instantiating to take
          * advantage of the context's cached NfcManager & NfcAdapter */
         NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE);
+        if (manager == null) {
+            // NFC not available
+            return null;
+        }
         return manager.getDefaultAdapter();
     }
 
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index d604a01..28e231e 100755
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -810,7 +810,7 @@
         }
     }
 
-    /*package*/ synchronized String getProperty(String name, boolean checkState) {
+    /*package*/ String getProperty(String name, boolean checkState) {
         // If checkState is false, check if the event loop is running.
         // before making the call to Bluez
         if (checkState) {
@@ -854,14 +854,14 @@
         return getProperty("Name", false);
     }
 
-    public synchronized ParcelUuid[] getUuids() {
+    public ParcelUuid[] getUuids() {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
         String value =  getProperty("UUIDs", true);
         if (value == null) return null;
         return convertStringToParcelUuid(value);
     }
 
-    private synchronized ParcelUuid[] convertStringToParcelUuid(String value) {
+    private ParcelUuid[] convertStringToParcelUuid(String value) {
         String[] uuidStrings = null;
         // The UUIDs are stored as a "," separated string.
         uuidStrings = value.split(",");
@@ -934,7 +934,7 @@
      * @return The discoverability window of the device, in seconds.  A negative
      *         value indicates an error.
      */
-    public synchronized int getDiscoverableTimeout() {
+    public int getDiscoverableTimeout() {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
         String timeout = getProperty("DiscoverableTimeout", true);
         if (timeout != null)
@@ -943,7 +943,7 @@
             return -1;
     }
 
-    public synchronized int getScanMode() {
+    public int getScanMode() {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
         if (!isEnabledInternal())
             return BluetoothAdapter.SCAN_MODE_NONE;
@@ -969,7 +969,7 @@
         return stopDiscoveryNative();
     }
 
-    public synchronized boolean isDiscovering() {
+    public boolean isDiscovering() {
         mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
 
         String discoveringProperty = getProperty("Discovering", false);
@@ -2387,7 +2387,7 @@
         mDeviceProfileState.remove(address);
     }
 
-    synchronized String[] getKnownDevices() {
+    String[] getKnownDevices() {
         String[] bonds = null;
         String val = getProperty("Devices", true);
         if (val != null) {
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 0c3f94e..f947f95 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -42,12 +42,14 @@
      * SINGLE_COLUMN moves all content into one column that is the width of the
      * view.
      * NARROW_COLUMNS makes all columns no wider than the screen if possible.
-     * @deprecated This enum is now obsolete.
      */
     // XXX: These must match LayoutAlgorithm in Settings.h in WebCore.
-    @Deprecated
     public enum LayoutAlgorithm {
         NORMAL,
+        /**
+         * @deprecated This algorithm is now obsolete.
+         */
+        @Deprecated
         SINGLE_COLUMN,
         NARROW_COLUMNS
     }
@@ -936,9 +938,7 @@
      * WebView.
      * @param l A LayoutAlgorithm enum specifying the algorithm to use.
      * @see WebSettings.LayoutAlgorithm
-     * @deprecated This method is now obsolete.
      */
-    @Deprecated
     public synchronized void setLayoutAlgorithm(LayoutAlgorithm l) {
         // XXX: This will only be affective if libwebcore was built with
         // ANDROID_LAYOUT defined.
@@ -953,9 +953,7 @@
      * @return LayoutAlgorithm enum value describing the layout algorithm
      *         being used.
      * @see WebSettings.LayoutAlgorithm
-     * @deprecated This method is now obsolete.
      */
-    @Deprecated
     public synchronized LayoutAlgorithm getLayoutAlgorithm() {
         return mLayoutAlgorithm;
     }
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 8aafc3d..f18a396 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -17,8 +17,10 @@
 package android.webkit;
 
 import android.content.Context;
+import android.graphics.Canvas;
 import android.graphics.Color;
 import android.graphics.Paint;
+import android.graphics.Paint.Style;
 import android.graphics.Rect;
 import android.graphics.drawable.ColorDrawable;
 import android.os.Bundle;
@@ -49,6 +51,7 @@
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
 import android.view.inputmethod.InputMethodManager;
+import android.widget.AbsoluteLayout;
 import android.widget.AbsoluteLayout.LayoutParams;
 import android.widget.AdapterView;
 import android.widget.ArrayAdapter;
@@ -71,6 +74,9 @@
 
     static final String LOGTAG = "webtextview";
 
+    private Paint mRingPaint;
+    private int mRingInset;
+
     private WebView         mWebView;
     private boolean         mSingle;
     private int             mWidthSpec;
@@ -201,7 +207,13 @@
                 }
             }
         };
+        float ringWidth = 4f * context.getResources().getDisplayMetrics().density;
         mReceiver = new MyResultReceiver(mHandler);
+        mRingPaint = new Paint();
+        mRingPaint.setColor(0x6633b5e5);
+        mRingPaint.setStrokeWidth(ringWidth);
+        mRingPaint.setStyle(Style.FILL);
+        mRingInset = (int) ringWidth;
     }
 
     public void setAutoFillable(int queryId) {
@@ -211,6 +223,40 @@
     }
 
     @Override
+    protected void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+        if (isFocused()) {
+            final int ib = getHeight() - mRingInset;
+            canvas.drawRect(0, 0, getWidth(), mRingInset, mRingPaint);
+            canvas.drawRect(0, ib, getWidth(), getHeight(), mRingPaint);
+            canvas.drawRect(0, mRingInset, mRingInset, ib, mRingPaint);
+            canvas.drawRect(getWidth() - mRingInset, mRingInset, getWidth(), ib, mRingPaint);
+        }
+    }
+
+    private void growOrShrink(boolean grow) {
+        AbsoluteLayout.LayoutParams lp = (AbsoluteLayout.LayoutParams) getLayoutParams();
+        if (grow) {
+            Log.i("webtextview", "grow");
+            lp.x -= mRingInset;
+            lp.y -= mRingInset;
+            lp.width += 2 * mRingInset;
+            lp.height += 2 * mRingInset;
+            setPadding(getPaddingLeft() + mRingInset, getPaddingTop() + mRingInset,
+                    getPaddingRight() + mRingInset, getPaddingBottom() + mRingInset);
+        } else {
+            Log.i("webtextview", "shrink");
+            lp.x += mRingInset;
+            lp.y += mRingInset;
+            lp.width -= 2 * mRingInset;
+            lp.height -= 2 * mRingInset;
+            setPadding(getPaddingLeft() - mRingInset, getPaddingTop() - mRingInset,
+                    getPaddingRight() - mRingInset, getPaddingBottom() - mRingInset);
+        }
+        setLayoutParams(lp);
+    }
+
+    @Override
     public boolean dispatchKeyEvent(KeyEvent event) {
         if (event.isSystem()) {
             return super.dispatchKeyEvent(event);
@@ -511,6 +557,7 @@
         } else if (!mInsideRemove) {
             mWebView.setActive(false);
         }
+        growOrShrink(focused);
         mFromFocusChange = false;
     }
 
@@ -567,7 +614,6 @@
                 mPreChange.substring(0, mMaxLength).equals(postChange))) {
             return;
         }
-        mPreChange = postChange;
         if (0 == count) {
             if (before > 0) {
                 // For this and all changes to the text, update our cache
@@ -605,9 +651,9 @@
         // Prefer sending javascript events, so when adding one character,
         // don't replace the unchanged text.
         if (count > 1 && before == count - 1) {
-            String replaceButOne =  s.subSequence(start,
+            String replaceButOne =  mPreChange.subSequence(start,
                     start + before).toString();
-            String replacedString = getText().subSequence(start,
+            String replacedString = s.subSequence(start,
                     start + before).toString();
             if (replaceButOne.equals(replacedString)) {
                 // we're just adding one character
@@ -616,6 +662,7 @@
                 count = 1;
             }
         }
+        mPreChange = postChange;
         // Find the last character being replaced.  If it can be represented by
         // events, we will pass them to native so we can see javascript events.
         // Otherwise, replace the text being changed in the textfield.
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 907e8db..35fd945 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -119,6 +119,11 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import javax.microedition.khronos.egl.EGL10;
+import javax.microedition.khronos.egl.EGLContext;
+import javax.microedition.khronos.egl.EGLDisplay;
+import static javax.microedition.khronos.egl.EGL10.*;
+
 /**
  * <p>A View that displays web pages. This class is the basis upon which you
  * can roll your own web browser or simply display some online content within your Activity.
@@ -909,6 +914,9 @@
     private Rect mScrollingLayerBounds = new Rect();
     private boolean mSentAutoScrollMessage = false;
 
+    // Temporary hack to work around the context removal upon memory pressure
+    private static boolean mIncrementEGLContextHack = false;
+
     // used for serializing asynchronously handled touch events.
     private final TouchEventQueue mTouchEventQueue = new TouchEventQueue();
 
@@ -4225,6 +4233,13 @@
         }
 
         if (canvas.isHardwareAccelerated()) {
+            if (mIncrementEGLContextHack == false) {
+                mIncrementEGLContextHack = true;
+                EGL10 egl = (EGL10) EGLContext.getEGL();
+                EGLDisplay eglDisplay = egl.eglGetDisplay(EGL_DEFAULT_DISPLAY);
+                int[] version = new int[2];
+                egl.eglInitialize(eglDisplay, version);
+            }
             mZoomManager.setHardwareAccelerated();
         }
 
@@ -5664,13 +5679,13 @@
             if (hasFocus()) {
                 // If our window regained focus, and we have focus, then begin
                 // drawing the cursor ring
-                mDrawCursorRing = true;
+                mDrawCursorRing = !inEditingMode();
                 setFocusControllerActive(true);
             } else {
+                mDrawCursorRing = false;
                 if (!inEditingMode()) {
                     // If our window gained focus, but we do not have it, do not
                     // draw the cursor ring.
-                    mDrawCursorRing = false;
                     setFocusControllerActive(false);
                 }
                 // We do not call recordButtons here because we assume
@@ -5745,7 +5760,7 @@
             // When we regain focus, if we have window focus, resume drawing
             // the cursor ring
             if (hasWindowFocus()) {
-                mDrawCursorRing = true;
+                mDrawCursorRing = !inEditingMode();
                 setFocusControllerActive(true);
             //} else {
                 // The WebView has gained focus while we do not have
@@ -5755,8 +5770,8 @@
         } else {
             // When we lost focus, unless focus went to the TextView (which is
             // true if we are in editing mode), stop drawing the cursor ring.
+            mDrawCursorRing = false;
             if (!inEditingMode()) {
-                mDrawCursorRing = false;
                 setFocusControllerActive(false);
             }
             mKeysPressed.clear();
diff --git a/core/java/android/webkit/WebViewDatabase.java b/core/java/android/webkit/WebViewDatabase.java
index e1392ae..695c154 100644
--- a/core/java/android/webkit/WebViewDatabase.java
+++ b/core/java/android/webkit/WebViewDatabase.java
@@ -42,7 +42,7 @@
     // log tag
     protected static final String LOGTAG = "webviewdatabase";
 
-    private static final int DATABASE_VERSION = 10;
+    private static final int DATABASE_VERSION = 11;
     // 2 -> 3 Modified Cache table to allow cache of redirects
     // 3 -> 4 Added Oma-Downloads table
     // 4 -> 5 Modified Cache table to support persistent contentLength
@@ -52,6 +52,9 @@
     // 7 -> 8 Move cache to its own db
     // 8 -> 9 Store both scheme and host when storing passwords
     // 9 -> 10 Update httpauth table UNIQUE
+    // 10 -> 11 Drop cookies and cache now managed by the chromium stack,
+    //          and update the form data table to use the new format
+    //          implemented for b/5265606.
     private static final int CACHE_DATABASE_VERSION = 4;
     // 1 -> 2 Add expires String
     // 2 -> 3 Add content-disposition
@@ -204,7 +207,9 @@
         }
 
         initDatabase(context);
-        if (!JniUtil.useChromiumHttpStack()) {
+        if (JniUtil.useChromiumHttpStack()) {
+            context.deleteDatabase(CACHE_DATABASE_FILE);
+        } else {
             initCacheDatabase(context);
         }
 
@@ -327,15 +332,59 @@
     }
 
     private static void upgradeDatabase() {
+        upgradeDatabaseToV10();
+        upgradeDatabaseFromV10ToV11();
+        // Add future database upgrade functions here, one version at a
+        // time.
+        mDatabase.setVersion(DATABASE_VERSION);
+    }
+
+    private static void upgradeDatabaseFromV10ToV11() {
         int oldVersion = mDatabase.getVersion();
+
+        if (oldVersion >= 11) {
+            // Nothing to do.
+            return;
+        }
+
+        if (JniUtil.useChromiumHttpStack()) {
+            // Clear out old java stack cookies - this data is now stored in
+            // a separate database managed by the Chrome stack.
+            mDatabase.execSQL("DROP TABLE IF EXISTS " + mTableNames[TABLE_COOKIES_ID]);
+
+            // Likewise for the old cache table.
+            mDatabase.execSQL("DROP TABLE IF EXISTS cache");
+        }
+
+        // Update form autocomplete  URLs to match new ICS formatting.
+        Cursor c = mDatabase.query(mTableNames[TABLE_FORMURL_ID], null, null,
+                null, null, null, null);
+        while (c.moveToNext()) {
+            String urlId = Long.toString(c.getLong(c.getColumnIndex(ID_COL)));
+            String url = c.getString(c.getColumnIndex(FORMURL_URL_COL));
+            ContentValues cv = new ContentValues(1);
+            cv.put(FORMURL_URL_COL, WebTextView.urlForAutoCompleteData(url));
+            mDatabase.update(mTableNames[TABLE_FORMURL_ID], cv, ID_COL + "=?",
+                    new String[] { urlId });
+        }
+        c.close();
+    }
+
+    private static void upgradeDatabaseToV10() {
+        int oldVersion = mDatabase.getVersion();
+
+        if (oldVersion >= 10) {
+            // Nothing to do.
+            return;
+        }
+
         if (oldVersion != 0) {
             Log.i(LOGTAG, "Upgrading database from version "
                     + oldVersion + " to "
                     + DATABASE_VERSION + ", which will destroy old data");
         }
-        boolean justPasswords = 8 == oldVersion && 9 == DATABASE_VERSION;
-        boolean justAuth = 9 == oldVersion && 10 == DATABASE_VERSION;
-        if (justAuth) {
+
+        if (9 == oldVersion) {
             mDatabase.execSQL("DROP TABLE IF EXISTS "
                     + mTableNames[TABLE_HTTPAUTH_ID]);
             mDatabase.execSQL("CREATE TABLE " + mTableNames[TABLE_HTTPAUTH_ID]
@@ -348,55 +397,49 @@
             return;
         }
 
-        if (!justPasswords) {
-            mDatabase.execSQL("DROP TABLE IF EXISTS "
-                    + mTableNames[TABLE_COOKIES_ID]);
-            mDatabase.execSQL("DROP TABLE IF EXISTS cache");
-            mDatabase.execSQL("DROP TABLE IF EXISTS "
-                    + mTableNames[TABLE_FORMURL_ID]);
-            mDatabase.execSQL("DROP TABLE IF EXISTS "
-                    + mTableNames[TABLE_FORMDATA_ID]);
-            mDatabase.execSQL("DROP TABLE IF EXISTS "
-                    + mTableNames[TABLE_HTTPAUTH_ID]);
-        }
+        mDatabase.execSQL("DROP TABLE IF EXISTS "
+                + mTableNames[TABLE_COOKIES_ID]);
+        mDatabase.execSQL("DROP TABLE IF EXISTS cache");
+        mDatabase.execSQL("DROP TABLE IF EXISTS "
+                + mTableNames[TABLE_FORMURL_ID]);
+        mDatabase.execSQL("DROP TABLE IF EXISTS "
+                + mTableNames[TABLE_FORMDATA_ID]);
+        mDatabase.execSQL("DROP TABLE IF EXISTS "
+                + mTableNames[TABLE_HTTPAUTH_ID]);
         mDatabase.execSQL("DROP TABLE IF EXISTS "
                 + mTableNames[TABLE_PASSWORD_ID]);
 
-        mDatabase.setVersion(DATABASE_VERSION);
+        // cookies
+        mDatabase.execSQL("CREATE TABLE " + mTableNames[TABLE_COOKIES_ID]
+                + " (" + ID_COL + " INTEGER PRIMARY KEY, "
+                + COOKIES_NAME_COL + " TEXT, " + COOKIES_VALUE_COL
+                + " TEXT, " + COOKIES_DOMAIN_COL + " TEXT, "
+                + COOKIES_PATH_COL + " TEXT, " + COOKIES_EXPIRES_COL
+                + " INTEGER, " + COOKIES_SECURE_COL + " INTEGER" + ");");
+        mDatabase.execSQL("CREATE INDEX cookiesIndex ON "
+                + mTableNames[TABLE_COOKIES_ID] + " (path)");
 
-        if (!justPasswords) {
-            // cookies
-            mDatabase.execSQL("CREATE TABLE " + mTableNames[TABLE_COOKIES_ID]
-                    + " (" + ID_COL + " INTEGER PRIMARY KEY, "
-                    + COOKIES_NAME_COL + " TEXT, " + COOKIES_VALUE_COL
-                    + " TEXT, " + COOKIES_DOMAIN_COL + " TEXT, "
-                    + COOKIES_PATH_COL + " TEXT, " + COOKIES_EXPIRES_COL
-                    + " INTEGER, " + COOKIES_SECURE_COL + " INTEGER" + ");");
-            mDatabase.execSQL("CREATE INDEX cookiesIndex ON "
-                    + mTableNames[TABLE_COOKIES_ID] + " (path)");
+        // formurl
+        mDatabase.execSQL("CREATE TABLE " + mTableNames[TABLE_FORMURL_ID]
+                + " (" + ID_COL + " INTEGER PRIMARY KEY, " + FORMURL_URL_COL
+                + " TEXT" + ");");
 
-            // formurl
-            mDatabase.execSQL("CREATE TABLE " + mTableNames[TABLE_FORMURL_ID]
-                    + " (" + ID_COL + " INTEGER PRIMARY KEY, " + FORMURL_URL_COL
-                    + " TEXT" + ");");
+        // formdata
+        mDatabase.execSQL("CREATE TABLE " + mTableNames[TABLE_FORMDATA_ID]
+                + " (" + ID_COL + " INTEGER PRIMARY KEY, "
+                + FORMDATA_URLID_COL + " INTEGER, " + FORMDATA_NAME_COL
+                + " TEXT, " + FORMDATA_VALUE_COL + " TEXT," + " UNIQUE ("
+                + FORMDATA_URLID_COL + ", " + FORMDATA_NAME_COL + ", "
+                + FORMDATA_VALUE_COL + ") ON CONFLICT IGNORE);");
 
-            // formdata
-            mDatabase.execSQL("CREATE TABLE " + mTableNames[TABLE_FORMDATA_ID]
-                    + " (" + ID_COL + " INTEGER PRIMARY KEY, "
-                    + FORMDATA_URLID_COL + " INTEGER, " + FORMDATA_NAME_COL
-                    + " TEXT, " + FORMDATA_VALUE_COL + " TEXT," + " UNIQUE ("
-                    + FORMDATA_URLID_COL + ", " + FORMDATA_NAME_COL + ", "
-                    + FORMDATA_VALUE_COL + ") ON CONFLICT IGNORE);");
-
-            // httpauth
-            mDatabase.execSQL("CREATE TABLE " + mTableNames[TABLE_HTTPAUTH_ID]
-                    + " (" + ID_COL + " INTEGER PRIMARY KEY, "
-                    + HTTPAUTH_HOST_COL + " TEXT, " + HTTPAUTH_REALM_COL
-                    + " TEXT, " + HTTPAUTH_USERNAME_COL + " TEXT, "
-                    + HTTPAUTH_PASSWORD_COL + " TEXT," + " UNIQUE ("
-                    + HTTPAUTH_HOST_COL + ", " + HTTPAUTH_REALM_COL
-                    + ") ON CONFLICT REPLACE);");
-        }
+        // httpauth
+        mDatabase.execSQL("CREATE TABLE " + mTableNames[TABLE_HTTPAUTH_ID]
+                + " (" + ID_COL + " INTEGER PRIMARY KEY, "
+                + HTTPAUTH_HOST_COL + " TEXT, " + HTTPAUTH_REALM_COL
+                + " TEXT, " + HTTPAUTH_USERNAME_COL + " TEXT, "
+                + HTTPAUTH_PASSWORD_COL + " TEXT," + " UNIQUE ("
+                + HTTPAUTH_HOST_COL + ", " + HTTPAUTH_REALM_COL
+                + ") ON CONFLICT REPLACE);");
         // passwords
         mDatabase.execSQL("CREATE TABLE " + mTableNames[TABLE_PASSWORD_ID]
                 + " (" + ID_COL + " INTEGER PRIMARY KEY, "
@@ -411,7 +454,7 @@
         if (oldVersion != 0) {
             Log.i(LOGTAG, "Upgrading cache database from version "
                     + oldVersion + " to "
-                    + DATABASE_VERSION + ", which will destroy all old data");
+                    + CACHE_DATABASE_VERSION + ", which will destroy all old data");
         }
         mCacheDatabase.execSQL("DROP TABLE IF EXISTS cache");
         mCacheDatabase.setVersion(CACHE_DATABASE_VERSION);
@@ -1150,7 +1193,7 @@
                 cursor = mDatabase.query(mTableNames[TABLE_FORMURL_ID],
                         ID_PROJECTION, urlSelection, new String[] { url }, null,
                         null, null);
-                if (cursor.moveToFirst()) {
+                while (cursor.moveToNext()) {
                     long urlid = cursor.getLong(cursor.getColumnIndex(ID_COL));
                     Cursor dataCursor = null;
                     try {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 230df39..97658a1 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -263,8 +263,7 @@
         android:label="@string/permlab_writeProfile"
         android:description="@string/permdesc_writeProfile" />
 
-    <!-- Allows an application to read from the user's social stream.
-         @hide -->
+    <!-- Allows an application to read from the user's social stream. -->
     <permission android:name="android.permission.READ_SOCIAL_STREAM"
         android:permissionGroup="android.permission-group.PERSONAL_INFO"
         android:protectionLevel="dangerous"
@@ -272,8 +271,7 @@
         android:description="@string/permdesc_readSocialStream" />
 
     <!-- Allows an application to write (but not read) the user's
-         social stream data.
-         @hide -->
+         social stream data. -->
     <permission android:name="android.permission.WRITE_SOCIAL_STREAM"
         android:permissionGroup="android.permission-group.PERSONAL_INFO"
         android:protectionLevel="dangerous"
diff --git a/docs/html/guide/appendix/market-filters.jd b/docs/html/guide/appendix/market-filters.jd
index dc79d95..6610f5f 100644
--- a/docs/html/guide/appendix/market-filters.jd
+++ b/docs/html/guide/appendix/market-filters.jd
@@ -25,7 +25,7 @@
 </ol>
 
 <h2>See also</h2>
- <ol> 
+ <ol>
 <li><a
 href="{@docRoot}guide/practices/compatibility.html">Android Compatibility</a></li>
 <li><code><a
@@ -48,7 +48,7 @@
   <img id="rule" src="{@docRoot}assets/images/grad-rule-qv.png">
   <div id="qv-sub-rule">
     <img src="{@docRoot}assets/images/icon_market.jpg" style="float:left;margin:0;padding:0 5px;">
-    <h2 style="color:#669999;">Interested in publishing your app on Android Market?</h2> 
+    <h2 style="color:#669999;">Interested in publishing your app on Android Market?</h2>
     <p><a id="publish-link"
 href="http://market.android.com/publish">Go to Android Market</a> to create a publisher
 account and upload your app.</p></div>
@@ -83,7 +83,7 @@
 manifest file and publishing details. If the application is
 compatible with the device according to the filter rules, Market displays the
 application to the user. Otherwise, Market hides your application from search
-results and category browsing, even if a user specifically requests 
+results and category browsing, even if a user specifically requests
 the app by clicking a deep link that points directly to the app's ID within Market..</p>
 
 <p class="note"><strong>Note:</strong> When users browse the <a
@@ -108,7 +108,7 @@
 
 <p>Most Market filters are triggered by elements within an application's
 manifest file, <a
-href="{@docRoot}guide/topics/manifest/manifest-intro.html">AndroidManifest.xml</a> 
+href="{@docRoot}guide/topics/manifest/manifest-intro.html">AndroidManifest.xml</a>
 (although not everything in the manifest file can trigger filtering).
 Table 1 lists the manifest elements that you should use to trigger Android
 Market filtering, and explains how the filtering for each element works.</p>
@@ -173,7 +173,7 @@
     </strong>The manifest declares <code>&lt;uses-sdk android:minSdkVersion="3"
     android:targetSdkVersion="4"&gt;</code> and does not include a
     <code>&lt;supports-screens&gt;</code> element.
-    <strong>Result</strong>: Android Market will show the app to users on all 
+    <strong>Result</strong>: Android Market will show the app to users on all
     devices, unless other filters apply. </p>
     <p><strong>Example 3<br />
     </strong>The manifest declares <code>&lt;uses-sdk android:minSdkVersion="4"&gt;</code>
@@ -402,9 +402,9 @@
     visible on devices that support that platform. For details about the NDK and using
     native libraries, see <a href="{@docRoot}sdk/ndk/index.html#overview">What is the
       Android NDK?</a></p> </tr> <tr>
-        <td valign="top">Forward-Locked Applications</td> <td valign="top"><p>To
-          forward lock an application, set copy protection to "On" when you upload the
-          application to Market. Market will not show copy-protected applications on
+        <td valign="top">Copy-Protected Applications</td> <td valign="top"><p>To
+          copy protect an application, set copy protection to "On" when you configure publishing
+options for your application. Market will not show copy-protected applications on
 developer devices or unreleased devices.</p></td> </tr> </table>
 
 
@@ -431,7 +431,7 @@
     <p>By using the <a href="{@docRoot}guide/topics/manifest/supports-screens-element.html">{@code
 &lt;supports-screens&gt;}</a> or <a
 href="{@docRoot}guide/topics/manifest/compatible-screens-element.html">{@code
-&lt;compatible-screens&gt;}</a> element.</p>   
+&lt;compatible-screens&gt;}</a> element.</p>
   </li>
   <li>API level
     <p>By using the <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index af379de..3eb7286 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -119,7 +119,7 @@
               </a></li>
           <li><a href="<?cs var:toroot ?>guide/topics/ui/actionbar.html">
                <span class="en">Action Bar</span>
-              </a></li>
+              </a> <span class="new">updated</span></li>
           <li><a href="<?cs var:toroot ?>guide/topics/ui/dialogs.html">
                 <span class="en">Dialogs</span>
               </a></li>
@@ -739,21 +739,21 @@
         <ul>
           <li class="toggle-list">
             <div><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/icon_design.html">
-                   <span class="en">Icon Design <span class="new">updated</span></span>
-                 </a></div>
+                   <span class="en">Icon Design</span>
+                 </a> <span class="new">updated</span></div>
             <ul>
               <li><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/icon_design_launcher.html">
-                    <span class="en">Launcher Icons <span class="new">updated</span></span>
-                  </a></li>
+                    <span class="en">Launcher Icons</span>
+                  </a> <span class="new">updated</span></li>
               <li><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/icon_design_menu.html">
                     <span class="en">Menu Icons</span>
                   </a></li>
               <li><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/icon_design_action_bar.html">
-                    <span class="en">Action Bar Icons <span class="new">new!</span></span>
-                  </a></li>
+                    <span class="en">Action Bar Icons</span>
+                  </a> <span class="new">new!</span></li>
               <li><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/icon_design_status_bar.html">
-                    <span class="en">Status Bar Icons <span class="new">updated</span></span>
-                  </a></li>
+                    <span class="en">Status Bar Icons</span>
+                  </a> <span class="new">updated</span></li>
               <li><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/icon_design_tab.html">
                     <span class="en">Tab Icons</span>
                   </a></li>
@@ -766,8 +766,8 @@
             </ul>
           </li>
           <li><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/widget_design.html">
-                <span class="en">App Widget Design <span class="new">updated</span></span>
-              </a></li>
+                <span class="en">App Widget Design</span>
+              </a> <span class="new">updated</span></li>
           <li><a href="<?cs var:toroot ?>guide/practices/ui_guidelines/activity_task_design.html">
                 <span class="en">Activity and Task Design</span>
               </a></li>
@@ -844,8 +844,8 @@
             <span class="en">App Install Location</span>
           </a></li>
       <li><a href="<?cs var:toroot ?>guide/appendix/media-formats.html">
-            <span class="en">Supported Media Formats <span class="new">updated</span></span>
-          </a></li>
+            <span class="en">Supported Media Formats</span>
+          </a> <span class="new">updated</span></li>
       <li><a href="<?cs var:toroot ?>guide/appendix/g-app-intents.html">
             <span class="en">Intents List: Google Apps</span>
           </a></li>
diff --git a/docs/html/guide/practices/tablets-and-handsets.jd b/docs/html/guide/practices/tablets-and-handsets.jd
index 7bc1ad7..dc35801 100644
--- a/docs/html/guide/practices/tablets-and-handsets.jd
+++ b/docs/html/guide/practices/tablets-and-handsets.jd
@@ -372,9 +372,8 @@
 value</strong>. In your <a
 href="{@docRoot}guide/topics/resources/menu-resource.html">menu resource</a>, use {@code "ifRoom"}
 for the {@code android:showAsAction} attribute if you'd like the menu item to appear in the action
-bar. However, you might need {@code "always"} when an action view does not provide an alternative
-action for the overflow menu (that is, it must appear as an action view) or when a menu item added
-by a fragment is low in the menu order and it must jump into the action bar at all times. However,
+bar. However, you might need {@code "always"} when an action view does not provide a default
+action for the overflow menu (that is, it must appear as an action view). However,
 you should not use {@code "always"} more than once or twice. In almost all other cases, use {@code
 "ifRoom"} as the value for {@code "android:showAsAction"} when you want the item to appear as an
 action item. Forcing too many action items into the action bar can create a cluttered UI and
diff --git a/docs/html/guide/publishing/licensing.jd b/docs/html/guide/publishing/licensing.jd
index fc0de9d..609241b 100644
--- a/docs/html/guide/publishing/licensing.jd
+++ b/docs/html/guide/publishing/licensing.jd
@@ -100,9 +100,14 @@
 <h4>Application, Android Market client, and server</h4>
 
 <p>The licensing service is based on the capability of the Android Market server
-to determine whether a given user is licensed to use a given application. The
-server considers a user licensed if the user is recorded to have purchased the
-application, or if the application is available for free. To properly identify
+to determine whether a given user is licensed to use a given application. The licensing server
+considers a user to be licensed if the user is a recorded purchaser of an application. If a paid
+application has been uploaded to Android Market but saved only as a draft application (in
+other words, the app is unpublished), the licensing server considers all users to be licensed users
+of the application. Keep in mind, you cannot implement Android Market Licensing in a free
+application.</p>
+
+<p>To properly identify
 the user and determine the license status, the server requires information about
 the application and user &mdash; the application and the Android Market client
 work together to assemble the information and pass it to the server. </p>
@@ -243,7 +248,7 @@
 
 <ul>
 <li>Only paid applications published through Market can use the
-service. </li>
+service.</li>
 <li>An application can use the service only if the Android Market client is
 installed on its host device and the device is running Android 1.5 (API level 3)
 or higher.</li>
@@ -258,8 +263,8 @@
 secure.</li>
 <li>Adding licensing to an application does not affect the way the application
 functions when run on a device that does not offer Android Market.</li>
-<li>Licensing is currently for paid apps only, since free apps are considered
-licensed for all users. If your application is already published as free, 
+<li>Licensing is currently for paid apps only, since draft apps are
+licensed for all users. If your application is already published as a free app,
 you won't be able to upload a new version that uses licensing.</li>
 </ul>
 
@@ -698,7 +703,7 @@
 <p>Next, open the application's project properties window, as shown below.
 Select the "Android" properties group and click <strong>Add</strong>, then
 choose the LVL library project (com_android_vending_licensing) and click
-<strong>OK</strong>. For more information, see 
+<strong>OK</strong>. For more information, see
 <a href="{@docRoot}guide/developing/projects/projects-eclipse.html#SettingUpLibraryProject">
 Managing Projects from Eclipse with ADT</a></p>.
 
@@ -727,7 +732,7 @@
 --library <em>path/to/my/library_project</em>
 </pre>
 
-<p>For more information about working with library projects, 
+<p>For more information about working with library projects,
 see <a href="{@docRoot}guide/developing/projects/projects-cmdline.html#SettingUpLibraryProject">
 Managing Projects from the Command Line</a></p>.
 
@@ -1226,6 +1231,8 @@
 <li>Otherwise, the LicenseChecker initiates a license check request that is sent
 to the licensing server.</li>
 </ul>
+<p class="note"><strong>Note:</strong> The licensing server always returns
+<code>LICENSED</code> when you perform a license check of a draft application.</p>
 </li>
 <li>When a response is received, LicenseChecker creates a LicenseValidator that
 verifies the signed license data and extracts the fields of the response, then
@@ -1384,7 +1391,7 @@
 </ol>
 
 <p>If you want your LicenseCheckerCallback methods to update the UI thread,
-instantiate a {@link android.os.Handler} in the main Activity's 
+instantiate a {@link android.os.Handler} in the main Activity's
 {@link android.app.Activity#onCreate(android.os.Bundle) onCreate()} method,
 as shown below. In this example, the LVL sample application's
 LicenseCheckerCallback methods (see above) call <code>displayResult()</code> to
@@ -2338,7 +2345,7 @@
 </p>
 
 <p>In general, the RETRY response code is a signal to the application that an
-error has occurred that has prevented a license check from completing. 
+error has occurred that has prevented a license check from completing.
 
 <p>The Android Market server helps an application to manage licensing under
 error conditions by setting a retry "grace period" and a recommended maximum
diff --git a/docs/html/guide/topics/ui/actionbar.jd b/docs/html/guide/topics/ui/actionbar.jd
index 4742923..3c0ef26 100644
--- a/docs/html/guide/topics/ui/actionbar.jd
+++ b/docs/html/guide/topics/ui/actionbar.jd
@@ -8,179 +8,249 @@
 
   <h2>Quickview</h2>
   <ul>
-    <li>A replacement for the title bar that includes the application icon and activity title</li>
-    <li>Provides action items from the Options Menu and modes of navigating around the
-application</li>
-    <li>Supports custom views, including an embedded search box</li>
-    <li>Requires API Level 11</li>
+    <li>A title bar that includes the application icon and activity title</li>
+    <li>Provides access to menu items and navigation modes such as tabs</li>
+    <li>Requires API level 11 or greater</li>
   </ul>
 
   <h2>In this document</h2>
-  <ol>
-    <li><a href="#Adding">Adding the Action Bar</a>
-      <ol>
-        <li><a href="#Removing">Removing the Action Bar</a></li>
-      </ol>
-    </li>
-    <li><a href="#ActionItems">Adding Action Items</a>
-      <ol>
-        <li><a href="#Home">Using the app icon as an action item</a></li>
-      </ol>
-    </li>
-    <li><a href="#ActionView">Adding an Action View</a></li>
-    <li><a href="#Tabs">Adding Tabs</a></li>
-    <li><a href="#Dropdown">Adding Drop-down Navigation</a></li>
-    <li><a href="#Style">Styling the Action Bar</a></li>
-  </ol>
+<ol>
+  <li><a href="#Adding">Adding the Action Bar</a>
+    <ol>
+      <li><a href="#Removing">Removing the action bar</a></li>
+    </ol>
+  </li>
+  <li><a href="#ActionItems">Adding Action Items</a>
+    <ol>
+      <li><a href="#ChoosingActionItems">Choosing your action items</a></li>
+      <li><a href="#SplitBar">Using split action bar</a></li>
+    </ol>
+  </li>
+  <li><a href="#Home">Using the App Icon for Navigation</a>
+    <ol>
+      <li><a href="#Up">Navigating up</a></li>
+    </ol>
+  </li>
+  <li><a href="#ActionView">Adding an Action View</a>
+    <ol>
+      <li><a href="#ActionViewCollapsing">Handling collapsible action views</a></li>
+    </ol>  
+  </li>
+  <li><a href="#ActionProvider">Adding an Action Provider</a>
+    <ol>
+      <li><a href="#ShareActionProvider">Using the ShareActionProvider</a></li>
+      <li><a href="#CreatingActionProvider">Creating a custom action provider</a></li>
+    </ol>
+  </li>
+  <li><a href="#Tabs">Adding Navigation Tabs</a></li>
+  <li><a href="#Dropdown">Adding Drop-down Navigation</a></li>
+  <li><a href="#Style">Styling the Action Bar</a>
+    <ol>
+      <li><a href="#GeneralStyles">General appearance</a></li>
+      <li><a href="#ActionItemStyles">Action items</a></li>
+      <li><a href="#NavigationStyles">Navigation tabs</a></li>
+      <li><a href="#DropDownStyles">Drop-down lists</a></li>
+      <li><a href="#AdvancedStyles">Advanced styling</a></li>
+    </ol>
+  </li>
+</ol>
 
   <h2>Key classes</h2>
   <ol>
     <li>{@link android.app.ActionBar}</li>
     <li>{@link android.view.Menu}</li>
+    <li>{@link android.view.ActionProvider}</li>
   </ol>
-  
+
   <h2>Related samples</h2>
   <ol>
-    <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/index.html#ActionBar">API
-        Demos</a></li>
     <li><a
 href="{@docRoot}resources/samples/HoneycombGallery/index.html">Honeycomb Gallery</a></li>
+    <li><a
+href="{@docRoot}resources/samples/ActionBarCompat/index.html">Action Bar Compatibility</a></li>
+    <li><a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/index.html#ActionBar">
+API Demos</a></li>
   </ol>
-  
-  <h2>See also</h2>
+
+  <h2>See also</h2>item
   <ol>
     <li><a href="{@docRoot}guide/topics/ui/menus.html">Menus</a></li>
+    <li><a href="{@docRoot}guide/practices/tablets-and-handsets.html">Supporting Tablets
+and Handsets</a></li>
   </ol>
 </div>
 </div>
 
-<p>The Action Bar is a widget for activities that replaces the traditional title bar at
-the top of the screen. By default, the Action Bar includes the application logo on the left side,
-followed by the activity title, and any available items from the Options Menu on the right side. The
-Action Bar offers several useful features, including the ability to:</p>
+<p>The action bar is a window feature that identifies the application and user location, and
+provides user actions and navigation modes. You should use the action bar in most activities that
+need to prominently present user actions or global navigation, because the action bar offers users a
+consistent interface across applications and the system gracefully adapts the action bar's
+appearance for different screen configurations. You can control the behaviors and visibility of the
+action bar with the {@link android.app.ActionBar} APIs, which were added in Android 3.0 (API level
+11).</p>
+
+<p>The primary goals of the action bar are to:</p>
 
 <ul>
-  <li>Display items from the <a
-href="{@docRoot}guide/topics/ui/menus.html#OptionsMenu">Options Menu</a> directly in the Action
-Bar, as "action
-items"&mdash;providing instant access to key user actions.
-    <p>Menu items that do not appear as action items are placed in the overflow menu, revealed
-by a drop-down list in the Action Bar.</p></li>
-  <li>Provide tabs for navigating between <a
-href="{@docRoot}guide/topics/fundamentals/fragments.html">fragments</a>.</li>
-  <li>Provide a drop-down list for navigation.</li>
-  <li>Provide interactive "action views" in place of action items (such as a search box).</li>
+  <li>Provide a dedicated space for identifying the application brand and user location.
+    <p>This is accomplished with the app icon or logo on the left side and the activity title.
+You might choose to remove the activity title, however, if the current view is identified by a
+navigation label, such as the currently selected tab.</p></li>
+
+  <li>Provide consistent navigation and view refinement across different applications.
+    <p>The action bar provides built-in tab navigation for switching between <a
+href="{@docRoot}guide/topics/fundamentals/fragments.html">fragments</a>. It also offers a drop-down
+list you can use as an alternative navigation mode or to refine the current view (such as to sort
+a list by different criteria).</p>
+  </li>
+
+  <li>Make key actions for the activity (such as "search", "create", "share", etc.) prominent and
+accessible to the user in a predictable way.
+    <p>You can provide instant access to key user actions by placing items from the <a
+href="{@docRoot}guide/topics/ui/menus.html#OptionsMenu">options menu</a> directly in the action bar,
+as "action items." Action items can also provide an "action view," which provides an embedded
+widget for even more immediate action behaviors. Menu items that are not promoted
+to an action item are available in the overflow menu, revealed by either the device MENU button
+(when available) or by an "overflow menu" button in the action bar (when the device does not
+include a MENU button).</p>
+</li>
 </ul>
 
-<img src="{@docRoot}images/ui/actionbar.png" height="36" alt="" />
+<img src="{@docRoot}images/ui/actionbar.png" alt="" />
+<p class="img-caption"><strong>Figure 1.</strong> Action bar from the <a
+href="{@docRoot}resources/samples/HoneycombGallery/index.html">Honeycomb Gallery</a> app (on a
+landscape handset), showing the logo on the left, navigation tabs, and an action item on the
+right (plus the overflow menu button).</p>
 
-<p class="img-caption"><strong>Figure 1.</strong> A screenshot of the Action Bar in the Email
-application, containing action items to compose new email and refresh the inbox.</p>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+  <h2>Remaining backward-compatible</h2>
+<p>If you want to provide an action bar in your application <em>and</em> remain compatible with
+versions of Android older than 3.0, you need to create the action bar in your
+activity's layout (because the {@link android.app.ActionBar} class is not available on older
+versions).</p>
+<p>To help you, the <a
+href="{@docRoot}resources/samples/ActionBarCompat/index.html">Action Bar Compatibility</a> sample
+app provides an API layer and action bar layout that allows your app to use some of the {@link
+android.app.ActionBar} APIs and also support older versions of Android by replacing the traditional
+title bar with a custom action bar layout.</p>
+</div>
+</div>
 
 
 <h2 id="Adding">Adding the Action Bar</h2>
 
-<p>The Action Bar is included by default in all activities that target Android 3.0 or greater. More
-specifically, all activities that use the new "holographic" theme include the Action Bar, and any
-application that targets Android 3.0 automatically receives this theme. An application is considered
-to "target" Android 3.0 when it has set either the {@code android:minSdkVersion} or {@code
-android:targetSdkVersion} attribute in the <a
-href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code &lt;uses-sdk&gt;}</a> element to
-{@code "11"} or greater. For example:</p>
+<p>Beginning with Android 3.0 (API level 11), the action bar is included in all
+activities that use the {@link android.R.style#Theme_Holo Theme.Holo} theme (or one of its
+descendants), which is the default theme when either the <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> or
+<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a>
+attribute is set to {@code "11"} or greater. For example:</p>
 
 <pre>
-&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
-      package="com.example.helloworld"
-      android:versionCode="1"
-      android:versionName="1.0"&gt;
+&lt;manifest ... &gt;
     &lt;uses-sdk android:minSdkVersion="4"
               <b>android:targetSdkVersion="11"</b> /&gt;
-    &lt;application ... &gt;
-        ...
-    &lt;/application&gt;
+    ...
 &lt;/manifest&gt;
 </pre>
 
-<p>In this example, the application requires a minimum version of API
-Level 4 (Android 1.6), but it also targets API Level 11 (Android 3.0). This way, when
-the application is installed on a device running Android 3.0 or greater, the system applies the
-holographic theme to each activity, and thus, each activity includes the Action Bar.</p>
+<p>In this example, the application requires a minimum version of API Level 4 (Android 1.6), but it
+also targets API level 11 (Android 3.0). This way, when the application runs on Android 3.0 or
+greater, the system applies the holographic theme to each activity, and thus, each activity includes
+the action bar.</p>
 
-<p>However, if you want to use Action Bar APIs, such as to add tabs or modify Action Bar styles,
-you need to set the {@code android:minSdkVersion} to {@code "11"}, so you can access the
-{@link android.app.ActionBar} class.</p>
+<p>If you want to use {@link android.app.ActionBar} APIs, such as to add navigation modes and modify
+action bar styles, you should set the <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> to {@code
+"11"} or greater. If you want your app
+to support older versions of Android, there are ways to use a limited set of {@link
+android.app.ActionBar} APIs on devices that support API level 11 or higher, while still running
+on older versions. See the sidebox for information about remaining backward-compatible.</p>
 
 
-<h3 id="Removing">Removing the Action Bar</h3>
+<h3 id="Removing">Removing the action bar</h3>
 
-<p>If you want to remove the Action Bar for a particular activity, set the activity theme to
+<p>If you don't want the action bar for a particular activity, set the activity theme to
 {@link android.R.style#Theme_Holo_NoActionBar Theme.Holo.NoActionBar}. For example:</p>
 
 <pre>
 &lt;activity android:theme="&#64;android:style/Theme.Holo.NoActionBar"&gt;
 </pre>
 
-<p class="note"><strong>Tip:</strong> If you have a custom activity theme in which you'd like to
-remove the Action Bar, set the {@link android.R.styleable#Theme_windowActionBar
-android:windowActionBar} style property {@code false}. See <a href="#Style">Styling the Action
-Bar</a> for more about Action Bar styles.</p>
-
-<p>You can also hide the Action Bar at runtime by calling {@link android.app.ActionBar#hide},
-then show it again by calling {@link android.app.ActionBar#show}. For example:</p>
+<p>You can also hide the action bar at runtime by calling {@link android.app.ActionBar#hide}. For
+example:</p>
 
 <pre>
-ActionBar actionBar = getActionBar();
+ActionBar actionBar = {@link android.app.Activity#getActionBar()};
 actionBar.hide();
 </pre>
 
-<p>When the Action Bar hides, the system adjusts your activity content to fill all the
-available screen space.</p>
+<p>When the action bar hides, the system adjusts your activity layout to fill all the
+screen space now available. You can bring the action bar back with {@link
+android.app.ActionBar#show()}.</p>
 
-<p class="note"><strong>Note:</strong> If you remove the Action Bar using a theme, then the
-window will not allow the Action Bar at all, so you cannot add it at runtime&mdash;calling
-{@link android.app.Activity#getActionBar getActionBar()} will return null.</p>
+<p>Beware that hiding and removing the action bar causes your activity to re-layout in order to
+account for the space consumed by the action bar. If your activity regularly hides and shows the
+action bar (such as in the Android Gallery app), you might want to use overlay mode. Overlay mode
+draws the action bar on top of your activity layout rather than in its own area of the screen. This
+way, your layout remains fixed when the action bar hides and re-appears. To enable overlay mode,
+create a theme for your activity and set {@link android.R.attr#windowActionBarOverlay
+android:windowActionBarOverlay} to {@code true}. For more information, see the section about <a
+href="#Style">Styling the Action Bar</a>.</p>
+
+<p class="note"><strong>Tip:</strong> If you have a custom activity theme in which you'd like to
+remove the action bar, set the {@link android.R.styleable#Theme_windowActionBar
+android:windowActionBar} style property to {@code false}. However, if you remove the action bar
+using a theme, then the window will not allow the action bar at all, so you cannot add it
+later&mdash;calling {@link android.app.Activity#getActionBar()} will return null.</p>
+
 
 
 <h2 id="ActionItems">Adding Action Items</h2>
 
-<p>An action item is simply a menu item from the <a
-href="{@docRoot}guide/topics/ui/menus.html#OptionsMenu">Options Menu</a> which you declare should
-appear directly in the Action Bar. An action item can include an icon and/or text. If a menu
-item does not appear as an action item, then the system places it in the overflow menu, which
-the user can open with the menu icon on the right side of the Action Bar.</p>
+<p>Sometimes you might want to give users immediate access to an item from the <a
+href="{@docRoot}guide/topics/ui/menus.html#OptionsMenu">options menu</a>. To do this, you can
+declare that the menu item should appear in the action bar as an "action item." An action item can
+include an icon and/or a text title. If a menu item does not appear as an action item, then the
+system places it in the overflow menu. The overflow menu is revealed either by the device MENU
+button (if provided by the device) or an additional button in the action bar (if the device does not
+provide the MENU button).</p>
 
 <div class="figure" style="width:359px">
   <img src="{@docRoot}images/ui/actionbar-item-withtext.png" height="57" alt="" />
-  <p class="img-caption"><strong>Figure 2.</strong> A screenshot from an Action Bar with two
-action items and the overflow menu.</p>
+  <p class="img-caption"><strong>Figure 2.</strong> Two action items with icon and text titles, and
+the overflow menu button.</p>
 </div>
 
-<p>When the activity first starts, the system populates the Action Bar and overflow menu by calling
+<p>When the activity first starts, the system populates the action bar and overflow menu by calling
 {@link android.app.Activity#onCreateOptionsMenu onCreateOptionsMenu()} for your activity. As
-discussed in the <a href="{@docRoot}guide/topics/ui/menus.html">Menus</a> developer guid, it's in
-this callback method that you define the Options Menu for the activity.</p>
+discussed in the <a href="{@docRoot}guide/topics/ui/menus.html">Menus</a> developer guide, it's in
+this callback method that you should inflate an XML <a
+href="{@docRoot}guide/topics/resources/menu-resource.html">menu resource</a> that defines the
+menu items. For example:</p>
 
-<p>You can specify a menu item to appear as an action item&mdash;if there is room
-for it&mdash;from your <a href="{@docRoot}guide/topics/resources/menu-resource.html">menu
-resource</a> by declaring {@code
+<pre>
+&#64;Override
+public boolean onCreateOptionsMenu(Menu menu) {
+    MenuInflater inflater = getMenuInflater();
+    inflater.inflate(R.menu.main_activity, menu);
+    return true;
+}
+</pre>
+
+<p>In the XML file, you can request a menu item to appear as an action item by declaring {@code
 android:showAsAction="ifRoom"} for the {@code &lt;item&gt;} element. This way, the menu item appears
-in the Action Bar for quick access only if there is room available for it. If there's not
-enough room, the item is placed the overflow menu (revealed by the menu icon on the right side
-of the Action Bar).</p>
+in the action bar for quick access only <em>if there is room</em> available. If there's not
+enough room, the item appears in the overflow menu.</p>
 
-<p>You can also declare a menu item to appear as an action item from your application code, by
-calling {@link android.view.MenuItem#setShowAsAction setShowAsAction()} on the {@link
-android.view.MenuItem} and passing {@link android.view.MenuItem#SHOW_AS_ACTION_IF_ROOM}.</p>
+<p>If your menu item supplies both a title and an icon&mdash;with the {@code android:title} and
+{@code android:icon} attributes&mdash;then the action item shows only the icon by default. If you
+want to display the text title, add {@code "withText"} to the {@code android:showAsAction}
+attribute. For example:</p>
 
-<p>If your menu item supplies both a title and an icon, then the action item shows only
-the icon by defult. If you want to include the text with the action item, add the "with
-text" flag: in XML, add {@code withText} to the {@code android:showAsAction} attribute or, in
-your application code, use the {@link android.view.MenuItem#SHOW_AS_ACTION_WITH_TEXT} flag when
-calling {@link android.view.MenuItem#setShowAsAction setShowAsAction()}. Figure 2 shows an Action
-Bar that has two action items with text and the icon for the overflow menu.</p>
-
-<p>Here's an example of how you can declare a menu item as an action item in a <a
-href="{@docRoot}guide/topics/resources/menu-resource.html">menu resource</a> file:</p>
 <pre>
 &lt;?xml version="1.0" encoding="utf-8"?&gt;
 &lt;menu xmlns:android="http://schemas.android.com/apk/res/android">
@@ -191,58 +261,200 @@
 &lt;/menu&gt;
 </pre>
 
-<p>In this case, both the {@code ifRoom} and {@code withText} flags are set, so that when this
-item appears as an action item, it includes the title text along with the icon.</p>
+<p class="note"><strong>Note:</strong> The {@code "withText"} value is a <em>hint</em> to the
+action bar that the text title should appear. The action bar will show the title when possible, but
+might not if an icon is available and the action bar is constrained for space.</p>
 
-<p>A menu item placed in the Action Bar triggers the same callback methods as other items in the
-Options Menu. When the user selects an action item, your activity receives a call to
-{@link android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()}, passing the
-item ID.</p>
+<p>When the user selects an action item, your activity receives a call to
+{@link android.app.Activity#onOptionsItemSelected(MenuItem)
+onOptionsItemSelected()}, passing the ID supplied by the {@code android:id} attribute&mdash;the same
+callback received for all items in the options menu.</p>
 
-<p class="note"><strong>Note:</strong> If you added the menu item from a fragment, then the
-respective {@link
-android.app.Fragment#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} method is called
-for that fragment. However the activity gets a chance to handle it first, so the system calls {@link
-android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} on the activity
-before calling the fragment.</p>
+<p>It's important that you always define {@code android:title} for each menu item&mdash;even if you
+don't declare that the title appear with the action item&mdash;for three reasons:</p>
+<ul>
+  <li>If there's not enough room in the action bar for the action item, the menu item appears
+in the overflow menu and only the title appears.</li>
+  <li>Screen readers for sight-impaired users read the menu item's title.</li>
+  <li>If the action item appears with only the icon, a user can long-press the item to reveal a
+tool-tip that displays the action item's title.</li>
+</ul>
 
-<p>You can also declare an item to <em>always</em> appear as an action item,  but you should avoid
-doing so, because it can create a cluttered UI if there are too many action items and they might
-collide with other elements in the Action Bar.</p>
+<p>The {@code android:icon} is always optional, but recommended. For icon design recommendations,
+see the <a href="{@docRoot}guide/practices/ui_guidelines/icon_design_action_bar.html">Action Bar
+Icon</a> design guidelines.</p>
 
-<p>For more information about menus, see the <a
+<p class="note"><strong>Note:</strong> If you added the menu item from a fragment, via the {@link
+android.app.Fragment} class's {@link android.app.Fragment#onCreateOptionsMenu onCreateOptionsMenu}
+callback, then the system calls the respective {@link
+android.app.Fragment#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} method for that
+fragment when the user selects one of the fragment's items. However the activity gets a chance to
+handle the event first, so the system calls {@link
+android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} on the activity before
+calling the same callback for the fragment.</p>
+
+<p>You can also declare an item to <em>"always"</em> appear as an action item, instead of being
+placed in the overflow menu when space is limited. In most cases, you <strong>should not</strong>
+force an item to appear in the action bar by using the {@code "always"} value. However, you might
+need an item to always appear when it provides an <a href="#ActionView">action view</a> that does
+not offer a default action for the overflow menu. Beware that too
+many action items can create a cluttered UI and cause layout problems on devices with a narrow
+screen. It's best to instead use {@code "ifRoom"} to request that an item appear in the action
+bar, but allow the system to move it into the overflow menu when there's not enough room.</p>
+
+<p>For more information about creating the options menu that defines your action items, see the <a
 href="{@docRoot}guide/topics/ui/menus.html#options-menu">Menus</a> developer guide.</p>
 
 
-<h3 id="Home">Using the app icon as an action item</h3>
 
-<p>By default, your application icon appears in the Action Bar on the left side. It also responds 
-to user interaction (when the user taps it, it visually responds the same way action
-items do) and it's your responsibility to do something when the user taps it.</p>
+<h3 id="ChoosingActionItems">Choosing your action items</h3>
 
-<img src="{@docRoot}images/ui/actionbar.png" height="36" alt="" />
-<p class="img-caption"><strong>Figure 3.</strong> Email's Action Bar, with the
-application icon on the left.</p>
+<div class="sidebox-wrapper">
+<div class="sidebox">
+ <h4>Menu items vs. other app controls</h4>
+ <p>As a general rule, all items in the <a
+href="{@docRoot}guide/topics/ui/menus.html#OptionsMenu">options menu</a> (let alone action items)
+should have a global impact on the app, rather than affect only a small portion of the interface.
+For example, if you have a multi-pane layout and one pane shows a video while another lists all
+videos, the video player controls should appear within the pane containing the video (not in the
+action bar), while the action bar might provide action items to share the video or save the video to
+a favorites list.</p>
+  <p>So, even before deciding whether a menu item should appear as an action item, be sure that
+the item has a global scope for the current activity. If it doesn't, then you should place it
+as a button in the appropriate context of the activity layout.</p>
+</div>
+</div>
 
-<p>The normal behavior should be for your application to return to the "home" activity or the
-initial state (such as when the activity hasn't changed, but fragments have changed) when the user
-taps the icon. If the user is already at home or the initial state, then you don't need to do
-anything.</p>
+<p>You should carefully choose which items from your options menu should appear as action items by
+assessing a few key traits. In general, each action item should be <em>at least one</em>
+of the following:</p>
 
-<p>When the user taps the icon, the system calls your activity's {@link
+<ol>
+  <li><strong>Frequently used</strong>: It's an action that your users need seven out of ten visits
+or they use it several times in a row.
+    <p>Example frequent actions: "New message" in the Messaging app and
+"Search" in Android Market.</p>
+  </li>
+
+  <li><strong>Important</strong>: It's an action that you need users to easily discover or, if it's
+not frequently used, it's important that it be effortless to perform in the few cases that users do
+need it.
+    <p>Example important actions: "Add network" in Wi-Fi settings and "Switch to camera" in the
+Gallery app.</p>
+  </li>
+
+  <li><strong>Typical</strong>: It's an action that is typically provided in the action bar in
+similar apps, so your users expect to find it in yours.
+    <p>Example typical actions: "Refresh" in an email or social app, and "New contact" in the
+People app.</p>
+</ol>
+
+<p>If you believe that more than four of your menu items can be justified as action items, then you
+should carefully consider their relative level of importance and try to set no more than four as
+action items (and do so using the {@code "ifRoom"} value to allow the system to put some back in the
+overflow menu when space is limited on smaller screens). Even if space is available on a wide
+screen, you should not create a long stream of action items that clutter the UI and appear like a
+desktop toolbar, so keep the number of action items to a minimum.</p>
+
+<p>Additionally, the following actions should never appear as action items: Settings, Help,
+Feedback, or similar. Always keep them in the overflow menu.</p>
+
+<p class="note"><strong>Note:</strong> Remember that not all devices provide a dedicated hardware
+button for Search, so if it's an important feature in your app, it should always appear as an
+action item (and usually as the first item, especially if you offer it with an <a
+href="#ActionView">action view</a>).</p>
+
+
+
+<h3 id="SplitBar">Using split action bar</h3>
+
+<p>When your application is running on Android 4.0 (API level 14) and higher, there's an extra mode
+available for the action bar called "split action bar." When you enable split action bar, a separate
+bar appears at the bottom of the screen to display all action items when the activity is running on
+a narrow screen (such as a portrait-oriented handset). Splitting the action bar to separate
+the action items ensures that a reasonable amount of space is available to display all your action
+items on a narrow screen, while leaving room for navigation and title elements at the top.</p>
+
+<p>To enable split action bar, simply add {@code uiOptions="splitActionBarWhenNarrow"} to your
+<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a> or
+<a href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application&gt;}</a>
+manifest element.</p>
+
+<p>Be aware that Android adjusts the action bar's appearance in a variety of ways, based on the
+current screen size. Using split action bar is just one option that you can enable to allow the
+action bar to further optimize the user experience for different screen sizes. In doing so, you
+may also allow the action bar to collapse navigation tabs into the main action bar. That is, if you
+use <a href="#Tabs">navigation tabs</a> in your action bar, once the action items are
+separated on a narrow screen, the navigation tabs may be able to fit into the main action bar rather
+than be separated into the "stacked action bar." Specifically, if you've disabled the action bar
+icon and title (with {@link android.app.ActionBar#setDisplayShowHomeEnabled
+setDisplayShowHomeEnabled(false)} and {@link android.app.ActionBar#setDisplayShowTitleEnabled
+setDisplayShowTitleEnabled(false)}), then the navigation tabs collapse into the main action bar, as
+shown by the second device in figure 3.</p>
+
+<img src="{@docRoot}images/practices/actionbar-phone-splitaction.png" alt=""/>
+<p class="img-caption"><strong>Figure 3.</strong> Mock-ups of split action bar with navigation tabs
+on the left; with the app icon and title disabled on the right.</p>
+
+<p class="note"><strong>Note:</strong> Although the {@link android.R.attr#uiOptions
+android:uiOptions} attribute was added in Android 4.0 (API level 14), you can safely include it in
+your application even if your <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> is set to
+a value lower than {@code "14"} to remain compatible with older versions of Android. When running on
+older versions, the system simply ignores the XML attribute because it doesn't understand it. The
+only condition to including it in your manifest is that you must compile your application against a
+platform version that supports API level 14 or higher. Just be sure that you don't openly use other
+APIs in your application code that aren't supported by the version declared by your <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a>
+attribute&mdash;only XML attributes are safely ignored by older platforms.</p>
+
+
+
+
+<h2 id="Home">Using the App Icon for Navigation</h2>
+
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+  <h2>Using a logo instead of icon</h2>
+<p>By default, the system uses your application icon in the action bar, as specified by the <a
+href="{@docRoot}guide/topics/manifest/application-element.html#icon">{@code android:icon}</a>
+attribute in the <a href="{@docRoot}guide/topics/manifest/application-element.html">{@code
+&lt;application&gt;}</a> or <a
+href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
+&lt;activity&gt;}</a> element. However, if you also specify the <a
+href="{@docRoot}guide/topics/manifest/application-element.html#logo">{@code android:logo}</a>
+attribute, then the action bar uses the logo image instead of the icon.</p>
+<p>A logo should usually be wider than the icon, but should not include unnecessary text. You
+should generally use a logo only when it represents your brand in a traditional format that users
+recognize. A good example is the YouTube app's logo&mdash;the logo represents the expected user
+brand, whereas the app's icon is a modified version that conforms to the square requirement.</p>
+</div>
+</div>
+
+
+<p>By default, your application icon appears in the action bar on the left side. If you'd like,
+you can enable the icon to behave as an action item. In response to user action on the icon, your
+application should do one of two things:</p>
+
+<ul>
+  <li>Go to the application "home" activity, or</li>
+  <li>Navigate "up" the application's structural hierarchy</li>
+</ul>
+
+<p>When the user touches the icon, the system calls your activity's {@link
 android.app.Activity#onOptionsItemSelected onOptionsItemSelected()} method with the  {@code
-android.R.id.home} ID. So, you need to add a condition to your {@link
-android.app.Activity#onOptionsItemSelected onOptionsItemSelected()} method to listen for {@code
-android.R.id.home} and perform the appropriate action, such as start the home activity or pop recent
-fragment transactions off the stack.</p>
+android.R.id.home} ID. In response, you should either start the home activity or
+take the user one step up in your application's structural hierarchy.</p>
 
 <p>If you respond to the application icon by returning to the home activity, you should include
 the {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP} flag in the {@link
 android.content.Intent}. With this flag, if the activity you're starting already exists in the
 current task, then all activities on top of it are destroyed and it is brought to the front.
-You should favor this approach, because going "home" is an action that's equivalent to "going
+Adding this flag is often important because going "home" is an action that's equivalent to "going
 back" and you should usually not create a new instance of the home activity. Otherwise, you
-might end up with a long stack of activities in the current task.</p>
+might end up with a long stack of activities in the current task with multiple instances of the
+home activity.</p>
 
 <p>For example, here's an implementation of {@link android.app.Activity#onOptionsItemSelected
 onOptionsItemSelected()} that returns to the application's "home" activity:</p>
@@ -252,7 +464,7 @@
 public boolean onOptionsItemSelected(MenuItem item) {
     switch (item.getItemId()) {
         case android.R.id.home:
-            // app icon in Action Bar clicked; go home
+            // app icon in action bar clicked; go home
             Intent intent = new Intent(this, HomeActivity.class);
             intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
             startActivity(intent);
@@ -263,129 +475,153 @@
 }
 </pre>
 
-
-
-
-<h4>Using the app icon to navigate "up"</h4>
-
-<div class="figure" style="width:144px">
-  <img src="{@docRoot}images/ui/actionbar-logo.png" height="140" alt="" />
-  <p class="img-caption"><strong>Figure 4.</strong> The standard icon for the Email application
-(top) and the "up" icon (bottom).</p>
-</div>
-
-<p>You can also use the application icon to provide "up" navigation for the user. This is especially
-useful when your application is composed of activities that generally appear in a certain order and
-you want to facilitate the ability for the user to navigate up the activity hierarchy
-(regardless of how they entered the current activity).</p>
-
-<p>The way you respond to this event is the same as when navigating home (as
-discussed above, except you start a different activity, based on the current activity). All you
-need to do to indicate to the user that the behavior is different is set the Action Bar to "show
-home as up." You can do so by calling {@link android.app.ActionBar#setDisplayHomeAsUpEnabled
-setDisplayHomeAsUpEnabled(true)} on your activity's {@link android.app.ActionBar}. When you do, the
-system draws your application icon with an arrow indicating the up behavior, as shown in figure
-4.</p>
-
-<p>For example, here's how you can show the application icon as an "up" action:</p>
+<p>In case the user can enter the current activity from another application, you might also want to
+add the {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag. This flag ensures that, when the
+user navigates either "home" or "up", the new activity is <strong>not</strong> added to the current
+task, but instead started in a task that belongs to your application. For example, if the user
+starts an activity in your application through an intent invoked by another application, then
+selects the action bar icon to navigate home or up, the {@link
+android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP} flag starts the activity in a task that belongs to
+your application (not the current task). The system either starts a new task with your new activity
+as the root activity or, if an existing task exists in the background with an instance of that
+activity, then that task is brought forward and the target activity receives {@link
+android.app.Activity#onNewIntent onNewIntent()}. So if your activity accepts intents from other
+applications (it declares any generic intent filters), you should usually add the {@link
+android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag to the intent:</p>
 
 <pre>
-&#64;Override
-protected void onStart() {
-    super.onStart();
-    ActionBar actionBar = this.getActionBar();
+intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
+</pre>
+
+<p>For more information about these flags and other back stack behaviors, read the <a
+href="{@docRoot}guide/topics/fundamentals/tasks-and-back-stack.html">Tasks and Back Stack</a>
+developer guide.</p>
+
+<p class="note"><strong>Note:</strong> If you're using the icon to navigate to the home
+activity, beware that beginning with Android 4.0 (API level 14), you must explicitly enable the
+icon as an action item by calling {@link android.app.ActionBar#setHomeButtonEnabled
+setHomeButtonEnabled(true)} (in previous versions, the icon was enabled as an action item by
+default).</p>
+
+
+
+<h3 id="Up">Navigating up</h3>
+
+<div class="figure" style="width:230px;margin-top:-1em">
+  <img src="{@docRoot}images/ui/actionbar-logo.png" alt="" />
+  <p class="img-caption"><strong>Figure 4.</strong> The Email app's standard icon
+(left) and the "navigate up" icon (right). The system automatically adds the "up" indicator.</p>
+</div>
+
+<p>As a supplement to traditional "back" navigation&mdash;which takes the user to the previous
+screen in the task history&mdash;you can enable the action bar icon to offer "up"
+navigation, which should take the user one step up in your application's structural hierarchy. For
+instance, if the current screen is somewhere deep in the hierarchy of the application, touching the
+app icon should navigate upward one level, to the parent of the current screen.</p>
+
+<p>For example, figure 5 illustrates how the BACK button behaves when the user navigates from one
+application to an activity belonging to a different application (specifically, when composing an
+email to a person selected from the People app).</p>
+
+<img src="{@docRoot}images/ui/actionbar-navigate-back.png" alt="" />
+<p class="img-caption"><strong>Figure 5.</strong> The BACK button behavior
+after entering the Email app from the People (or Contacts) app.</p>
+
+<p>However, if the user wants to stay within the email application after composing the email,
+up navigation allows the user to navigate upward in the email application, rather than go back
+to the previous activity. Figure 6 illustrates this scenario, in which the user again comes into
+the email application, but presses the action bar icon to navigate up, rather than back.</p>
+
+<img src="{@docRoot}images/ui/actionbar-navigate-up.png" alt="" />
+<p class="img-caption"><strong>Figure 6.</strong> Example behavior for UP navigation after
+entering the Email app from the People app.</p>
+
+<p>To enable the icon for up navigation (which displays the "up" indicator next to the icon), call
+{@link android.app.ActionBar#setDisplayHomeAsUpEnabled setDisplayHomeAsUpEnabled(true)} on your
+{@link android.app.ActionBar}:</p>
+
+<pre>
+protected void onCreate(Bundle savedInstanceState) {
+    super.onCreate(savedInstanceState);
+
+    setContentView(R.layout.main);
+    ActionBar actionBar = getActionBar();
     actionBar.setDisplayHomeAsUpEnabled(true);
+    ...
 }
 </pre>
 
-<p>Then, your activity should respond to the user tapping the icon, from the {@link
-android.app.Activity#onOptionsItemSelected
-onOptionsItemSelected()}, by listening for the {@code android.R.id.home} ID (as shown above). In
-this case, when navigating up, it's even more important that you use the {@link
-android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP} flag in the {@link android.content.Intent}, so that
-you don't create a new instance of the parent activity if one already exists.</p>
+<p>When the user touches the icon, the system calls your activity's {@link
+android.app.Activity#onOptionsItemSelected onOptionsItemSelected()} method with the {@code
+android.R.id.home} ID, as shown in the above section about <a href="#Home">Using the App Icon
+for Navigation</a>.</p>
+
+<p>Remember to use the {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP} flag in the {@link
+android.content.Intent}, so that you don't create a new instance of the parent activity if one
+already exists. For instance, if you don't use the {@link
+android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP} flag, then after navigating up, the BACK button will
+actually take the user "forward", with respect to the application structure, which would be
+strange.</p>
+
+<p class="note"><strong>Note:</strong> If there are many paths that the user could have taken to
+reach the current activity within your application, the up icon should navigate backward along the
+path the user actually followed to get to the current activity.</p>
 
 
 
 
 <h2 id="ActionView">Adding an Action View</h2>
 
-<div class="figure" style="width:429px">
-  <img src="{@docRoot}images/ui/actionbar-actionview.png" alt="" />
-  <p class="img-caption"><strong>Figure 5.</strong> An action view with a {@link
-android.widget.SearchView} widget.</p>
+<div class="figure" style="width:300px;margin-top:-1em">
+  <img src="/images/ui/actionbar-searchview.png" alt="" />
+  <p class="img-caption"><strong>Figure 7.</strong> An action bar with a collapsed action
+view for Search (top), then expanded action view with the <code><a
+href="/reference/android/widget/SearchView.html">SearchView</a></code> widget (bottom).</p>
 </div>
 
-<p>An action view is a widget that appears in the Action Bar as a substitute for an action 
-item. For example, if you have an item in the Options Menu for "Search", you can add an action view
-for the item that provides a {@link android.widget.SearchView} widget in the Action Bar whenever
-the item is enabled as an action item.</p>
 
-<p>When adding an action view for a menu item, it's important that you still allow the item to
-behave as a normal menu item when it does not appear in the Action Bar. For example, a menu item to
-perform a search should, by default, bring up the Android search dialog, but if the item is
-placed in the Action Bar, the action view appears with a {@link android.widget.SearchView}
-widget. Figure 4 shows an example of  the {@link android.widget.SearchView} widget in an action
-view.</p>
+<p>An action view is a widget that appears in the action bar as a substitute for an action item's
+button. For example, if you have an item in the options menu for "Search," you can add an action
+view that replaces the button with a {@link android.widget.SearchView} widget, as shown in figure
+7.</p>
 
-<p>The best way to declare an action view for an item is in your <a
-href="{@docRoot}guide/topics/resources/menu-resource.html">menu resource</a>, using the {@code
-android:actionLayout} or {@code android:actionViewClass} attribute:</p>
+<p>To declare an action view for an item in your <a
+href="{@docRoot}guide/topics/resources/menu-resource.html">menu resource</a>, use either the {@code
+android:actionLayout} or {@code android:actionViewClass} attribute to specify either a layout
+resource or widget class to use, respectively. For example:</p>
 
-<ul>
-  <li>The value for {@code android:actionLayout} must be a resource pointer to a layout file.
-For example:
 <pre>
 &lt;?xml version="1.0" encoding="utf-8"?>
 &lt;menu xmlns:android="http://schemas.android.com/apk/res/android">
     &lt;item android:id="@+id/menu_search"
-        android:title="Search"
-        android:icon="@drawable/ic_menu_search"
-        android:showAsAction="ifRoom"
-        <b>android:actionLayout="@layout/searchview"</b> /&gt;
+          android:title="@string/menu_search"
+          android:icon="@drawable/ic_menu_search"
+          android:showAsAction="ifRoom|collapseActionView"
+          <b>android:actionViewClass="android.widget.SearchView"</b> /&gt;
 &lt;/menu>
 </pre>
-</li>
 
-  <li>The value for {@code android:actionViewClass} must be a fully-qualified class name for
-the {@link android.view.View} you want to use. For example:
-<pre>
-&lt;?xml version="1.0" encoding="utf-8"?>
-&lt;menu xmlns:android="http://schemas.android.com/apk/res/android">
-    &lt;item android:id="@+id/menu_search"
-        android:title="Search"
-        android:icon="@drawable/ic_menu_search"
-        android:showAsAction="ifRoom"
-        <b>android:actionViewClass="android.widget.SearchView"</b> /&gt;
-&lt;/menu>
-</pre></li>
-</ul>
+<p>Notice that the {@code android:showAsAction} attribute also includes {@code
+"collapseActionView"}. This is optional and declares that the action view should be collapsed into a
+button. When the user selects the button, the action view expands. Otherwise, the action view is
+visible by default and might consume valuable action bar space even when the user is not using it.
+For more information, see the next section about <a href="#ActionViewCollapsing">Handling
+collapsible action views</a>.</p>
 
-<p class="note">You must include {@code android:showAsAction="ifRoom"} in order for the item to
-appear as an action view when room is available. If necessary, however, you can force the item to 
-always appear as an action view by setting {@code android:showAsAction} to {@code "always"}.</p>
-
-<p>Now, when the menu item is displayed as an action item, it's action view appears instead of
-the icon and/or title text. However, if there's not enough room in the Action Bar, the item appears
-in the overflow menu as a normal menu item and you must respond to it from the {@link
-android.app.Activity#onOptionsItemSelected onOptionsItemSelected()} callback method.</p>
-
-<p>When the activity first starts, the system populates the Action Bar and overflow menu by calling
-{@link android.app.Activity#onCreateOptionsMenu onCreateOptionsMenu()}.
-After you've inflated your menu in this method, you can acquire elements in an action view
-(perhaps in order to attach listeners) by calling {@link android.view.Menu#findItem
-findItem()} with the ID of the menu item, then {@link android.view.MenuItem#getActionView} on
-the returned {@link android.view.MenuItem}. For example, the search widget from the above samples is
-acquired like this:</p>
+<p>If you need to add some event hooks to your action view, you can do so during the {@link
+android.app.Activity#onCreateOptionsMenu onCreateOptionsMenu()} callback. You can acquire elements
+in an action view by calling {@link android.view.Menu#findItem findItem()} with the ID of the menu
+item, then call {@link android.view.MenuItem#getActionView}. For
+example, the search widget from the above sample is acquired like this:</p>
 
 <pre>
 &#64;Override
 public boolean onCreateOptionsMenu(Menu menu) {
-  getMenuInflater().inflate(R.menu.options, menu);
-  SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
-  // Set appropriate listeners for searchView
-  ...
-  return super.onCreateOptionsMenu(menu);
+    getMenuInflater().inflate(R.menu.options, menu);
+    SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
+    // Configure the search info and add any event listeners
+    ...
+    return super.onCreateOptionsMenu(menu);
 }
 </pre>
 
@@ -393,167 +629,487 @@
 href="{@docRoot}guide/topics/search/search-dialog.html">Creating a Search Interface</a>.</p>
 
 
+<h3 id="ActionViewCollapsing">Handling collapsible action views</h3>
 
-
-<h2 id="Tabs">Adding Tabs</h2>
-
-
-<div class="figure" style="width:504px">
-  <img src="{@docRoot}images/ui/actionbar-tabs.png" alt="" />
-  <p class="img-caption"><strong>Figure 6.</strong> Screenshot of tabs in the
-Action Bar, from the <a
-href="{@docRoot}resources/samples/HoneycombGallery/index.html">Honeycomb Gallery</a> sample
-application.</p>
+<div class="sidebox-wrapper">
+<div class="sidebox">
+  <h3>Supporting Android 3.0 with an action view</h3>
+  <p>The {@code "collapseActionView"} option was added with Android 4.0 (API level 14). However, if
+your application supports older versions, you should
+still declare {@code "collapseActionView"} in order to better support smaller screens.
+Devices running Android 4.0 and higher will show the action view collapsed, while older versions
+work as designed otherwise.</p>
+  <p>Adding this value requires that you set your build target to Android 4.0 or higher in order to
+compile. Older versions of Android ignore the {@code "collapseActionView"} value because they don't
+understand it. Just be sure not to use other APIs in your source code that are not supported in the
+version declared by your <a href="{@docRoot}guide/topics/manifest/uses-sdk-elementl.html#min">{@code
+minSdkVersion}</a>, unless you add the appropriate version check at runtime.</p>
+</div>
 </div>
 
-<p>The Action Bar can display tabs that allow the user navigate between different fragments in the
-activity. Each tab can include a title and/or an icon.</p>
 
-<p>To begin, your layout must include a {@link android.view.View} in which each {@link
-android.app.Fragment} associated with a tab is displayed. Be sure the view has an ID that you
-can use to reference it from your code.</p>
+<p>Action views allow you to provide fast access to rich actions without changing activities or
+fragments, or replacing the action bar. However, it might not be appropriate to make an action view
+visible by default. To preserve the action bar space (especially when running on smaller screens),
+you can collapse your action view into an action item button. When the user selects the
+button, the action view appears in the action bar. When collapsed, the system might place the item
+into the overflow menu if you've defined {@code android:showAsAction} with {@code "ifRoom"}, but the
+action view still appears in the action bar when the user selects the item. You can make your action
+view collapsible by adding {@code "collapseActionView"} to the {@code android:showAsAction}
+attribute, as shown in the XML above.</p>
 
-<p>To add tabs to the Action Bar:</p>
-<ol>
-  <li>Create an implementation of {@link android.app.ActionBar.TabListener} to handle the
-interaction events on the Action Bar tabs. You must implement all methods: {@link
-android.app.ActionBar.TabListener#onTabSelected onTabSelected()}, {@link
-android.app.ActionBar.TabListener#onTabUnselected onTabUnselected()}, and {@link
-android.app.ActionBar.TabListener#onTabReselected onTabReselected()}.
-    <p>Each callback method passes the {@link android.app.ActionBar.Tab} that received the
-event and a {@link android.app.FragmentTransaction} for you to perform the fragment
-transactions (add or remove fragments).</p>
-    <p>For example:</p>
+<p>Because the system will expand the action view when the user selects the item, so you
+<em>do not</em> need to respond to the item in the {@link
+android.app.Activity#onOptionsItemSelected onOptionsItemSelected} callback. The system still calls
+{@link android.app.Activity#onOptionsItemSelected onOptionsItemSelected()} when the user selects it,
+but the system will always expand the action view unless you return {@code true} (indicating
+you've handled the event instead).</p>
+
+<p>The system also collapses your action view when the user selects the "up" icon in the action
+bar or presses the BACK button.</p>
+
+<p>If necessary, you can expand or collapse the action view in your own code by calling {@link
+android.view.MenuItem#expandActionView()} and {@link android.view.MenuItem#collapseActionView()} on
+the {@link android.view.MenuItem}.</p>
+
+<p class="note"><strong>Note:</strong> Although collapsing your action view is optional, we
+recommend that you always collapse your action view if it includes {@link
+android.widget.SearchView}. Also be aware that some devices provide a dedicated SEARCH button and
+you should expand your search action view if the user presses the SEARCH button. Simply override 
+your activity's {@link android.app.Activity#onKeyUp onKeyUp()} callback method, listen for the
+{@link android.view.KeyEvent#KEYCODE_SEARCH} event, then call {@link
+android.view.MenuItem#expandActionView()}.</p>
+
+<p>If you need to update your activity based on the visibility of your action view, you can receive
+callbacks when it's expanded and collapsed by defining an {@link
+android.view.MenuItem.OnActionExpandListener OnActionExpandListener} and registering it with {@link
+android.view.MenuItem#setOnActionExpandListener setOnActionExpandListener()}. For example:</p>
+
 <pre>
-private class MyTabListener implements ActionBar.TabListener {
-    private TabContentFragment mFragment;
+&#64;Override
+public boolean onCreateOptionsMenu(Menu menu) {
+    getMenuInflater().inflate(R.menu.options, menu);
+    MenuItem menuItem = menu.findItem(R.id.actionItem);
+    ...
 
-    // Called to create an instance of the listener when adding a new tab
-    public MyTabListener(TabContentFragment fragment) {
-        mFragment = fragment;
+    menuItem.setOnActionExpandListener(new OnActionExpandListener() {
+        &#64;Override
+        public boolean onMenuItemActionCollapse(MenuItem item) {
+            // Do something when collapsed
+            return true;  // Return true to collapse action view
+        }
+
+        &#64;Override
+        public boolean onMenuItemActionExpand(MenuItem item) {
+            // Do something when expanded
+            return true;  // Return true to expand action view
+        }
+    });
+}
+</pre>
+
+
+
+
+<h2 id="ActionProvider">Adding an Action Provider</h2>
+
+<div class="figure" style="width:200px">
+  <img src="{@docRoot}images/ui/actionbar-shareaction.png" alt="" />
+  <p class="img-caption"><strong>Figure 8.</strong> Screenshot from the Gallery app, with the
+  {@link android.widget.ShareActionProvider} submenu expanded to show share targets.</p>
+</div>
+
+<p>Similar to an <a href="#ActionView">action view</a>, an action provider (defined by the {@link
+android.view.ActionProvider} class) replaces an action item with a customized layout, but it also
+takes control of all the item's behaviors. When you declare an action provider for a menu
+item in the action bar, it not only controls the appearance of the item in the action bar with a
+custom layout, but also handles the default event for the menu item when it appears in the overflow
+menu. It can also provide a submenu from either the action bar or the overflow menu.</p>
+
+<p>For example, the {@link android.widget.ShareActionProvider} is an extension of {@link
+android.view.ActionProvider} that facilitates a “share" action by showing a list of available share
+targets from the action bar. Instead of using a
+traditional action item that invokes the {@link android.content.Intent#ACTION_SEND} intent, you can
+declare an instance of {@link android.widget.ShareActionProvider} to handle an action item. This
+action provider presents an action view with a drop-down list of applications that handle
+the {@link android.content.Intent#ACTION_SEND} intent, even when the menu item appears in the
+overflow menu. Hence, when you use an action provider such as this one, you don't
+have to handle user events on the menu item.</p>
+
+<p>To declare an action provider for an action item, define the {@code android:actionProviderClass}
+attribute for the appropriate the {@code &lt;item&gt;} element in your <a
+href="{@docRoot}guide/topics/resources/menu-resource.html">menu resource</a>, using the
+fully-qualified class name of the action provider. For example:</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;menu xmlns:android="http://schemas.android.com/apk/res/android">
+    &lt;item android:id="@+id/menu_share"
+          android:title="@string/share"
+          android:showAsAction="ifRoom"
+          <strong>android:actionProviderClass="android.widget.ShareActionProvider"</strong> /&gt;
+    ...
+&lt;/menu>
+</pre>
+
+<p>In this example, the {@link android.widget.ShareActionProvider} is used as the action provider.
+At this point, the action provider officially takes control of the menu item and handles both
+its appearance and behavior in the action bar and its behavior in the overflow menu. You must
+still provide a text title for the item to be used in the overflow menu.</p>
+
+<p>Although the action provider can perform the default action for the menu item when it appears in
+the overflow menu, your activity (or fragment) can override that behavior by
+also handling the click event from the {@link android.app.Activity#onOptionsItemSelected
+onOptionsItemSelected()} callback method. If you do not handle the event in that callback, then
+the action provider receives the {@link android.view.ActionProvider#onPerformDefaultAction()}
+callback to handle the event. However, if the action provider provides a submenu, then your
+activity will not receive the {@link android.app.Activity#onOptionsItemSelected
+onOptionsItemSelected()} callback, because the submenu is shown instead of invoking the default
+menu item behavior when selected.</p>
+
+
+
+<h3 id="ShareActionProvider">Using the ShareActionProvider</h3>
+
+<p>If you want to provide a "share" action in your action bar by leveraging other applications
+installed on the device (for example, to share a photo using a messaging or social app), then using
+{@link android.widget.ShareActionProvider} is an effective way to do so, rather than adding an
+action item that invokes the {@link android.content.Intent#ACTION_SEND} intent. When
+you use {@link android.widget.ShareActionProvider} for an action item, it presents an action view
+with a drop-down list of applications that handle the {@link android.content.Intent#ACTION_SEND}
+intent (as shown in figure 8).</p>
+
+<p>All the logic for creating the submenu, populating it with share targets, and handling click
+events (including when the item appears in the overflow menu) is implemented by the {@link
+android.widget.ShareActionProvider}&mdash;the only code you need to write is to declare the action
+provider for the menu item and specify the share intent.</p>
+
+<p>By default, the {@link android.widget.ShareActionProvider} retains a ranking for each
+share target based on how often the user selects each one. The share targets used more frequently
+appear at the top of the drop-down list and the target used most often appears directly in the
+action bar as the default share target. By default, the ranking information is
+saved in a private file with a name specified by {@link
+android.widget.ShareActionProvider#DEFAULT_SHARE_HISTORY_FILE_NAME}. If you use the {@link
+android.widget.ShareActionProvider} or an extension of it for only one type of action, then you
+should continue to use this default history file and there's nothing you need to do. However, if you
+use {@link android.widget.ShareActionProvider} or an extension of it for multiple actions with
+semantically different meanings, then each {@link android.widget.ShareActionProvider} should specify
+its own history file in order to maintain its own history. To specify a
+different history file for the {@link android.widget.ShareActionProvider}, call {@link
+android.widget.ShareActionProvider#setShareHistoryFileName setShareHistoryFileName()} and provide
+an XML file name (for example, {@code "custom_share_history.xml"}).</p>
+
+<p class="note"><strong>Note:</strong> Although the {@link android.widget.ShareActionProvider} ranks
+share targets based on frequency of use, the behavior is extensible and extensions of {@link
+android.widget.ShareActionProvider} can perform different behaviors and ranking based on the history
+file (if appropriate).</p>
+
+<p>To add {@link android.widget.ShareActionProvider}, simply define the {@code
+android:actionProviderClass} attribute with {@code "android.widget.ShareActionProvider"}, as shown
+in the XML example above. The only thing left to do is define
+the {@link android.content.Intent} you want to use for sharing. To do so, you must call {@link
+android.view.MenuItem#getActionProvider} to retrieve the {@link android.widget.ShareActionProvider}
+that's associated with a {@link android.view.MenuItem}, then call {@link
+android.widget.ShareActionProvider#setShareIntent setShareIntent()}.</p>
+
+<p>If the format for the share intent depends on the selected item or other variables that change
+during the activity lifecycle, you should save the {@link android.widget.ShareActionProvider} in a
+member field and update it by calling {@link android.widget.ShareActionProvider#setShareIntent
+setShareIntent()} as necessary. For example:</p>
+
+<pre>
+private ShareActionProvider mShareActionProvider;
+...
+
+&#64;Override
+public boolean onCreateOptionsMenu(Menu menu) {
+    mShareActionProvider = (ShareActionProvider) menu.findItem(R.id.menu_share).getActionProvider();
+
+    // If you use more than one ShareActionProvider, each for a different action,
+    // use the following line to specify a unique history file for each one.
+    // mShareActionProvider.setShareHistoryFileName("custom_share_history.xml");
+
+    // Set the default share intent
+    mShareActionProvider.setShareIntent(getDefaultShareIntent());
+
+    return true;
+}
+// When you need to update the share intent somewhere else in the app, call
+// mShareActionProvider.{@link android.widget.ShareActionProvider#setShareIntent setShareIntent()}
+</pre>
+
+<p>The {@link android.widget.ShareActionProvider} now handles all user interaction with the item and
+you <em>do not</em> need to handle click events from the {@link
+android.app.Activity#onOptionsItemSelected onOptionsItemSelected()} callback method.</p>
+
+<p>For a sample using the share action provider, see
+<a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/ActionBarActionProviderActivity.html"
+>ActionBarActionProviderActivity</a>.
+
+
+
+<h3 id="CreatingActionProvider">Creating a custom action provider</h3>
+
+<p>When you want to create an action view that has dynamic behaviors and a default action in the
+overflow menu, extending {@link android.view.ActionProvider} to define those behaviors is a good
+solution. Creating your own action provider offers you an organized and reusable component, rather
+than handling the various action item transformations and behaviors in your fragment or activity
+code. As shown in the previous section, Android provides one implementation of {@link
+android.view.ActionProvider} for share actions: the {@link android.widget.ShareActionProvider}.</p>
+
+<p>To create your own, simply extend the {@link android.view.ActionProvider} class and implement
+its callback methods as appropriate. Most importantly, you should implement the following:</p>
+
+<dl>
+  <dt>{@link android.view.ActionProvider#ActionProvider ActionProvider()}</dt>
+  <dd>This constructor passes you the application {@link android.content.Context}, which you
+should save in a member field to use in the other callback methods.</dd>
+
+  <dt>{@link android.view.ActionProvider#onCreateActionView()}</dt>
+  <dd>This is where you define the action view for the item. Use the {@link
+android.content.Context} acquired from the constructor to instantiate a {@link
+android.view.LayoutInflater} and inflate your action view layout from an XML resource, then hook
+up event listeners. For example:
+<pre>
+public View onCreateActionView() {
+    // Inflate the action view to be shown on the action bar.
+    LayoutInflater layoutInflater = LayoutInflater.from(mContext);
+    View view = layoutInflater.inflate(R.layout.action_provider, null);
+    ImageButton button = (ImageButton) view.findViewById(R.id.button);
+    button.setOnClickListener(new View.OnClickListener() {
+        &#064;Override
+        public void onClick(View v) {
+            // Do something...
+        }
+    });
+    return view;
+}
+</pre>
+</dd>
+
+  <dt>{@link android.view.ActionProvider#onPerformDefaultAction()}</dt>
+  <dd>The system calls this when the menu item is selected from the overflow menu and the
+action provider should perform a default action for the menu item.
+  <p>However, if your action provider provides a submenu, through the {@link
+android.view.ActionProvider#onPrepareSubMenu onPrepareSubMenu()} callback, then the submenu
+appears even when the menu item is in the overflow menu. Thus, {@link
+android.view.ActionProvider#onPerformDefaultAction()} is never called when there is a
+submenu.</p>
+  <p class="note"><strong>Note:</strong> An activity or a fragment that implements {@link
+android.app.Activity#onOptionsItemSelected onOptionsItemSelected()} can override the action
+provider's default behavior by handling the item-selected event (and returning true), in which
+case, the system does not call {@link android.view.ActionProvider#onPerformDefaultAction()}.</p>
+</dd>
+</dl>
+
+<p>For an example extension of {@link android.view.ActionProvider}, see <a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/ActionBarSettingsActionProviderActivity.html"
+>ActionBarSettingsActionProviderActivity</a>.</p>
+
+
+
+
+<h2 id="Tabs">Adding Navigation Tabs</h2>
+
+
+<div class="figure" style="width:450px">
+  <img src="{@docRoot}images/ui/actionbar.png" alt="" />
+  <p class="img-caption"><strong>Figure 9.</strong> Screenshot of action bar tabs from the <a
+href="{@docRoot}resources/samples/HoneycombGallery/index.html">Honeycomb Gallery</a> app.</p>
+</div>
+
+<div class="figure" style="width:250px">
+  <img src="{@docRoot}images/ui/actionbar-stacked.png" alt="" />
+  <p class="img-caption"><strong>Figure 10.</strong> Screenshot of tabs in the stacked action
+bar on a narrow screen.</p>
+</div>
+
+<p>When you want to provide navigation tabs in an activity, using the action bar's
+tabs is a great option (instead of using {@link android.widget.TabWidget}), because the
+system adapts the action bar tabs for different screen sizes&mdash;placing them in the main action
+bar when the screen is sufficiently wide, or in a separate bar (known as the "stacked action bar")
+when the screen is too narrow, as shown in figures 9 and 10.</p>
+
+<p>To switch between fragments using the tabs, you must perform a fragment
+transaction each time a tab is selected. If you're not familiar with how to change fragments
+using {@link android.app.FragmentTransaction}, first read the <a
+href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a> developer guide.</p>
+
+<p>To get started, your layout must include a {@link android.view.ViewGroup} in which you place each
+{@link android.app.Fragment} associated with a tab. Be sure the {@link android.view.ViewGroup} has a
+resource ID so you can reference it from your tab-swapping code. Alternatively, if the tab content
+will fill the activity layout (excluding the action bar), then your activity doesn't need a layout
+at all (you don't even need to call {@link android.app.Activity#setContentView
+setContentView()}). Instead, you can place each fragment in the default root {@link
+android.view.ViewGroup}, which you can refer to with the {@code android.R.id.content} ID (you can
+see this ID used in the sample code below, during fragment transactions).</p>
+
+<p>Once you determine where the fragments appear in the layout, the basic procedure to add tabs
+is:</p>
+<ol>
+  <li>Implement the {@link android.app.ActionBar.TabListener} interface. Callbacks in this
+interface respond to user events on the tabs so you can swap fragments.</li>
+  <li>For each tab you want to add, instantiate an {@link android.app.ActionBar.Tab} and set the
+{@link android.app.ActionBar.TabListener} by calling {@link android.app.ActionBar.Tab#setTabListener
+setTabListener()}. Also set the tab's title and/or icon with {@link
+android.app.ActionBar.Tab#setText setText()} and/or {@link android.app.ActionBar.Tab#setIcon
+setIcon()}.</li>
+  <li>Add each tab to the action bar by calling {@link android.app.ActionBar#addTab addTab()}.</li>
+</ol>
+
+<p>When looking at the {@link android.app.ActionBar.TabListener} interface, notice that the
+callback methods provide only the {@link android.app.ActionBar.Tab} that was selected and a {@link
+android.app.FragmentTransaction} for you to perform fragment transactions&mdash;it doesn't say
+anything about what fragment you should swap in or out. Thus, you must define your own association
+between each {@link android.app.ActionBar.Tab} and the appropriate {@link android.app.Fragment} that
+it represents (in order to perform the appropriate fragment transaction). There are several ways you
+can define the association, depending on your design. In the example below, the {@link
+android.app.ActionBar.TabListener} implementation provides a constructor such that each new tab uses
+its own instance of the listener. Each instance of the listener defines several fields that are
+necessary to later perform a transaction on the appropriate fragment.</p>
+
+<p>For example, here's how you might implement the {@link android.app.ActionBar.TabListener}
+such that each tab uses its own instance of the listener:</p>
+<pre>
+public static class TabListener&lt;T extends Fragment> implements ActionBar.TabListener {
+    private Fragment mFragment;
+    private final Activity mActivity;
+    private final String mTag;
+    private final Class&lt;T> mClass;
+
+    /** Constructor used each time a new tab is created.
+      * @param activity  The host Activity, used to instantiate the fragment
+      * @param tag  The identifier tag for the fragment
+      * @param clz  The fragment's Class, used to instantiate the fragment
+      */
+    public TabListener(Activity activity, String tag, Class&lt;T> clz) {
+        mActivity = activity;
+        mTag = tag;
+        mClass = clz;
     }
 
+    /* The following are each of the {@link android.app.ActionBar.TabListener} callbacks */
+
     public void onTabSelected(Tab tab, FragmentTransaction ft) {
-        ft.add(R.id.fragment_content, mFragment, null);
+        // Check if the fragment is already initialized
+        if (mFragment == null) {
+            // If not, instantiate and add it to the activity
+            mFragment = Fragment.instantiate(mActivity, mClass.getName());
+            ft.add(android.R.id.content, mFragment, mTag);
+        } else {
+            // If it exists, simply attach it in order to show it
+            ft.attach(mFragment);
+        }
     }
 
     public void onTabUnselected(Tab tab, FragmentTransaction ft) {
-        ft.remove(mFragment);
+        if (mFragment != null) {
+            // Detach the fragment, because another one is being attached
+            ft.detach(mFragment);
+        }
     }
 
     public void onTabReselected(Tab tab, FragmentTransaction ft) {
-        // do nothing
+        // User selected the already selected tab. Usually do nothing.
     }
-
 }
 </pre>
-  <p>This implementation of {@link android.app.ActionBar.TabListener} adds a constructor
-that saves the {@link android.app.Fragment} associated with a tab so that each callback
-can add or remove that fragment.</p>
-  </li>
-  <li>Get the {@link android.app.ActionBar} for your activity by calling {@link
-android.app.Activity#getActionBar} from your {@link android.app.Activity}, during {@link
-android.app.Activity#onCreate onCreate()} (but be sure you do so <em>after</em> you've called
-{@link android.app.Activity#setContentView setContentView()}).</li>
-  <li>Call {@link android.app.ActionBar#setNavigationMode(int)
-setNavigationMode(NAVIGATION_MODE_TABS)} to enable tab mode for the {@link
-android.app.ActionBar}.</li>
-  <li>Create each tab for the Action Bar:
-    <ol>
-      <li>Create a new {@link android.app.ActionBar.Tab} by calling {@link
-android.app.ActionBar#newTab()} on the {@link android.app.ActionBar}.</li>
-      <li>Add title text and/or an icon for the tab by calling {@link
-android.app.ActionBar.Tab#setText setText()} and/or {@link android.app.ActionBar.Tab#setIcon
-setIcon()}.
-        <p class="note"><strong>Tip:</strong> These methods return the same {@link
-android.app.ActionBar.Tab} instance, so you can chain the calls together.</p></li>
-      <li>Declare the {@link android.app.ActionBar.TabListener} to use for the tab by passing an
-instance of your implementation to {@link android.app.ActionBar.Tab#setTabListener
-setTabListener()}.
-    </ol>
-  </li>
-  <li>Add each {@link android.app.ActionBar.Tab} to the Action Bar by calling {@link
-android.app.ActionBar#addTab addTab()} on the {@link android.app.ActionBar} and passing the
-{@link android.app.ActionBar.Tab}.</li>
-</ol>
-<p>For example, the following code combines steps 2 - 5 to create two tabs and add them to
-the Action Bar:</p>
+
+<p class="caution"><strong>Caution:</strong> You <strong>must not</strong> call {@link
+android.app.FragmentTransaction#commit} for the fragment transaction in each of these
+callbacks&mdash;the system calls it for you and it may throw an exception if you call it yourself.
+You also <strong>cannot</strong> add these fragment transactions to the back stack.</p>
+
+<p>In this example, the listener simply attaches ({@link android.app.FragmentTransaction#attach
+attach()}) a fragment to the activity layout&mdash;or if not instantiated, creates the fragment and
+adds ({@link android.app.FragmentTransaction#add add()}) it to the layout (as a child of the {@code
+android.R.id.content} view group)&mdash;when the respective tab is selected, and detaches ({@link
+android.app.FragmentTransaction#detach detach()}) it when the tab is unselected.</p>
+
+<p>The {@link android.app.ActionBar.TabListener} implementation is the bulk of the work. All that
+remains is to create each {@link android.app.ActionBar.Tab} and add it to the {@link
+android.app.ActionBar}. Additionally, you must call {@link
+android.app.ActionBar#setNavigationMode(int) setNavigationMode(NAVIGATION_MODE_TABS)} to make the
+tabs visible. You might also want to disable the activity title by calling {@link
+android.app.ActionBar#setDisplayShowTitleEnabled setDisplayShowTitleEnabled(false)} if the tab
+titles actually indicate the current view.</p>
+
+<p>For example, the following code adds two tabs using the listener defined above:</p>
+
 <pre>
 &#64;Override
 protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
-    setContentView(R.layout.main);
+    // Notice that setContentView() is not used, because we use the root
+    // android.R.id.content as the container for each fragment
 
-    // setup Action Bar for tabs
-    final ActionBar actionBar = getActionBar();
+    // setup action bar for tabs
+    ActionBar actionBar = getActionBar();
     actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
-    // remove the activity title to make space for tabs
     actionBar.setDisplayShowTitleEnabled(false);
 
-    // instantiate fragment for the tab
-    Fragment artistsFragment = new ArtistsFragment();
-    // add a new tab and set its title text and tab listener
-    actionBar.addTab(actionBar.newTab().setText(R.string.tab_artists)
-            .setTabListener(new TabListener(artistsFragment)));
+    Tab tab = actionBar.newTab()
+            .setText(R.string.artist)
+            .setTabListener(new TabListener&lt;ArtistFragment>(
+                    this, "artist", ArtistFragment.class));
+    actionBar.addTab(tab);
 
-    Fragment albumsFragment = new AlbumsFragment();
-    actionBar.addTab(actionBar.newTab().setText(R.string.tab_albums)
-            .setTabListener(new TabListener(albumsFragment)));
+    tab = actionBar.newTab()
+        .setText(R.string.album)
+        .setTabListener(new TabListener&lt;AlbumFragment>(
+                this, "album", AlbumFragment.class));
+    actionBar.addTab(tab);
 }
 </pre>
 
-<p>All the behaviors that occur when a tab is selected must be defined by your {@link
-android.app.ActionBar.TabListener} callback methods. When a tab is selected, it receives a call to
-{@link android.app.ActionBar.TabListener#onTabSelected onTabSelected()} and that's where you should
-add the appropriate fragment to the designated view in your layout, using {@link
-android.app.FragmentTransaction#add add()} with the provided {@link
-android.app.FragmentTransaction}. Likewise, when a tab is deselected (because another tab becomes
-selected), you should remove that fragment from the layout, using {@link
-android.app.FragmentTransaction#remove remove()}.</p>
+<p class="note"><strong>Note:</strong> The above implementation for {@link
+android.app.ActionBar.TabListener} is one of several possible techniques. You can see more of
+this style in the <a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/FragmentTabs.html"
+>API Demos</a> app.</p>
 
-<p class="caution"><strong>Caution:</strong> You <strong>must not</strong> call {@link
-android.app.FragmentTransaction#commit} for these transactions&mdash;the system calls it for you
-and it may throw an exception if you call it yourself. You also <strong>cannot</strong> add these
-fragment transactions to the back stack.</p>
 
-<p>If your activity is stopped, you should retain the currently selected tab with the saved state so
-that when the user returns to your application, you can open the tab. When it's time to save the
+<p>If your activity stops, you should retain the currently selected tab with the <a
+href="{@docRoot}guide/topics/fundamentals/activities.html#SavingActivityState">saved instance
+state</a> so you can open the appropriate tab when the user returns. When it's time to save the
 state, you can query the currently selected tab with {@link
 android.app.ActionBar#getSelectedNavigationIndex()}. This returns the index position of the selected
 tab.</p>
 
-<p class="caution"><strong>Caution:</strong> It's important that you save
-the state of each fragment as necessary, so when the user switches fragments with the tabs,
-then returns to a previous fragment, it appears the way they left. For information about saving
-the state of your fragment, see the <a
-href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a> developer guide.</p>
+<p class="caution"><strong>Caution:</strong> It's important that you save the state of each fragment
+as necessary, so that when users switch fragments with the tabs and then return to a previous
+fragment, it looks the way it did when they left. For information about saving the state of your
+fragment, see the <a href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a>
+developer guide.</p>
 
 
+<p class="note"><strong>Note:</strong> In some cases, the Android system will show your action
+bar tabs as a drop-down list in order to ensure the best fit in the action bar.</p>
 
 
 <h2 id="Dropdown">Adding Drop-down Navigation</h2>
 
-<p>As another mode of navigation within your activity, you can provide a drop-down list in the
-Action Bar. For example, the drop-down list can provide alternative modes for sorting the content in
-the activity or switching the user's account.</p>
+<p>As another mode of navigation (or filtering) within your activity, the action bar offers a
+built in drop-down list. For example, the drop-down list can offer different modes by which content
+in the activity is sorted.</p>
 
 <!--
 <div class="figure" style="width:135px">
   <img src="{@docRoot}images/ui/actionbar-dropdown.png" alt="" />
   <p class="img-caption"><strong>Figure 5.</strong> Screenshot of a drop-down navigation list in the
-Action Bar.</p>
+action bar.</p>
 </div>
 -->
 
-<p>Here's a quick list of steps to enable drop-down navigation:</p>
+<p>The basic procedure to enable drop-down navigation is:</p>
 
 <ol>
   <li>Create a {@link android.widget.SpinnerAdapter} that provides the
 list of selectable items for the drop-down and the layout to use when drawing each item in the
 list.</li>
-  <li>Implement {@link android.app.ActionBar.OnNavigationListener} to define the behavior when the
-user selects an item from the list.</li>
-  <li>Enable navigation mode for the Action Bar with {@link
+  <li>Implement {@link android.app.ActionBar.OnNavigationListener} to define the behavior that
+occurs when the user selects an item from the list.</li>
+  <li>Enable navigation mode for the action bar with {@link
 android.app.ActionBar#setNavigationMode setNavigationMode()}. For example:
 <pre>
 ActionBar actionBar = getActionBar();
@@ -563,13 +1119,13 @@
 android.app.Activity#onCreate
 onCreate()} method.</p>
   </li>
-  <li>Then, set the callback for the drop-down list with {@link
+  <li>Set the callback for the drop-down list with {@link
 android.app.ActionBar#setListNavigationCallbacks setListNavigationCallbacks()}. For example:
 <pre>
 actionBar.setListNavigationCallbacks(mSpinnerAdapter, mNavigationCallback);
 </pre>
 <p>This method takes your {@link android.widget.SpinnerAdapter} and {@link
-android.app.ActionBar.OnNavigationListener}. More about these next.</p>
+android.app.ActionBar.OnNavigationListener}.</p>
 </li>
 </ol>
 
@@ -594,7 +1150,7 @@
   <div class="toggle-content-toggleme">
 
 <p>{@link android.widget.SpinnerAdapter} is an adapter that provides data for a spinner widget,
-such as the drop-down list in the Action Bar. {@link android.widget.SpinnerAdapter} is an interface
+such as the drop-down list in the action bar. {@link android.widget.SpinnerAdapter} is an interface
 that you can implement, but Android includes some useful implementations that you can extend, such
 as {@link android.widget.ArrayAdapter} and {@link
 android.widget.SimpleCursorAdapter}. For example, here's an easy way to create a {@link
@@ -713,140 +1269,199 @@
 
 <h2 id="Style">Styling the Action Bar</h2>
 
-<p>The Action Bar is the heading for your application and a primary interaction point for users,
-so you might want to modify some of its design in order to make it feel more integrated with your
-application design. There are several ways you can do this if you wish.</p>
+<p>If you've implemented a custom design for the widgets in your application, you might
+also want to redesign some of the action bar to match your app design. To do so, you need to use
+Android's <a
+href="{@docRoot}guide/topics/ui/themes.html">style and theme</a> framework to restyle the action
+bar using special style properties.</p>
 
-<p>For simple modifications to the {@link android.app.ActionBar}, you can use the following
-methods:</p>
+
+<p class="note"><strong>Note:</strong> In order for background images to change appearance
+depending on the current button state (selected, pressed, unselected), the drawable resource you use
+must be a <a href="{@docRoot}guide/topics/resources/drawable-resource.html#StateList">state
+list drawable</a>.</p>
+
+<p class="caution"><strong>Caution:</strong> For all background drawables you provide, be sure to use <a
+href="{@docRoot}guide/topics/graphics/2d-graphics.html#nine-patch">Nine-Patch drawables</a> to allow
+stretching. The Nine-Patch image should be <em>smaller</em> than 40px tall and 30px wide (for the mdpi asset).</p>
+
+
+<h3 id="GeneralStyles">General appearance</h3>
 
 <dl>
-  <dt>{@link android.app.ActionBar#setBackgroundDrawable setBackgroundDrawable()}</dt>
-  <dd>Sets a drawable to use as the Action Bar's background. The drawable should be a <a
-href="{@docRoot}guide/topics/graphics/2d-graphics.html#nine-patch">Nine-patch</a> image, a <a
-href="{@docRoot}guide/topics/resources/drawable-resource.html#Shape">shape</a>, or a <a
-href="{@docRoot}guide/topics/resources/more-resources.html#Color">solid color</a>, so the system can
-resize the drawable based on the size of the Action Bar (you should <em>not</em> use a fixed-size
-bitmap image).</dd>
 
-  <dt>{@link android.app.ActionBar#setDisplayUseLogoEnabled setDisplayUseLogoEnabled()}</dt>
-  <dd>Enables the use of an alternative image (a "logo") in the Action Bar, instead of the default
-application icon. A logo is often a wider, more detailed image that represents the application.
-When this is enabled, the system uses the logo image defined for the application (or the
-individual activity) in the manifest file, with the <a
-href="{@docRoot}guide/topics/manifest/application-element.html#logo">{@code android:logo}</a>
-attribute. The logo will be resized as necessary to fit the height of the Action Bar. (Best
-practice is to design the logo at the same size as your application icon.)</dd>
-</dl>
-
-
-<p>For more complex customizations, you can use Android's <a
-href="{@docRoot}guide/topics/ui/themes.html">style and theme</a> framework to restyle your Action
-Bar in several ways.</p>
-
-<p>The Action Bar has two standard themes, "dark" and "light". The dark theme is applied with
-the default holographic theme, as specified by the {@link android.R.style#Theme_Holo Theme.Holo}
-theme. If you want a white background with dark text, instead, you can apply the {@link
-android.R.style#Theme_Holo_Light Theme.Holo.Light} theme to the activity in the manifest file. For
-example:</p>
-
+  <dt>{@link android.R.attr#windowActionBarOverlay
+      android:windowActionBarOverlay}</dt>
+  <dd>Declares whether the action bar should overlay the activity layout rather than offset the
+activity's layout position (for example, the Gallery app uses overlay mode). This is
+{@code false} by default.
+  <p>Normally, the action bar requires its own space on the screen and your activity layout fills in
+what's left over. When the action bar is in overlay mode, your activity layout uses all the
+available space and the system draws the action bar on top. Overlay mode can be useful if you want
+your content to keep a fixed size and position when the action bar is hidden and shown. You might
+also like to use it purely as a visual effect, because you can use a semi-transparent background
+for the action bar so the user can still see some of your activity layout behind the action
+bar.</p>
+  <p class="note"><strong>Note:</strong> The {@link android.R.style#Theme_Holo Holo} theme families
+draw the action bar with a semi-transparent background by default. However, you can modify it with
+your own styles and the {@link android.R.style#Theme_DeviceDefault DeviceDefault} theme on
+different devices might use an opaque background by default.</p>
+  <p>When overlay mode is enabled, your activity layout has no awareness of the action bar laying on
+top of it. So, you must be careful not to place any important information or UI components in the
+area overlayed by the action bar. If appropriate, you can refer to the platform's value for {@link
+android.R.attr#actionBarSize} to determine the height of the action bar, by referencing it
+in your XML layout. For example:</p>
 <pre>
-&lt;activity android:name=".ExampleActivity"
-          android:theme="@android:style/Theme.Holo.Light" />
+&lt;SomeView
+    ...
+    android:layout_marginTop="?android:attr/actionBarSize" /&gt;
 </pre>
-
-<p>For more control, you can override either the {@link android.R.style#Theme_Holo
-Theme.Holo} or {@link android.R.style#Theme_Holo_Light Theme.Holo.Light} theme and apply custom
-styles to certain aspects of the Action Bar. Some of the Action Bar properties you can customize
-include the following:</p>
-
-<dl>
-  <dt>{@link android.R.styleable#Theme_actionBarTabStyle
-      android:actionBarTabStyle}</dt>
-  <dd>Style for tabs in the Action Bar.</dd>
-
-  <dt>{@link android.R.styleable#Theme_actionBarTabBarStyle
-      android:actionBarTabBarStyle}</dt>
-  <dd>Style for the bar that appears below tabs in the Action Bar.</dd>
-
-  <dt>{@link android.R.styleable#Theme_actionBarTabTextStyle
-      android:actionBarTabTextStyle}</dt>
-  <dd>Style for the text in the tabs.</dd>
-
-  <dt>{@link android.R.styleable#Theme_actionDropDownStyle
-      android:actionDropDownStyle}</dt>
-  <dd>Style for the drop-down list used for the overflow menu and drop-down navigation.</dd>
-
-  <dt>{@link android.R.styleable#Theme_actionButtonStyle
-      android:actionButtonStyle}</dt>
-  <dd>Style for the background image used for buttons in the Action Bar.</dd>
+  <p>You can also retrieve the action bar height at runtime with {@link
+android.app.ActionBar#getHeight()}. This reflects the height of the action bar at the time it's
+called, which might not include the stacked action bar (due to navigation tabs) if called during early 
+activity lifecycle methods. To see how you can determine the total height at runtime, including the
+stacked action bar, see the <a
+href="{@docRoot}resources/samples/HoneycombGallery/src/com/example/android/hcgallery/TitlesFragment.html"
+>{@code TitlesFragment}</a> class in the <a
+href="{@docRoot}resources/samples/HoneycombGallery/index.html"
+>Honeycomb Gallery</a> sample app.</p>
+</dd>
 
 </dl>
 
-<p>For example, here's a resource file that defines a custom theme for the Action Bar, based on
-the standard {@link android.R.style#Theme_Holo Theme.Holo} theme:</p>
+
+<h3 id="ActionItemStyles">Action items</h3>
+
+<dl>
+  <dt>{@link android.R.attr#actionButtonStyle
+      android:actionButtonStyle}</dt>
+  <dd>Defines a style resource for the action item buttons.</dd>
+
+  <dt>{@link android.R.attr#actionBarItemBackground
+      android:actionBarItemBackground}</dt>
+  <dd>Defines a drawable resource for each action item's background. (Added in API level 14.)</dd>
+
+  <dt>{@link android.R.attr#itemBackground
+      android:itemBackground}</dt>
+  <dd>Defines a drawable resource for each overflow menu item's background.</dd>
+
+  <dt>{@link android.R.attr#actionBarDivider
+      android:actionBarDivider}</dt>
+  <dd>Defines a drawable resource for the divider between action items. (Added in API level
+14.)</dd>
+
+  <dt>{@link android.R.attr#actionMenuTextColor
+      android:actionMenuTextColor}</dt>
+  <dd>Defines a color for text that appears in an action item.</dd>
+
+  <dt>{@link android.R.attr#actionMenuTextAppearance
+      android:actionMenuTextAppearance}</dt>
+  <dd>Defines a style resource for text that appears in an action item.</dd>
+
+  <dt>{@link android.R.attr#actionBarWidgetTheme
+      android:actionBarWidgetTheme}</dt>
+  <dd>Defines a theme resource for widgets that are inflated into the action bar as <a
+href="#ActionView">action views</a>. (Added in API level 14.)</dd>
+</dl>
+
+
+<h3 id="NavigationStyles">Navigation tabs</h3>
+
+<dl>
+  <dt>{@link android.R.attr#actionBarTabStyle
+      android:actionBarTabStyle}</dt>
+  <dd>Defines a style resource for tabs in the action bar.</dd>
+
+  <dt>{@link android.R.attr#actionBarTabBarStyle
+      android:actionBarTabBarStyle}</dt>
+  <dd>Defines a style resource for the thin bar that appears below the navigation tabs.</dd>
+
+  <dt>{@link android.R.attr#actionBarTabTextStyle
+      android:actionBarTabTextStyle}</dt>
+  <dd>Defines a style resource for text in the navigation tabs.</dd>
+</dl>
+
+
+<h3 id="DropDownStyles">Drop-down lists</h3>
+
+<dl>
+  <dt>{@link android.R.attr#actionDropDownStyle
+      android:actionDropDownStyle}</dt>
+  <dd>Defines a style for the drop-down navigation (such as the background and text styles).</dd>
+</dl>
+
+
+
+<p>For example, here's a file that defines a few custom styles for the action bar:</p>
 
 <pre>
 &lt;?xml version="1.0" encoding="utf-8"?>
 &lt;resources>
     &lt;!-- the theme applied to the application or activity -->
-    &lt;style name="CustomActionBar" parent="android:style/Theme.Holo.Light">
-        &lt;item name="android:actionBarTabTextStyle">@style/customActionBarTabTextStyle&lt;/item>
-        &lt;item name="android:actionBarTabStyle">@style/customActionBarTabStyle&lt;/item>
-        &lt;item name="android:actionBarTabBarStyle">@style/customActionBarTabBarStyle&lt;/item>
+    &lt;style name="CustomActivityTheme" parent="@android:style/Theme.Holo">
+        &lt;item name="android:actionBarTabTextStyle">@style/CustomTabTextStyle&lt;/item>
+        &lt;item name="android:actionBarDivider">@drawable/ab_divider&lt;/item>
+        &lt;item name="android:actionBarItemBackground">@drawable/ab_item_background&lt;/item>
     &lt;/style>
 
-    &lt;!-- style for the tab text -->
-    &lt;style name="customActionBarTabTextStyle">
-        &lt;item name="android:textColor">#2966c2&lt;/item>
-        &lt;item name="android:textSize">20sp&lt;/item>
-        &lt;item name="android:typeface">sans&lt;/item>
-    &lt;/style>
-
-    &lt;!-- style for the tabs -->
-    &lt;style name="customActionBarTabStyle">
-        &lt;item name="android:background">@drawable/actionbar_tab_bg&lt;/item>
-        &lt;item name="android:paddingLeft">20dp&lt;/item>
-        &lt;item name="android:paddingRight">20dp&lt;/item>
-    &lt;/style>
-
-    &lt;!-- style for the tab bar -->
-    &lt;style name="customActionBarTabBarStyle">
-        &lt;item name="android:background">@drawable/actionbar_tab_bar&lt;/item>
+    &lt;!-- style for the action bar tab text -->
+    &lt;style name="CustomTabTextStyle">
+        &lt;item name="android:textColor">#2456c2&lt;/item>
     &lt;/style>
 &lt;/resources>
 </pre>
 
-<p class="note"><strong>Note:</strong> In order for the tab background image to change,
-depending on the current tab state (selected, pressed, unselected), the drawable resource used
-must be a <a href="{@docRoot}guide/topics/resources/drawable-resource.html#StateList">state
-list drawable</a>. Also be certain that your theme declares a parent theme, from which it
-inherits all styles not explicitly declared in your theme.</p>
+<p class="note"><strong>Note:</strong> Be certain that your theme declares a parent theme in the
+{@code &lt;style>} tag, from which it inherits all styles not explicitly declared by your theme.
+When modifying the action bar, using a parent theme is important so that you can simply override the
+action bar styles you want to change without re-implementing the styles you want to leave alone
+(such as text appearance or padding in action items).</p>
 
 <p>You can apply your custom theme to the entire application or to individual activities in your
-manifest file, like this:</p>
+manifest file like this:</p>
 
 <pre>
-&lt;application android:theme="&#64;style/CustomActionBar"
+&lt;application android:theme="&#64;style/CustomActivityTheme"
              ... />
 </pre>
 
-<p>Additionally, if you want to create a custom theme for your activity that removes the Action
-Bar completely, use the following style attributes:</p>
-
-<dl>
-  <dt>{@link android.R.styleable#Theme_windowActionBar
-      android:windowActionBar}</dt>
-  <dd>Set this style property {@code false} to remove the Action Bar.</dd>
-
-  <dt>{@link android.R.styleable#Theme_windowNoTitle
-      android:windowNoTitle}</dt>
-  <dd>Set this style property {@code true} to also remove the traditional title bar.</dd>
-</dl>
-  
-<p>For more information about using themes in your application, read <a
+<p>For more information about using style and theme resources in your application, read <a
 href="{@docRoot}guide/topics/ui/themes.html">Styles and Themes</a>.</p>
 
 
+<h3 id="AdvancedStyles">Advanced styling</h3>
+
+  <p>If you need more advanced styling for the action bar than is available with the
+properties above, you can include {@link android.R.attr#actionBarStyle android:actionBarStyle} and
+{@link android.R.attr#actionBarSplitStyle android:actionBarSplitStyle} in your activity's theme.
+Each of these specifies another style that can define various properties for the action bar,
+including different backgrounds with {@link android.R.attr#background android:background}, {@link
+android.R.attr#backgroundSplit android:backgroundSplit}, and {@link android.R.attr#backgroundStacked
+android:backgroundStacked}. If you override these action bar styles, be sure that you define a
+parent action bar style such as {@link android.R.style#Widget_Holo_ActionBar
+Widget.Holo.ActionBar}.</p>
+
+<p>For example, if you want to change the action bar's background, you could use the following
+styles:</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;resources>
+    &lt;!-- the theme applied to the application or activity -->
+    &lt;style name="CustomActivityTheme" parent="@android:style/Theme.Holo">
+        &lt;item name="android:actionBarTabTextStyle">@style/customTabTextStyle&lt;/item>
+        &lt;!-- other activity and action bar styles here -->
+    &lt;/style>
+
+    &lt;!-- style for the action bar, simply to change the background -->
+    &lt;style parent="@android:style/Widget.Holo.ActionBar">
+        &lt;item name="android:background">@drawable/ab_background&lt;/item>
+        &lt;item name="android:backgroundSplit">@drawable/ab_background&lt;/item>
+    &lt;/style>
+&lt;/resources>
+</pre>
+
+
+
 
 
diff --git a/docs/html/images/ui/actionbar-actionview.png b/docs/html/images/ui/actionbar-actionview.png
index cc18f9b..9103dc4 100644
--- a/docs/html/images/ui/actionbar-actionview.png
+++ b/docs/html/images/ui/actionbar-actionview.png
Binary files differ
diff --git a/docs/html/images/ui/actionbar-item-withtext.png b/docs/html/images/ui/actionbar-item-withtext.png
index 61742d3..5f7aecc 100644
--- a/docs/html/images/ui/actionbar-item-withtext.png
+++ b/docs/html/images/ui/actionbar-item-withtext.png
Binary files differ
diff --git a/docs/html/images/ui/actionbar-logo.png b/docs/html/images/ui/actionbar-logo.png
index df914bc..c62b3e2 100644
--- a/docs/html/images/ui/actionbar-logo.png
+++ b/docs/html/images/ui/actionbar-logo.png
Binary files differ
diff --git a/docs/html/images/ui/actionbar-navigate-back.png b/docs/html/images/ui/actionbar-navigate-back.png
new file mode 100644
index 0000000..9431bca
--- /dev/null
+++ b/docs/html/images/ui/actionbar-navigate-back.png
Binary files differ
diff --git a/docs/html/images/ui/actionbar-navigate-up.png b/docs/html/images/ui/actionbar-navigate-up.png
new file mode 100644
index 0000000..09243b4
--- /dev/null
+++ b/docs/html/images/ui/actionbar-navigate-up.png
Binary files differ
diff --git a/docs/html/images/ui/actionbar-navigate-up.xcf b/docs/html/images/ui/actionbar-navigate-up.xcf
new file mode 100644
index 0000000..bf1849a
--- /dev/null
+++ b/docs/html/images/ui/actionbar-navigate-up.xcf
Binary files differ
diff --git a/docs/html/images/ui/actionbar-searchview.png b/docs/html/images/ui/actionbar-searchview.png
new file mode 100644
index 0000000..7ae46a0
--- /dev/null
+++ b/docs/html/images/ui/actionbar-searchview.png
Binary files differ
diff --git a/docs/html/images/ui/actionbar-shareaction.png b/docs/html/images/ui/actionbar-shareaction.png
new file mode 100644
index 0000000..fdbb02c
--- /dev/null
+++ b/docs/html/images/ui/actionbar-shareaction.png
Binary files differ
diff --git a/docs/html/images/ui/actionbar-stacked.png b/docs/html/images/ui/actionbar-stacked.png
new file mode 100644
index 0000000..76c8908
--- /dev/null
+++ b/docs/html/images/ui/actionbar-stacked.png
Binary files differ
diff --git a/docs/html/images/ui/actionbar.png b/docs/html/images/ui/actionbar.png
index dcd8449..1d01583 100644
--- a/docs/html/images/ui/actionbar.png
+++ b/docs/html/images/ui/actionbar.png
Binary files differ
diff --git a/docs/html/sdk/eclipse-adt.jd b/docs/html/sdk/eclipse-adt.jd
index 941f693..50b20ce 100644
--- a/docs/html/sdk/eclipse-adt.jd
+++ b/docs/html/sdk/eclipse-adt.jd
@@ -1,8 +1,8 @@
 page.title=ADT Plugin for Eclipse
-adt.zip.version=15.0.0
-adt.zip.download=ADT-15.0.0.zip
-adt.zip.bytes=6750682
-adt.zip.checksum=264f40a89a1107b0c422adae4e1ce0d1
+adt.zip.version=15.0.1
+adt.zip.download=ADT-15.0.1.zip
+adt.zip.bytes=6752327
+adt.zip.checksum=2c12a71d7124aa512b8ee016e19c0e69
 
 @jd:body
 
@@ -109,10 +109,44 @@
 </style>
 
 
+
 <div class="toggleable opened">
   <a href="#" onclick="return toggleDiv(this)">
         <img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px"
 width="9px" />
+ADT 15.0.1</a> <em>(November 2011)</em>
+  <div class="toggleme">
+<dl>
+  <dt>Dependencies:</dt>
+  
+  <dd>ADT 15.0.1 is designed for use with <a href="{@docRoot}sdk/tools-notes.html">SDK Tools r15</a>.
+  If you haven't already installed SDK Tools r15 into your SDK, use the Android SDK and AVD Manager to
+  do so.</dd>
+  
+  <dt>Bug fixes:</dt>
+  <dd>
+    <ul>
+      <li>Fixed how source files are attached to library project <code>.jar</code> files.</li>
+      <li>Fixed how the <code>bin/</code> folder for library projects are refreshed. This ensures that parent projects pick up changes in library projects.</li>
+      <li>Fixed how a parent project's library container is updated when a library project is recompiled. This ensures that parent projects are
+      recompiled when code in a library project changes.</li>
+      <li>Fixed how <code>res/</code> folders are checked in library projects. This ensures that all <code>res</code> folders are properly included
+      even if Eclipse is not aware of them due to refresh issues.</li>
+      <li>Fixed issue that prevented <code>aapt</code> from running when editing certain XML files.</li>
+      <li>Fixed minor XML formatting issues.</li>
+    </ul>
+  </dd>
+</dl>
+
+</div>
+</div>
+
+
+
+<div class="toggleable closed">
+  <a href="#" onclick="return toggleDiv(this)">
+        <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px"
+width="9px" />
 ADT 15.0.0</a> <em>(October 2011)</em>
   <div class="toggleme">
 <dl>
diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs
index afe6a6e..0ae2c6d 100644
--- a/docs/html/sdk/sdk_toc.cs
+++ b/docs/html/sdk/sdk_toc.cs
@@ -169,7 +169,7 @@
       <span style="display:none" class="zh-TW"></span>
       </h2>
     <ul>
-      <li><a href="<?cs var:toroot ?>sdk/eclipse-adt.html">ADT 15.0.0
+      <li><a href="<?cs var:toroot ?>sdk/eclipse-adt.html">ADT 15.0.1
       <span style="display:none" class="de"></span>
       <span style="display:none" class="es"></span>
       <span style="display:none" class="fr"></span>
diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp
index 3c0d475..0561909 100644
--- a/libs/gui/SurfaceTexture.cpp
+++ b/libs/gui/SurfaceTexture.cpp
@@ -437,6 +437,11 @@
             mSlots[buf].mEglImage = EGL_NO_IMAGE_KHR;
             mSlots[buf].mEglDisplay = EGL_NO_DISPLAY;
         }
+        if (mCurrentTexture == buf) {
+            // The current texture no longer references the buffer in this slot
+            // since we just allocated a new buffer.
+            mCurrentTexture = INVALID_BUFFER_SLOT;
+        }
         returnFlags |= ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;
     }
     ST_LOGV("dequeueBuffer: returning slot=%d buf=%p flags=%#x", buf,
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 7d9d7ed..f6d054d 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -224,17 +224,18 @@
     mClient.disconnect();
 }
 
-void AwesomePlayer::cancelPlayerEvents(bool keepBufferingGoing) {
+void AwesomePlayer::cancelPlayerEvents(bool keepNotifications) {
     mQueue.cancelEvent(mVideoEvent->eventID());
     mVideoEventPending = false;
-    mQueue.cancelEvent(mStreamDoneEvent->eventID());
-    mStreamDoneEventPending = false;
-    mQueue.cancelEvent(mCheckAudioStatusEvent->eventID());
-    mAudioStatusEventPending = false;
     mQueue.cancelEvent(mVideoLagEvent->eventID());
     mVideoLagEventPending = false;
 
-    if (!keepBufferingGoing) {
+    if (!keepNotifications) {
+        mQueue.cancelEvent(mStreamDoneEvent->eventID());
+        mStreamDoneEventPending = false;
+        mQueue.cancelEvent(mCheckAudioStatusEvent->eventID());
+        mAudioStatusEventPending = false;
+
         mQueue.cancelEvent(mBufferingEvent->eventID());
         mBufferingEventPending = false;
     }
@@ -1095,7 +1096,7 @@
         return OK;
     }
 
-    cancelPlayerEvents(true /* keepBufferingGoing */);
+    cancelPlayerEvents(true /* keepNotifications */);
 
     if (mAudioPlayer != NULL && (mFlags & AUDIO_RUNNING)) {
         if (at_eos) {
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index c13d6cb..0985f47 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -250,7 +250,7 @@
     void notifyVideoSize_l();
     void seekAudioIfNecessary_l();
 
-    void cancelPlayerEvents(bool keepBufferingGoing = false);
+    void cancelPlayerEvents(bool keepNotifications = false);
 
     void setAudioSource(sp<MediaSource> source);
     status_t initAudioDecoder();
diff --git a/opengl/java/android/opengl/GLES11Ext.java b/opengl/java/android/opengl/GLES11Ext.java
index 25d5467..484439a 100644
--- a/opengl/java/android/opengl/GLES11Ext.java
+++ b/opengl/java/android/opengl/GLES11Ext.java
@@ -125,6 +125,10 @@
     public static final int GL_TEXTURE_MAX_ANISOTROPY_EXT                           = 0x84FE;
     public static final int GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT                       = 0x84FF;
     public static final int GL_BGRA                                                 = 0x80E1;
+    public static final int GL_TEXTURE_EXTERNAL_OES                                 = 0x8D65;
+    public static final int GL_SAMPLER_EXTERNAL_OES                                 = 0x8D66;
+    public static final int GL_TEXTURE_BINDING_EXTERNAL_OES                         = 0x8D67;
+    public static final int GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES                     = 0x8D68;
 
     native private static void _nativeClassInit();
     static {
diff --git a/opengl/libs/EGL/egl_cache.cpp b/opengl/libs/EGL/egl_cache.cpp
index 13a4929..fe32d43 100644
--- a/opengl/libs/EGL/egl_cache.cpp
+++ b/opengl/libs/EGL/egl_cache.cpp
@@ -85,7 +85,7 @@
             bool atStart = !strncmp(BC_EXT_STR " ", exts, bcExtLen+1);
             bool atEnd = (bcExtLen+1) < extsLen &&
                     !strcmp(" " BC_EXT_STR, exts + extsLen - (bcExtLen+1));
-            bool inMiddle = strstr(" " BC_EXT_STR " ", exts);
+            bool inMiddle = strstr(exts, " " BC_EXT_STR " ");
             if (equal || atStart || atEnd || inMiddle) {
                 PFNEGLSETBLOBCACHEFUNCSANDROIDPROC eglSetBlobCacheFuncsANDROID;
                 eglSetBlobCacheFuncsANDROID =
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 862b48d2..31119f9 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -220,15 +220,19 @@
         if (end) {
             // length of the extension string
             const size_t len = end - start;
-            // NOTE: we could avoid the copy if we had strnstr.
-            const String8 ext(start, len);
-            // now go through all implementations and look for this extension
-            for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
-                // if we find it, add this extension string to our list
-                // (and don't forget the space)
-                const char* match = strstr(disp[i].queryString.extensions, ext.string());
-                if (match && (match[len] == ' ' || match[len] == 0)) {
-                    mExtensionString.append(start, len+1);
+            if (len) {
+                // NOTE: we could avoid the copy if we had strnstr.
+                const String8 ext(start, len);
+                // now go through all implementations and look for this extension
+                for (int i = 0; i < IMPL_NUM_IMPLEMENTATIONS; i++) {
+                    if (disp[i].queryString.extensions) {
+                        // if we find it, add this extension string to our list
+                        // (and don't forget the space)
+                        const char* match = strstr(disp[i].queryString.extensions, ext.string());
+                        if (match && (match[len] == ' ' || match[len] == 0)) {
+                            mExtensionString.append(start, len+1);
+                        }
+                    }
                 }
             }
             // process the next extension string, and skip the space.
diff --git a/opengl/tools/glgen/stubs/gles11/GLES11ExtHeader.java-if b/opengl/tools/glgen/stubs/gles11/GLES11ExtHeader.java-if
index c5e34cd..0c5fa04 100644
--- a/opengl/tools/glgen/stubs/gles11/GLES11ExtHeader.java-if
+++ b/opengl/tools/glgen/stubs/gles11/GLES11ExtHeader.java-if
@@ -124,6 +124,10 @@
     public static final int GL_TEXTURE_MAX_ANISOTROPY_EXT                           = 0x84FE;
     public static final int GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT                       = 0x84FF;
     public static final int GL_BGRA                                                 = 0x80E1;
+    public static final int GL_TEXTURE_EXTERNAL_OES                                 = 0x8D65;
+    public static final int GL_SAMPLER_EXTERNAL_OES                                 = 0x8D66;
+    public static final int GL_TEXTURE_BINDING_EXTERNAL_OES                         = 0x8D67;
+    public static final int GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES                     = 0x8D68;
 
     native private static void _nativeClassInit();
     static {
@@ -135,4 +139,4 @@
     private static final int GL_FLOAT = GLES10.GL_FLOAT;
     private static final int GL_SHORT = GLES10.GL_SHORT;
     
-    private static Buffer _matrixIndexPointerOES;
\ No newline at end of file
+    private static Buffer _matrixIndexPointerOES;
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 5495d08..aa08e64 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -723,6 +723,8 @@
             upgradeVersion = 57;
         }
 
+        /************* The following are Honeycomb changes ************/
+
         if (upgradeVersion == 57) {
             /*
              * New settings to:
@@ -751,13 +753,13 @@
 
         if (upgradeVersion == 58) {
             /* Add default for new Auto Time Zone */
+            int autoTimeValue = getIntValueFromSystem(db, Settings.System.AUTO_TIME, 0);
             db.beginTransaction();
             SQLiteStatement stmt = null;
             try {
-                stmt = db.compileStatement("INSERT INTO secure(name,value)"
-                        + " VALUES(?,?);");
-                loadBooleanSetting(stmt, Settings.System.AUTO_TIME_ZONE,
-                        R.bool.def_auto_time_zone); // Sync timezone to NITZ
+                stmt = db.compileStatement("INSERT INTO system(name,value)" + " VALUES(?,?);");
+                loadSetting(stmt, Settings.System.AUTO_TIME_ZONE,
+                        autoTimeValue); // Sync timezone to NITZ if auto_time was enabled
                 db.setTransactionSuccessful();
             } finally {
                 db.endTransaction();
@@ -784,18 +786,24 @@
         }
 
         if (upgradeVersion == 60) {
-            upgradeScreenTimeout(db);
+            // Don't do this for upgrades from Gingerbread
+            // Were only required for intra-Honeycomb upgrades for testing
+            // upgradeScreenTimeout(db);
             upgradeVersion = 61;
         }
 
         if (upgradeVersion == 61) {
-            upgradeScreenTimeout(db);
+            // Don't do this for upgrades from Gingerbread
+            // Were only required for intra-Honeycomb upgrades for testing
+            // upgradeScreenTimeout(db);
             upgradeVersion = 62;
         }
 
         // Change the default for screen auto-brightness mode
         if (upgradeVersion == 62) {
-            upgradeAutoBrightness(db);
+            // Don't do this for upgrades from Gingerbread
+            // Were only required for intra-Honeycomb upgrades for testing
+            // upgradeAutoBrightness(db);
             upgradeVersion = 63;
         }
 
@@ -839,6 +847,8 @@
             upgradeVersion = 65;
         }
 
+        /************* The following are Ice Cream Sandwich changes ************/
+
         if (upgradeVersion == 65) {
             /*
              * Animations are removed from Settings. Turned on by default
@@ -1232,12 +1242,13 @@
             stmt = db.compileStatement("INSERT OR IGNORE INTO system(name,value)"
                     + " VALUES(?,?);");
     
-            // Vibrate off by default for ringer, on for notification
+            // Vibrate on by default for ringer, on for notification
             int vibrate = 0;
             vibrate = AudioService.getValueForVibrateSetting(vibrate,
-                    AudioManager.VIBRATE_TYPE_NOTIFICATION, AudioManager.VIBRATE_SETTING_ON);
+                    AudioManager.VIBRATE_TYPE_NOTIFICATION,
+                    AudioManager.VIBRATE_SETTING_ONLY_SILENT);
             vibrate |= AudioService.getValueForVibrateSetting(vibrate,
-                    AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_OFF);
+                    AudioManager.VIBRATE_TYPE_RINGER, AudioManager.VIBRATE_SETTING_ONLY_SILENT);
             loadSetting(stmt, Settings.System.VIBRATE_ON, vibrate);
         } finally {
             if (stmt != null) stmt.close();
@@ -1509,4 +1520,20 @@
         loadSetting(stmt, key,
                 Float.toString(mContext.getResources().getFraction(resid, base, base)));
     }
+
+    private int getIntValueFromSystem(SQLiteDatabase db, String name, int defaultValue) {
+        int value = defaultValue;
+        Cursor c = null;
+        try {
+            c = db.query("system", new String[] { Settings.System.VALUE }, "name='" + name + "'",
+                    null, null, null, null);
+            if (c != null && c.moveToFirst()) {
+                String val = c.getString(0);
+                value = val == null ? defaultValue : Integer.parseInt(val);
+            }
+        } finally {
+            if (c != null) c.close();
+        }
+        return value;
+    }
 }
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index aa36b07..dff41c9 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -46,17 +46,26 @@
             </intent-filter>
         </receiver>
 
-        <!-- handle dock insertion, launch screensaver instead -->
+        <!-- should you need to launch the screensaver, this is a good way to do it -->
         <activity android:name=".DreamsDockLauncher"
                 android:theme="@android:style/Theme.Dialog"
                 android:label="@string/dreams_dock_launcher">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.DEFAULT" />
-                <category android:name="android.intent.category.DESK_DOCK" />
             </intent-filter>
         </activity>
 
+        <!-- launch screensaver on (desk) dock event -->
+        <receiver android:name=".DreamsDockLauncher$DockEventReceiver" 
+            android:exported="true"
+            >
+            <intent-filter>
+                <action android:name="android.intent.action.DOCK_EVENT" />
+            </intent-filter>
+        </receiver>
+
+
         <activity android:name=".usb.UsbStorageActivity"
                 android:excludeFromRecents="true">
         </activity>
diff --git a/packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java b/packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java
index def785b..0035296 100644
--- a/packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java
+++ b/packages/SystemUI/src/com/android/systemui/DreamsDockLauncher.java
@@ -12,14 +12,22 @@
 
 public class DreamsDockLauncher extends Activity {
     private static final String TAG = "DreamsDockLauncher";
+
+    // Launch the screen saver if started as an activity.
     @Override
     protected void onCreate (Bundle icicle) {
         super.onCreate(icicle);
+        launchDream(this);
+        finish();
+    }
+
+    private static void launchDream(Context context) {
         try {
             String component = Settings.Secure.getString(
-                    getContentResolver(), Settings.Secure.DREAM_COMPONENT);
+                    context.getContentResolver(), Settings.Secure.DREAM_COMPONENT);
             if (component == null) {
-                component = getResources().getString(com.android.internal.R.string.config_defaultDreamComponent);
+                component = context.getResources().getString(
+                    com.android.internal.R.string.config_defaultDreamComponent);
             }
             if (component != null) {
                 ComponentName cn = ComponentName.unflattenFromString(component);
@@ -29,7 +37,8 @@
                         | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
                         | Intent.FLAG_ACTIVITY_NO_USER_ACTION
                         );
-                startActivity(zzz);
+                Slog.v(TAG, "Starting screen saver on dock event: " + component);
+                context.startActivity(zzz);
             } else {
                 Slog.e(TAG, "Couldn't start screen saver: none selected");
             }
@@ -37,6 +46,22 @@
             // no screensaver? give up
             Slog.e(TAG, "Couldn't start screen saver: none installed");
         }
-        finish();
+    }
+
+    // Trap low-level dock events and launch the screensaver.
+    public static class DockEventReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (Intent.ACTION_DOCK_EVENT.equals(intent.getAction())) {
+                Bundle extras = intent.getExtras();
+                int state = extras
+                        .getInt(Intent.EXTRA_DOCK_STATE, Intent.EXTRA_DOCK_STATE_UNDOCKED);
+                if (state == Intent.EXTRA_DOCK_STATE_DESK
+                        || state == Intent.EXTRA_DOCK_STATE_LE_DESK
+                        || state == Intent.EXTRA_DOCK_STATE_HE_DESK) {
+                    launchDream(context);
+                }
+            }
+        }
     }
 }
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
index 84540a15..b4b82aa 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
@@ -110,10 +110,14 @@
      * the intent and provide a {@link SimCard.State} result.
      */
     private static class SimArgs {
-
         public final IccCard.State simState;
 
-        private SimArgs(Intent intent) {
+        SimArgs(IccCard.State state) {
+            simState = state;
+        }
+
+        static SimArgs fromIntent(Intent intent) {
+            IccCard.State state;
             if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
                 throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
             }
@@ -124,27 +128,28 @@
 
                 if (IccCard.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
                         absentReason)) {
-                    this.simState = IccCard.State.PERM_DISABLED;
+                    state = IccCard.State.PERM_DISABLED;
                 } else {
-                    this.simState = IccCard.State.ABSENT;
+                    state = IccCard.State.ABSENT;
                 }
             } else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
-                this.simState = IccCard.State.READY;
+                state = IccCard.State.READY;
             } else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
                 final String lockedReason = intent
                         .getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON);
                 if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
-                    this.simState = IccCard.State.PIN_REQUIRED;
+                    state = IccCard.State.PIN_REQUIRED;
                 } else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
-                    this.simState = IccCard.State.PUK_REQUIRED;
+                    state = IccCard.State.PUK_REQUIRED;
                 } else {
-                    this.simState = IccCard.State.UNKNOWN;
+                    state = IccCard.State.UNKNOWN;
                 }
             } else if (IccCard.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
-                this.simState = IccCard.State.NETWORK_LOCKED;
+                state = IccCard.State.NETWORK_LOCKED;
             } else {
-                this.simState = IccCard.State.UNKNOWN;
+                state = IccCard.State.UNKNOWN;
             }
+            return new SimArgs(state);
         }
 
         public String toString() {
@@ -279,8 +284,7 @@
                     mHandler.sendMessage(msg);
                 } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
                     mHandler.sendMessage(mHandler.obtainMessage(
-                            MSG_SIM_STATE_CHANGE,
-                            new SimArgs(intent)));
+                            MSG_SIM_STATE_CHANGE, SimArgs.fromIntent(intent)));
                 } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
                     mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
                             intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
@@ -571,12 +575,16 @@
     }
 
     /**
-     * Report that the user succesfully entered the sim pin or puk so we
+     * Report that the user successfully entered the SIM PIN or PUK/SIM PIN so we
      * have the information earlier than waiting for the intent
      * broadcast from the telephony code.
+     *
+     * NOTE: Because handleSimStateChange() invokes callbacks immediately without going
+     * through mHandler, this *must* be called from the UI thread.
      */
     public void reportSimUnlocked() {
         mSimState = IccCard.State.READY;
+        handleSimStateChange(new SimArgs(mSimState));
     }
 
     public boolean isKeyguardBypassEnabled() {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index f0d19d1..e00a54c 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -157,6 +157,11 @@
     static final boolean SHOW_STARTING_ANIMATIONS = true;
     static final boolean SHOW_PROCESSES_ON_ALT_MENU = false;
 
+    // Whether to allow dock apps with METADATA_DOCK_HOME to temporarily take over the Home key.
+    // No longer recommended for desk docks; still useful in car docks.
+    static final boolean ENABLE_CAR_DOCK_HOME_CAPTURE = true;
+    static final boolean ENABLE_DESK_DOCK_HOME_CAPTURE = false;
+
     static final int LONG_PRESS_POWER_NOTHING = 0;
     static final int LONG_PRESS_POWER_GLOBAL_ACTIONS = 1;
     static final int LONG_PRESS_POWER_SHUT_OFF = 2;
@@ -3511,21 +3516,35 @@
     }
 
     /**
-     * Return an Intent to launch the currently active dock as home.  Returns
-     * null if the standard home should be launched.
+     * Return an Intent to launch the currently active dock app as home.  Returns
+     * null if the standard home should be launched, which is the case if any of the following is
+     * true:
+     * <ul>
+     *  <li>The device is not in either car mode or desk mode
+     *  <li>The device is in car mode but ENABLE_CAR_DOCK_HOME_CAPTURE is false
+     *  <li>The device is in desk mode but ENABLE_DESK_DOCK_HOME_CAPTURE is false
+     *  <li>The device is in car mode but there's no CAR_DOCK app with METADATA_DOCK_HOME
+     *  <li>The device is in desk mode but there's no DESK_DOCK app with METADATA_DOCK_HOME
+     * </ul>
      * @return
      */
     Intent createHomeDockIntent() {
-        Intent intent;
+        Intent intent = null;
         
         // What home does is based on the mode, not the dock state.  That
         // is, when in car mode you should be taken to car home regardless
         // of whether we are actually in a car dock.
         if (mUiMode == Configuration.UI_MODE_TYPE_CAR) {
-            intent = mCarDockIntent;
+            if (ENABLE_CAR_DOCK_HOME_CAPTURE) {
+                intent = mCarDockIntent;
+            }
         } else if (mUiMode == Configuration.UI_MODE_TYPE_DESK) {
-            intent = mDeskDockIntent;
-        } else {
+            if (ENABLE_DESK_DOCK_HOME_CAPTURE) {
+                intent = mDeskDockIntent;
+            }
+        }
+
+        if (intent == null) {
             return null;
         }
         
diff --git a/policy/src/com/android/internal/policy/impl/SimPukUnlockScreen.java b/policy/src/com/android/internal/policy/impl/SimPukUnlockScreen.java
index 47a7157..0d1f436 100644
--- a/policy/src/com/android/internal/policy/impl/SimPukUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/SimPukUnlockScreen.java
@@ -242,20 +242,24 @@
 
         new CheckSimPuk(mPukText.getText().toString(),
                 mPinText.getText().toString()) {
-            void onSimLockChangedResponse(boolean success) {
-                if (mSimUnlockProgressDialog != null) {
-                    mSimUnlockProgressDialog.hide();
-                }
-                if (success) {
-                    // before closing the keyguard, report back that
-                    // the sim is unlocked so it knows right away
-                    mUpdateMonitor.reportSimUnlocked();
-                    mCallback.goToUnlockScreen();
-                } else {
-                    mHeaderText.setText(R.string.badPuk);
-                    mPukText.setText("");
-                    mPinText.setText("");
-                }
+            void onSimLockChangedResponse(final boolean success) {
+                mPinText.post(new Runnable() {
+                    public void run() {
+                        if (mSimUnlockProgressDialog != null) {
+                            mSimUnlockProgressDialog.hide();
+                        }
+                        if (success) {
+                            // before closing the keyguard, report back that
+                            // the sim is unlocked so it knows right away
+                            mUpdateMonitor.reportSimUnlocked();
+                            mCallback.goToUnlockScreen();
+                        } else {
+                            mHeaderText.setText(R.string.badPuk);
+                            mPukText.setText("");
+                            mPinText.setText("");
+                        }
+                    }
+                });
             }
         }.start();
     }
diff --git a/policy/src/com/android/internal/policy/impl/SimUnlockScreen.java b/policy/src/com/android/internal/policy/impl/SimUnlockScreen.java
index 99e1ce1..f80637a 100644
--- a/policy/src/com/android/internal/policy/impl/SimUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/SimUnlockScreen.java
@@ -214,21 +214,25 @@
         getSimUnlockProgressDialog().show();
 
         new CheckSimPin(mPinText.getText().toString()) {
-            void onSimLockChangedResponse(boolean success) {
-                if (mSimUnlockProgressDialog != null) {
-                    mSimUnlockProgressDialog.hide();
-                }
-                if (success) {
-                    // before closing the keyguard, report back that
-                    // the sim is unlocked so it knows right away
-                    mUpdateMonitor.reportSimUnlocked();
-                    mCallback.goToUnlockScreen();
-                } else {
-                    mHeaderText.setText(R.string.keyguard_password_wrong_pin_code);
-                    mPinText.setText("");
-                    mEnteredDigits = 0;
-                }
-                mCallback.pokeWakelock();
+            void onSimLockChangedResponse(final boolean success) {
+                mPinText.post(new Runnable() {
+                    public void run() {
+                        if (mSimUnlockProgressDialog != null) {
+                            mSimUnlockProgressDialog.hide();
+                        }
+                        if (success) {
+                            // before closing the keyguard, report back that
+                            // the sim is unlocked so it knows right away
+                            mUpdateMonitor.reportSimUnlocked();
+                            mCallback.goToUnlockScreen();
+                        } else {
+                            mHeaderText.setText(R.string.keyguard_password_wrong_pin_code);
+                            mPinText.setText("");
+                            mEnteredDigits = 0;
+                        }
+                        mCallback.pokeWakelock();
+                    }
+                });
             }
         }.start();
     }
diff --git a/services/java/com/android/server/EventLogTags.logtags b/services/java/com/android/server/EventLogTags.logtags
index a7eff93..5408436 100644
--- a/services/java/com/android/server/EventLogTags.logtags
+++ b/services/java/com/android/server/EventLogTags.logtags
@@ -142,5 +142,5 @@
 # ---------------------------
 # NetworkStatsService.java
 # ---------------------------
-51100 netstats_mobile_sample (dev_rx_bytes|2|2),(dev_tx_bytes|2|2),(dev_rx_pkts|2|1),(dev_tx_pkts|2|1),(xt_rx_bytes|2|2),(xt_tx_bytes|2|2),(xt_rx_pkts|2|1),(xt_tx_pkts|2|1),(uid_rx_bytes|2|2),(uid_tx_bytes|2|2),(uid_rx_pkts|2|1),(uid_tx_pkts|2|1),(trusted_time|2|3)
-51101 netstats_wifi_sample (dev_rx_bytes|2|2),(dev_tx_bytes|2|2),(dev_rx_pkts|2|1),(dev_tx_pkts|2|1),(xt_rx_bytes|2|2),(xt_tx_bytes|2|2),(xt_rx_pkts|2|1),(xt_tx_pkts|2|1),(uid_rx_bytes|2|2),(uid_tx_bytes|2|2),(uid_rx_pkts|2|1),(uid_tx_pkts|2|1),(trusted_time|2|3)
+51100 netstats_mobile_sample (dev_rx_bytes|2|2),(dev_tx_bytes|2|2),(dev_rx_pkts|2|1),(dev_tx_pkts|2|1),(xt_rx_bytes|2|2),(xt_tx_bytes|2|2),(xt_rx_pkts|2|1),(xt_tx_pkts|2|1),(uid_rx_bytes|2|2),(uid_tx_bytes|2|2),(uid_rx_pkts|2|1),(uid_tx_pkts|2|1),(trusted_time|2|3),(dev_history_start|2|3)
+51101 netstats_wifi_sample (dev_rx_bytes|2|2),(dev_tx_bytes|2|2),(dev_rx_pkts|2|1),(dev_tx_pkts|2|1),(xt_rx_bytes|2|2),(xt_tx_bytes|2|2),(xt_rx_pkts|2|1),(xt_tx_pkts|2|1),(uid_rx_bytes|2|2),(uid_tx_bytes|2|2),(uid_rx_pkts|2|1),(uid_tx_pkts|2|1),(trusted_time|2|3),(dev_history_start|2|3)
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index ddac35c..f5c4ed4 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -382,6 +382,7 @@
         public void onReceive(Context context, Intent intent) {
             if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
                 mScreenOn = true;
+                refreshImeWindowVisibilityLocked();
             } else if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
                 mScreenOn = false;
                 setImeWindowVisibilityStatusHiddenLocked();
@@ -640,6 +641,21 @@
         updateImeWindowStatusLocked();
     }
 
+    private void refreshImeWindowVisibilityLocked() {
+        final Configuration conf = mRes.getConfiguration();
+        final boolean haveHardKeyboard = conf.keyboard
+                != Configuration.KEYBOARD_NOKEYS;
+        final boolean hardKeyShown = haveHardKeyboard
+                && conf.hardKeyboardHidden
+                        != Configuration.HARDKEYBOARDHIDDEN_YES;
+        final boolean isScreenLocked = mKeyguardManager != null
+                && mKeyguardManager.isKeyguardLocked()
+                && mKeyguardManager.isKeyguardSecure();
+        mImeWindowVis = (!isScreenLocked && (mInputShown || hardKeyShown)) ?
+                (InputMethodService.IME_ACTIVE | InputMethodService.IME_VISIBLE) : 0;
+        updateImeWindowStatusLocked();
+    }
+
     private void updateImeWindowStatusLocked() {
         setImeWindowStatus(mCurToken, mImeWindowVis, mBackDisposition);
     }
@@ -1285,16 +1301,7 @@
                     }
                     if (mCurMethod != null) {
                         try {
-                            final Configuration conf = mRes.getConfiguration();
-                            final boolean haveHardKeyboard = conf.keyboard
-                                    != Configuration.KEYBOARD_NOKEYS;
-                            final boolean hardKeyShown = haveHardKeyboard
-                                    && conf.hardKeyboardHidden
-                                            != Configuration.HARDKEYBOARDHIDDEN_YES;
-                            mImeWindowVis = (mInputShown || hardKeyShown) ? (
-                                    InputMethodService.IME_ACTIVE | InputMethodService.IME_VISIBLE)
-                                    : 0;
-                            updateImeWindowStatusLocked();
+                            refreshImeWindowVisibilityLocked();
                             // If subtype is null, try to find the most applicable one from
                             // getCurrentInputMethodSubtype.
                             if (subtype == null) {
diff --git a/services/java/com/android/server/UiModeManagerService.java b/services/java/com/android/server/UiModeManagerService.java
index 280b329..e6392d7 100644
--- a/services/java/com/android/server/UiModeManagerService.java
+++ b/services/java/com/android/server/UiModeManagerService.java
@@ -63,6 +63,10 @@
 
     private static final String KEY_LAST_UPDATE_INTERVAL = "LAST_UPDATE_INTERVAL";
 
+    // Enable launching of applications when entering the dock.
+    private static final boolean ENABLE_LAUNCH_CAR_DOCK_APP = true;
+    private static final boolean ENABLE_LAUNCH_DESK_DOCK_APP = false;
+
     private static final int MSG_UPDATE_TWILIGHT = 0;
     private static final int MSG_ENABLE_LOCATION_UPDATES = 1;
     private static final int MSG_GET_NEW_LOCATION_UPDATE = 2;
@@ -139,14 +143,16 @@
                 if (UiModeManager.ACTION_ENTER_CAR_MODE.equals(intent.getAction())) {
                     // Only launch car home when car mode is enabled and the caller
                     // has asked us to switch to it.
-                    if ((enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
+                    if (ENABLE_LAUNCH_CAR_DOCK_APP
+                            && (enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
                         category = Intent.CATEGORY_CAR_DOCK;
                     }
                 } else if (UiModeManager.ACTION_ENTER_DESK_MODE.equals(intent.getAction())) {
                     // Only launch car home when desk mode is enabled and the caller
                     // has asked us to switch to it.  Currently re-using the car
                     // mode flag since we don't have a formal API for "desk mode".
-                    if ((enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
+                    if (ENABLE_LAUNCH_DESK_DOCK_APP
+                            && (enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
                         category = Intent.CATEGORY_DESK_DOCK;
                     }
                 } else {
@@ -550,11 +556,13 @@
             } else {
                 Intent homeIntent = null;
                 if (mCarModeEnabled) {
-                    if ((enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
+                    if (ENABLE_LAUNCH_CAR_DOCK_APP
+                            && (enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
                         homeIntent = buildHomeIntent(Intent.CATEGORY_CAR_DOCK);
                     }
                 } else if (isDeskDockState(mDockState)) {
-                    if ((enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
+                    if (ENABLE_LAUNCH_DESK_DOCK_APP
+                            && (enableFlags&UiModeManager.ENABLE_CAR_MODE_GO_CAR_HOME) != 0) {
                         homeIntent = buildHomeIntent(Intent.CATEGORY_DESK_DOCK);
                     }
                 } else {
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index 2a1b1db..8c0f1e0 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -393,6 +393,7 @@
             // on background handler thread, and verified
             // READ_NETWORK_USAGE_HISTORY permission above.
 
+            maybeRefreshTrustedTime();
             synchronized (mRulesLock) {
                 updateNetworkEnabledLocked();
                 updateNotificationsLocked();
@@ -445,7 +446,7 @@
         // cycle boundary to recompute notifications.
 
         // examine stats for each active policy
-        final long currentTime = currentTimeMillis(true);
+        final long currentTime = currentTimeMillis();
         for (NetworkPolicy policy : mNetworkPolicy.values()) {
             // ignore policies that aren't relevant to user
             if (!isTemplateRelevant(policy.template)) continue;
@@ -683,6 +684,8 @@
         public void onReceive(Context context, Intent intent) {
             // on background handler thread, and verified CONNECTIVITY_INTERNAL
             // permission above.
+
+            maybeRefreshTrustedTime();
             synchronized (mRulesLock) {
                 ensureActiveMobilePolicyLocked();
                 updateNetworkEnabledLocked();
@@ -702,7 +705,7 @@
         // TODO: reset any policy-disabled networks when any policy is removed
         // completely, which is currently rare case.
 
-        final long currentTime = currentTimeMillis(true);
+        final long currentTime = currentTimeMillis();
         for (NetworkPolicy policy : mNetworkPolicy.values()) {
             // shortcut when policy has no limit
             if (policy.limitBytes == LIMIT_DISABLED) {
@@ -802,7 +805,7 @@
 
         // apply each policy that we found ifaces for; compute remaining data
         // based on current cycle and historical stats, and push to kernel.
-        final long currentTime = currentTimeMillis(true);
+        final long currentTime = currentTimeMillis();
         for (NetworkPolicy policy : mNetworkRules.keySet()) {
             final String[] ifaces = mNetworkRules.get(policy);
 
@@ -1092,6 +1095,7 @@
     public void setNetworkPolicies(NetworkPolicy[] policies) {
         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
 
+        maybeRefreshTrustedTime();
         synchronized (mRulesLock) {
             mNetworkPolicy.clear();
             for (NetworkPolicy policy : policies) {
@@ -1119,7 +1123,8 @@
     public void snoozePolicy(NetworkTemplate template) {
         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
 
-        final long currentTime = currentTimeMillis(true);
+        maybeRefreshTrustedTime();
+        final long currentTime = currentTimeMillis();
         synchronized (mRulesLock) {
             // find and snooze local policy that matches
             final NetworkPolicy policy = mNetworkPolicy.get(template);
@@ -1140,6 +1145,7 @@
     public void setRestrictBackground(boolean restrictBackground) {
         mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
 
+        maybeRefreshTrustedTime();
         synchronized (mRulesLock) {
             mRestrictBackground = restrictBackground;
             updateRulesForRestrictBackgroundLocked();
@@ -1193,7 +1199,7 @@
             return null;
         }
 
-        final long currentTime = currentTimeMillis(false);
+        final long currentTime = currentTimeMillis();
 
         // find total bytes used under policy
         final long start = computeLastCycleBoundary(currentTime, policy);
@@ -1472,6 +1478,7 @@
                 case MSG_LIMIT_REACHED: {
                     final String iface = (String) msg.obj;
 
+                    maybeRefreshTrustedTime();
                     synchronized (mRulesLock) {
                         if (mMeteredIfaces.contains(iface)) {
                             try {
@@ -1551,12 +1558,16 @@
         }
     }
 
-    private long currentTimeMillis(boolean allowRefresh) {
-        // try refreshing time source when stale
-        if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE && allowRefresh) {
+    /**
+     * Try refreshing {@link #mTime} when stale.
+     */
+    private void maybeRefreshTrustedTime() {
+        if (mTime.getCacheAge() > TIME_CACHE_MAX_AGE) {
             mTime.forceRefresh();
         }
+    }
 
+    private long currentTimeMillis() {
         return mTime.hasCache() ? mTime.currentTimeMillis() : System.currentTimeMillis();
     }
 
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index 28cb983..871ed68 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -203,6 +203,8 @@
     /** Set of historical {@code xtables} stats for known UIDs. */
     private HashMap<UidStatsKey, NetworkStatsHistory> mUidStats = Maps.newHashMap();
 
+    /** Flag if {@link #mNetworkDevStats} have been loaded from disk. */
+    private boolean mNetworkStatsLoaded = false;
     /** Flag if {@link #mUidStats} have been loaded from disk. */
     private boolean mUidStatsLoaded = false;
 
@@ -272,6 +274,7 @@
             // until actually needed.
             readNetworkDevStatsLocked();
             readNetworkXtStatsLocked();
+            mNetworkStatsLoaded = true;
         }
 
         // bootstrap initial stats to prevent double-counting later
@@ -322,14 +325,17 @@
 
         mTeleManager.listen(mPhoneListener, LISTEN_NONE);
 
-        writeNetworkDevStatsLocked();
-        writeNetworkXtStatsLocked();
+        if (mNetworkStatsLoaded) {
+            writeNetworkDevStatsLocked();
+            writeNetworkXtStatsLocked();
+        }
         if (mUidStatsLoaded) {
             writeUidStatsLocked();
         }
         mNetworkDevStats.clear();
         mNetworkXtStats.clear();
         mUidStats.clear();
+        mNetworkStatsLoaded = false;
         mUidStatsLoaded = false;
     }
 
@@ -472,6 +478,18 @@
         }
     }
 
+    private long getHistoryStartLocked(
+            NetworkTemplate template, HashMap<NetworkIdentitySet, NetworkStatsHistory> source) {
+        long start = Long.MAX_VALUE;
+        for (NetworkIdentitySet ident : source.keySet()) {
+            if (templateMatches(template, ident)) {
+                final NetworkStatsHistory history = source.get(ident);
+                start = Math.min(start, history.getStart());
+            }
+        }
+        return start;
+    }
+
     @Override
     public NetworkStats getSummaryForAllUid(
             NetworkTemplate template, long start, long end, boolean includeTags) {
@@ -771,6 +789,12 @@
     private void performPoll(int flags) {
         synchronized (mStatsLock) {
             mWakeLock.acquire();
+
+            // try refreshing time source when stale
+            if (mTime.getCacheAge() > mSettings.getTimeCacheMaxAge()) {
+                mTime.forceRefresh();
+            }
+
             try {
                 performPollLocked(flags);
             } finally {
@@ -791,11 +815,6 @@
         final boolean persistUid = (flags & FLAG_PERSIST_UID) != 0;
         final boolean persistForce = (flags & FLAG_PERSIST_FORCE) != 0;
 
-        // try refreshing time source when stale
-        if (mTime.getCacheAge() > mSettings.getTimeCacheMaxAge()) {
-            mTime.forceRefresh();
-        }
-
         // TODO: consider marking "untrusted" times in historical stats
         final long currentTime = mTime.hasCache() ? mTime.currentTimeMillis()
                 : System.currentTimeMillis();
@@ -981,6 +1000,7 @@
         final long start = end - largestBucketSize;
 
         final long trustedTime = mTime.hasCache() ? mTime.currentTimeMillis() : -1;
+        long devHistoryStart = Long.MAX_VALUE;
 
         NetworkTemplate template = null;
         NetworkStats.Entry devTotal = null;
@@ -990,24 +1010,27 @@
         // collect mobile sample
         template = buildTemplateMobileAll(getActiveSubscriberId(mContext));
         devTotal = getSummaryForNetworkDev(template, start, end).getTotal(devTotal);
+        devHistoryStart = getHistoryStartLocked(template, mNetworkDevStats);
         xtTotal = getSummaryForNetworkXt(template, start, end).getTotal(xtTotal);
         uidTotal = getSummaryForAllUid(template, start, end, false).getTotal(uidTotal);
+
         EventLogTags.writeNetstatsMobileSample(
                 devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
                 xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
                 uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
-                trustedTime);
+                trustedTime, devHistoryStart);
 
         // collect wifi sample
         template = buildTemplateWifi();
         devTotal = getSummaryForNetworkDev(template, start, end).getTotal(devTotal);
+        devHistoryStart = getHistoryStartLocked(template, mNetworkDevStats);
         xtTotal = getSummaryForNetworkXt(template, start, end).getTotal(xtTotal);
         uidTotal = getSummaryForAllUid(template, start, end, false).getTotal(uidTotal);
         EventLogTags.writeNetstatsWifiSample(
                 devTotal.rxBytes, devTotal.rxPackets, devTotal.txBytes, devTotal.txPackets,
                 xtTotal.rxBytes, xtTotal.rxPackets, xtTotal.txBytes, xtTotal.txPackets,
                 uidTotal.rxBytes, uidTotal.rxPackets, uidTotal.txBytes, uidTotal.txPackets,
-                trustedTime);
+                trustedTime, devHistoryStart);
     }
 
     /**
@@ -1243,11 +1266,28 @@
 
         // trim any history beyond max
         if (mTime.hasCache()) {
-            final long currentTime = Math.min(
-                    System.currentTimeMillis(), mTime.currentTimeMillis());
+            final long systemCurrentTime = System.currentTimeMillis();
+            final long trustedCurrentTime = mTime.currentTimeMillis();
+
+            final long currentTime = Math.min(systemCurrentTime, trustedCurrentTime);
             final long maxHistory = mSettings.getNetworkMaxHistory();
+
             for (NetworkStatsHistory history : input.values()) {
+                final int beforeSize = history.size();
                 history.removeBucketsBefore(currentTime - maxHistory);
+                final int afterSize = history.size();
+
+                if (beforeSize > 24 && afterSize < beforeSize / 2) {
+                    // yikes, dropping more than half of significant history
+                    final StringBuilder builder = new StringBuilder();
+                    builder.append("yikes, dropping more than half of history").append('\n');
+                    builder.append("systemCurrentTime=").append(systemCurrentTime).append('\n');
+                    builder.append("trustedCurrentTime=").append(trustedCurrentTime).append('\n');
+                    builder.append("maxHistory=").append(maxHistory).append('\n');
+                    builder.append("beforeSize=").append(beforeSize).append('\n');
+                    builder.append("afterSize=").append(afterSize).append('\n');
+                    mDropBox.addText(TAG_NETSTATS_ERROR, builder.toString());
+                }
             }
         }
 
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index 0618374..7c61e9a 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -693,12 +693,13 @@
             expectSetInterfaceQuota(TEST_IFACE, Long.MAX_VALUE);
             expectMeteredIfacesChanged(TEST_IFACE);
 
-            expectClearNotifications();
+            future = expectClearNotifications();
             tagFuture = expectEnqueueNotification();
 
             replay();
             mService.snoozePolicy(sTemplateWifi);
             assertNotificationType(TYPE_LIMIT_SNOOZED, tagFuture.get());
+            future.get();
             verifyAndReset();
         }
     }
@@ -734,9 +735,11 @@
         expectLastCall().atLeastOnce();
     }
 
-    private void expectClearNotifications() throws Exception {
+    private Future<Void> expectClearNotifications() throws Exception {
+        final FutureAnswer future = new FutureAnswer();
         mNotifManager.cancelNotificationWithTag(isA(String.class), isA(String.class), anyInt());
-        expectLastCall().anyTimes();
+        expectLastCall().andAnswer(future).anyTimes();
+        return future;
     }
 
     private Future<String> expectEnqueueNotification() throws Exception {
diff --git a/telephony/java/android/telephony/PhoneNumberUtils.java b/telephony/java/android/telephony/PhoneNumberUtils.java
index f2ccb5b..07afe30 100644
--- a/telephony/java/android/telephony/PhoneNumberUtils.java
+++ b/telephony/java/android/telephony/PhoneNumberUtils.java
@@ -1575,6 +1575,17 @@
         // If the number passed in is null, just return false:
         if (number == null) return false;
 
+        // If the number passed in is a SIP address, return false, since the
+        // concept of "emergency numbers" is only meaningful for calls placed
+        // over the cell network.
+        // (Be sure to do this check *before* calling extractNetworkPortionAlt(),
+        // since the whole point of extractNetworkPortionAlt() is to filter out
+        // any non-dialable characters (which would turn 'abc911def@example.com'
+        // into '911', for example.))
+        if (isUriNumber(number)) {
+            return false;
+        }
+
         // Strip the separators from the number before comparing it
         // to the list.
         number = extractNetworkPortionAlt(number);
@@ -2107,6 +2118,31 @@
     }
 
     /**
+     * @return the "username" part of the specified SIP address,
+     *         i.e. the part before the "@" character (or "%40").
+     *
+     * @param number SIP address of the form "username@domainname"
+     *               (or the URI-escaped equivalent "username%40domainname")
+     * @see isUriNumber
+     *
+     * @hide
+     */
+    public static String getUsernameFromUriNumber(String number) {
+        // The delimiter between username and domain name can be
+        // either "@" or "%40" (the URI-escaped equivalent.)
+        int delimiterIndex = number.indexOf('@');
+        if (delimiterIndex < 0) {
+            delimiterIndex = number.indexOf("%40");
+        }
+        if (delimiterIndex < 0) {
+            Log.w(LOG_TAG,
+                  "getUsernameFromUriNumber: no delimiter found in SIP addr '" + number + "'");
+            delimiterIndex = number.length();
+        }
+        return number.substring(0, delimiterIndex);
+    }
+
+    /**
      * This function handles the plus code conversion within NANP CDMA network
      * If the number format is
      * 1)+1NANP,remove +,
diff --git a/telephony/java/com/android/internal/telephony/CallerInfo.java b/telephony/java/com/android/internal/telephony/CallerInfo.java
index 6324550..5d1f758 100644
--- a/telephony/java/com/android/internal/telephony/CallerInfo.java
+++ b/telephony/java/com/android/internal/telephony/CallerInfo.java
@@ -288,7 +288,7 @@
             String number, CallerInfo previousResult) {
         if (!previousResult.contactExists
                 && PhoneNumberUtils.isUriNumber(number)) {
-            String username = number.substring(0, number.indexOf('@'));
+            String username = PhoneNumberUtils.getUsernameFromUriNumber(number);
             if (PhoneNumberUtils.isGlobalPhoneNumber(username)) {
                 previousResult = getCallerInfo(context,
                         Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,
diff --git a/tests/FrameworkPerf/src/com/android/frameworkperf/TestService.java b/tests/FrameworkPerf/src/com/android/frameworkperf/TestService.java
index 3d939bd..8cf1ac2 100644
--- a/tests/FrameworkPerf/src/com/android/frameworkperf/TestService.java
+++ b/tests/FrameworkPerf/src/com/android/frameworkperf/TestService.java
@@ -33,6 +33,7 @@
 import android.content.res.XmlResourceParser;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
+import android.graphics.Paint;
 import android.os.Bundle;
 import android.os.FileUtils;
 import android.os.Handler;
@@ -64,6 +65,9 @@
             new MethodCallOp(), new ReadFileOp(),
             new SchedulerOp(), new SchedulerOp(),
             new GcOp(), new NoOp(),
+            new ObjectGcOp(), new NoOp(),
+            new FinalizingGcOp(), new NoOp(),
+            new PaintGcOp(), new NoOp(),
             new IpcOp(), new NoOp(),
             new IpcOp(), new CpuOp(),
             new IpcOp(), new SchedulerOp(),
@@ -111,6 +115,10 @@
             new CpuOp(),
             new SchedulerOp(),
             new MethodCallOp(),
+            new GcOp(),
+            new ObjectGcOp(),
+            new FinalizingGcOp(),
+            new PaintGcOp(),
             new IpcOp(),
             new CreateFileOp(),
             new CreateWriteFileOp(),
@@ -467,6 +475,47 @@
         }
     }
 
+    static class ObjectGcOp extends Op {
+        ObjectGcOp() {
+            super("ObjectGc", "Run garbage collector with simple objects");
+        }
+
+        boolean onRun() {
+            Object obj = new Object();
+            return true;
+        }
+    }
+
+    static class FinalizingGcOp extends Op {
+        class Finalizable {
+            Finalizable() {}
+            @Override
+            protected void finalize() throws Throwable {
+                super.finalize();
+            }
+        }
+
+        FinalizingGcOp() {
+            super("FinalizingGc", "Run garbage collector with finalizable objects");
+        }
+
+        boolean onRun() {
+            Finalizable obj = new Finalizable();
+            return true;
+        }
+    }
+
+    static class PaintGcOp extends Op {
+        PaintGcOp() {
+            super("PaintGc", "Run garbage collector with Paint objects");
+        }
+
+        boolean onRun() {
+            Paint p = new Paint();
+            return true;
+        }
+    }
+
     static class MethodCallOp extends Op {
         MethodCallOp() {
             super("MethodCall", "Method call");