auto import from //branches/cupcake/...@137873
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index d447eb2..15e0a4d 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -31,6 +31,7 @@
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.Handler;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
@@ -125,7 +126,14 @@
 
     // support for AutoCompleteTextView suggestions display
     private SuggestionsAdapter mSuggestionsAdapter;
-
+    private Handler mHandler = new Handler();
+    private Runnable mInstallSuggestionAdapter = new Runnable() {
+        public void run() {
+            if (mSearchTextField != null) {
+                mSearchTextField.setAdapter(mSuggestionsAdapter);
+            }
+        }
+    };
 
     /**
      * Constructor - fires it up and makes it look like the search UI.
@@ -253,7 +261,8 @@
             mSearchTextField.setAdapter(mSuggestionsAdapter);
             mSearchTextField.setText(initialQuery);
         } else {
-            mSuggestionsAdapter = new SuggestionsAdapter(getContext(), mSearchable);
+            mSuggestionsAdapter = new SuggestionsAdapter(getContext(), mSearchable,
+                    mHandler, mInstallSuggestionAdapter);
             mSearchTextField.setAdapter(mSuggestionsAdapter);
 
             // finally, load the user's initial text (which may trigger suggestions)
@@ -1296,10 +1305,15 @@
         // These private variables are shared by the filter thread and must be protected
         private WeakReference<Cursor> mRecentCursor = new WeakReference<Cursor>(null);
         private boolean mNonUserQuery = false;
+        private Handler mHandler;
+        private Runnable mInstallSuggestionAdapter;
 
-        public SuggestionsAdapter(Context context, SearchableInfo searchable) {
+        public SuggestionsAdapter(Context context, SearchableInfo searchable,
+                Handler handler, Runnable installSuggestionAdapter) {
             super(context, -1, null, null, null);
             mSearchable = searchable;
+            mHandler = handler;
+            mInstallSuggestionAdapter = installSuggestionAdapter;
             
             // set up provider resources (gives us icons, etc.)
             Context activityContext = mSearchable.getActivityContext(mContext);
@@ -1414,7 +1428,11 @@
                 }
                 // Now actually set up the cursor, columns, and the list view
                 changeCursorAndColumns(c, from, to);
-                setViewResource(layout);              
+                setViewResource(layout);          
+                // Force the underlying ListView to discard and reload all layouts
+                // (Note, this could be optimized for cases where layout/cursor remain same)
+                mHandler.post(mInstallSuggestionAdapter);
+
             } else {
                 // Provide some help for developers instead of just silently discarding
                 Log.w(LOG_TAG, "Suggestions cursor discarded due to missing required columns.");
diff --git a/core/java/android/gadget/GadgetHost.java b/core/java/android/appwidget/AppWidgetHost.java
similarity index 62%
rename from core/java/android/gadget/GadgetHost.java
rename to core/java/android/appwidget/AppWidgetHost.java
index 3d88b58..10c2b02 100644
--- a/core/java/android/gadget/GadgetHost.java
+++ b/core/java/android/appwidget/AppWidgetHost.java
@@ -1,5 +1,4 @@
 /*
- * Copyright (C) 2006 The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -14,7 +13,7 @@
  * limitations under the License.
  */
 
-package android.gadget;
+package android.appwidget;
 
 import android.content.Context;
 import android.os.Handler;
@@ -29,35 +28,35 @@
 import java.util.HashMap;
 import java.util.List;
 
-import com.android.internal.gadget.IGadgetHost;
-import com.android.internal.gadget.IGadgetService;
+import com.android.internal.appwidget.IAppWidgetHost;
+import com.android.internal.appwidget.IAppWidgetService;
 
 /**
- * GadgetHost provides the interaction with the Gadget Service for apps,
- * like the home screen, that want to embed gadgets in their UI.
+ * AppWidgetHost provides the interaction with the AppWidget service for apps,
+ * like the home screen, that want to embed AppWidgets in their UI.
  */
-public class GadgetHost {
+public class AppWidgetHost {
 
     static final int HANDLE_UPDATE = 1;
     static final int HANDLE_PROVIDER_CHANGED = 2;
 
     static Object sServiceLock = new Object();
-    static IGadgetService sService;
+    static IAppWidgetService sService;
 
     Context mContext;
     String mPackageName;
 
-    class Callbacks extends IGadgetHost.Stub {
-        public void updateGadget(int gadgetId, RemoteViews views) {
+    class Callbacks extends IAppWidgetHost.Stub {
+        public void updateAppWidget(int appWidgetId, RemoteViews views) {
             Message msg = mHandler.obtainMessage(HANDLE_UPDATE);
-            msg.arg1 = gadgetId;
+            msg.arg1 = appWidgetId;
             msg.obj = views;
             msg.sendToTarget();
         }
 
-        public void providerChanged(int gadgetId, GadgetProviderInfo info) {
+        public void providerChanged(int appWidgetId, AppWidgetProviderInfo info) {
             Message msg = mHandler.obtainMessage(HANDLE_PROVIDER_CHANGED);
-            msg.arg1 = gadgetId;
+            msg.arg1 = appWidgetId;
             msg.obj = info;
             msg.sendToTarget();
         }
@@ -71,11 +70,11 @@
         public void handleMessage(Message msg) {
             switch (msg.what) {
                 case HANDLE_UPDATE: {
-                    updateGadgetView(msg.arg1, (RemoteViews)msg.obj);
+                    updateAppWidgetView(msg.arg1, (RemoteViews)msg.obj);
                     break;
                 }
                 case HANDLE_PROVIDER_CHANGED: {
-                    onProviderChanged(msg.arg1, (GadgetProviderInfo)msg.obj);
+                    onProviderChanged(msg.arg1, (AppWidgetProviderInfo)msg.obj);
                     break;
                 }
             }
@@ -86,22 +85,22 @@
 
     int mHostId;
     Callbacks mCallbacks = new Callbacks();
-    HashMap<Integer,GadgetHostView> mViews = new HashMap();
+    HashMap<Integer,AppWidgetHostView> mViews = new HashMap();
 
-    public GadgetHost(Context context, int hostId) {
+    public AppWidgetHost(Context context, int hostId) {
         mContext = context;
         mHostId = hostId;
         mHandler = new UpdateHandler(context.getMainLooper());
         synchronized (sServiceLock) {
             if (sService == null) {
-                IBinder b = ServiceManager.getService(Context.GADGET_SERVICE);
-                sService = IGadgetService.Stub.asInterface(b);
+                IBinder b = ServiceManager.getService(Context.APPWIDGET_SERVICE);
+                sService = IAppWidgetService.Stub.asInterface(b);
             }
         }
     }
 
     /**
-     * Start receiving onGadgetChanged calls for your gadgets.  Call this when your activity
+     * Start receiving onAppWidgetChanged calls for your AppWidgets.  Call this when your activity
      * becomes visible, i.e. from onStart() in your Activity.
      */
     public void startListening() {
@@ -120,12 +119,12 @@
 
         final int N = updatedIds.length;
         for (int i=0; i<N; i++) {
-            updateGadgetView(updatedIds[i], updatedViews.get(i));
+            updateAppWidgetView(updatedIds[i], updatedViews.get(i));
         }
     }
 
     /**
-     * Stop receiving onGadgetChanged calls for your gadgets.  Call this when your activity is
+     * Stop receiving onAppWidgetChanged calls for your AppWidgets.  Call this when your activity is
      * no longer visible, i.e. from onStop() in your Activity.
      */
     public void stopListening() {
@@ -138,16 +137,16 @@
     }
 
     /**
-     * Get a gadgetId for a host in the calling process.
+     * Get a appWidgetId for a host in the calling process.
      *
-     * @return a gadgetId
+     * @return a appWidgetId
      */
-    public int allocateGadgetId() {
+    public int allocateAppWidgetId() {
         try {
             if (mPackageName == null) {
                 mPackageName = mContext.getPackageName();
             }
-            return sService.allocateGadgetId(mPackageName, mHostId);
+            return sService.allocateAppWidgetId(mPackageName, mHostId);
         }
         catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
@@ -155,13 +154,13 @@
     }
 
     /**
-     * Stop listening to changes for this gadget.  
+     * Stop listening to changes for this AppWidget.  
      */
-    public void deleteGadgetId(int gadgetId) {
+    public void deleteAppWidgetId(int appWidgetId) {
         synchronized (mViews) {
-            mViews.remove(gadgetId);
+            mViews.remove(appWidgetId);
             try {
-                sService.deleteGadgetId(gadgetId);
+                sService.deleteAppWidgetId(appWidgetId);
             }
             catch (RemoteException e) {
                 throw new RuntimeException("system server dead?", e);
@@ -170,10 +169,10 @@
     }
 
     /**
-     * Remove all records about this host from the gadget manager.
+     * Remove all records about this host from the AppWidget manager.
      * <ul>
      *   <li>Call this when initializing your database, as it might be because of a data wipe.</li>
-     *   <li>Call this to have the gadget manager release all resources associated with your
+     *   <li>Call this to have the AppWidget manager release all resources associated with your
      *   host.  Any future calls about this host will cause the records to be re-allocated.</li>
      * </ul>
      */
@@ -190,7 +189,7 @@
      * Remove all records about all hosts for your package.
      * <ul>
      *   <li>Call this when initializing your database, as it might be because of a data wipe.</li>
-     *   <li>Call this to have the gadget manager release all resources associated with your
+     *   <li>Call this to have the AppWidget manager release all resources associated with your
      *   host.  Any future calls about this host will cause the records to be re-allocated.</li>
      * </ul>
      */
@@ -203,45 +202,45 @@
         }
     }
 
-    public final GadgetHostView createView(Context context, int gadgetId,
-            GadgetProviderInfo gadget) {
-        GadgetHostView view = onCreateView(context, gadgetId, gadget);
-        view.setGadget(gadgetId, gadget);
+    public final AppWidgetHostView createView(Context context, int appWidgetId,
+            AppWidgetProviderInfo appWidget) {
+        AppWidgetHostView view = onCreateView(context, appWidgetId, appWidget);
+        view.setAppWidget(appWidgetId, appWidget);
         synchronized (mViews) {
-            mViews.put(gadgetId, view);
+            mViews.put(appWidgetId, view);
         }
         RemoteViews views = null;
         try {
-            views = sService.getGadgetViews(gadgetId);
+            views = sService.getAppWidgetViews(appWidgetId);
         } catch (RemoteException e) {
             throw new RuntimeException("system server dead?", e);
         }
-        view.updateGadget(views);
+        view.updateAppWidget(views);
         return view;
     }
 
     /**
-     * Called to create the GadgetHostView.  Override to return a custom subclass if you
+     * Called to create the AppWidgetHostView.  Override to return a custom subclass if you
      * need it.  {@more}
      */
-    protected GadgetHostView onCreateView(Context context, int gadgetId,
-            GadgetProviderInfo gadget) {
-        return new GadgetHostView(context);
+    protected AppWidgetHostView onCreateView(Context context, int appWidgetId,
+            AppWidgetProviderInfo appWidget) {
+        return new AppWidgetHostView(context);
     }
     
     /**
-     * Called when the gadget provider for a gadget has been upgraded to a new apk.
+     * Called when the AppWidget provider for a AppWidget has been upgraded to a new apk.
      */
-    protected void onProviderChanged(int gadgetId, GadgetProviderInfo gadget) {
+    protected void onProviderChanged(int appWidgetId, AppWidgetProviderInfo appWidget) {
     }
 
-    void updateGadgetView(int gadgetId, RemoteViews views) {
-        GadgetHostView v;
+    void updateAppWidgetView(int appWidgetId, RemoteViews views) {
+        AppWidgetHostView v;
         synchronized (mViews) {
-            v = mViews.get(gadgetId);
+            v = mViews.get(appWidgetId);
         }
         if (v != null) {
-            v.updateGadget(views);
+            v.updateAppWidget(views);
         }
     }
 }
diff --git a/core/java/android/gadget/GadgetHostView.java b/core/java/android/appwidget/AppWidgetHostView.java
similarity index 88%
rename from core/java/android/gadget/GadgetHostView.java
rename to core/java/android/appwidget/AppWidgetHostView.java
index 5cbd988..be0f96e 100644
--- a/core/java/android/gadget/GadgetHostView.java
+++ b/core/java/android/appwidget/AppWidgetHostView.java
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.gadget;
+package android.appwidget;
 
 import android.content.Context;
 import android.content.pm.PackageManager;
@@ -37,12 +37,12 @@
 import android.widget.TextView;
 
 /**
- * Provides the glue to show gadget views. This class offers automatic animation
+ * Provides the glue to show AppWidget views. This class offers automatic animation
  * between updates, and will try recycling old views for each incoming
  * {@link RemoteViews}.
  */
-public class GadgetHostView extends FrameLayout {
-    static final String TAG = "GadgetHostView";
+public class AppWidgetHostView extends FrameLayout {
+    static final String TAG = "AppWidgetHostView";
     static final boolean LOGD = false;
     static final boolean CROSSFADE = false;
 
@@ -53,7 +53,7 @@
 
     static final int FADE_DURATION = 1000;
 
-    // When we're inflating the initialLayout for a gadget, we only allow
+    // When we're inflating the initialLayout for a AppWidget, we only allow
     // views that are allowed in RemoteViews.
     static final LayoutInflater.Filter sInflaterFilter = new LayoutInflater.Filter() {
         public boolean onLoadClass(Class clazz) {
@@ -63,8 +63,8 @@
 
     Context mContext;
     
-    int mGadgetId;
-    GadgetProviderInfo mInfo;
+    int mAppWidgetId;
+    AppWidgetProviderInfo mInfo;
     View mView;
     int mViewMode = VIEW_MODE_NOINIT;
     int mLayoutId = -1;
@@ -75,44 +75,44 @@
     /**
      * Create a host view.  Uses default fade animations.
      */
-    public GadgetHostView(Context context) {
+    public AppWidgetHostView(Context context) {
         this(context, android.R.anim.fade_in, android.R.anim.fade_out);
     }
 
     /**
      * Create a host view. Uses specified animations when pushing
-     * {@link #updateGadget(RemoteViews)}.
+     * {@link #updateAppWidget(RemoteViews)}.
      * 
      * @param animationIn Resource ID of in animation to use
      * @param animationOut Resource ID of out animation to use
      */
-    public GadgetHostView(Context context, int animationIn, int animationOut) {
+    public AppWidgetHostView(Context context, int animationIn, int animationOut) {
         super(context);
         mContext = context;
     }
     
     /**
-     * Set the gadget that will be displayed by this view.
+     * Set the AppWidget that will be displayed by this view.
      */
-    public void setGadget(int gadgetId, GadgetProviderInfo info) {
-        mGadgetId = gadgetId;
+    public void setAppWidget(int appWidgetId, AppWidgetProviderInfo info) {
+        mAppWidgetId = appWidgetId;
         mInfo = info;
     }
     
-    public int getGadgetId() {
-        return mGadgetId;
+    public int getAppWidgetId() {
+        return mAppWidgetId;
     }
     
-    public GadgetProviderInfo getGadgetInfo() {
+    public AppWidgetProviderInfo getAppWidgetInfo() {
         return mInfo;
     }
 
     /**
      * Process a set of {@link RemoteViews} coming in as an update from the
-     * gadget provider. Will animate into these new views as needed.
+     * AppWidget provider. Will animate into these new views as needed.
      */
-    public void updateGadget(RemoteViews remoteViews) {
-        if (LOGD) Log.d(TAG, "updateGadget called mOld=" + mOld);
+    public void updateAppWidget(RemoteViews remoteViews) {
+        if (LOGD) Log.d(TAG, "updateAppWidget called mOld=" + mOld);
         
         boolean recycled = false;
         View content = null;
@@ -180,7 +180,7 @@
                 // We've already done this -- nothing to do.
                 return ;
             }
-            Log.w(TAG, "updateGadget couldn't find any view, using error view", exception);
+            Log.w(TAG, "updateAppWidget couldn't find any view, using error view", exception);
             content = getErrorView();
             mViewMode = VIEW_MODE_ERROR;
         }
@@ -263,7 +263,7 @@
     }
     
     /**
-     * Inflate and return the default layout requested by gadget provider.
+     * Inflate and return the default layout requested by AppWidget provider.
      */
     protected View getDefaultView() {
         View defaultView = null;
@@ -288,7 +288,7 @@
         }
         
         if (exception != null && LOGD) {
-            Log.w(TAG, "Error inflating gadget " + mInfo, exception);
+            Log.w(TAG, "Error inflating AppWidget " + mInfo, exception);
         }
         
         if (defaultView == null) {
diff --git a/core/java/android/appwidget/AppWidgetManager.java b/core/java/android/appwidget/AppWidgetManager.java
new file mode 100644
index 0000000..3b10ed2
--- /dev/null
+++ b/core/java/android/appwidget/AppWidgetManager.java
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.appwidget;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+import android.widget.RemoteViews;
+
+import com.android.internal.appwidget.IAppWidgetService;
+
+import java.lang.ref.WeakReference;
+import java.util.List;
+import java.util.WeakHashMap;
+
+/**
+ * Updates AppWidget state; gets information about installed AppWidget providers and other
+ * AppWidget related state.
+ */
+public class AppWidgetManager {
+    static final String TAG = "AppWidgetManager";
+
+    /**
+     * Send this from your {@link AppWidgetHost} activity when you want to pick an AppWidget to display.
+     * The AppWidget picker activity will be launched.
+     * <p>
+     * You must supply the following extras:
+     * <table>
+     *   <tr>
+     *     <td>{@link #EXTRA_APPWIDGET_ID}</td>
+     *     <td>A newly allocated appWidgetId, which will be bound to the AppWidget provider
+     *         once the user has selected one.</td>
+     *  </tr>
+     * </table>
+     *
+     * <p>
+     * The system will respond with an onActivityResult call with the following extras in
+     * the intent:
+     * <table>
+     *   <tr>
+     *     <td>{@link #EXTRA_APPWIDGET_ID}</td>
+     *     <td>The appWidgetId that you supplied in the original intent.</td>
+     *  </tr>
+     * </table>
+     * <p>
+     * When you receive the result from the AppWidget pick activity, if the resultCode is
+     * {@link android.app.Activity#RESULT_OK}, an AppWidget has been selected.  You should then
+     * check the AppWidgetProviderInfo for the returned AppWidget, and if it has one, launch its configuration
+     * activity.  If {@link android.app.Activity#RESULT_CANCELED} is returned, you should delete
+     * the appWidgetId.
+     *
+     * @see #ACTION_APPWIDGET_CONFIGURE
+     */
+    public static final String ACTION_APPWIDGET_PICK = "android.appwidget.action.APPWIDGET_PICK";
+
+    /**
+     * Sent when it is time to configure your AppWidget while it is being added to a host.
+     * This action is not sent as a broadcast to the AppWidget provider, but as a startActivity
+     * to the activity specified in the {@link AppWidgetProviderInfo AppWidgetProviderInfo meta-data}.
+     *
+     * <p>
+     * The intent will contain the following extras:
+     * <table>
+     *   <tr>
+     *     <td>{@link #EXTRA_APPWIDGET_ID}</td>
+     *     <td>The appWidgetId to configure.</td>
+     *  </tr>
+     * </table>
+     *
+     * <p>If you return {@link android.app.Activity#RESULT_OK} using
+     * {@link android.app.Activity#setResult Activity.setResult()}, the AppWidget will be added,
+     * and you will receive an {@link #ACTION_APPWIDGET_UPDATE} broadcast for this AppWidget.
+     * If you return {@link android.app.Activity#RESULT_CANCELED}, the host will cancel the add
+     * and not display this AppWidget, and you will receive a {@link #ACTION_APPWIDGET_DELETED} broadcast.
+     */
+    public static final String ACTION_APPWIDGET_CONFIGURE = "android.appwidget.action.APPWIDGET_CONFIGURE";
+
+    /**
+     * An intent extra that contains one appWidgetId.
+     * <p>
+     * The value will be an int that can be retrieved like this:
+     * {@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/src/com/android/tests/appwidgethost/AppWidgetHostActivity.java getExtra_EXTRA_APPWIDGET_ID}
+     */
+    public static final String EXTRA_APPWIDGET_ID = "appWidgetId";
+
+    /**
+     * An intent extra that contains multiple appWidgetIds.
+     * <p>
+     * The value will be an int array that can be retrieved like this:
+     * {@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/src/com/android/tests/appwidgethost/TestAppWidgetProvider.java getExtra_EXTRA_APPWIDGET_IDS}
+     */
+    public static final String EXTRA_APPWIDGET_IDS = "appWidgetIds";
+
+    /**
+     * A sentiel value that the AppWidget manager will never return as a appWidgetId.
+     */
+    public static final int INVALID_APPWIDGET_ID = 0;
+
+    /**
+     * Sent when it is time to update your AppWidget.
+     *
+     * <p>This may be sent in response to a new instance for this AppWidget provider having
+     * been instantiated, the requested {@link AppWidgetProviderInfo#updatePeriodMillis update interval}
+     * having lapsed, or the system booting.
+     *
+     * <p>
+     * The intent will contain the following extras:
+     * <table>
+     *   <tr>
+     *     <td>{@link #EXTRA_APPWIDGET_IDS}</td>
+     *     <td>The appWidgetIds to update.  This may be all of the AppWidgets created for this
+     *     provider, or just a subset.  The system tries to send updates for as few AppWidget
+     *     instances as possible.</td>
+     *  </tr>
+     * </table>
+     * 
+     * @see AppWidgetProvider#onUpdate AppWidgetProvider.onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
+     */
+    public static final String ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE";
+
+    /**
+     * Sent when an instance of an AppWidget is deleted from its host.
+     *
+     * @see AppWidgetProvider#onDeleted AppWidgetProvider.onDeleted(Context context, int[] appWidgetIds)
+     */
+    public static final String ACTION_APPWIDGET_DELETED = "android.appwidget.action.APPWIDGET_DELETED";
+
+    /**
+     * Sent when an instance of an AppWidget is removed from the last host.
+     * 
+     * @see AppWidgetProvider#onEnabled AppWidgetProvider.onEnabled(Context context)
+     */
+    public static final String ACTION_APPWIDGET_DISABLED = "android.appwidget.action.APPWIDGET_DISABLED";
+
+    /**
+     * Sent when an instance of an AppWidget is added to a host for the first time.
+     * This broadcast is sent at boot time if there is a AppWidgetHost installed with
+     * an instance for this provider.
+     * 
+     * @see AppWidgetProvider#onEnabled AppWidgetProvider.onEnabled(Context context)
+     */
+    public static final String ACTION_APPWIDGET_ENABLED = "android.appwidget.action.APPWIDGET_ENABLED";
+
+    /**
+     * Field for the manifest meta-data tag.
+     *
+     * @see AppWidgetProviderInfo
+     */
+    public static final String META_DATA_APPWIDGET_PROVIDER = "android.appwidget.provider";
+
+    static WeakHashMap<Context, WeakReference<AppWidgetManager>> sManagerCache = new WeakHashMap();
+    static IAppWidgetService sService;
+    
+    Context mContext;
+
+    /**
+     * Get the AppWidgetManager instance to use for the supplied {@link android.content.Context
+     * Context} object.
+     */
+    public static AppWidgetManager getInstance(Context context) {
+        synchronized (sManagerCache) {
+            if (sService == null) {
+                IBinder b = ServiceManager.getService(Context.APPWIDGET_SERVICE);
+                sService = IAppWidgetService.Stub.asInterface(b);
+            }
+
+            WeakReference<AppWidgetManager> ref = sManagerCache.get(context);
+            AppWidgetManager result = null;
+            if (ref != null) {
+                result = ref.get();
+            }
+            if (result == null) {
+                result = new AppWidgetManager(context);
+                sManagerCache.put(context, new WeakReference(result));
+            }
+            return result;
+        }
+    }
+
+    private AppWidgetManager(Context context) {
+        mContext = context;
+    }
+
+    /**
+     * Set the RemoteViews to use for the specified appWidgetIds.
+     *
+     * <p>
+     * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
+     * and outside of the handler.
+     * This method will only work when called from the uid that owns the AppWidget provider.
+     *
+     * @param appWidgetIds     The AppWidget instances for which to set the RemoteViews.
+     * @param views         The RemoteViews object to show.
+     */
+    public void updateAppWidget(int[] appWidgetIds, RemoteViews views) {
+        try {
+            sService.updateAppWidgetIds(appWidgetIds, views);
+        }
+        catch (RemoteException e) {
+            throw new RuntimeException("system server dead?", e);
+        }
+    }
+
+    /**
+     * Set the RemoteViews to use for the specified appWidgetId.
+     *
+     * <p>
+     * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
+     * and outside of the handler.
+     * This method will only work when called from the uid that owns the AppWidget provider.
+     *
+     * @param appWidgetId      The AppWidget instance for which to set the RemoteViews.
+     * @param views         The RemoteViews object to show.
+     */
+    public void updateAppWidget(int appWidgetId, RemoteViews views) {
+        updateAppWidget(new int[] { appWidgetId }, views);
+    }
+
+    /**
+     * Set the RemoteViews to use for all AppWidget instances for the supplied AppWidget provider.
+     *
+     * <p>
+     * It is okay to call this method both inside an {@link #ACTION_APPWIDGET_UPDATE} broadcast,
+     * and outside of the handler.
+     * This method will only work when called from the uid that owns the AppWidget provider.
+     *
+     * @param provider      The {@link ComponentName} for the {@link
+     * android.content.BroadcastReceiver BroadcastReceiver} provider
+     *                      for your AppWidget.
+     * @param views         The RemoteViews object to show.
+     */
+    public void updateAppWidget(ComponentName provider, RemoteViews views) {
+        try {
+            sService.updateAppWidgetProvider(provider, views);
+        }
+        catch (RemoteException e) {
+            throw new RuntimeException("system server dead?", e);
+        }
+    }
+
+    /**
+     * Return a list of the AppWidget providers that are currently installed.
+     */
+    public List<AppWidgetProviderInfo> getInstalledProviders() {
+        try {
+            return sService.getInstalledProviders();
+        }
+        catch (RemoteException e) {
+            throw new RuntimeException("system server dead?", e);
+        }
+    }
+
+    /**
+     * Get the available info about the AppWidget.
+     *
+     * @return A appWidgetId.  If the appWidgetId has not been bound to a provider yet, or
+     * you don't have access to that appWidgetId, null is returned.
+     */
+    public AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId) {
+        try {
+            return sService.getAppWidgetInfo(appWidgetId);
+        }
+        catch (RemoteException e) {
+            throw new RuntimeException("system server dead?", e);
+        }
+    }
+
+    /**
+     * Set the component for a given appWidgetId.
+     *
+     * <p class="note">You need the APPWIDGET_LIST permission.  This method is to be used by the
+     * AppWidget picker.
+     *
+     * @param appWidgetId     The AppWidget instance for which to set the RemoteViews.
+     * @param provider      The {@link android.content.BroadcastReceiver} that will be the AppWidget
+     *                      provider for this AppWidget.
+     */
+    public void bindAppWidgetId(int appWidgetId, ComponentName provider) {
+        try {
+            sService.bindAppWidgetId(appWidgetId, provider);
+        }
+        catch (RemoteException e) {
+            throw new RuntimeException("system server dead?", e);
+        }
+    }
+
+    /**
+     * Get the list of appWidgetIds that have been bound to the given AppWidget
+     * provider.
+     * 
+     * @param provider The {@link android.content.BroadcastReceiver} that is the
+     *            AppWidget provider to find appWidgetIds for.
+     */
+    public int[] getAppWidgetIds(ComponentName provider) {
+        try {
+            return sService.getAppWidgetIds(provider);
+        }
+        catch (RemoteException e) {
+            throw new RuntimeException("system server dead?", e);
+        }
+    }
+}
+
diff --git a/core/java/android/appwidget/AppWidgetProvider.java b/core/java/android/appwidget/AppWidgetProvider.java
new file mode 100755
index 0000000..f70de9c
--- /dev/null
+++ b/core/java/android/appwidget/AppWidgetProvider.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.appwidget;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
+
+/**
+ * A conveience class to aid in implementing an AppWidget provider.
+ * Everything you can do with AppWidgetProvider, you can do with a regular {@link BroadcastReceiver}.
+ * AppWidgetProvider merely parses the relevant fields out of the Intent that is received in
+ * {@link #onReceive(Context,Intent) onReceive(Context,Intent)}, and calls hook methods
+ * with the received extras.
+ *
+ * <p>Extend this class and override one or more of the {@link #onUpdate}, {@link #onDeleted},
+ * {@link #onEnabled} or {@link #onDisabled} methods to implement your own AppWidget functionality.
+ *
+ * <h3>Sample Code</h3>
+ * For an example of how to write a AppWidget provider, see the
+ * <a href="{@toroot}reference/android/appwidget/package-descr.html#providers">android.appwidget
+ * package overview</a>.
+ */
+public class AppWidgetProvider extends BroadcastReceiver {
+    /**
+     * Constructor to initialize AppWidgetProvider.
+     */
+    public AppWidgetProvider() {
+    }
+
+    /**
+     * Implements {@link BroadcastReceiver#onReceive} to dispatch calls to the various
+     * other methods on AppWidgetProvider.  
+     *
+     * @param context The Context in which the receiver is running.
+     * @param intent The Intent being received.
+     */
+    // BEGIN_INCLUDE(onReceive)
+    public void onReceive(Context context, Intent intent) {
+        // Protect against rogue update broadcasts (not really a security issue,
+        // just filter bad broacasts out so subclasses are less likely to crash).
+        String action = intent.getAction();
+        if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
+            Bundle extras = intent.getExtras();
+            if (extras != null) {
+                int[] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
+                if (appWidgetIds != null && appWidgetIds.length > 0) {
+                    this.onUpdate(context, AppWidgetManager.getInstance(context), appWidgetIds);
+                }
+            }
+        }
+        else if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action)) {
+            Bundle extras = intent.getExtras();
+            if (extras != null) {
+                int[] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
+                if (appWidgetIds != null && appWidgetIds.length > 0) {
+                    this.onDeleted(context, appWidgetIds);
+                }
+            }
+        }
+        else if (AppWidgetManager.ACTION_APPWIDGET_ENABLED.equals(action)) {
+            this.onEnabled(context);
+        }
+        else if (AppWidgetManager.ACTION_APPWIDGET_DISABLED.equals(action)) {
+            this.onDisabled(context);
+        }
+    }
+    // END_INCLUDE(onReceive)
+    
+    /**
+     * Called in response to the {@link AppWidgetManager#ACTION_APPWIDGET_UPDATE} broadcast when
+     * this AppWidget provider is being asked to provide {@link android.widget.RemoteViews RemoteViews}
+     * for a set of AppWidgets.  Override this method to implement your own AppWidget functionality.
+     *
+     * {@more}
+     * 
+     * @param context   The {@link android.content.Context Context} in which this receiver is
+     *                  running.
+     * @param appWidgetManager A {@link AppWidgetManager} object you can call {@link
+     *                  AppWidgetManager#updateAppWidget} on.
+     * @param appWidgetIds The appWidgetIds for which an update is needed.  Note that this
+     *                  may be all of the AppWidget instances for this provider, or just
+     *                  a subset of them.
+     *
+     * @see AppWidgetManager#ACTION_APPWIDGET_UPDATE
+     */
+    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
+    }
+    
+    /**
+     * Called in response to the {@link AppWidgetManager#ACTION_APPWIDGET_DELETED} broadcast when
+     * one or more AppWidget instances have been deleted.  Override this method to implement
+     * your own AppWidget functionality.
+     *
+     * {@more}
+     * 
+     * @param context   The {@link android.content.Context Context} in which this receiver is
+     *                  running.
+     * @param appWidgetIds The appWidgetIds that have been deleted from their host.
+     *
+     * @see AppWidgetManager#ACTION_APPWIDGET_DELETED
+     */
+    public void onDeleted(Context context, int[] appWidgetIds) {
+    }
+
+    /**
+     * Called in response to the {@link AppWidgetManager#ACTION_APPWIDGET_ENABLED} broadcast when
+     * the a AppWidget for this provider is instantiated.  Override this method to implement your
+     * own AppWidget functionality.
+     *
+     * {@more}
+     * When the last AppWidget for this provider is deleted,
+     * {@link AppWidgetManager#ACTION_APPWIDGET_DISABLED} is sent by the AppWidget manager, and
+     * {@link #onDisabled} is called.  If after that, an AppWidget for this provider is created
+     * again, onEnabled() will be called again.
+     *
+     * @param context   The {@link android.content.Context Context} in which this receiver is
+     *                  running.
+     *
+     * @see AppWidgetManager#ACTION_APPWIDGET_ENABLED
+     */
+    public void onEnabled(Context context) {
+    }
+
+    /**
+     * Called in response to the {@link AppWidgetManager#ACTION_APPWIDGET_DISABLED} broadcast, which
+     * is sent when the last AppWidget instance for this provider is deleted.  Override this method
+     * to implement your own AppWidget functionality.
+     *
+     * {@more}
+     * 
+     * @param context   The {@link android.content.Context Context} in which this receiver is
+     *                  running.
+     *
+     * @see AppWidgetManager#ACTION_APPWIDGET_DISABLED
+     */
+    public void onDisabled(Context context) {
+    }
+}
diff --git a/core/java/android/gadget/GadgetProviderInfo.aidl b/core/java/android/appwidget/AppWidgetProviderInfo.aidl
similarity index 90%
rename from core/java/android/gadget/GadgetProviderInfo.aidl
rename to core/java/android/appwidget/AppWidgetProviderInfo.aidl
index 589f886..82b3ada 100644
--- a/core/java/android/gadget/GadgetProviderInfo.aidl
+++ b/core/java/android/appwidget/AppWidgetProviderInfo.aidl
@@ -14,6 +14,6 @@
  * limitations under the License.
  */
 
-package android.gadget;
+package android.appwidget;
 
-parcelable GadgetProviderInfo;
+parcelable AppWidgetProviderInfo;
diff --git a/core/java/android/gadget/GadgetProviderInfo.java b/core/java/android/appwidget/AppWidgetProviderInfo.java
similarity index 63%
rename from core/java/android/gadget/GadgetProviderInfo.java
rename to core/java/android/appwidget/AppWidgetProviderInfo.java
index 95c0432..8530c35 100644
--- a/core/java/android/gadget/GadgetProviderInfo.java
+++ b/core/java/android/appwidget/AppWidgetProviderInfo.java
@@ -14,21 +14,21 @@
  * limitations under the License.
  */
 
-package android.gadget;
+package android.appwidget;
 
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.content.ComponentName;
 
 /**
- * Describes the meta data for an installed gadget provider.  The fields in this class
- * correspond to the fields in the <code>&lt;gadget-provider&gt;</code> xml tag.
+ * Describes the meta data for an installed AppWidget provider.  The fields in this class
+ * correspond to the fields in the <code>&lt;appwidget-provider&gt;</code> xml tag.
  */
-public class GadgetProviderInfo implements Parcelable {
+public class AppWidgetProviderInfo implements Parcelable {
     /**
-     * Identity of this gadget component.  This component should be a {@link
-     * android.content.BroadcastReceiver}, and it will be sent the Gadget intents
-     * {@link android.gadget as described in the gadget package documentation}.
+     * Identity of this AppWidget component.  This component should be a {@link
+     * android.content.BroadcastReceiver}, and it will be sent the AppWidget intents
+     * {@link android.appwidget as described in the AppWidget package documentation}.
      *
      * <p>This field corresponds to the <code>android:name</code> attribute in
      * the <code>&lt;receiver&gt;</code> element in the AndroidManifest.xml file.
@@ -36,50 +36,50 @@
     public ComponentName provider;
 
     /**
-     * Minimum width of the gadget, in dp.
+     * Minimum width of the AppWidget, in dp.
      *
      * <p>This field corresponds to the <code>android:minWidth</code> attribute in
-     * the gadget meta-data file.
+     * the AppWidget meta-data file.
      */
     public int minWidth;
 
     /**
-     * Minimum height of the gadget, in dp.
+     * Minimum height of the AppWidget, in dp.
      *
      * <p>This field corresponds to the <code>android:minHeight</code> attribute in
-     * the gadget meta-data file.
+     * the AppWidget meta-data file.
      */
     public int minHeight;
 
     /**
-     * How often, in milliseconds, that this gadget wants to be updated.
-     * The gadget manager may place a limit on how often a gadget is updated.
+     * How often, in milliseconds, that this AppWidget wants to be updated.
+     * The AppWidget manager may place a limit on how often a AppWidget is updated.
      *
      * <p>This field corresponds to the <code>android:updatePeriodMillis</code> attribute in
-     * the gadget meta-data file.
+     * the AppWidget meta-data file.
      */
     public int updatePeriodMillis;
 
     /**
-     * The resource id of the initial layout for this gadget.  This should be
-     * displayed until the RemoteViews for the gadget is available.
+     * The resource id of the initial layout for this AppWidget.  This should be
+     * displayed until the RemoteViews for the AppWidget is available.
      *
      * <p>This field corresponds to the <code>android:initialLayout</code> attribute in
-     * the gadget meta-data file.
+     * the AppWidget meta-data file.
      */
     public int initialLayout;
 
     /**
-     * The activity to launch that will configure the gadget.
+     * The activity to launch that will configure the AppWidget.
      *
      * <p>This class name of field corresponds to the <code>android:configure</code> attribute in
-     * the gadget meta-data file.  The package name always corresponds to the package containing
-     * the gadget provider.
+     * the AppWidget meta-data file.  The package name always corresponds to the package containing
+     * the AppWidget provider.
      */
     public ComponentName configure;
 
     /**
-     * The label to display to the user in the gadget picker.  If not supplied in the
+     * The label to display to the user in the AppWidget picker.  If not supplied in the
      * xml, the application label will be used.
      *
      * <p>This field corresponds to the <code>android:label</code> attribute in
@@ -88,7 +88,7 @@
     public String label;
 
     /**
-     * The icon to display for this gadget in the gadget picker.  If not supplied in the
+     * The icon to display for this AppWidget in the AppWidget picker.  If not supplied in the
      * xml, the application icon will be used.
      *
      * <p>This field corresponds to the <code>android:icon</code> attribute in
@@ -96,13 +96,13 @@
      */
     public int icon;
 
-    public GadgetProviderInfo() {
+    public AppWidgetProviderInfo() {
     }
 
     /**
-     * Unflatten the GadgetProviderInfo from a parcel.
+     * Unflatten the AppWidgetProviderInfo from a parcel.
      */
-    public GadgetProviderInfo(Parcel in) {
+    public AppWidgetProviderInfo(Parcel in) {
         if (0 != in.readInt()) {
             this.provider = new ComponentName(in);
         }
@@ -144,24 +144,24 @@
     }
 
     /**
-     * Parcelable.Creator that instantiates GadgetProviderInfo objects
+     * Parcelable.Creator that instantiates AppWidgetProviderInfo objects
      */
-    public static final Parcelable.Creator<GadgetProviderInfo> CREATOR
-            = new Parcelable.Creator<GadgetProviderInfo>()
+    public static final Parcelable.Creator<AppWidgetProviderInfo> CREATOR
+            = new Parcelable.Creator<AppWidgetProviderInfo>()
     {
-        public GadgetProviderInfo createFromParcel(Parcel parcel)
+        public AppWidgetProviderInfo createFromParcel(Parcel parcel)
         {
-            return new GadgetProviderInfo(parcel);
+            return new AppWidgetProviderInfo(parcel);
         }
 
-        public GadgetProviderInfo[] newArray(int size)
+        public AppWidgetProviderInfo[] newArray(int size)
         {
-            return new GadgetProviderInfo[size];
+            return new AppWidgetProviderInfo[size];
         }
     };
 
     public String toString() {
-        return "GadgetProviderInfo(provider=" + this.provider + ")";
+        return "AppWidgetProviderInfo(provider=" + this.provider + ")";
     }
 }
 
diff --git a/core/java/android/appwidget/package.html b/core/java/android/appwidget/package.html
new file mode 100644
index 0000000..b6cd9c7
--- /dev/null
+++ b/core/java/android/appwidget/package.html
@@ -0,0 +1,136 @@
+<body>
+<p>Android allows applications to publish views to be embedded in other applications.  These
+views are called widgets, and are published by "AppWidget providers."  The component that can
+contain widgets is called a "AppWidget host."
+</p>
+<h3><a href="package-descr.html#providers">AppWidget Providers</a></h3>
+<ul>
+  <li><a href="package-descr.html#provider_manifest">Declaring a widget in the AndroidManifest</a></li>
+  <li><a href="package-descr.html#provider_meta_data">Adding the AppWidgetProviderInfo meta-data</a></li>
+  <li><a href="package-descr.html#provider_AppWidgetProvider">Using the AppWidgetProvider class</a></li>
+  <li><a href="package-descr.html#provider_configuration">AppWidget Configuration UI</a></li>
+  <li><a href="package-descr.html#provider_broadcasts">AppWidget Broadcast Intents</a></li>
+</ul>
+<h3><a href="package-descr.html#">AppWidget Hosts</a></h3>
+
+
+{@more}
+
+
+<h2><a name="providers"></a>AppWidget Providers</h2>
+<p>
+Any application can publish widgets.  All an application needs to do to publish a widget is
+to have a {@link android.content.BroadcastReceiver} that receives the {@link
+android.appwidget.AppWidgetManager#ACTION_APPWIDGET_UPDATE AppWidgetManager.ACTION_APPWIDGET_UPDATE} intent,
+and provide some meta-data about the widget.  Android provides the
+{@link android.appwidget.AppWidgetProvider} class, which extends BroadcastReceiver, as a convenience
+class to aid in handling the broadcasts.
+
+<h3><a name="provider_manifest"></a>Declaring a widget in the AndroidManifest</h3>
+
+<p>
+First, declare the {@link android.content.BroadcastReceiver} in your application's
+<code>AndroidManifest.xml</code> file.
+
+{@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/AndroidManifest.xml AppWidgetProvider}
+
+<p>
+The <b><code>&lt;receiver&gt;</b> element has the following attributes:
+<ul>
+  <li><b><code>android:name</code> -</b> which specifies the
+        {@link android.content.BroadcastReceiver} or {@link android.appwidget.AppWidgetProvider}
+        class.</li>
+  <li><b><code>android:label</code> -</b> which specifies the string resource that
+        will be shown by the widget picker as the label.</li>
+  <li><b><code>android:icon</code> -</b> which specifies the drawable resource that
+        will be shown by the widget picker as the icon.</li>
+</ul>
+
+<p>
+The <b><code>&lt;intent-filter&gt;</b> element tells the {@link android.content.pm.PackageManager}
+that this {@link android.content.BroadcastReceiver} receives the {@link
+android.appwidget.AppWidgetManager#ACTION_APPWIDGET_UPDATE AppWidgetManager.ACTION_APPWIDGET_UPDATE} broadcast.
+The widget manager will send other broadcasts directly to your widget provider as required.
+It is only necessary to explicitly declare that you accept the {@link
+android.appwidget.AppWidgetManager#ACTION_APPWIDGET_UPDATE AppWidgetManager.ACTION_APPWIDGET_UPDATE} broadcast.
+
+<p>
+The <b><code>&lt;meta-data&gt;</code></b> element tells the widget manager which xml resource to
+read to find the {@link android.appwidget.AppWidgetProviderInfo} for your widget provider.  It has the following
+attributes:
+<ul>
+  <li><b><code>android:name="android.appwidget.provider"</code> -</b> identifies this meta-data
+        as the {@link android.appwidget.AppWidgetProviderInfo} descriptor.</li>
+  <li><b><code>android:resource</code> -</b> is the xml resource to use as that descriptor.</li>
+</ul>
+
+
+<h3><a name="provider_meta_data"></a>Adding the {@link android.appwidget.AppWidgetProviderInfo AppWidgetProviderInfo} meta-data</h3>
+
+<p>
+For a widget, the values in the {@link android.appwidget.AppWidgetProviderInfo} structure are supplied
+in an XML resource.  In the example above, the xml resource is referenced with
+<code>android:resource="@xml/appwidget_info"</code>.  That XML file would go in your application's
+directory at <code>res/xml/appwidget_info.xml</code>.  Here is a simple example.
+
+{@sample frameworks/base/tests/appwidgets/AppWidgetHostTest/res/xml/appwidget_info.xml AppWidgetProviderInfo}
+
+<p>
+The attributes are as documented in the {@link android.appwidget.AppWidgetProviderInfo GagetInfo} class.  (86400000 milliseconds means once per day)
+
+
+<h3><a name="provider_AppWidgetProvider"></a>Using the {@link android.appwidget.AppWidgetProvider AppWidgetProvider} class</h3>
+
+<p>The AppWidgetProvider class is the easiest way to handle the widget provider intent broadcasts.
+See the <code>src/com/example/android/apis/appwidget/ExampleAppWidgetProvider.java</code>
+sample class in ApiDemos for an example.
+
+<p class="note">Keep in mind that since the the AppWidgetProvider is a BroadcastReceiver,
+your process is not guaranteed to keep running after the callback methods return.  See
+<a href="../../../guide/topics/fundamentals.html#broadlife">Application Fundamentals &gt;
+Broadcast Receiver Lifecycle</a> for more information.
+
+
+
+<h3><a name="provider_configuration"></a>AppWidget Configuration UI</h3>
+
+<p>
+Widget hosts have the ability to start a configuration activity when a widget is instantiated.
+The activity should be declared as normal in AndroidManifest.xml, and it should be listed in
+the AppWidgetProviderInfo XML file in the <code>android:configure</code> attribute.
+
+<p>The activity you specified will be launched with the {@link
+android.appwidget.AppWidgetManager#ACTION_APPWIDGET_CONFIGURE} action.  See the documentation for that
+action for more info.
+
+<p>See the <code>src/com/example/android/apis/appwidget/ExampleAppWidgetConfigure.java</code>
+sample class in ApiDemos for an example.
+
+
+
+<h3><a name="providers_broadcasts"></a>AppWidget Broadcast Intents</h3>
+
+<p>{@link android.appwidget.AppWidgetProvider} is just a convenience class.  If you would like
+to receive the widget broadcasts directly, you can.  The four intents you need to care about are:
+<ul>
+  <li>{@link android.appwidget.AppWidgetManager#ACTION_APPWIDGET_UPDATE}</li>
+  <li>{@link android.appwidget.AppWidgetManager#ACTION_APPWIDGET_DELETED}</li>
+  <li>{@link android.appwidget.AppWidgetManager#ACTION_APPWIDGET_ENABLED}</li>
+  <li>{@link android.appwidget.AppWidgetManager#ACTION_APPWIDGET_DISABLED}</li>
+</ul>
+
+<p>By way of example, the implementation of
+{@link android.appwidget.AppWidgetProvider#onReceive} is quite simple:</p>
+
+{@sample frameworks/base/core/java/android/appwidget/AppWidgetProvider.java onReceive}
+
+
+<h2>AppWidget Hosts</h3>
+<p>Widget hosts are the containers in which widgets can be placed.  Most of the look and feel
+details are left up to the widget hosts.  For example, the home screen has one way of viewing
+widgets, but the lock screen could also contain widgets, and it would have a different way of
+adding, removing and otherwise managing widgets.</p>
+<p>For more information on implementing your own widget host, see the
+{@link android.appwidget.AppWidgetHost AppWidgetHost} class.</p>
+</body>
+
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index e0fe533..9a0dc9f 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1250,12 +1250,12 @@
 
     /**
      * Use with {@link #getSystemService} to retrieve a
-     * {@blink android.gadget.GadgetManager} for accessing wallpapers.
+     * {@blink android.appwidget.AppWidgetManager} for accessing AppWidgets.
      *
      * @hide
      * @see #getSystemService
      */
-    public static final String GADGET_SERVICE = "gadget";
+    public static final String APPWIDGET_SERVICE = "appwidget";
     
     /**
      * Determine whether the given permission is allowed for a particular
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 824fd9b..bb80e10 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -525,7 +525,6 @@
  *     <li> {@link #CATEGORY_INFO}
  *     <li> {@link #CATEGORY_HOME}
  *     <li> {@link #CATEGORY_PREFERENCE}
- *     <li> {@link #CATEGORY_GADGET}
  *     <li> {@link #CATEGORY_TEST}
  * </ul>
  *
@@ -1544,12 +1543,6 @@
     @SdkConstant(SdkConstantType.INTENT_CATEGORY)
     public static final String CATEGORY_TAB = "android.intent.category.TAB";
     /**
-     * This activity can be embedded inside of another activity that is hosting
-     * gadgets.
-     */
-    @SdkConstant(SdkConstantType.INTENT_CATEGORY)
-    public static final String CATEGORY_GADGET = "android.intent.category.GADGET";
-    /**
      * Should be displayed in the top-level launcher.
      */
     @SdkConstant(SdkConstantType.INTENT_CATEGORY)
@@ -1579,9 +1572,6 @@
     public static final String CATEGORY_DEVELOPMENT_PREFERENCE = "android.intent.category.DEVELOPMENT_PREFERENCE";
     /**
      * Capable of running inside a parent activity container.
-     *
-     * <p>Note: being removed in favor of more explicit categories such as
-     * CATEGORY_GADGET
      */
     @SdkConstant(SdkConstantType.INTENT_CATEGORY)
     public static final String CATEGORY_EMBED = "android.intent.category.EMBED";
diff --git a/core/java/android/content/res/ColorStateList.java b/core/java/android/content/res/ColorStateList.java
index 0f3f270..453a83d3 100644
--- a/core/java/android/content/res/ColorStateList.java
+++ b/core/java/android/content/res/ColorStateList.java
@@ -304,7 +304,6 @@
         for (int i=0; i<N; i++) {
             dest.writeIntArray(mStateSpecs[i]);
         }
-        dest.writeArray(mStateSpecs);
         dest.writeIntArray(mColors);
     }
 
diff --git a/core/java/android/gadget/GadgetManager.java b/core/java/android/gadget/GadgetManager.java
deleted file mode 100644
index d2c4055..0000000
--- a/core/java/android/gadget/GadgetManager.java
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.gadget;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.util.Log;
-import android.widget.RemoteViews;
-
-import com.android.internal.gadget.IGadgetService;
-
-import java.lang.ref.WeakReference;
-import java.util.List;
-import java.util.WeakHashMap;
-
-/**
- * Updates gadget state; gets information about installed gadget providers and other
- * gadget related state.
- */
-public class GadgetManager {
-    static final String TAG = "GadgetManager";
-
-    /**
-     * Send this from your gadget host activity when you want to pick a gadget to display.
-     * The gadget picker activity will be launched.
-     * <p>
-     * You must supply the following extras:
-     * <table>
-     *   <tr>
-     *     <td>{@link #EXTRA_GADGET_ID}</td>
-     *     <td>A newly allocated gadgetId, which will be bound to the gadget provider
-     *         once the user has selected one.</td>
-     *  </tr>
-     * </table>
-     *
-     * <p>
-     * The system will respond with an onActivityResult call with the following extras in
-     * the intent:
-     * <table>
-     *   <tr>
-     *     <td>{@link #EXTRA_GADGET_ID}</td>
-     *     <td>The gadgetId that you supplied in the original intent.</td>
-     *  </tr>
-     * </table>
-     * <p>
-     * When you receive the result from the gadget pick activity, if the resultCode is
-     * {@link android.app.Activity#RESULT_OK}, a gadget has been selected.  You should then
-     * check the GadgetProviderInfo for the returned gadget, and if it has one, launch its configuration
-     * activity.  If {@link android.app.Activity#RESULT_CANCELED} is returned, you should delete
-     * the gadgetId.
-     *
-     * @see #ACTION_GADGET_CONFIGURE
-     */
-    public static final String ACTION_GADGET_PICK = "android.gadget.action.GADGET_PICK";
-
-    /**
-     * Sent when it is time to configure your gadget while it is being added to a host.
-     * This action is not sent as a broadcast to the gadget provider, but as a startActivity
-     * to the activity specified in the {@link GadgetProviderInfo GadgetProviderInfo meta-data}.
-     *
-     * <p>
-     * The intent will contain the following extras:
-     * <table>
-     *   <tr>
-     *     <td>{@link #EXTRA_GADGET_ID}</td>
-     *     <td>The gadgetId to configure.</td>
-     *  </tr>
-     * </table>
-     *
-     * <p>If you return {@link android.app.Activity#RESULT_OK} using
-     * {@link android.app.Activity#setResult Activity.setResult()}, the gadget will be added,
-     * and you will receive an {@link #ACTION_GADGET_UPDATE} broadcast for this gadget.
-     * If you return {@link android.app.Activity#RESULT_CANCELED}, the host will cancel the add
-     * and not display this gadget, and you will receive a {@link #ACTION_GADGET_DELETED} broadcast.
-     */
-    public static final String ACTION_GADGET_CONFIGURE = "android.gadget.action.GADGET_CONFIGURE";
-
-    /**
-     * An intent extra that contains one gadgetId.
-     * <p>
-     * The value will be an int that can be retrieved like this:
-     * {@sample frameworks/base/tests/gadgets/GadgetHostTest/src/com/android/tests/gadgethost/GadgetHostActivity.java getExtra_EXTRA_GADGET_ID}
-     */
-    public static final String EXTRA_GADGET_ID = "gadgetId";
-
-    /**
-     * An intent extra that contains multiple gadgetIds.
-     * <p>
-     * The value will be an int array that can be retrieved like this:
-     * {@sample frameworks/base/tests/gadgets/GadgetHostTest/src/com/android/tests/gadgethost/TestGadgetProvider.java getExtra_EXTRA_GADGET_IDS}
-     */
-    public static final String EXTRA_GADGET_IDS = "gadgetIds";
-
-    /**
-     * A sentiel value that the gadget manager will never return as a gadgetId.
-     */
-    public static final int INVALID_GADGET_ID = 0;
-
-    /**
-     * Sent when it is time to update your gadget.
-     *
-     * <p>This may be sent in response to a new instance for this gadget provider having
-     * been instantiated, the requested {@link GadgetProviderInfo#updatePeriodMillis update interval}
-     * having lapsed, or the system booting.
-     *
-     * <p>
-     * The intent will contain the following extras:
-     * <table>
-     *   <tr>
-     *     <td>{@link #EXTRA_GADGET_IDS}</td>
-     *     <td>The gadgetIds to update.  This may be all of the gadgets created for this
-     *     provider, or just a subset.  The system tries to send updates for as few gadget
-     *     instances as possible.</td>
-     *  </tr>
-     * </table>
-     * 
-     * @see GadgetProvider#onUpdate GadgetProvider.onUpdate(Context context, GadgetManager gadgetManager, int[] gadgetIds)
-     */
-    public static final String ACTION_GADGET_UPDATE = "android.gadget.action.GADGET_UPDATE";
-
-    /**
-     * Sent when an instance of a gadget is deleted from its host.
-     *
-     * @see GadgetProvider#onDeleted GadgetProvider.onDeleted(Context context, int[] gadgetIds)
-     */
-    public static final String ACTION_GADGET_DELETED = "android.gadget.action.GADGET_DELETED";
-
-    /**
-     * Sent when an instance of a gadget is removed from the last host.
-     * 
-     * @see GadgetProvider#onEnabled GadgetProvider.onEnabled(Context context)
-     */
-    public static final String ACTION_GADGET_DISABLED = "android.gadget.action.GADGET_DISABLED";
-
-    /**
-     * Sent when an instance of a gadget is added to a host for the first time.
-     * This broadcast is sent at boot time if there is a gadget host installed with
-     * an instance for this provider.
-     * 
-     * @see GadgetProvider#onEnabled GadgetProvider.onEnabled(Context context)
-     */
-    public static final String ACTION_GADGET_ENABLED = "android.gadget.action.GADGET_ENABLED";
-
-    /**
-     * Field for the manifest meta-data tag.
-     *
-     * @see GadgetProviderInfo
-     */
-    public static final String META_DATA_GADGET_PROVIDER = "android.gadget.provider";
-
-    static WeakHashMap<Context, WeakReference<GadgetManager>> sManagerCache = new WeakHashMap();
-    static IGadgetService sService;
-    
-    Context mContext;
-
-    /**
-     * Get the GadgetManager instance to use for the supplied {@link android.content.Context
-     * Context} object.
-     */
-    public static GadgetManager getInstance(Context context) {
-        synchronized (sManagerCache) {
-            if (sService == null) {
-                IBinder b = ServiceManager.getService(Context.GADGET_SERVICE);
-                sService = IGadgetService.Stub.asInterface(b);
-            }
-
-            WeakReference<GadgetManager> ref = sManagerCache.get(context);
-            GadgetManager result = null;
-            if (ref != null) {
-                result = ref.get();
-            }
-            if (result == null) {
-                result = new GadgetManager(context);
-                sManagerCache.put(context, new WeakReference(result));
-            }
-            return result;
-        }
-    }
-
-    private GadgetManager(Context context) {
-        mContext = context;
-    }
-
-    /**
-     * Set the RemoteViews to use for the specified gadgetIds.
-     *
-     * <p>
-     * It is okay to call this method both inside an {@link #ACTION_GADGET_UPDATE} broadcast,
-     * and outside of the handler.
-     * This method will only work when called from the uid that owns the gadget provider.
-     *
-     * @param gadgetIds     The gadget instances for which to set the RemoteViews.
-     * @param views         The RemoteViews object to show.
-     */
-    public void updateGadget(int[] gadgetIds, RemoteViews views) {
-        try {
-            sService.updateGadgetIds(gadgetIds, views);
-        }
-        catch (RemoteException e) {
-            throw new RuntimeException("system server dead?", e);
-        }
-    }
-
-    /**
-     * Set the RemoteViews to use for the specified gadgetId.
-     *
-     * <p>
-     * It is okay to call this method both inside an {@link #ACTION_GADGET_UPDATE} broadcast,
-     * and outside of the handler.
-     * This method will only work when called from the uid that owns the gadget provider.
-     *
-     * @param gadgetId      The gadget instance for which to set the RemoteViews.
-     * @param views         The RemoteViews object to show.
-     */
-    public void updateGadget(int gadgetId, RemoteViews views) {
-        updateGadget(new int[] { gadgetId }, views);
-    }
-
-    /**
-     * Set the RemoteViews to use for all gadget instances for the supplied gadget provider.
-     *
-     * <p>
-     * It is okay to call this method both inside an {@link #ACTION_GADGET_UPDATE} broadcast,
-     * and outside of the handler.
-     * This method will only work when called from the uid that owns the gadget provider.
-     *
-     * @param provider      The {@link ComponentName} for the {@link
-     * android.content.BroadcastReceiver BroadcastReceiver} provider
-     *                      for your gadget.
-     * @param views         The RemoteViews object to show.
-     */
-    public void updateGadget(ComponentName provider, RemoteViews views) {
-        try {
-            sService.updateGadgetProvider(provider, views);
-        }
-        catch (RemoteException e) {
-            throw new RuntimeException("system server dead?", e);
-        }
-    }
-
-    /**
-     * Return a list of the gadget providers that are currently installed.
-     */
-    public List<GadgetProviderInfo> getInstalledProviders() {
-        try {
-            return sService.getInstalledProviders();
-        }
-        catch (RemoteException e) {
-            throw new RuntimeException("system server dead?", e);
-        }
-    }
-
-    /**
-     * Get the available info about the gadget.
-     *
-     * @return A gadgetId.  If the gadgetId has not been bound to a provider yet, or
-     * you don't have access to that gadgetId, null is returned.
-     */
-    public GadgetProviderInfo getGadgetInfo(int gadgetId) {
-        try {
-            return sService.getGadgetInfo(gadgetId);
-        }
-        catch (RemoteException e) {
-            throw new RuntimeException("system server dead?", e);
-        }
-    }
-
-    /**
-     * Set the component for a given gadgetId.
-     *
-     * <p class="note">You need the GADGET_LIST permission.  This method is to be used by the
-     * gadget picker.
-     *
-     * @param gadgetId     The gadget instance for which to set the RemoteViews.
-     * @param provider      The {@link android.content.BroadcastReceiver} that will be the gadget
-     *                      provider for this gadget.
-     */
-    public void bindGadgetId(int gadgetId, ComponentName provider) {
-        try {
-            sService.bindGadgetId(gadgetId, provider);
-        }
-        catch (RemoteException e) {
-            throw new RuntimeException("system server dead?", e);
-        }
-    }
-
-    /**
-     * Get the list of gadgetIds that have been bound to the given gadget
-     * provider.
-     * 
-     * @param provider The {@link android.content.BroadcastReceiver} that is the
-     *            gadget provider to find gadgetIds for.
-     */
-    public int[] getGadgetIds(ComponentName provider) {
-        try {
-            return sService.getGadgetIds(provider);
-        }
-        catch (RemoteException e) {
-            throw new RuntimeException("system server dead?", e);
-        }
-    }
-}
-
diff --git a/core/java/android/gadget/GadgetProvider.java b/core/java/android/gadget/GadgetProvider.java
deleted file mode 100755
index 7e10e78..0000000
--- a/core/java/android/gadget/GadgetProvider.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.gadget;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.os.Bundle;
-
-/**
- * A conveience class to aid in implementing a gadget provider.
- * Everything you can do with GadgetProvider, you can do with a regular {@link BroadcastReceiver}.
- * GadgetProvider merely parses the relevant fields out of the Intent that is received in
- * {@link #onReceive(Context,Intent) onReceive(Context,Intent)}, and calls hook methods
- * with the received extras.
- *
- * <p>Extend this class and override one or more of the {@link #onUpdate}, {@link #onDeleted},
- * {@link #onEnabled} or {@link #onDisabled} methods to implement your own gadget functionality.
- *
- * <h3>Sample Code</h3>
- * For an example of how to write a gadget provider, see the
- * <a href="{@toroot}reference/android/gadget/package-descr.html#providers">android.gadget
- * package overview</a>.
- */
-public class GadgetProvider extends BroadcastReceiver {
-    /**
-     * Constructor to initialize GadgetProvider.
-     */
-    public GadgetProvider() {
-    }
-
-    /**
-     * Implements {@link BroadcastReceiver#onReceive} to dispatch calls to the various
-     * other methods on GadgetProvider.  
-     *
-     * @param context The Context in which the receiver is running.
-     * @param intent The Intent being received.
-     */
-    // BEGIN_INCLUDE(onReceive)
-    public void onReceive(Context context, Intent intent) {
-        // Protect against rogue update broadcasts (not really a security issue,
-        // just filter bad broacasts out so subclasses are less likely to crash).
-        String action = intent.getAction();
-        if (GadgetManager.ACTION_GADGET_UPDATE.equals(action)) {
-            Bundle extras = intent.getExtras();
-            if (extras != null) {
-                int[] gadgetIds = extras.getIntArray(GadgetManager.EXTRA_GADGET_IDS);
-                if (gadgetIds != null && gadgetIds.length > 0) {
-                    this.onUpdate(context, GadgetManager.getInstance(context), gadgetIds);
-                }
-            }
-        }
-        else if (GadgetManager.ACTION_GADGET_DELETED.equals(action)) {
-            Bundle extras = intent.getExtras();
-            if (extras != null) {
-                int[] gadgetIds = extras.getIntArray(GadgetManager.EXTRA_GADGET_IDS);
-                if (gadgetIds != null && gadgetIds.length > 0) {
-                    this.onDeleted(context, gadgetIds);
-                }
-            }
-        }
-        else if (GadgetManager.ACTION_GADGET_ENABLED.equals(action)) {
-            this.onEnabled(context);
-        }
-        else if (GadgetManager.ACTION_GADGET_DISABLED.equals(action)) {
-            this.onDisabled(context);
-        }
-    }
-    // END_INCLUDE(onReceive)
-    
-    /**
-     * Called in response to the {@link GadgetManager#ACTION_GADGET_UPDATE} broadcast when
-     * this gadget provider is being asked to provide {@link android.widget.RemoteViews RemoteViews}
-     * for a set of gadgets.  Override this method to implement your own gadget functionality.
-     *
-     * {@more}
-     * 
-     * @param context   The {@link android.content.Context Context} in which this receiver is
-     *                  running.
-     * @param gadgetManager A {@link GadgetManager} object you can call {@link
-     *                  GadgetManager#updateGadget} on.
-     * @param gadgetIds The gadgetsIds for which an update is needed.  Note that this
-     *                  may be all of the gadget instances for this provider, or just
-     *                  a subset of them.
-     *
-     * @see GadgetManager#ACTION_GADGET_UPDATE
-     */
-    public void onUpdate(Context context, GadgetManager gadgetManager, int[] gadgetIds) {
-    }
-    
-    /**
-     * Called in response to the {@link GadgetManager#ACTION_GADGET_DELETED} broadcast when
-     * one or more gadget instances have been deleted.  Override this method to implement
-     * your own gadget functionality.
-     *
-     * {@more}
-     * 
-     * @param context   The {@link android.content.Context Context} in which this receiver is
-     *                  running.
-     * @param gadgetIds The gadgetsIds that have been deleted from their host.
-     *
-     * @see GadgetManager#ACTION_GADGET_DELETED
-     */
-    public void onDeleted(Context context, int[] gadgetIds) {
-    }
-
-    /**
-     * Called in response to the {@link GadgetManager#ACTION_GADGET_ENABLED} broadcast when
-     * the a gadget for this provider is instantiated.  Override this method to implement your
-     * own gadget functionality.
-     *
-     * {@more}
-     * When the last gadget for this provider is deleted,
-     * {@link GadgetManager#ACTION_GADGET_DISABLED} is sent by the gadget manager, and
-     * {@link #onDisabled} is called.  If after that, a gadget for this provider is created
-     * again, onEnabled() will be called again.
-     *
-     * @param context   The {@link android.content.Context Context} in which this receiver is
-     *                  running.
-     *
-     * @see GadgetManager#ACTION_GADGET_ENABLED
-     */
-    public void onEnabled(Context context) {
-    }
-
-    /**
-     * Called in response to the {@link GadgetManager#ACTION_GADGET_DISABLED} broadcast, which
-     * is sent when the last gadget instance for this provider is deleted.  Override this method
-     * to implement your own gadget functionality.
-     *
-     * {@more}
-     * 
-     * @param context   The {@link android.content.Context Context} in which this receiver is
-     *                  running.
-     *
-     * @see GadgetManager#ACTION_GADGET_DISABLED
-     */
-    public void onDisabled(Context context) {
-    }
-}
diff --git a/core/java/android/gadget/package.html b/core/java/android/gadget/package.html
deleted file mode 100644
index 4c04396..0000000
--- a/core/java/android/gadget/package.html
+++ /dev/null
@@ -1,136 +0,0 @@
-<body>
-<p>Android allows applications to publish views to be embedded in other applications.  These
-views are called gadgets, and are published by "gadget providers."  The component that can
-contain gadgets is called a "gadget host."
-</p>
-<h3><a href="package-descr.html#providers">Gadget Providers</a></h3>
-<ul>
-  <li><a href="package-descr.html#provider_manifest">Declaring a gadget in the AndroidManifest</a></li>
-  <li><a href="package-descr.html#provider_meta_data">Adding the GadgetProviderInfo meta-data</a></li>
-  <li><a href="package-descr.html#provider_GadgetProvider">Using the GadgetProvider class</a></li>
-  <li><a href="package-descr.html#provider_configuration">Gadget Configuration UI</a></li>
-  <li><a href="package-descr.html#provider_broadcasts">Gadget Broadcast Intents</a></li>
-</ul>
-<h3><a href="package-descr.html#">Gadget Hosts</a></h3>
-
-
-{@more}
-
-
-<h2><a name="providers"></a>Gadget Providers</h2>
-<p>
-Any application can publish gadgets.  All an application needs to do to publish a gadget is
-to have a {@link android.content.BroadcastReceiver} that receives the {@link
-android.gadget.GadgetManager#ACTION_GADGET_UPDATE GadgetManager.ACTION_GADGET_UPDATE} intent,
-and provide some meta-data about the gadget.  Android provides the
-{@link android.gadget.GadgetProvider} class, which extends BroadcastReceiver, as a convenience
-class to aid in handling the broadcasts.
-
-<h3><a name="provider_manifest"></a>Declaring a gadget in the AndroidManifest</h3>
-
-<p>
-First, declare the {@link android.content.BroadcastReceiver} in your application's
-<code>AndroidManifest.xml</code> file.
-
-{@sample frameworks/base/tests/gadgets/GadgetHostTest/AndroidManifest.xml GadgetProvider}
-
-<p>
-The <b><code>&lt;receiver&gt;</b> element has the following attributes:
-<ul>
-  <li><b><code>android:name</code> -</b> which specifies the
-        {@link android.content.BroadcastReceiver} or {@link android.gadget.GadgetProvider}
-        class.</li>
-  <li><b><code>android:label</code> -</b> which specifies the string resource that
-        will be shown by the gadget picker as the label.</li>
-  <li><b><code>android:icon</code> -</b> which specifies the drawable resource that
-        will be shown by the gadget picker as the icon.</li>
-</ul>
-
-<p>
-The <b><code>&lt;intent-filter&gt;</b> element tells the {@link android.content.pm.PackageManager}
-that this {@link android.content.BroadcastReceiver} receives the {@link
-android.gadget.GadgetManager#ACTION_GADGET_UPDATE GadgetManager.ACTION_GADGET_UPDATE} broadcast.
-The gadget manager will send other broadcasts directly to your gadget provider as required.
-It is only necessary to explicitly declare that you accept the {@link
-android.gadget.GadgetManager#ACTION_GADGET_UPDATE GadgetManager.ACTION_GADGET_UPDATE} broadcast.
-
-<p>
-The <b><code>&lt;meta-data&gt;</code></b> element tells the gadget manager which xml resource to
-read to find the {@link android.gadget.GadgetProviderInfo} for your gadget provider.  It has the following
-attributes:
-<ul>
-  <li><b><code>android:name="android.gadget.provider"</code> -</b> identifies this meta-data
-        as the {@link android.gadget.GadgetProviderInfo} descriptor.</li>
-  <li><b><code>android:resource</code> -</b> is the xml resource to use as that descriptor.</li>
-</ul>
-
-
-<h3><a name="provider_meta_data"></a>Adding the {@link android.gadget.GadgetProviderInfo GadgetProviderInfo} meta-data</h3>
-
-<p>
-For a gadget, the values in the {@link android.gadget.GadgetProviderInfo} structure are supplied
-in an XML resource.  In the example above, the xml resource is referenced with
-<code>android:resource="@xml/gadget_info"</code>.  That XML file would go in your application's
-directory at <code>res/xml/gadget_info.xml</code>.  Here is a simple example.
-
-{@sample frameworks/base/tests/gadgets/GadgetHostTest/res/xml/gadget_info.xml GadgetProviderInfo}
-
-<p>
-The attributes are as documented in the {@link android.gadget.GadgetProviderInfo GagetInfo} class.  (86400000 milliseconds means once per day)
-
-
-<h3><a name="provider_GadgetProvider"></a>Using the {@link android.gadget.GadgetProvider GadgetProvider} class</h3>
-
-<p>The GadgetProvider class is the easiest way to handle the gadget provider intent broadcasts.
-See the <code>src/com/example/android/apis/gadget/ExampleGadgetProvider.java</code>
-sample class in ApiDemos for an example.
-
-<p class="note">Keep in mind that since the the GadgetProvider is a BroadcastReceiver,
-your process is not guaranteed to keep running after the callback methods return.  See
-<a href="../../../guide/topics/fundamentals.html#broadlife">Application Fundamentals &gt;
-Broadcast Receiver Lifecycle</a> for more information.
-
-
-
-<h3><a name="provider_configuration"></a>Gadget Configuration UI</h3>
-
-<p>
-Gadget hosts have the ability to start a configuration activity when a gadget is instantiated.
-The activity should be declared as normal in AndroidManifest.xml, and it should be listed in
-the GadgetProviderInfo XML file in the <code>android:configure</code> attribute.
-
-<p>The activity you specified will be launched with the {@link
-android.gadget.GadgetManager#ACTION_GADGET_CONFIGURE} action.  See the documentation for that
-action for more info.
-
-<p>See the <code>src/com/example/android/apis/gadget/ExampleGadgetConfigure.java</code>
-sample class in ApiDemos for an example.
-
-
-
-<h3><a name="providers_broadcasts"></a>Gadget Broadcast Intents</h3>
-
-<p>{@link android.gadget.GadgetProvider} is just a convenience class.  If you would like
-to receive the gadget broadcasts directly, you can.  The four intents you need to care about are:
-<ul>
-  <li>{@link android.gadget.GadgetManager#ACTION_GADGET_UPDATE}</li>
-  <li>{@link android.gadget.GadgetManager#ACTION_GADGET_DELETED}</li>
-  <li>{@link android.gadget.GadgetManager#ACTION_GADGET_ENABLED}</li>
-  <li>{@link android.gadget.GadgetManager#ACTION_GADGET_DISABLED}</li>
-</ul>
-
-<p>By way of example, the implementation of
-{@link android.gadget.GadgetProvider#onReceive} is quite simple:</p>
-
-{@sample frameworks/base/core/java/android/gadget/GadgetProvider.java onReceive}
-
-
-<h2>Gadget Hosts</h3>
-<p>Gadget hosts are the containers in which gadgets can be placed.  Most of the look and feel
-details are left up to the gadget hosts.  For example, the home screen has one way of viewing
-gadgets, but the lock screen could also contain gadgets, and it would have a different way of
-adding, removing and otherwise managing gadgets.</p>
-<p>For more information on implementing your own gadget host, see the
-{@link android.gadget.GadgetHost GadgetHost} class.</p>
-</body>
-
diff --git a/core/java/android/inputmethodservice/ExtractButton.java b/core/java/android/inputmethodservice/ExtractButton.java
new file mode 100644
index 0000000..d6fe38d
--- /dev/null
+++ b/core/java/android/inputmethodservice/ExtractButton.java
@@ -0,0 +1,30 @@
+package android.inputmethodservice;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.widget.Button;
+
+/***
+ * Specialization of {@link Button} that ignores the window not being focused.
+ */
+class ExtractButton extends Button {
+    public ExtractButton(Context context) {
+        super(context, null);
+    }
+
+    public ExtractButton(Context context, AttributeSet attrs) {
+        super(context, attrs, com.android.internal.R.attr.buttonStyle);
+    }
+
+    public ExtractButton(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+    
+    /**
+     * Pretend like the window this view is in always has focus, so it will
+     * highlight when selected.
+     */
+    @Override public boolean hasWindowFocus() {
+        return this.isEnabled() ? true : false;
+    }
+}
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 34d5695..32270c4 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -1398,10 +1398,17 @@
             int newSelStart, int newSelEnd,
             int candidatesStart, int candidatesEnd) {
         final ExtractEditText eet = mExtractEditText;
-        if (eet != null && mExtractedText != null) {
+        if (eet != null && isFullscreenMode() && mExtractedText != null) {
             final int off = mExtractedText.startOffset;
             eet.startInternalChanges();
-            eet.setSelection(newSelStart-off, newSelEnd-off);
+            newSelStart -= off;
+            newSelEnd -= off;
+            final int len = eet.getText().length();
+            if (newSelStart < 0) newSelStart = 0;
+            else if (newSelStart > len) newSelStart = len;
+            if (newSelEnd < 0) newSelEnd = 0;
+            else if (newSelEnd > len) newSelEnd = len;
+            eet.setSelection(newSelStart, newSelEnd);
             eet.finishInternalChanges();
         }
     }
diff --git a/core/java/android/provider/Contacts.java b/core/java/android/provider/Contacts.java
index 3bffaec..d0bd2a5 100644
--- a/core/java/android/provider/Contacts.java
+++ b/core/java/android/provider/Contacts.java
@@ -1423,7 +1423,42 @@
          */
         public static final String ATTACH_IMAGE =
                 "com.android.contacts.action.ATTACH_IMAGE";
-        
+
+        /**
+         * Takes as input a data URI with a mailto: or tel: scheme. If a single
+         * contact exists with the given data it will be shown. If no contact
+         * exists, a dialog will ask the user if they want to create a new
+         * contact with the provided details filled in. If multiple contacts
+         * share the data the user will be prompted to pick which contact they
+         * want to view.
+         * <p>
+         * For <code>mailto:</code> URIs, the scheme specific portion must be a
+         * raw email address, such as one built using
+         * {@link Uri#fromParts(String, String, String)}.
+         * <p>
+         * For <code>tel:</code> URIs, the scheme specific portion is compared
+         * to existing numbers using the standard caller ID lookup algorithm.
+         * The number must be properly encoded, for example using
+         * {@link Uri#fromParts(String, String, String)}.
+         * <p>
+         * Any extras from the {@link Insert} class will be passed along to the
+         * create activity if there are no contacts to show.
+         * <p>
+         * Passing true for the {@link #EXTRA_FORCE_CREATE} extra will skip
+         * prompting the user when the contact doesn't exist.
+         */
+        public static final String SHOW_OR_CREATE_CONTACT =
+                "com.android.contacts.action.SHOW_OR_CREATE_CONTACT";
+
+        /**
+         * Used with {@link #SHOW_OR_CREATE_CONTACT} to force creating a new contact if no matching
+         * contact found.  Otherwise, default behavior is to prompt user with dialog before creating.
+         *
+         * <P>Type: BOOLEAN</P>
+         */
+        public static final String EXTRA_FORCE_CREATE =
+                "com.android.contacts.action.FORCE_CREATE";
+
         /**
          * Intents related to the Contacts app UI.
          */
diff --git a/core/java/android/provider/Gmail.java b/core/java/android/provider/Gmail.java
index 5b3c223..cc03968 100644
--- a/core/java/android/provider/Gmail.java
+++ b/core/java/android/provider/Gmail.java
@@ -1540,7 +1540,15 @@
 
         /** Returns the number of unread conversation with a given label. */
         public int getNumUnreadConversations(long labelId) {
-            return getLabelIdValues(labelId).getAsInteger(LabelColumns.NUM_UNREAD_CONVERSATIONS);
+            Integer unreadConversations =
+                    getLabelIdValues(labelId).getAsInteger(LabelColumns.NUM_UNREAD_CONVERSATIONS);
+            // There seems to be a race condition here that can get the label maps into a bad
+            // state and lose state on a particular label.
+            if (unreadConversations == null) {
+                return 0;
+            } else {
+                return unreadConversations;
+            }
         }
 
         /**
diff --git a/core/java/android/server/BluetoothA2dpService.java b/core/java/android/server/BluetoothA2dpService.java
index f8bc765..3aa4078 100644
--- a/core/java/android/server/BluetoothA2dpService.java
+++ b/core/java/android/server/BluetoothA2dpService.java
@@ -208,6 +208,15 @@
         if (mAudioDevices == null) {
             return BluetoothError.ERROR;
         }
+        // ignore if there are any active sinks
+        if (lookupSinksMatchingStates(new int[] {
+                BluetoothA2dp.STATE_CONNECTING,
+                BluetoothA2dp.STATE_CONNECTED,
+                BluetoothA2dp.STATE_PLAYING,
+                BluetoothA2dp.STATE_DISCONNECTING}).size() != 0) {
+            return BluetoothError.ERROR;
+        }
+
         String path = lookupPath(address);
         if (path == null) {
             path = createHeadsetNative(address);
diff --git a/core/java/android/server/BluetoothDeviceService.java b/core/java/android/server/BluetoothDeviceService.java
index 6f5513a..e271909 100644
--- a/core/java/android/server/BluetoothDeviceService.java
+++ b/core/java/android/server/BluetoothDeviceService.java
@@ -287,6 +287,7 @@
             } else {
                 intent = new Intent(BluetoothIntent.DISABLED_ACTION);
             }
+            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
             mContext.sendBroadcast(intent, BLUETOOTH_PERM);
 
             mEnableThread = null;
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index e4ebcca..8e77eed 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -52,6 +52,7 @@
     private Context mContext;
 
     private static final int EVENT_AUTO_PAIRING_FAILURE_ATTEMPT_DELAY = 1;
+    private static final int EVENT_RESTART_BLUETOOTH = 2;
 
     // The time (in millisecs) to delay the pairing attempt after the first
     // auto pairing attempt fails. We use an exponential delay with
@@ -74,6 +75,10 @@
                     return;
                 }
                 break;
+            case EVENT_RESTART_BLUETOOTH:
+                mBluetoothService.disable();
+                mBluetoothService.enable(null);
+                break;
             }
         }
     };
@@ -372,6 +377,13 @@
         }
     }
 
+    private void onRestartRequired() {
+        if (mBluetoothService.isEnabled()) {
+            Log.e(TAG, "*** A serious error occured (did hcid crash?) - restarting Bluetooth ***");
+            mHandler.sendEmptyMessage(EVENT_RESTART_BLUETOOTH);
+        }
+    }
+
     private static void log(String msg) {
         Log.d(TAG, msg);
     }
diff --git a/core/java/android/text/method/QwertyKeyListener.java b/core/java/android/text/method/QwertyKeyListener.java
index 3f8288c..21bc2a6 100644
--- a/core/java/android/text/method/QwertyKeyListener.java
+++ b/core/java/android/text/method/QwertyKeyListener.java
@@ -298,8 +298,10 @@
                 content.removeSpan(repl[0]);
 
                 // only cancel the autocomplete if the cursor is at the end of
-                // the replaced span
-                if (selStart == en) {
+                // the replaced span (or after it, because the user is
+                // backspacing over the space after the word, not the word
+                // itself).
+                if (selStart >= en) {
                     content.setSpan(TextKeyListener.INHIBIT_REPLACEMENT,
                                     en, en, Spannable.SPAN_POINT_POINT);
                     content.replace(st, en, old);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index d78320a..c3e00c4 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1511,8 +1511,14 @@
     @ViewDebug.ExportedProperty
     int mUserPaddingBottom;
 
-    private int mOldWidthMeasureSpec = Integer.MIN_VALUE;
-    private int mOldHeightMeasureSpec = Integer.MIN_VALUE;
+    /**
+     * @hide
+     */
+    int mOldWidthMeasureSpec = Integer.MIN_VALUE;
+    /**
+     * @hide
+     */
+    int mOldHeightMeasureSpec = Integer.MIN_VALUE;
 
     private Resources mResources = null;
 
@@ -2661,9 +2667,9 @@
      * @attr ref android.R.styleable#View_visibility
      */
     @ViewDebug.ExportedProperty(mapping = {
-        @ViewDebug.IntToString(from = 0, to = "VISIBLE"),
-        @ViewDebug.IntToString(from = 4, to = "INVISIBLE"),
-        @ViewDebug.IntToString(from = 8, to = "GONE")
+        @ViewDebug.IntToString(from = VISIBLE,   to = "VISIBLE"),
+        @ViewDebug.IntToString(from = INVISIBLE, to = "INVISIBLE"),
+        @ViewDebug.IntToString(from = GONE,      to = "GONE")
     })
     public int getVisibility() {
         return mViewFlags & VISIBILITY_MASK;
@@ -3291,8 +3297,7 @@
      * when ViewDebug.SYSTEM_PROPERTY_CAPTURE_VIEW) is set
      */
     private static void captureViewInfo(String subTag, View v) {
-        if (v == null ||
-           SystemProperties.getInt(ViewDebug.SYSTEM_PROPERTY_CAPTURE_VIEW, 0) == 0) {
+        if (v == null || SystemProperties.getInt(ViewDebug.SYSTEM_PROPERTY_CAPTURE_VIEW, 0) == 0) {
             return;
         }
         ViewDebug.dumpCapturedView(subTag, v);
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index 883c7bd..0a043bd 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -17,9 +17,12 @@
 package android.view;
 
 import android.util.Log;
+import android.util.DisplayMetrics;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
+import android.graphics.Canvas;
 import android.os.Environment;
+import android.os.Debug;
 
 import java.io.File;
 import java.io.BufferedWriter;
@@ -43,6 +46,7 @@
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.AccessibleObject;
 
 /**
  * Various debugging/tracing tools related to {@link View} and the view hierarchy.
@@ -73,7 +77,7 @@
      * when it is set, we log key events, touch/motion and trackball events
      */    
     static final String SYSTEM_PROPERTY_CAPTURE_EVENT = "debug.captureevent";
-    
+
     /**
      * This annotation can be used to mark fields and methods to be dumped by
      * the view server. Only non-void methods with no arguments can be annotated
@@ -113,6 +117,27 @@
         IntToString[] mapping() default { };
 
         /**
+         * A mapping can be defined to map array indices to specific strings.
+         * A mapping can be used to see human readable values for the indices
+         * of an array:
+         *
+         * <pre>
+         * @ViewDebug.ExportedProperty(mapping = {
+         *     @ViewDebug.IntToString(from = 0, to = "INVALID"),
+         *     @ViewDebug.IntToString(from = 1, to = "FIRST"),
+         *     @ViewDebug.IntToString(from = 2, to = "SECOND")
+         * })
+         * private int[] mElements;
+         * <pre>
+         *
+         * @return An array of int to String mappings
+         *
+         * @see android.view.ViewDebug.IntToString
+         * @see #mapping()
+         */
+        IntToString[] indexMapping() default { };
+
+        /**
          * When deep export is turned on, this property is not dumped. Instead, the
          * properties contained in this property are dumped. Each child property
          * is prefixed with the name of this property.
@@ -187,10 +212,12 @@
     private static final String REMOTE_COMMAND_DUMP = "DUMP";
     private static final String REMOTE_COMMAND_INVALIDATE = "INVALIDATE";
     private static final String REMOTE_COMMAND_REQUEST_LAYOUT = "REQUEST_LAYOUT";
+    private static final String REMOTE_PROFILE = "PROFILE";
 
     private static HashMap<Class<?>, Field[]> sFieldsForClasses;
     private static HashMap<Class<?>, Method[]> sMethodsForClasses;
-        
+    private static HashMap<AccessibleObject, ExportedProperty> sAnnotations;
+
     /**
      * Defines the type of hierarhcy trace to output to the hierarchy traces file.
      */
@@ -347,6 +374,7 @@
         }
 
         File recyclerDump = new File(Environment.getExternalStorageDirectory(), "view-recycler/");
+        //noinspection ResultOfMethodCallIgnored
         recyclerDump.mkdirs();
 
         recyclerDump = new File(recyclerDump, sRecyclerTracePrefix + ".recycler");
@@ -450,6 +478,7 @@
         }
 
         File hierarchyDump = new File(Environment.getExternalStorageDirectory(), "view-hierarchy/");
+        //noinspection ResultOfMethodCallIgnored
         hierarchyDump.mkdirs();
 
         hierarchyDump = new File(hierarchyDump, prefix + ".traces");
@@ -497,6 +526,7 @@
         sHierarchyTraces = null;
 
         File hierarchyDump = new File(Environment.getExternalStorageDirectory(), "view-hierarchy/");
+        //noinspection ResultOfMethodCallIgnored
         hierarchyDump.mkdirs();
         hierarchyDump = new File(hierarchyDump, sHierarchyTracePrefix + ".tree");
 
@@ -538,32 +568,41 @@
                 invalidate(view, params[0]);
             } else if (REMOTE_COMMAND_REQUEST_LAYOUT.equalsIgnoreCase(command)) {
                 requestLayout(view, params[0]);
+            } else if (REMOTE_PROFILE.equalsIgnoreCase(command)) {
+                profile(view, clientStream, params[0]);
             }
         }
     }
 
-    private static View findViewByHashCode(View root, String parameter) {
-        final String[] ids = parameter.split("@");
-        final String className = ids[0];
-        final int hashCode = Integer.parseInt(ids[1], 16);
+    private static View findView(View root, String parameter) {
+        // Look by type/hashcode
+        if (parameter.indexOf('@') != -1) {
+            final String[] ids = parameter.split("@");
+            final String className = ids[0];
+            final int hashCode = Integer.parseInt(ids[1], 16);
 
-        View view = root.getRootView();
-        if (view instanceof ViewGroup) {
-            return findView((ViewGroup) view, className, hashCode);
+            View view = root.getRootView();
+            if (view instanceof ViewGroup) {
+                return findView((ViewGroup) view, className, hashCode);
+            }
+        } else {
+            // Look by id
+            final int id = root.getResources().getIdentifier(parameter, null, null);
+            return root.getRootView().findViewById(id);
         }
 
         return null;
     }
 
     private static void invalidate(View root, String parameter) {
-        final View view = findViewByHashCode(root, parameter);
+        final View view = findView(root, parameter);
         if (view != null) {
             view.postInvalidate();
         }
     }
 
     private static void requestLayout(View root, String parameter) {
-        final View view = findViewByHashCode(root, parameter);
+        final View view = findView(root, parameter);
         if (view != null) {
             root.post(new Runnable() {
                 public void run() {
@@ -573,19 +612,139 @@
         }
     }
 
+    private static void profile(View root, OutputStream clientStream, String parameter)
+            throws IOException {
+
+        final View view = findView(root, parameter);
+        BufferedWriter out = null;
+        try {
+            out = new BufferedWriter(new OutputStreamWriter(clientStream), 32 * 1024);
+
+            if (view != null) {
+                final long durationMeasure = profileViewOperation(view, new ViewOperation<Void>() {
+                    public Void[] pre() {
+                        forceLayout(view);
+                        return null;
+                    }
+
+                    private void forceLayout(View view) {
+                        view.forceLayout();
+                        if (view instanceof ViewGroup) {
+                            ViewGroup group = (ViewGroup) view;
+                            final int count = group.getChildCount();
+                            for (int i = 0; i < count; i++) {
+                                forceLayout(group.getChildAt(i));
+                            }
+                        }
+                    }
+
+                    public void run(Void... data) {
+                        view.measure(view.mOldWidthMeasureSpec, view.mOldHeightMeasureSpec);
+                    }
+
+                    public void post(Void... data) {
+                    }
+                });
+
+                final long durationLayout = profileViewOperation(view, new ViewOperation<Void>() {
+                    public Void[] pre() {
+                        return null;
+                    }
+
+                    public void run(Void... data) {
+                        view.layout(view.mLeft, view.mTop, view.mRight, view.mBottom);
+                    }
+
+                    public void post(Void... data) {
+                    }
+                });
+
+                final long durationDraw = profileViewOperation(view, new ViewOperation<Object>() {
+                    public Object[] pre() {
+                        final DisplayMetrics metrics = view.getResources().getDisplayMetrics();
+                        final Bitmap bitmap = Bitmap.createBitmap(metrics.widthPixels,
+                                metrics.heightPixels, Bitmap.Config.ARGB_8888);
+                        final Canvas canvas = new Canvas(bitmap);
+                        return new Object[] { bitmap, canvas };
+                    }
+
+                    public void run(Object... data) {
+                        view.draw((Canvas) data[1]);
+                    }
+
+                    public void post(Object... data) {
+                        ((Bitmap) data[0]).recycle();
+                    }
+                });
+
+                out.write(String.valueOf(durationMeasure));
+                out.write(' ');
+                out.write(String.valueOf(durationLayout));
+                out.write(' ');
+                out.write(String.valueOf(durationDraw));
+                out.newLine();
+            } else {
+                out.write("-1 -1 -1");
+                out.newLine();
+            }
+        } catch (Exception e) {
+            android.util.Log.w("View", "Problem profiling the view:", e);
+        } finally {
+            if (out != null) {
+                out.close();
+            }
+        }
+    }
+
+    interface ViewOperation<T> {
+        T[] pre();
+        void run(T... data);
+        void post(T... data);
+    }
+
+    private static <T> long profileViewOperation(View view, final ViewOperation<T> operation) {
+        final CountDownLatch latch = new CountDownLatch(1);
+        final long[] duration = new long[1];
+
+        view.post(new Runnable() {
+            public void run() {
+                try {
+                    T[] data = operation.pre();
+                    long start = Debug.threadCpuTimeNanos();
+                    operation.run(data);
+                    duration[0] = Debug.threadCpuTimeNanos() - start;
+                    operation.post(data);
+                } finally {
+                    latch.countDown();
+                }
+            }
+        });
+
+        try {
+            latch.await(CAPTURE_TIMEOUT, TimeUnit.MILLISECONDS);
+        } catch (InterruptedException e) {
+            Log.w("View", "Could not complete the profiling of the view " + view);
+            Thread.currentThread().interrupt();
+            return -1;
+        }
+
+        return duration[0];
+    }
+
     private static void capture(View root, final OutputStream clientStream, String parameter)
             throws IOException {
 
-        final CountDownLatch latch = new CountDownLatch(1);
-        final View captureView = findViewByHashCode(root, parameter);
+        final View captureView = findView(root, parameter);
 
         if (captureView != null) {
+            final CountDownLatch latch = new CountDownLatch(1);
             final Bitmap[] cache = new Bitmap[1];
 
             final boolean hasCache = captureView.isDrawingCacheEnabled();
             final boolean willNotCache = captureView.willNotCacheDrawing();
 
             if (willNotCache) {
+                // TODO: Should happen on the UI thread
                 captureView.setWillNotCacheDrawing(false);
             }
 
@@ -619,12 +778,15 @@
                     }
                 }
             } catch (InterruptedException e) {
-                Log.w("View", "Could not complete the capture of the view " + captureView);                
+                Log.w("View", "Could not complete the capture of the view " + captureView);
+                Thread.currentThread().interrupt();
             } finally {
                 if (willNotCache) {
+                    // TODO: Should happen on the UI thread
                     captureView.setWillNotCacheDrawing(true);
                 }
                 if (!hasCache) {
+                    // TODO: Should happen on the UI thread                    
                     captureView.destroyDrawingCache();
                 }
             }
@@ -642,6 +804,8 @@
             }
             out.write("DONE.");
             out.newLine();
+        } catch (Exception e) {
+            android.util.Log.w("View", "Problem dumping the view:", e);
         } finally {
             if (out != null) {
                 out.close();
@@ -713,7 +877,12 @@
         if (sFieldsForClasses == null) {
             sFieldsForClasses = new HashMap<Class<?>, Field[]>();
         }
+        if (sAnnotations == null) {
+            sAnnotations = new HashMap<AccessibleObject, ExportedProperty>(512);
+        }
+
         final HashMap<Class<?>, Field[]> map = sFieldsForClasses;
+        final HashMap<AccessibleObject, ExportedProperty> annotations = sAnnotations;
 
         Field[] fields = map.get(klass);
         if (fields != null) {
@@ -729,6 +898,7 @@
             if (field.isAnnotationPresent(ExportedProperty.class)) {
                 field.setAccessible(true);
                 foundFields.add(field);
+                annotations.put(field, field.getAnnotation(ExportedProperty.class));
             }
         }
 
@@ -740,9 +910,14 @@
 
     private static Method[] getExportedPropertyMethods(Class<?> klass) {
         if (sMethodsForClasses == null) {
-            sMethodsForClasses = new HashMap<Class<?>, Method[]>();
+            sMethodsForClasses = new HashMap<Class<?>, Method[]>(100);
         }
+        if (sAnnotations == null) {
+            sAnnotations = new HashMap<AccessibleObject, ExportedProperty>(512);
+        }
+
         final HashMap<Class<?>, Method[]> map = sMethodsForClasses;
+        final HashMap<AccessibleObject, ExportedProperty> annotations = sAnnotations;
 
         Method[] methods = map.get(klass);
         if (methods != null) {
@@ -756,10 +931,11 @@
         for (int i = 0; i < count; i++) {
             final Method method = methods[i];            
             if (method.getParameterTypes().length == 0 &&
-                        method.isAnnotationPresent(ExportedProperty.class) &&
-                        method.getReturnType() != Void.class) {
+                    method.isAnnotationPresent(ExportedProperty.class) &&
+                    method.getReturnType() != Void.class) {
                 method.setAccessible(true);
                 foundMethods.add(method);
+                annotations.put(method, method.getAnnotation(ExportedProperty.class));
             }
         }
 
@@ -799,20 +975,10 @@
                 final Class<?> returnType = method.getReturnType();
 
                 if (returnType == int.class) {
-                    ExportedProperty property = method.getAnnotation(ExportedProperty.class);
+                    final ExportedProperty property = sAnnotations.get(method);
                     if (property.resolveId() && view instanceof View) {
-                        final Resources resources = ((View) view).getContext().getResources();
                         final int id = (Integer) methodValue;
-                        if (id >= 0) {
-                            try {
-                                methodValue = resources.getResourceTypeName(id) + '/' +
-                                        resources.getResourceEntryName(id);
-                            } catch (Resources.NotFoundException e) {
-                                methodValue = "UNKNOWN";
-                            }
-                        } else {
-                            methodValue = "NO_ID";
-                        }
+                        methodValue = resolveId(view, id);
                     } else {
                         final IntToString[] mapping = property.mapping();
                         if (mapping.length > 0) {
@@ -833,28 +999,22 @@
                             }
                         }
                     }
+                } else if (returnType == int[].class) {
+                    final ExportedProperty property = sAnnotations.get(method);
+                    final int[] array = (int[]) methodValue;
+                    final String valuePrefix = prefix + method.getName() + '_';
+                    final String suffix = "()";
+
+                    exportUnrolledArray(view, out, property, array, valuePrefix, suffix);
                 } else if (!returnType.isPrimitive()) {
-                    ExportedProperty property = method.getAnnotation(ExportedProperty.class);
+                    final ExportedProperty property = sAnnotations.get(method);
                     if (property.deepExport()) {
                         dumpViewProperties(methodValue, out, prefix + property.prefix());
                         continue;
                     }
                 }
 
-                out.write(prefix);
-                out.write(method.getName());
-                out.write("()=");
-
-                if (methodValue != null) {
-                    final String value = methodValue.toString().replace("\n", "\\n");
-                    out.write(String.valueOf(value.length()));
-                    out.write(",");
-                    out.write(value);
-                } else {
-                    out.write("4,null");
-                }
-
-                out.write(' ');
+                writeEntry(out, prefix, method.getName(), "()", methodValue);
             } catch (IllegalAccessException e) {
             } catch (InvocationTargetException e) {
             }
@@ -875,20 +1035,10 @@
                 final Class<?> type = field.getType();
 
                 if (type == int.class) {
-                    ExportedProperty property = field.getAnnotation(ExportedProperty.class);
+                    final ExportedProperty property = sAnnotations.get(field);
                     if (property.resolveId() && view instanceof View) {
-                        final Resources resources = ((View) view).getContext().getResources();
                         final int id = field.getInt(view);
-                        if (id >= 0) {
-                            try {
-                                fieldValue = resources.getResourceTypeName(id) + '/' +
-                                        resources.getResourceEntryName(id);
-                            } catch (Resources.NotFoundException e) {
-                                fieldValue = "UNKNOWN";
-                            }
-                        } else {
-                            fieldValue = "NO_ID";
-                        }
+                        fieldValue = resolveId(view, id);
                     } else {
                         final IntToString[] mapping = property.mapping();
                         if (mapping.length > 0) {
@@ -907,8 +1057,18 @@
                             }
                         }
                     }
+                } else if (type == int[].class) {
+                    final ExportedProperty property = sAnnotations.get(field);
+                    final int[] array = (int[]) field.get(view);
+                    final String valuePrefix = prefix + field.getName() + '_';
+                    final String suffix = "";
+
+                    exportUnrolledArray(view, out, property, array, valuePrefix, suffix);
+
+                    // We exit here!
+                    return;
                 } else if (!type.isPrimitive()) {
-                    ExportedProperty property = field.getAnnotation(ExportedProperty.class);
+                    final ExportedProperty property = sAnnotations.get(field);
                     if (property.deepExport()) {
                         dumpViewProperties(field.get(view), out, prefix + property.prefix());
                         continue;
@@ -917,27 +1077,103 @@
 
                 if (fieldValue == null) {
                     fieldValue = field.get(view);
-                }                
-
-                out.write(prefix);
-                out.write(field.getName());
-                out.write('=');
-
-                if (fieldValue != null) {
-                    final String value = fieldValue.toString().replace("\n", "\\n");
-                    out.write(String.valueOf(value.length()));
-                    out.write(",");
-                    out.write(value);
-                } else {
-                    out.write("4,null");
                 }
 
-                out.write(' ');
+                writeEntry(out, prefix, field.getName(), "", fieldValue);
             } catch (IllegalAccessException e) {
             }
         }
     }
 
+    private static void writeEntry(BufferedWriter out, String prefix, String name,
+            String suffix, Object value) throws IOException {
+
+        out.write(prefix);
+        out.write(name);
+        out.write(suffix);
+        out.write("=");
+        writeValue(out, value);
+        out.write(' ');
+    }
+
+    private static void exportUnrolledArray(Object view, BufferedWriter out,
+            ExportedProperty property, int[] array, String prefix, String suffix)
+            throws IOException {
+
+        final IntToString[] indexMapping = property.indexMapping();
+        final boolean hasIndexMapping = indexMapping.length > 0;
+
+        final IntToString[] mapping = property.mapping();
+        final boolean hasMapping = mapping.length > 0;
+
+        final boolean resolveId = property.resolveId() && view instanceof View;
+        final int valuesCount = array.length;
+
+        for (int j = 0; j < valuesCount; j++) {
+            String name;
+            String value;
+
+            final int intValue = array[j];
+
+            name = String.valueOf(j);
+            if (hasIndexMapping) {
+                int mappingCount = indexMapping.length;
+                for (int k = 0; k < mappingCount; k++) {
+                    final IntToString mapped = indexMapping[k];
+                    if (mapped.from() == j) {
+                        name = mapped.to();
+                        break;
+                    }
+                }
+            }
+
+            value = String.valueOf(intValue);
+            if (hasMapping) {
+                int mappingCount = mapping.length;
+                for (int k = 0; k < mappingCount; k++) {
+                    final IntToString mapped = mapping[k];
+                    if (mapped.from() == intValue) {
+                        value = mapped.to();
+                        break;
+                    }
+                }
+            }
+
+            if (resolveId) {
+                value = (String) resolveId(view, intValue);
+            }
+
+            writeEntry(out, prefix, name, suffix, value);
+        }
+    }
+
+    private static Object resolveId(Object view, int id) {
+        Object fieldValue;
+        final Resources resources = ((View) view).getContext().getResources();
+        if (id >= 0) {
+            try {
+                fieldValue = resources.getResourceTypeName(id) + '/' +
+                        resources.getResourceEntryName(id);
+            } catch (Resources.NotFoundException e) {
+                fieldValue = "id/0x" + Integer.toHexString(id);
+            }
+        } else {
+            fieldValue = "NO_ID";
+        }
+        return fieldValue;
+    }
+
+    private static void writeValue(BufferedWriter out, Object value) throws IOException {
+        if (value != null) {
+            String output = value.toString().replace("\n", "\\n");
+            out.write(String.valueOf(output.length()));
+            out.write(",");
+            out.write(output);
+        } else {
+            out.write("4,null");
+        }
+    }
+
     private static void dumpViewHierarchy(ViewGroup group, BufferedWriter out, int level) {
         if (!dumpView(group, out, level)) {
             return;
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 0f15b17..220869c 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -54,7 +54,7 @@
  * window manager is a very low-level system service, there are few other
  * system services you can call with this lock held.  It is explicitly okay to
  * make calls into the package manager and power manager; it is explicitly not
- * okay to make calls into the activity manager.  Note that
+ * okay to make calls into the activity manager or most other services.  Note that
  * {@link android.content.Context#checkPermission(String, int, int)} and
  * variations require calling into the activity manager.
  * <dt> Li <dd> Called with the input thread lock held.  This lock can be
@@ -748,7 +748,7 @@
      * ActivityInfo.SCREEN_ORIENTATION_PORTRAIT}), return a surface
      * rotation.
      */
-    public int rotationForOrientation(int orientation, int lastRotation,
+    public int rotationForOrientationLw(int orientation, int lastRotation,
             boolean displayEnabled);
     
     /**
@@ -781,16 +781,16 @@
      */
     public boolean isCheekPressedAgainstScreen(MotionEvent ev);
     
-    public void setCurrentOrientation(int newOrientation);
+    public void setCurrentOrientationLw(int newOrientation);
     
     /**
      * Call from application to perform haptic feedback on its window.
      */
-    public boolean performHapticFeedback(WindowState win, int effectId, boolean always);
+    public boolean performHapticFeedbackLw(WindowState win, int effectId, boolean always);
     
     /**
      * Called when we have stopped keeping the screen on because a window
      * requesting this is no longer visible.
      */
-    public void screenOnStopped();
+    public void screenOnStoppedLw();
 }
diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java
index 4e98591..b4c5b72 100644
--- a/core/java/android/view/inputmethod/InputMethodInfo.java
+++ b/core/java/android/view/inputmethod/InputMethodInfo.java
@@ -174,6 +174,14 @@
     }
 
     /**
+     * Return the raw information about the Service implementing this
+     * input method.  Do not modify the returned object.
+     */
+    public ServiceInfo getServiceInfo() {
+        return mService.serviceInfo;
+    }
+
+    /**
      * Return the component of the service that implements this input
      * method.
      */
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 7f2142e..4de9eef 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -921,6 +921,7 @@
                     startInputInner();
                 }
             });
+            return;
         }
         
         // Okay we are now ready to call into the served view and have it
diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java
index 8d4b220..f9fb0b0 100644
--- a/core/java/android/webkit/LoadListener.java
+++ b/core/java/android/webkit/LoadListener.java
@@ -376,6 +376,11 @@
                 }
             }
         }
+
+        // if there is buffered data, commit them in the end
+        boolean needToCommit = mAuthHeader != null && !mustAuthenticate
+                && mNativeLoader != 0 && !mDataBuilder.isEmpty();
+
         // it is only here that we can reset the last mAuthHeader object
         // (if existed) and start a new one!!!
         mAuthHeader = null;
@@ -410,6 +415,10 @@
             }
         }
         commitHeadersCheckRedirect();
+
+        if (needToCommit) {
+            commitLoad();
+        }
     }
 
     /**
diff --git a/core/java/android/webkit/TextDialog.java b/core/java/android/webkit/TextDialog.java
index efc131f..9de97c9 100644
--- a/core/java/android/webkit/TextDialog.java
+++ b/core/java/android/webkit/TextDialog.java
@@ -540,7 +540,9 @@
     public void setSingleLine(boolean single) {
         int inputType = EditorInfo.TYPE_CLASS_TEXT;
         if (!single) {
-            inputType |= EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE;
+            inputType |= EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE
+                    | EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES
+                    | EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT;
         }
         mSingle = single;
         setHorizontallyScrolling(single);
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 4e2b2ab..65544d4 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -134,7 +134,7 @@
     private int             mDefaultFixedFontSize = 13;
     private boolean         mLoadsImagesAutomatically = true;
     private boolean         mBlockNetworkImage = false;
-    private boolean         mBlockNetworkLoads = false;
+    private boolean         mBlockNetworkLoads;
     private boolean         mJavaScriptEnabled = false;
     private boolean         mPluginsEnabled = false;
     private boolean         mJavaScriptCanOpenWindowsAutomatically = false;
@@ -248,7 +248,9 @@
         mUserAgent = getCurrentUserAgent();
         mUseDefaultUserAgent = true;
 
-        verifyNetworkAccess();
+        mBlockNetworkLoads = mContext.checkPermission(
+                "android.permission.INTERNET", android.os.Process.myPid(),
+                android.os.Process.myUid()) != PackageManager.PERMISSION_GRANTED;
     }
 
     /**
@@ -835,7 +837,7 @@
     private void verifyNetworkAccess() {
         if (!mBlockNetworkLoads) {
             if (mContext.checkPermission("android.permission.INTERNET", 
-                    android.os.Process.myPid(), 0) != 
+                    android.os.Process.myPid(), android.os.Process.myUid()) != 
                         PackageManager.PERMISSION_GRANTED) {
                 throw new SecurityException
                         ("Permission denied - " +
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index dc39b90..f61ce40 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -21,7 +21,6 @@
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.DialogInterface.OnCancelListener;
-import android.content.res.TypedArray;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -46,9 +45,6 @@
 import android.util.Config;
 import android.util.EventLog;
 import android.util.Log;
-import android.view.animation.AlphaAnimation;
-import android.view.animation.Animation;
-import android.view.animation.AnimationUtils;
 import android.view.Gravity;
 import android.view.KeyEvent;
 import android.view.LayoutInflater;
@@ -68,12 +64,9 @@
 import android.widget.ArrayAdapter;
 import android.widget.ImageView;
 import android.widget.ListView;
-import android.widget.RelativeLayout;
 import android.widget.Scroller;
 import android.widget.Toast;
 import android.widget.ZoomButtonsController;
-import android.widget.ZoomControls;
-import android.widget.FrameLayout;
 import android.widget.AdapterView.OnItemClickListener;
 
 import java.io.File;
@@ -113,57 +106,6 @@
     static final boolean DEBUG = false;
     static final boolean LOGV_ENABLED = DEBUG ? Config.LOGD : Config.LOGV;
 
-    private class ExtendedZoomControls extends FrameLayout {
-        public ExtendedZoomControls(Context context, AttributeSet attrs) {
-            super(context, attrs);
-            LayoutInflater inflater = (LayoutInflater)
-                    context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-            inflater.inflate(com.android.internal.R.layout.zoom_magnify, this, true);
-            mZoomControls = (ZoomControls) findViewById(com.android.internal.R.id.zoomControls);
-            mZoomMagnify = (ImageView) findViewById(com.android.internal.R.id.zoomMagnify);
-        }
-        
-        public void show(boolean showZoom, boolean canZoomOut) {
-            mZoomControls.setVisibility(showZoom ? View.VISIBLE : View.GONE);
-            mZoomMagnify.setVisibility(canZoomOut ? View.VISIBLE : View.GONE);
-            fade(View.VISIBLE, 0.0f, 1.0f);
-        }
-        
-        public void hide() {
-            fade(View.GONE, 1.0f, 0.0f);
-        }
-        
-        private void fade(int visibility, float startAlpha, float endAlpha) {
-            AlphaAnimation anim = new AlphaAnimation(startAlpha, endAlpha);
-            anim.setDuration(500);
-            startAnimation(anim);
-            setVisibility(visibility);
-        }
-        
-        public void setIsZoomMagnifyEnabled(boolean isEnabled) {
-            mZoomMagnify.setEnabled(isEnabled);
-        }
-        
-        public boolean hasFocus() {
-            return mZoomControls.hasFocus() || mZoomMagnify.hasFocus();
-        }
-        
-        public void setOnZoomInClickListener(OnClickListener listener) {
-            mZoomControls.setOnZoomInClickListener(listener);
-        }
-            
-        public void setOnZoomOutClickListener(OnClickListener listener) {
-            mZoomControls.setOnZoomOutClickListener(listener);
-        }
-            
-        public void setOnZoomMagnifyClickListener(OnClickListener listener) {
-            mZoomMagnify.setOnClickListener(listener);
-        }
-
-        ZoomControls mZoomControls;
-        ImageView mZoomMagnify;
-    }
-    
     /**
      *  Transportation object for returning WebView across thread boundaries.
      */
@@ -281,8 +223,10 @@
      */
     // pre-computed square of ViewConfiguration.getScaledTouchSlop()
     private int mTouchSlopSquare;
-    // pre-computed square of ViewConfiguration.getScaledDoubleTapSlop()
+    // pre-computed square of the density adjusted double tap slop
     private int mDoubleTapSlopSquare;
+    // pre-computed density adjusted navigation slop
+    private int mNavSlop;
     // This should be ViewConfiguration.getTapTimeout()
     // But system time out is 100ms, which is too short for the browser.
     // In the browser, if it switches out of tap too soon, jump tap won't work.
@@ -295,9 +239,6 @@
     private static final int LONG_PRESS_TIMEOUT = 1000;
     // needed to avoid flinging after a pause of no movement
     private static final int MIN_FLING_TIME = 250;
-    // The time that the Zoom Controls are visible before fading away
-    private static final long ZOOM_CONTROLS_TIMEOUT = 
-            ViewConfiguration.getZoomControlsTimeout();
     // The amount of content to overlap between two screens when going through
     // pages with the space bar, in pixels.
     private static final int PAGE_SCROLL_OVERLAP = 24;
@@ -337,10 +278,6 @@
 
     private boolean mWrapContent;
 
-    // The View containing the zoom controls
-    private ExtendedZoomControls mZoomControls;
-    private Runnable mZoomControlRunnable;
-
     // true if we should call webcore to draw the content, false means we have
     // requested something but it isn't ready to draw yet.
     private WebViewCore.FocusData mFocusData;
@@ -550,6 +487,7 @@
 
     private ZoomButtonsController mZoomButtonsController; 
     private ImageView mZoomOverviewButton;
+    private ImageView mZoomFitPageButton;
 
     // These keep track of the center point of the zoom.  They are used to
     // determine the point around which we should zoom.
@@ -564,28 +502,13 @@
             // in this callback
         }
 
-        public void onOverview() {
-            mZoomButtonsController.setVisible(false);
-            zoomScrollOut();
-            if (mLogEvent) {
-                Checkin.updateStats(mContext.getContentResolver(),
-                        Checkin.Stats.Tag.BROWSER_ZOOM_OVERVIEW, 1, 0.0);
-            }
-        }
-
         public void onVisibilityChanged(boolean visible) {
             if (visible) {
                 switchOutDrawHistory();
-                mZoomButtonsController.setOverviewVisible(true);
-                updateButtonsEnabled();
+                updateZoomButtonsEnabled();
             }
         }
 
-        private void updateButtonsEnabled() {
-            mZoomButtonsController.setZoomInEnabled(mActualScale < mMaxZoomScale);
-            mZoomButtonsController.setZoomOutEnabled(mActualScale > mMinZoomScale);
-        }
-
         public void onZoom(boolean zoomIn) {
             if (zoomIn) {
                 zoomIn();
@@ -593,7 +516,7 @@
                 zoomOut();
             }
             
-            updateButtonsEnabled();
+            updateZoomButtonsEnabled();
         }
     };
     
@@ -633,8 +556,49 @@
         mFocusData.mX = 0;
         mFocusData.mY = 0;
         mScroller = new Scroller(context);
+
+        initZoomController(context);
+    }
+
+    private void initZoomController(Context context) {
+        // Create the buttons controller
         mZoomButtonsController = new ZoomButtonsController(context, this);
         mZoomButtonsController.setCallback(mZoomListener);
+
+        // Create the accessory buttons
+        LayoutInflater inflater =
+                (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+        ViewGroup container = mZoomButtonsController.getContainer();
+        inflater.inflate(com.android.internal.R.layout.zoom_browser_accessory_buttons, container);
+        mZoomOverviewButton =
+                (ImageView) container.findViewById(com.android.internal.R.id.zoom_page_overview);
+        mZoomOverviewButton.setOnClickListener(
+            new View.OnClickListener() {
+                public void onClick(View v) {
+                    mZoomButtonsController.setVisible(false);
+                    zoomScrollOut();
+                    if (mLogEvent) {
+                        Checkin.updateStats(mContext.getContentResolver(),
+                                Checkin.Stats.Tag.BROWSER_ZOOM_OVERVIEW, 1, 0.0);
+                    }
+                }
+            });
+        mZoomFitPageButton =
+                (ImageView) container.findViewById(com.android.internal.R.id.zoom_fit_page);
+        mZoomFitPageButton.setOnClickListener(
+            new View.OnClickListener() {
+                public void onClick(View v) {
+                    zoomWithPreview(1f);
+                    updateZoomButtonsEnabled();
+                }
+            });
+    }
+
+    private void updateZoomButtonsEnabled() {
+        mZoomButtonsController.setZoomInEnabled(mActualScale < mMaxZoomScale);
+        mZoomButtonsController.setZoomOutEnabled(mActualScale > mMinZoomScale);
+        mZoomFitPageButton.setEnabled(mActualScale != 1);
+        mZoomOverviewButton.setEnabled(canZoomScrollOut());
     }
 
     private void init() {
@@ -647,9 +611,16 @@
         final int slop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
         mTouchSlopSquare = slop * slop;
         mMinLockSnapReverseDistance = slop;
-        final int doubleTapslop = ViewConfiguration.get(getContext())
-                .getScaledDoubleTapSlop();
+        // use twice the line height, 32 based on our current default font, for
+        // the double tap slop as the ViewConfiguration's double tap slop, 100,
+        // is too big for the Browser
+        final int doubleTapslop = (int) (32 * getContext().getResources()
+                .getDisplayMetrics().density);
         mDoubleTapSlopSquare = doubleTapslop * doubleTapslop;
+        // use one line height, 16 based on our current default font, for how
+        // far we allow a touch be away from the edge of a link
+        mNavSlop = (int) (16 * getContext().getResources()
+                .getDisplayMetrics().density);
     }
 
     /* package */ boolean onSavePassword(String schemePlusHost, String username,
@@ -1380,13 +1351,7 @@
             return;
         }
         clearTextEntry();
-        ExtendedZoomControls zoomControls = (ExtendedZoomControls) 
-                getZoomControls();
-        zoomControls.show(true, canZoomScrollOut());
-        zoomControls.requestFocus();
-        mPrivateHandler.removeCallbacks(mZoomControlRunnable);
-        mPrivateHandler.postDelayed(mZoomControlRunnable,
-                ZOOM_CONTROLS_TIMEOUT);
+        mZoomButtonsController.setVisible(true);
     }
 
     /**
@@ -1498,7 +1463,8 @@
     private static int pinLoc(int x, int viewMax, int docMax) {
 //        Log.d(LOGTAG, "-- pinLoc " + x + " " + viewMax + " " + docMax);
         if (docMax < viewMax) {   // the doc has room on the sides for "blank"
-            x = -(viewMax - docMax) >> 1;
+            // pin the short document to the top/left of the screen
+            x = 0;
 //            Log.d(LOGTAG, "--- center " + x);
         } else if (x < 0) {
             x = 0;
@@ -2589,11 +2555,8 @@
     private void startZoomScrollOut() {
         setHorizontalScrollBarEnabled(false);
         setVerticalScrollBarEnabled(false);
-        if (mZoomControlRunnable != null) {
-            mPrivateHandler.removeCallbacks(mZoomControlRunnable);
-        }
-        if (mZoomControls != null) {
-            mZoomControls.hide();
+        if (mZoomButtonsController.isVisible()) {
+            mZoomButtonsController.setVisible(false);
         }
         int width = getViewWidth();
         int height = getViewHeight();
@@ -3263,6 +3226,7 @@
 
         // Clean up the zoom controller
         mZoomButtonsController.setVisible(false);
+        ZoomButtonsController.finishZoomTutorial(mContext, false);
     }
     
     // Implementation for OnHierarchyChangeListener
@@ -3518,22 +3482,29 @@
                     nativeMoveSelection(viewToContent(mSelectX)
                             , viewToContent(mSelectY), false);
                     mTouchSelection = mExtendSelection = true;
-                } else if (!ZoomButtonsController.useOldZoom(mContext) &&
-                        mPrivateHandler.hasMessages(RELEASE_SINGLE_TAP) &&
-                        (deltaX * deltaX + deltaY * deltaY < mDoubleTapSlopSquare)) {
-                    // Found doubletap, invoke the zoom controller
+                } else if (!ZoomButtonsController.useOldZoom(mContext)
+                        && mPrivateHandler.hasMessages(RELEASE_SINGLE_TAP)) {
                     mPrivateHandler.removeMessages(RELEASE_SINGLE_TAP);
-                    int contentX = viewToContent((int) mLastTouchX + mScrollX);
-                    int contentY = viewToContent((int) mLastTouchY + mScrollY);
-                    if (inEditingMode()) {
-                        mTextEntry.updateCachedTextfield();
+                    if (deltaX * deltaX + deltaY * deltaY < mDoubleTapSlopSquare) {
+                        // Found doubletap, invoke the zoom controller
+                        int contentX = viewToContent((int) mLastTouchX
+                                + mScrollX);
+                        int contentY = viewToContent((int) mLastTouchY
+                                + mScrollY);
+                        if (inEditingMode()) {
+                            mTextEntry.updateCachedTextfield();
+                        }
+                        nativeClearFocus(contentX, contentY);
+                        if (mLogEvent) {
+                            EventLog.writeEvent(EVENT_LOG_DOUBLE_TAP_DURATION,
+                                    (eventTime - mLastTouchUpTime), eventTime);
+                        }
+                        return mZoomButtonsController.handleDoubleTapEvent(ev);
+                    } else {
+                        // commit the short press action
+                        doShortPress();
+                        // continue, mTouchMode should be still TOUCH_INIT_MODE
                     }
-                    nativeClearFocus(contentX, contentY);
-                    if (mLogEvent) {
-                        EventLog.writeEvent(EVENT_LOG_DOUBLE_TAP_DURATION,
-                                (eventTime - mLastTouchUpTime), eventTime);
-                    }
-                    return mZoomButtonsController.handleDoubleTapEvent(ev);
                 } else {
                     mTouchMode = TOUCH_INIT_MODE;
                     mPreventDrag = mForwardTouchEvents;
@@ -3678,20 +3649,6 @@
                     mLastTouchTime = eventTime;
                     mUserScroll = true;
                 }
-
-                if (ZoomButtonsController.useOldZoom(mContext)) {
-                    boolean showPlusMinus = mMinZoomScale < mMaxZoomScale;
-                    boolean showMagnify = canZoomScrollOut();
-                    if (mZoomControls != null && (showPlusMinus || showMagnify)) {
-                        if (mZoomControls.getVisibility() == View.VISIBLE) {
-                            mPrivateHandler.removeCallbacks(mZoomControlRunnable);
-                        } else {
-                            mZoomControls.show(showPlusMinus, showMagnify);
-                        }
-                        mPrivateHandler.postDelayed(mZoomControlRunnable,
-                                ZOOM_CONTROLS_TIMEOUT);
-                    }
-                }
                 if (done) {
                     // return false to indicate that we can't pan out of the
                     // view space
@@ -3706,8 +3663,7 @@
                         mPrivateHandler.removeMessages(SWITCH_TO_SHORTPRESS);
                         if (getSettings().supportZoom()) {
                             mPrivateHandler.sendMessageDelayed(mPrivateHandler
-                                    .obtainMessage(RELEASE_SINGLE_TAP,
-                                            new Boolean(true)),
+                                    .obtainMessage(RELEASE_SINGLE_TAP),
                                     DOUBLE_TAP_TIMEOUT);
                         } else {
                             // do short press now
@@ -3755,8 +3711,7 @@
                             // as tap instead of short press.
                             mTouchMode = TOUCH_INIT_MODE;
                             mPrivateHandler.sendMessageDelayed(mPrivateHandler
-                                    .obtainMessage(RELEASE_SINGLE_TAP,
-                                            new Boolean(true)),
+                                    .obtainMessage(RELEASE_SINGLE_TAP),
                                     DOUBLE_TAP_TIMEOUT);
                         } else {
                             mTouchMode = TOUCH_DONE_MODE;
@@ -4178,42 +4133,41 @@
     }
 
     /**
+     * An InvisibleView is an invisible, zero-sized View for backwards
+     * compatibility
+     */
+    private final class InvisibleView extends View {
+
+        private InvisibleView(Context context) {
+            super(context);
+            setVisibility(GONE);
+        }
+
+        @Override
+        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+            setMeasuredDimension(0, 0);
+        }
+
+        @Override
+        public void draw(Canvas canvas) {
+        }
+
+        @Override
+        protected void dispatchDraw(Canvas canvas) {
+        }
+    }
+
+    /**
      * Returns a view containing zoom controls i.e. +/- buttons. The caller is
      * in charge of installing this view to the view hierarchy. This view will
      * become visible when the user starts scrolling via touch and fade away if
      * the user does not interact with it.
+     * <p/>
+     * From 1.5, WebView change to use ZoomButtonsController. This will return
+     * an invisible dummy view for backwards compatibility.
      */
     public View getZoomControls() {
-        if (!getSettings().supportZoom()) {
-            Log.w(LOGTAG, "This WebView doesn't support zoom.");
-            return null;
-        }
-        if (mZoomControls == null) {
-            mZoomControls = createZoomControls();
-            
-            /*
-             * need to be set to VISIBLE first so that getMeasuredHeight() in
-             * {@link #onSizeChanged()} can return the measured value for proper
-             * layout.
-             */
-            mZoomControls.setVisibility(View.VISIBLE);
-            mZoomControlRunnable = new Runnable() {
-                public void run() {
-                    
-                    /* Don't dismiss the controls if the user has
-                     * focus on them. Wait and check again later.
-                     */
-                    if (!mZoomControls.hasFocus()) {
-                        mZoomControls.hide();
-                    } else {
-                        mPrivateHandler.removeCallbacks(mZoomControlRunnable);
-                        mPrivateHandler.postDelayed(mZoomControlRunnable,
-                                ZOOM_CONTROLS_TIMEOUT);
-                    }
-                }
-            };
-        }
-        return mZoomControls;
+        return new InvisibleView(mContext);
     }
 
     /**
@@ -4236,46 +4190,6 @@
         return zoomWithPreview(mActualScale * 0.8f);
     }
 
-    private ExtendedZoomControls createZoomControls() {
-        ExtendedZoomControls zoomControls = new ExtendedZoomControls(mContext
-            , null);
-        zoomControls.setOnZoomInClickListener(new OnClickListener() {
-            public void onClick(View v) {
-                // reset time out
-                mPrivateHandler.removeCallbacks(mZoomControlRunnable);
-                mPrivateHandler.postDelayed(mZoomControlRunnable,
-                        ZOOM_CONTROLS_TIMEOUT);
-                zoomIn();
-            }
-        });
-        zoomControls.setOnZoomOutClickListener(new OnClickListener() {
-            public void onClick(View v) {
-                // reset time out
-                mPrivateHandler.removeCallbacks(mZoomControlRunnable);
-                mPrivateHandler.postDelayed(mZoomControlRunnable,
-                        ZOOM_CONTROLS_TIMEOUT);
-                zoomOut();
-            }
-        });
-        zoomControls.setOnZoomMagnifyClickListener(new OnClickListener() {
-            public void onClick(View v) {
-                mPrivateHandler.removeCallbacks(mZoomControlRunnable);
-                mPrivateHandler.postDelayed(mZoomControlRunnable,
-                        ZOOM_CONTROLS_TIMEOUT);
-                zoomScrollOut();
-            }
-        });
-        return zoomControls;
-    }
-
-    // This used to be the value returned by ViewConfiguration.getTouchSlop().
-    // We pass this to the navigation cache to find where the user clicked.
-    // TouchSlop has been increased for other purposes, but for the
-    // navigation cache it is too big, and may result in clicking the wrong
-    // spot.  This is a concern when the cache is out of date, and clicking
-    // finds a node which is wrong but nearby.
-    private static final int NAV_SLOP = 12;
-
     private void updateSelection() {
         if (mNativeClass == 0) {
             return;
@@ -4283,9 +4197,8 @@
         // mLastTouchX and mLastTouchY are the point in the current viewport
         int contentX = viewToContent((int) mLastTouchX + mScrollX);
         int contentY = viewToContent((int) mLastTouchY + mScrollY);
-        int contentSize = NAV_SLOP;
-        Rect rect = new Rect(contentX - contentSize, contentY - contentSize,
-                contentX + contentSize, contentY + contentSize);
+        Rect rect = new Rect(contentX - mNavSlop, contentY - mNavSlop,
+                contentX + mNavSlop, contentY + mNavSlop);
         // If we were already focused on a textfield, update its cache.
         if (inEditingMode()) {
             mTextEntry.updateCachedTextfield();
@@ -4298,8 +4211,7 @@
             View v = mTextEntry;
             int x = viewToContent((v.getLeft() + v.getRight()) >> 1);
             int y = viewToContent((v.getTop() + v.getBottom()) >> 1);
-            int contentSize = NAV_SLOP;
-            nativeMotionUp(x, y, contentSize, true);
+            nativeMotionUp(x, y, mNavSlop, true);
         }
     }
 
@@ -4311,8 +4223,7 @@
         // mLastTouchX and mLastTouchY are the point in the current viewport
         int contentX = viewToContent((int) mLastTouchX + mScrollX);
         int contentY = viewToContent((int) mLastTouchY + mScrollY);
-        int contentSize = NAV_SLOP;
-        if (nativeMotionUp(contentX, contentY, contentSize, true)) {
+        if (nativeMotionUp(contentX, contentY, mNavSlop, true)) {
             if (mLogEvent) {
                 Checkin.updateStats(mContext.getContentResolver(),
                         Checkin.Stats.Tag.BROWSER_SNAP_CENTER, 1, 0.0);
@@ -4538,9 +4449,7 @@
                 }
                 case RELEASE_SINGLE_TAP: {
                     mTouchMode = TOUCH_DONE_MODE;
-                    if ((Boolean)msg.obj) {
-                        doShortPress();
-                    }
+                    doShortPress();
                     break;
                 }
                 case SWITCH_TO_ENTER:
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 6ab088d..e10ffa1 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -271,11 +271,6 @@
     static native String nativeFindAddress(String addr);
 
     /**
-     * Rebuild the nav cache if the dom changed.
-     */
-    private native void nativeCheckNavCache();
-
-    /**
      * Empty the picture set.
      */
     private native void nativeClearContent();
@@ -1298,7 +1293,6 @@
                     mViewportMinimumScale == 0 ? nativeGetContentMinPrefWidth()
                             : 0,
                     0, draw).sendToTarget();
-            nativeCheckNavCache();
             if (mWebkitScrollX != 0 || mWebkitScrollY != 0) {
                 // as we have the new picture, try to sync the scroll position
                 Message.obtain(mWebView.mPrivateHandler,
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index f517dc9..7fc96fc 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -41,10 +41,8 @@
 import android.view.ViewDebug;
 import android.view.ViewGroup;
 import android.view.ViewTreeObserver;
-import android.view.inputmethod.CompletionInfo;
 import android.view.inputmethod.EditorInfo;
 import android.view.inputmethod.InputConnection;
-import android.view.inputmethod.InputConnectionWrapper;
 import android.view.inputmethod.InputMethodManager;
 import android.view.ContextMenu.ContextMenuInfo;
 
@@ -2917,11 +2915,14 @@
      */
     @Override
     public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
-        // XXX we need to have the text filter created, so we can get an
-        // InputConnection to proxy to.  Unfortunately this means we pretty
-        // much need to make it as soon as a list view gets focus.
-        createTextFilter(false);
-        return mTextFilter.onCreateInputConnection(outAttrs);
+        if (isTextFilterEnabled()) {
+            // XXX we need to have the text filter created, so we can get an
+            // InputConnection to proxy to.  Unfortunately this means we pretty
+            // much need to make it as soon as a list view gets focus.
+            createTextFilter(false);
+            return mTextFilter.onCreateInputConnection(outAttrs);
+        }
+        return null;
     }
     
     /**
@@ -3015,7 +3016,7 @@
      * filtering as the text changes.
      */
     public void onTextChanged(CharSequence s, int start, int before, int count) {
-        if (mPopup != null) {
+        if (mPopup != null && isTextFilterEnabled()) {
             int length = s.length();
             boolean showing = mPopup.isShowing();
             if (!showing && length > 0) {
diff --git a/core/java/android/widget/ArrayAdapter.java b/core/java/android/widget/ArrayAdapter.java
index c65a3ce..c28210d 100644
--- a/core/java/android/widget/ArrayAdapter.java
+++ b/core/java/android/widget/ArrayAdapter.java
@@ -25,6 +25,8 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.Comparator;
+import java.util.Collections;
 
 /**
  * A ListAdapter that manages a ListView backed by an array of arbitrary
@@ -227,6 +229,17 @@
     }
 
     /**
+     * Sorts the content of this adapter using the specified comparator.
+     *
+     * @param comparator The comparator used to sort the objects contained
+     *        in this adapter.
+     */
+    public void sort(Comparator<? super T> comparator) {
+        Collections.sort(mObjects, comparator);
+        if (mNotifyOnChange) notifyDataSetChanged();        
+    }
+
+    /**
      * {@inheritDoc}
      */
     @Override
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 0c1c72a..7b9670b 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -461,14 +461,6 @@
                     // by ensuring it has focus and getting its window out
                     // of touch mode.
                     mDropDownList.requestFocusFromTouch();
-                    if (false) {
-                        // Update whether the pop-up is in front of or behind
-                        // the input method, depending on whether the user has
-                        // moved down in it.
-                        mPopup.setInputMethodMode(curIndex > 0
-                                ? PopupWindow.INPUT_METHOD_NOT_NEEDED
-                                : PopupWindow.INPUT_METHOD_NEEDED);
-                    }
                     mPopup.update();
 
                     switch (keyCode) {
@@ -504,6 +496,10 @@
         boolean handled = super.onKeyDown(keyCode, event);
         mLastKeyCode = KeyEvent.KEYCODE_UNKNOWN;
 
+        if (handled && isPopupShowing() && mDropDownList != null) {
+            clearListSelection();
+        }
+
         return handled;
     }
 
@@ -833,7 +829,6 @@
             mPopup.update(getDropDownAnchorView(), mDropDownHorizontalOffset,
                     mDropDownVerticalOffset, widthSpec, height);
         } else {
-            int widthSpec;
             if (mDropDownWidth == ViewGroup.LayoutParams.FILL_PARENT) {
                 mPopup.setWindowLayoutMode(ViewGroup.LayoutParams.FILL_PARENT,
                         ViewGroup.LayoutParams.WRAP_CONTENT);
@@ -1119,6 +1114,7 @@
         
         protected int[] onCreateDrawableState(int extraSpace) {
             int[] res = super.onCreateDrawableState(extraSpace);
+            //noinspection ConstantIfStatement
             if (false) {
                 StringBuilder sb = new StringBuilder("Created drawable state: [");
                 for (int i=0; i<res.length; i++) {
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index c2f3a85..aced533 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -126,7 +126,7 @@
     private SparseBooleanArray mCheckStates;
 
     // used for temporary calculations.
-    private Rect mTempRect = new Rect();
+    private final Rect mTempRect = new Rect();
 
     // the single allocated result per list view; kinda cheesey but avoids
     // allocating these thingies too often.
@@ -1656,7 +1656,8 @@
         }
         p.viewType = mAdapter.getItemViewType(position);
 
-        if (recycled || (p.recycledHeaderFooter && p.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER)) {
+        if (recycled || (p.recycledHeaderFooter &&
+                p.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER)) {
             attachViewToParent(child, flowDown ? -1 : 0, p);
         } else {
             if (p.viewType == AdapterView.ITEM_VIEW_TYPE_HEADER_OR_FOOTER) {
@@ -2643,6 +2644,7 @@
 
         final int listBottom = getHeight() - mListPadding.bottom;
         final int listTop = mListPadding.top;
+        final AbsListView.RecycleBin recycleBin = mRecycler;
 
         if (amount < 0) {
             // shifted items up
@@ -2670,8 +2672,13 @@
             // top views may be panned off screen
             View first = getChildAt(0);
             while (first.getBottom() < listTop) {
-                removeViewInLayout(first);
-                mRecycler.addScrapView(first);
+                AbsListView.LayoutParams layoutParams = (LayoutParams) first.getLayoutParams();
+                if (recycleBin.shouldRecycleViewType(layoutParams.viewType)) {
+                    removeViewInLayout(first);
+                    recycleBin.addScrapView(first);
+                } else {
+                    detachViewFromParent(first);
+                }
                 first = getChildAt(0);
                 mFirstPosition++;
             }
@@ -2696,8 +2703,13 @@
 
             // bottom view may be panned off screen
             while (last.getTop() > listBottom) {
-                removeViewInLayout(last);
-                mRecycler.addScrapView(last);
+                AbsListView.LayoutParams layoutParams = (LayoutParams) last.getLayoutParams();
+                if (recycleBin.shouldRecycleViewType(layoutParams.viewType)) {
+                    removeViewInLayout(last);
+                    recycleBin.addScrapView(last);
+                } else {
+                    detachViewFromParent(last);
+                }
                 last = getChildAt(--lastIndex);
             }
         }
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 53db77e..a4f729f 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -837,7 +837,7 @@
         if (!mTouchable) {
             curFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
         }
-        if (mTouchable) {
+        if (mOutsideTouchable) {
             curFlags |= WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
         }
         if (!mClippingEnabled) {
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index ba63ec3..52c421c 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -22,6 +22,7 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.Gravity;
+import android.view.ViewDebug;
 import android.widget.RemoteViews.RemoteView;
 import android.graphics.Rect;
 import com.android.internal.R;
@@ -803,13 +804,33 @@
      * @attr ref android.R.styleable#RelativeLayout_Layout_layout_centerVertical
      */
     public static class LayoutParams extends ViewGroup.MarginLayoutParams {
+        @ViewDebug.ExportedProperty(resolveId = true, indexMapping = {
+            @ViewDebug.IntToString(from = ABOVE,               to = "above"),
+            @ViewDebug.IntToString(from = ALIGN_BASELINE,      to = "alignBaseline"),
+            @ViewDebug.IntToString(from = ALIGN_BOTTOM,        to = "alignBottom"),
+            @ViewDebug.IntToString(from = ALIGN_LEFT,          to = "alignLeft"),
+            @ViewDebug.IntToString(from = ALIGN_PARENT_BOTTOM, to = "alignParentBottom"),
+            @ViewDebug.IntToString(from = ALIGN_PARENT_LEFT,   to = "alignParentLeft"),
+            @ViewDebug.IntToString(from = ALIGN_PARENT_RIGHT,  to = "alignParentRight"),
+            @ViewDebug.IntToString(from = ALIGN_PARENT_TOP,    to = "alignParentTop"),
+            @ViewDebug.IntToString(from = ALIGN_RIGHT,         to = "alignRight"),
+            @ViewDebug.IntToString(from = ALIGN_TOP,           to = "alignTop"),
+            @ViewDebug.IntToString(from = BELOW,               to = "below"),
+            @ViewDebug.IntToString(from = CENTER_HORIZONTAL,   to = "centerHorizontal"),
+            @ViewDebug.IntToString(from = CENTER_IN_PARENT,    to = "center"),
+            @ViewDebug.IntToString(from = CENTER_VERTICAL,     to = "centerVertical"),
+            @ViewDebug.IntToString(from = LEFT_OF,             to = "leftOf"),
+            @ViewDebug.IntToString(from = RIGHT_OF,            to = "rightOf")
+        }, mapping = { @ViewDebug.IntToString(from = TRUE, to = "true") })
         private int[] mRules = new int[VERB_COUNT];
+
         private int mLeft, mTop, mRight, mBottom;
 
         /**
          * When true, uses the parent as the anchor if the anchor doesn't exist or if
          * the anchor's visibility is GONE.
          */
+        @ViewDebug.ExportedProperty
         public boolean alignWithParent;
 
         public LayoutParams(Context c, AttributeSet attrs) {
diff --git a/core/java/android/widget/SlidingDrawer.java b/core/java/android/widget/SlidingDrawer.java
index e77c4ca..e0f1bb4 100644
--- a/core/java/android/widget/SlidingDrawer.java
+++ b/core/java/android/widget/SlidingDrawer.java
@@ -358,15 +358,17 @@
         }
 
         if (action == MotionEvent.ACTION_DOWN) {
-            if (mOnDrawerScrollListener != null) {
-                mOnDrawerScrollListener.onScrollStarted();
-            }
             mTracking = true;
 
             handle.setPressed(true);
             // Must be called before prepareTracking()
             prepareContent();
 
+            // Must be called after prepareContent()
+            if (mOnDrawerScrollListener != null) {
+                mOnDrawerScrollListener.onScrollStarted();
+            }
+
             if (mVertical) {
                 final int top = mHandle.getTop();
                 mTouchDelta = (int) y - top;
@@ -447,6 +449,8 @@
                                 } else {
                                     animateOpen(vertical ? top : left);
                                 }
+                            } else {
+                                performFling(vertical ? top : left, velocity, false);
                             }
 
                         } else {
@@ -762,11 +766,11 @@
      * @see #toggle()
      */
     public void animateClose() {
+        prepareContent();
         final OnDrawerScrollListener scrollListener = mOnDrawerScrollListener;
         if (scrollListener != null) {
             scrollListener.onScrollStarted();
         }
-        prepareContent();
         animateClose(mVertical ? mHandle.getTop() : mHandle.getLeft());
         if (scrollListener != null) {
             scrollListener.onScrollEnded();
@@ -783,11 +787,11 @@
      * @see #toggle()
      */
     public void animateOpen() {
+        prepareContent();
         final OnDrawerScrollListener scrollListener = mOnDrawerScrollListener;
         if (scrollListener != null) {
             scrollListener.onScrollStarted();
         }
-        prepareContent();
         animateOpen(mVertical ? mHandle.getTop() : mHandle.getLeft());
         if (scrollListener != null) {
             scrollListener.onScrollEnded();
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 8271a9a..426d711 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -3242,6 +3242,9 @@
                 }
             };
             mPopup.setFocusable(false);
+            // The user is entering text, so the input method is needed.  We
+            // don't want the popup to be displayed on top of it.
+            mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);
         }
 
         TextView tv = (TextView) mPopup.getContentView();
diff --git a/core/java/android/widget/VideoView.java b/core/java/android/widget/VideoView.java
index ec6f88b..4c5df2f 100644
--- a/core/java/android/widget/VideoView.java
+++ b/core/java/android/widget/VideoView.java
@@ -302,15 +302,15 @@
 
     private MediaPlayer.OnErrorListener mErrorListener =
         new MediaPlayer.OnErrorListener() {
-        public boolean onError(MediaPlayer mp, int a, int b) {
-            Log.d(TAG, "Error: " + a + "," + b);
+        public boolean onError(MediaPlayer mp, int framework_err, int impl_err) {
+            Log.d(TAG, "Error: " + framework_err + "," + impl_err);
             if (mMediaController != null) {
                 mMediaController.hide();
             }
 
             /* If an error handler has been supplied, use it and finish. */
             if (mOnErrorListener != null) {
-                if (mOnErrorListener.onError(mMediaPlayer, a, b)) {
+                if (mOnErrorListener.onError(mMediaPlayer, framework_err, impl_err)) {
                     return true;
                 }
             }
@@ -322,9 +322,17 @@
              */
             if (getWindowToken() != null) {
                 Resources r = mContext.getResources();
+                int messageId;
+
+                if (framework_err == MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK) {
+                    messageId = com.android.internal.R.string.VideoView_error_text_invalid_progressive_playback;
+                } else {
+                    messageId = com.android.internal.R.string.VideoView_error_text_unknown;
+                }
+
                 new AlertDialog.Builder(mContext)
                         .setTitle(com.android.internal.R.string.VideoView_error_title)
-                        .setMessage(com.android.internal.R.string.VideoView_error_text_unknown)
+                        .setMessage(messageId)
                         .setPositiveButton(com.android.internal.R.string.VideoView_error_button,
                                 new DialogInterface.OnClickListener() {
                                     public void onClick(DialogInterface dialog, int whichButton) {
diff --git a/core/java/android/widget/ZoomButtonsController.java b/core/java/android/widget/ZoomButtonsController.java
index 1ba2dce..6729fd1 100644
--- a/core/java/android/widget/ZoomButtonsController.java
+++ b/core/java/android/widget/ZoomButtonsController.java
@@ -36,6 +36,7 @@
 import android.view.MotionEvent;
 import android.view.View;
 import android.view.ViewConfiguration;
+import android.view.ViewGroup;
 import android.view.Window;
 import android.view.WindowManager;
 import android.view.View.OnClickListener;
@@ -61,7 +62,7 @@
 
     // TODO: scaled to density
     private static final int ZOOM_CONTROLS_TOUCH_PADDING = 20;
-    
+
     private Context mContext;
     private WindowManager mWindowManager;
 
@@ -84,7 +85,7 @@
     private int[] mContainerLocation = new int[2];
 
     private ZoomControls mControls;
-    
+
     /**
      * The view (or null) that should receive touch events. This will get set if
      * the touch down hits the container. It will be reset on the touch up.
@@ -100,7 +101,7 @@
      * up/cancel, and then set the owner's touch listener to null.
      */
     private boolean mReleaseTouchListenerOnUp;
-    
+
     private boolean mIsSecondTapDown;
 
     private boolean mIsVisible;
@@ -145,7 +146,7 @@
      * we delay the setVisible(true) call until it is not null.
      */
     private static final int MSG_POST_SET_VISIBLE = 4;
-    
+
     private Handler mHandler = new Handler() {
         @Override
         public void handleMessage(Message msg) {
@@ -157,7 +158,7 @@
                 case MSG_DISMISS_ZOOM_CONTROLS:
                     setVisible(false);
                     break;
-                    
+
                 case MSG_POST_SET_VISIBLE:
                     if (mOwnerView.getWindowToken() == null) {
                         // Doh, it is still null, throw an exception
@@ -179,19 +180,19 @@
 
         mContainer = createContainer();
     }
-    
+
     public void setZoomInEnabled(boolean enabled) {
         mControls.setIsZoomInEnabled(enabled);
     }
-    
+
     public void setZoomOutEnabled(boolean enabled) {
         mControls.setIsZoomOutEnabled(enabled);
     }
-    
+
     public void setZoomSpeed(long speed) {
         mControls.setZoomSpeed(speed);
     }
-    
+
     private FrameLayout createContainer() {
         LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
         lp.gravity = Gravity.BOTTOM | Gravity.CENTER;
@@ -202,19 +203,18 @@
         lp.width = LayoutParams.FILL_PARENT;
         lp.type = LayoutParams.TYPE_APPLICATION_PANEL;
         lp.format = PixelFormat.TRANSPARENT;
-        // TODO: make a new animation for this
-        lp.windowAnimations = com.android.internal.R.style.Animation_InputMethodFancy;
+        lp.windowAnimations = com.android.internal.R.style.Animation_ZoomButtons;
         mContainerLayoutParams = lp;
-        
+
         FrameLayout container = new FrameLayout(mContext);
         container.setLayoutParams(lp);
         container.setMeasureAllChildren(true);
         container.setOnKeyListener(this);
-        
+
         LayoutInflater inflater = (LayoutInflater) mContext
                 .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
-        inflater.inflate(com.android.internal.R.layout.zoom_magnify, container);
-        
+        inflater.inflate(com.android.internal.R.layout.zoom_container, container);
+
         mControls = (ZoomControls) container.findViewById(com.android.internal.R.id.zoomControls);
         mControls.setOnZoomInClickListener(new OnClickListener() {
             public void onClick(View v) {
@@ -229,38 +229,24 @@
             }
         });
 
-        View overview = container.findViewById(com.android.internal.R.id.zoomMagnify);
-        overview.setVisibility(View.GONE);
-        overview.setOnClickListener(new OnClickListener() {
-            public void onClick(View v) {
-                dismissControlsDelayed(ZOOM_CONTROLS_TIMEOUT);
-                if (mCallback != null) mCallback.onOverview();
-            }
-        });
-        
         return container;
     }
-    
+
     public void setCallback(OnZoomListener callback) {
         mCallback = callback;
     }
 
     public void setFocusable(boolean focusable) {
         if (focusable) {
-            mContainerLayoutParams.flags &= ~LayoutParams.FLAG_NOT_FOCUSABLE; 
+            mContainerLayoutParams.flags &= ~LayoutParams.FLAG_NOT_FOCUSABLE;
         } else {
             mContainerLayoutParams.flags |= LayoutParams.FLAG_NOT_FOCUSABLE;
         }
-        
+
         if (mIsVisible) {
             mWindowManager.updateViewLayout(mContainer, mContainerLayoutParams);
         }
     }
-    
-    public void setOverviewVisible(boolean visible) {
-        mContainer.findViewById(com.android.internal.R.id.zoomMagnify)
-                .setVisibility(visible ? View.VISIBLE : View.GONE);
-    }
 
     public boolean isVisible() {
         return mIsVisible;
@@ -269,7 +255,7 @@
     public void setVisible(boolean visible) {
 
         if (!useThisZoom(mContext)) return;
-        
+
         if (visible) {
             if (mOwnerView.getWindowToken() == null) {
                 /*
@@ -282,7 +268,7 @@
                 }
                 return;
             }
-            
+
             dismissControlsDelayed(ZOOM_CONTROLS_TIMEOUT);
         }
 
@@ -350,14 +336,10 @@
      *
      * @return TODO
      */
-    public FrameLayout getContainer() {
+    public ViewGroup getContainer() {
         return mContainer;
     }
 
-    public int getZoomControlsId() {
-        return mControls.getId();
-    }
-
     private void dismissControlsDelayed(int delay) {
         mHandler.removeMessages(MSG_DISMISS_ZOOM_CONTROLS);
         mHandler.sendEmptyMessageDelayed(MSG_DISMISS_ZOOM_CONTROLS, delay);
@@ -372,7 +354,7 @@
      */
     public boolean handleDoubleTapEvent(MotionEvent event) {
         if (!useThisZoom(mContext)) return false;
-        
+
         int action = event.getAction();
 
         if (action == MotionEvent.ACTION_DOWN) {
@@ -428,7 +410,7 @@
             // The second tap can no longer be down
             mIsSecondTapDown = false;
         }
-        
+
         if (mReleaseTouchListenerOnUp) {
             // The controls were dismissed but we need to throw away all events until the up
             if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
@@ -443,7 +425,7 @@
 
         // TODO: optimize this (it ends up removing message and queuing another)
         dismissControlsDelayed(ZOOM_CONTROLS_TIMEOUT);
-        
+
         View targetView = mTouchTargetView;
 
         switch (action) {
@@ -556,7 +538,7 @@
                 com.android.internal.R.layout.alert_dialog_simple_text, null)
                 .findViewById(android.R.id.text1);
         textView.setText(com.android.internal.R.string.tutorial_double_tap_to_zoom_message_short);
-        
+
         sTutorialDialog = new AlertDialog.Builder(context)
                 .setView(textView)
                 .setIcon(0)
@@ -603,7 +585,7 @@
 
     // Temporary methods for different zoom types
     static int getZoomType(Context context) {
-        return Settings.System.getInt(context.getContentResolver(), "zoom", 1);
+        return Settings.System.getInt(context.getContentResolver(), "zoom", 2);
     }
 
     public static boolean useOldZoom(Context context) {
@@ -618,6 +600,5 @@
         void onCenter(int x, int y);
         void onVisibilityChanged(boolean visible);
         void onZoom(boolean zoomIn);
-        void onOverview();
     }
 }
diff --git a/core/java/com/android/internal/gadget/IGadgetHost.aidl b/core/java/com/android/internal/appwidget/IAppWidgetHost.aidl
similarity index 73%
rename from core/java/com/android/internal/gadget/IGadgetHost.aidl
rename to core/java/com/android/internal/appwidget/IAppWidgetHost.aidl
index e7b5a1e..2ed4773 100644
--- a/core/java/com/android/internal/gadget/IGadgetHost.aidl
+++ b/core/java/com/android/internal/appwidget/IAppWidgetHost.aidl
@@ -14,15 +14,15 @@
  * limitations under the License.
  */
 
-package com.android.internal.gadget;
+package com.android.internal.appwidget;
 
 import android.content.ComponentName;
-import android.gadget.GadgetProviderInfo;
+import android.appwidget.AppWidgetProviderInfo;
 import android.widget.RemoteViews;
 
 /** {@hide} */
-oneway interface IGadgetHost {
-    void updateGadget(int gadgetId, in RemoteViews views);
-    void providerChanged(int gadgetId, in GadgetProviderInfo info);
+oneway interface IAppWidgetHost {
+    void updateAppWidget(int appWidgetId, in RemoteViews views);
+    void providerChanged(int appWidgetId, in AppWidgetProviderInfo info);
 }
 
diff --git a/core/java/com/android/internal/appwidget/IAppWidgetService.aidl b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
new file mode 100644
index 0000000..496aa1a
--- /dev/null
+++ b/core/java/com/android/internal/appwidget/IAppWidgetService.aidl
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.appwidget;
+
+import android.content.ComponentName;
+import android.appwidget.AppWidgetProviderInfo;
+import com.android.internal.appwidget.IAppWidgetHost;
+import android.widget.RemoteViews;
+
+/** {@hide} */
+interface IAppWidgetService {
+    
+    //
+    // for AppWidgetHost
+    //
+    int[] startListening(IAppWidgetHost host, String packageName, int hostId,
+            out List<RemoteViews> updatedViews);
+    void stopListening(int hostId);
+    int allocateAppWidgetId(String packageName, int hostId);
+    void deleteAppWidgetId(int appWidgetId);
+    void deleteHost(int hostId);
+    void deleteAllHosts();
+    RemoteViews getAppWidgetViews(int appWidgetId);
+
+    //
+    // for AppWidgetManager
+    //
+    void updateAppWidgetIds(in int[] appWidgetIds, in RemoteViews views);
+    void updateAppWidgetProvider(in ComponentName provider, in RemoteViews views);
+    List<AppWidgetProviderInfo> getInstalledProviders();
+    AppWidgetProviderInfo getAppWidgetInfo(int appWidgetId);
+    void bindAppWidgetId(int appWidgetId, in ComponentName provider);
+    int[] getAppWidgetIds(in ComponentName provider);
+
+}
+
diff --git a/core/java/com/android/internal/gadget/package.html b/core/java/com/android/internal/appwidget/package.html
similarity index 100%
rename from core/java/com/android/internal/gadget/package.html
rename to core/java/com/android/internal/appwidget/package.html
diff --git a/core/java/com/android/internal/gadget/IGadgetService.aidl b/core/java/com/android/internal/gadget/IGadgetService.aidl
deleted file mode 100644
index 9c66b95..0000000
--- a/core/java/com/android/internal/gadget/IGadgetService.aidl
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.gadget;
-
-import android.content.ComponentName;
-import android.gadget.GadgetProviderInfo;
-import com.android.internal.gadget.IGadgetHost;
-import android.widget.RemoteViews;
-
-/** {@hide} */
-interface IGadgetService {
-    
-    //
-    // for GadgetHost
-    //
-    int[] startListening(IGadgetHost host, String packageName, int hostId,
-            out List<RemoteViews> updatedViews);
-    void stopListening(int hostId);
-    int allocateGadgetId(String packageName, int hostId);
-    void deleteGadgetId(int gadgetId);
-    void deleteHost(int hostId);
-    void deleteAllHosts();
-    RemoteViews getGadgetViews(int gadgetId);
-
-    //
-    // for GadgetManager
-    //
-    void updateGadgetIds(in int[] gadgetIds, in RemoteViews views);
-    void updateGadgetProvider(in ComponentName provider, in RemoteViews views);
-    List<GadgetProviderInfo> getInstalledProviders();
-    GadgetProviderInfo getGadgetInfo(int gadgetId);
-    void bindGadgetId(int gadgetId, in ComponentName provider);
-    int[] getGadgetIds(in ComponentName provider);
-
-}
-
diff --git a/core/java/com/android/internal/widget/NumberPicker.java b/core/java/com/android/internal/widget/NumberPicker.java
index 1647c20..2f08c8d 100644
--- a/core/java/com/android/internal/widget/NumberPicker.java
+++ b/core/java/com/android/internal/widget/NumberPicker.java
@@ -30,6 +30,7 @@
 import android.view.View.OnLongClickListener;
 import android.widget.TextView;
 import android.widget.LinearLayout;
+import android.widget.EditText;
 
 import com.android.internal.R;
 
@@ -76,7 +77,7 @@
         }
     };
 
-    private final TextView mText;
+    private final EditText mText;
     private final InputFilter mNumberInputFilter;
 
     private String[] mDisplayedValues;
@@ -117,7 +118,7 @@
         mDecrementButton.setOnLongClickListener(this);
         mDecrementButton.setNumberPicker(this);
         
-        mText = (TextView) findViewById(R.id.timepicker_input);
+        mText = (EditText) findViewById(R.id.timepicker_input);
         mText.setOnFocusChangeListener(this);
         mText.setFilters(new InputFilter[] {inputFilter});
         mText.setRawInputType(InputType.TYPE_CLASS_NUMBER);
@@ -188,11 +189,8 @@
     }
     
     public void onClick(View v) {
-        
-        /* The text view may still have focus so clear it's focus which will
-         * trigger the on focus changed and any typed values to be pulled.
-         */
-        mText.clearFocus();
+        validateInput(mText);
+        if (!mText.hasFocus()) mText.requestFocus();
 
         // now perform the increment/decrement
         if (R.id.increment == v.getId()) {
@@ -239,6 +237,7 @@
         } else {
             mText.setText(mDisplayedValues[mCurrent - mStart]);
         }
+        mText.setSelection(mText.getText().length());
     }
     
     private void validateCurrentView(CharSequence str) {
@@ -257,16 +256,20 @@
          * has valid values.
          */
         if (!hasFocus) {
-            String str = String.valueOf(((TextView) v).getText());
-            if ("".equals(str)) {
-                
-                // Restore to the old value as we don't allow empty values
-                updateView();
-            } else {
-                
-                // Check the new value and ensure it's in range
-                validateCurrentView(str);
-            }
+            validateInput(v);
+        }
+    }
+
+    private void validateInput(View v) {
+        String str = String.valueOf(((TextView) v).getText());
+        if ("".equals(str)) {
+
+            // Restore to the old value as we don't allow empty values
+            updateView();
+        } else {
+
+            // Check the new value and ensure it's in range
+            validateCurrentView(str);
         }
     }
 
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 28c602b..f4643f4 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -220,7 +220,7 @@
 
 AndroidRuntime::AndroidRuntime()
 {
-    SkGraphics::Init(false);    // true means run unittests (slow)
+    SkGraphics::Init();
     // this sets our preference for 16bit images during decode
     // in case the src is opaque and 24bit
     SkImageDecoder::SetDeviceConfig(SkBitmap::kRGB_565_Config);
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index adfd912..c03bab6 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -61,6 +61,8 @@
 static jmethodID method_onAuthAgentAuthorize;
 static jmethodID method_onAuthAgentCancel;
 
+static jmethodID method_onRestartRequired;
+
 typedef event_loop_native_data_t native_data_t;
 
 // Only valid during waitForAndDispatchEventNative()
@@ -99,6 +101,8 @@
     method_onAuthAgentCancel = env->GetMethodID(clazz, "onAuthAgentCancel", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
     method_onGetRemoteServiceChannelResult = env->GetMethodID(clazz, "onGetRemoteServiceChannelResult", "(Ljava/lang/String;I)V");
 
+    method_onRestartRequired = env->GetMethodID(clazz, "onRestartRequired", "()V");
+
     field_mNativeData = env->GetFieldID(clazz, "mNativeData", "I");
 #endif
 }
@@ -165,6 +169,13 @@
 
         // Set which messages will be processed by this dbus connection
         dbus_bus_add_match(nat->conn,
+                "type='signal',interface='org.freedesktop.DBus'",
+                &err);
+        if (dbus_error_is_set(&err)) {
+            LOG_AND_FREE_DBUS_ERROR(&err);
+            return JNI_FALSE;
+        }
+        dbus_bus_add_match(nat->conn,
                 "type='signal',interface='"BLUEZ_DBUS_BASE_IFC".Adapter'",
                 &err);
         if (dbus_error_is_set(&err)) {
@@ -302,6 +313,12 @@
         if (dbus_error_is_set(&err)) {
             LOG_AND_FREE_DBUS_ERROR(&err);
         }
+        dbus_bus_remove_match(nat->conn,
+                "type='signal',interface='org.freedesktop.DBus'",
+                &err);
+        if (dbus_error_is_set(&err)) {
+            LOG_AND_FREE_DBUS_ERROR(&err);
+        }
 
         dbus_connection_remove_filter(nat->conn, event_filter, nat);
     }
@@ -509,6 +526,28 @@
                                 env->NewStringUTF(c_name));
         } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
         return DBUS_HANDLER_RESULT_HANDLED;
+    } else if (dbus_message_is_signal(msg,
+                                      "org.freedesktop.DBus",
+                                      "NameOwnerChanged")) {
+        char *c_name;
+        char *c_old_owner;
+        char *c_new_owner;
+        if (dbus_message_get_args(msg, &err,
+                                  DBUS_TYPE_STRING, &c_name,
+                                  DBUS_TYPE_STRING, &c_old_owner,
+                                  DBUS_TYPE_STRING, &c_new_owner,
+                                  DBUS_TYPE_INVALID)) {
+            LOGV("... name = %s", c_name);
+            LOGV("... old_owner = %s", c_old_owner);
+            LOGV("... new_owner = %s", c_new_owner);
+            if (!strcmp(c_name, "org.bluez") && c_new_owner[0] != '\0') {
+                // New owner of org.bluez. This can only happen when hcid
+                // restarts. Need to restart framework BT services to recover.
+                LOGE("Looks like hcid restarted");
+                env->CallVoidMethod(nat->me, method_onRestartRequired);
+            }
+        } else LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, msg);
+        return DBUS_HANDLER_RESULT_HANDLED;
     }
 
     return a2dp_event_filter(msg, env);
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index e9db5f0..1b145af 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -924,13 +924,13 @@
         android:description="@string/permdesc_batteryStats"
         android:protectionLevel="normal" />
 
-    <!-- Allows an application to tell the gadget service which application
-         can access gadget's data.  The normal user flow is that a user
-         picks a gadget to go into a particular host, thereby giving that
-         host application access to the private data from the gadget app.
+    <!-- Allows an application to tell the AppWidget service which application
+         can access AppWidget's data.  The normal user flow is that a user
+         picks an AppWidget to go into a particular host, thereby giving that
+         host application access to the private data from the AppWidget app.
          An application that has this permission should honor that contract.
          Very few applications should need to use this permission. -->
-    <permission android:name="android.permission.BIND_GADGET"
+    <permission android:name="android.permission.BIND_APPWIDGET"
         android:permissionGroup="android.permission-group.PERSONAL_INFO"
         android:label="@string/permlab_bindGadget"
         android:description="@string/permdesc_bindGadget"
diff --git a/core/res/res/drawable/btn_browser_zoom_fit_page.xml b/core/res/res/drawable/btn_browser_zoom_fit_page.xml
new file mode 100644
index 0000000..2f4761a
--- /dev/null
+++ b/core/res/res/drawable/btn_browser_zoom_fit_page.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@android:drawable/btn_square_overlay" />
+    <item android:drawable="@android:drawable/ic_btn_square_browser_zoom_fit_page" />
+</layer-list>
diff --git a/core/res/res/drawable/btn_browser_zoom_page_overview.xml b/core/res/res/drawable/btn_browser_zoom_page_overview.xml
new file mode 100644
index 0000000..16fb1e6
--- /dev/null
+++ b/core/res/res/drawable/btn_browser_zoom_page_overview.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:drawable="@android:drawable/btn_square_overlay" />
+    <item android:drawable="@android:drawable/ic_btn_square_browser_zoom_page_overview" />
+</layer-list>
diff --git a/core/res/res/drawable/btn_square_overlay.xml b/core/res/res/drawable/btn_square_overlay.xml
new file mode 100644
index 0000000..a2c698c
--- /dev/null
+++ b/core/res/res/drawable/btn_square_overlay.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="false" android:state_focused="true"
+            android:state_window_focused="true"
+            android:drawable="@drawable/btn_square_overlay_disabled_focused" />
+    <item android:state_enabled="false" android:drawable="@drawable/btn_square_overlay_disabled" />
+    <item android:state_pressed="true" android:drawable="@drawable/btn_square_overlay_pressed" />
+    <item android:state_focused="true" android:state_window_focused="true"
+            android:drawable="@drawable/btn_square_overlay_selected" />
+    <item android:drawable="@drawable/btn_square_overlay_normal" />
+</selector>
\ No newline at end of file
diff --git a/core/res/res/drawable/btn_square_overlay_disabled.png b/core/res/res/drawable/btn_square_overlay_disabled.png
new file mode 100644
index 0000000..cf7e4ea
--- /dev/null
+++ b/core/res/res/drawable/btn_square_overlay_disabled.png
Binary files differ
diff --git a/core/res/res/drawable/btn_square_overlay_disabled_focused.png b/core/res/res/drawable/btn_square_overlay_disabled_focused.png
new file mode 100644
index 0000000..5aa1143
--- /dev/null
+++ b/core/res/res/drawable/btn_square_overlay_disabled_focused.png
Binary files differ
diff --git a/core/res/res/drawable/btn_square_overlay_normal.png b/core/res/res/drawable/btn_square_overlay_normal.png
new file mode 100644
index 0000000..45fa4fe
--- /dev/null
+++ b/core/res/res/drawable/btn_square_overlay_normal.png
Binary files differ
diff --git a/core/res/res/drawable/btn_square_overlay_pressed.png b/core/res/res/drawable/btn_square_overlay_pressed.png
new file mode 100644
index 0000000..952571b
--- /dev/null
+++ b/core/res/res/drawable/btn_square_overlay_pressed.png
Binary files differ
diff --git a/core/res/res/drawable/btn_square_overlay_selected.png b/core/res/res/drawable/btn_square_overlay_selected.png
new file mode 100644
index 0000000..ce4515e
--- /dev/null
+++ b/core/res/res/drawable/btn_square_overlay_selected.png
Binary files differ
diff --git a/core/res/res/drawable/btn_zoom_down.xml b/core/res/res/drawable/btn_zoom_down.xml
new file mode 100644
index 0000000..e7449aa
--- /dev/null
+++ b/core/res/res/drawable/btn_zoom_down.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="false" android:state_focused="true"
+        android:state_window_focused="true"
+        android:drawable="@drawable/btn_zoom_down_disabled_focused" />
+    <item android:state_enabled="false" android:drawable="@drawable/btn_zoom_down_disabled" />
+    <item android:state_pressed="true" android:drawable="@drawable/btn_zoom_down_pressed" />
+    <item android:state_focused="true" android:state_window_focused="true"
+        android:drawable="@drawable/btn_zoom_down_selected" />
+    <item android:drawable="@drawable/btn_zoom_down_normal" />
+</selector>
+
diff --git a/core/res/res/drawable/btn_zoom_down_disabled.9.png b/core/res/res/drawable/btn_zoom_down_disabled.9.png
new file mode 100644
index 0000000..7780bd7
--- /dev/null
+++ b/core/res/res/drawable/btn_zoom_down_disabled.9.png
Binary files differ
diff --git a/core/res/res/drawable/btn_zoom_down_disabled_focused.9.png b/core/res/res/drawable/btn_zoom_down_disabled_focused.9.png
new file mode 100644
index 0000000..39131c5
--- /dev/null
+++ b/core/res/res/drawable/btn_zoom_down_disabled_focused.9.png
Binary files differ
diff --git a/core/res/res/drawable/btn_zoom_down_longpress.9.png b/core/res/res/drawable/btn_zoom_down_longpress.9.png
new file mode 100644
index 0000000..09a3bb3
--- /dev/null
+++ b/core/res/res/drawable/btn_zoom_down_longpress.9.png
Binary files differ
diff --git a/core/res/res/drawable/btn_zoom_down_normal.9.png b/core/res/res/drawable/btn_zoom_down_normal.9.png
new file mode 100644
index 0000000..b589a84
--- /dev/null
+++ b/core/res/res/drawable/btn_zoom_down_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable/btn_zoom_down_pressed.9.png b/core/res/res/drawable/btn_zoom_down_pressed.9.png
new file mode 100644
index 0000000..a8ca467
--- /dev/null
+++ b/core/res/res/drawable/btn_zoom_down_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable/btn_zoom_down_selected.9.png b/core/res/res/drawable/btn_zoom_down_selected.9.png
new file mode 100644
index 0000000..af551e7
--- /dev/null
+++ b/core/res/res/drawable/btn_zoom_down_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable/btn_zoom_up.xml b/core/res/res/drawable/btn_zoom_up.xml
new file mode 100644
index 0000000..045b3c3
--- /dev/null
+++ b/core/res/res/drawable/btn_zoom_up.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="false" android:state_focused="true"
+        android:state_window_focused="true"
+        android:drawable="@drawable/btn_zoom_up_disabled_focused" />
+    <item android:state_enabled="false" android:drawable="@drawable/btn_zoom_up_disabled" />
+    <item android:state_pressed="true" android:drawable="@drawable/btn_zoom_up_pressed" />
+    <item android:state_focused="true" android:state_window_focused="true"
+        android:drawable="@drawable/btn_zoom_up_selected" />
+    <item android:drawable="@drawable/btn_zoom_up_normal" />
+</selector>
+
diff --git a/core/res/res/drawable/btn_zoom_up_disabled.9.png b/core/res/res/drawable/btn_zoom_up_disabled.9.png
new file mode 100644
index 0000000..5203630
--- /dev/null
+++ b/core/res/res/drawable/btn_zoom_up_disabled.9.png
Binary files differ
diff --git a/core/res/res/drawable/btn_zoom_up_disabled_focused.9.png b/core/res/res/drawable/btn_zoom_up_disabled_focused.9.png
new file mode 100644
index 0000000..c72c9cd
--- /dev/null
+++ b/core/res/res/drawable/btn_zoom_up_disabled_focused.9.png
Binary files differ
diff --git a/core/res/res/drawable/btn_zoom_up_longpress.9.png b/core/res/res/drawable/btn_zoom_up_longpress.9.png
new file mode 100644
index 0000000..8de48d1
--- /dev/null
+++ b/core/res/res/drawable/btn_zoom_up_longpress.9.png
Binary files differ
diff --git a/core/res/res/drawable/btn_zoom_up_normal.9.png b/core/res/res/drawable/btn_zoom_up_normal.9.png
new file mode 100644
index 0000000..5027348
--- /dev/null
+++ b/core/res/res/drawable/btn_zoom_up_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable/btn_zoom_up_pressed.9.png b/core/res/res/drawable/btn_zoom_up_pressed.9.png
new file mode 100644
index 0000000..1a93e3a
--- /dev/null
+++ b/core/res/res/drawable/btn_zoom_up_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable/btn_zoom_up_selected.9.png b/core/res/res/drawable/btn_zoom_up_selected.9.png
new file mode 100644
index 0000000..26aafee
--- /dev/null
+++ b/core/res/res/drawable/btn_zoom_up_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable/ic_btn_square_browser_zoom_fit_page.xml b/core/res/res/drawable/ic_btn_square_browser_zoom_fit_page.xml
new file mode 100644
index 0000000..bec869a
--- /dev/null
+++ b/core/res/res/drawable/ic_btn_square_browser_zoom_fit_page.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:state_enabled="false" android:drawable="@drawable/ic_btn_square_browser_zoom_fit_page_disabled" />
+    <item android:drawable="@drawable/ic_btn_square_browser_zoom_fit_page_normal" />
+</selector>
\ No newline at end of file
diff --git a/core/res/res/drawable/ic_btn_square_browser_zoom_fit_page_disabled.png b/core/res/res/drawable/ic_btn_square_browser_zoom_fit_page_disabled.png
new file mode 100644
index 0000000..326397c
--- /dev/null
+++ b/core/res/res/drawable/ic_btn_square_browser_zoom_fit_page_disabled.png
Binary files differ
diff --git a/core/res/res/drawable/ic_btn_square_browser_zoom_fit_page_normal.png b/core/res/res/drawable/ic_btn_square_browser_zoom_fit_page_normal.png
new file mode 100644
index 0000000..5583401
--- /dev/null
+++ b/core/res/res/drawable/ic_btn_square_browser_zoom_fit_page_normal.png
Binary files differ
diff --git a/core/res/res/drawable/ic_btn_square_browser_zoom_page_overview.png b/core/res/res/drawable/ic_btn_square_browser_zoom_page_overview.png
new file mode 100644
index 0000000..4e8ff35
--- /dev/null
+++ b/core/res/res/drawable/ic_btn_square_browser_zoom_page_overview.png
Binary files differ
diff --git a/core/res/res/drawable/seek_thumb.xml b/core/res/res/drawable/seek_thumb.xml
index 7fe51b3..c7a862d 100644
--- a/core/res/res/drawable/seek_thumb.xml
+++ b/core/res/res/drawable/seek_thumb.xml
@@ -14,7 +14,7 @@
      limitations under the License.
 -->
 
-<!-- This is the rating bar drawable that is used to a show a filled star. -->
+<!-- This is the thumb on the seek bar. -->
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
 
     <item android:state_pressed="true"
diff --git a/core/res/res/drawable/seek_thumb_normal.png b/core/res/res/drawable/seek_thumb_normal.png
index dbaae91..e9f2e23 100644
--- a/core/res/res/drawable/seek_thumb_normal.png
+++ b/core/res/res/drawable/seek_thumb_normal.png
Binary files differ
diff --git a/core/res/res/drawable/seek_thumb_pressed.png b/core/res/res/drawable/seek_thumb_pressed.png
index dbaae91..3ea5051 100644
--- a/core/res/res/drawable/seek_thumb_pressed.png
+++ b/core/res/res/drawable/seek_thumb_pressed.png
Binary files differ
diff --git a/core/res/res/drawable/seek_thumb_selected.png b/core/res/res/drawable/seek_thumb_selected.png
index dbaae91..98b7ba0 100644
--- a/core/res/res/drawable/seek_thumb_selected.png
+++ b/core/res/res/drawable/seek_thumb_selected.png
Binary files differ
diff --git a/core/res/res/layout/input_method_extract_view.xml b/core/res/res/layout/input_method_extract_view.xml
index 13b619a..1244c1d 100644
--- a/core/res/res/layout/input_method_extract_view.xml
+++ b/core/res/res/layout/input_method_extract_view.xml
@@ -44,7 +44,7 @@
             android:background="@android:drawable/keyboard_accessory_bg_landscape"
         >
         
-        <Button android:id="@+id/inputExtractAction"
+        <android.inputmethodservice.ExtractButton android:id="@+id/inputExtractAction"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="center"
diff --git a/core/res/res/layout/keyguard_screen_glogin_unlock.xml b/core/res/res/layout/keyguard_screen_glogin_unlock.xml
index b78bb94..4834b28 100644
--- a/core/res/res/layout/keyguard_screen_glogin_unlock.xml
+++ b/core/res/res/layout/keyguard_screen_glogin_unlock.xml
@@ -20,7 +20,7 @@
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:orientation="vertical"
-    android:background="#A0000000"
+    android:background="@android:color/background_dark"
         >
     <ScrollView
         android:layout_width="fill_parent"
@@ -35,10 +35,11 @@
             <TextView 
                 android:id="@+id/topHeader"
                 android:layout_width="fill_parent"
-                android:layout_height="wrap_content"
+                android:layout_height="64dip"
                 android:layout_alignParentTop="true"
-                android:textSize="24sp"
-                android:layout_marginTop="8dip"
+                android:layout_marginLeft="4dip"
+                android:textAppearance="?android:attr/textAppearanceMedium"
+                android:gravity="center_vertical"
                 android:drawableLeft="@drawable/ic_lock_idle_lock"
                 android:drawablePadding="5dip"
                 android:text="@android:string/lockscreen_glogin_too_many_attempts"
@@ -50,8 +51,7 @@
                 android:layout_width="fill_parent"
                 android:layout_height="1dip"
                 android:layout_below="@id/topHeader"
-                android:layout_marginTop="8dip"
-                android:background="@android:drawable/divider_horizontal_bright"/>
+                android:background="@drawable/divider_horizontal_dark"/>
         
             <TextView
                 android:id="@+id/instructions"
@@ -59,8 +59,8 @@
                 android:layout_height="wrap_content"
                 android:layout_below="@+id/spacerTop"
                 android:layout_marginTop="8dip"
-                android:gravity="center"
-                android:textSize="18sp"
+                android:layout_marginLeft="9dip"
+                android:textAppearance="?android:attr/textAppearanceSmall"
                 android:text="@android:string/lockscreen_glogin_instructions"
                 />
         
@@ -70,6 +70,8 @@
                 android:layout_height="wrap_content"
                 android:layout_below="@id/instructions"
                 android:layout_marginTop="8dip"
+                android:layout_marginLeft="7dip"
+                android:layout_marginRight="7dip"
                 android:hint="@android:string/lockscreen_glogin_username_hint"
                 android:inputType="textEmailAddress"
                 />
@@ -79,7 +81,9 @@
                 android:layout_width="fill_parent"
                 android:layout_height="wrap_content"
                 android:layout_below="@id/login"
-                android:layout_marginTop="8dip"
+                android:layout_marginTop="15dip"
+                android:layout_marginLeft="7dip"
+                android:layout_marginRight="7dip"
                 android:inputType="textPassword"
                 android:hint="@android:string/lockscreen_glogin_password_hint"
                 android:nextFocusRight="@+id/ok"
@@ -89,38 +93,35 @@
             <!-- ok below password, aligned to right of screen -->
             <Button
                 android:id="@+id/ok"
-                android:layout_width="wrap_content"
+                android:layout_width="85dip"
                 android:layout_height="wrap_content"
                 android:layout_below="@id/password"
-                android:layout_marginTop="8dip"
+                android:layout_marginTop="7dip"
+                android:layout_marginRight="7dip"
                 android:layout_alignParentRight="true"
-                android:textSize="18sp"
                 android:text="@android:string/lockscreen_glogin_submit_button"
                 />
         
         </RelativeLayout>
     </ScrollView>
     
-    <View android:layout_width="1dp" android:layout_height="3dp" />
-    
+    <!-- spacer above emergency call -->
+    <View
+        android:layout_width="fill_parent"
+        android:layout_height="1dip"
+        android:layout_marginBottom="4dip"
+
+        android:background="@drawable/divider_horizontal_dark"/>
+
     <!-- emergency call button at bottom center -->
     <Button
         android:id="@+id/emergencyCall"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_gravity="center"
-        android:layout_weight="0"
-        android:textSize="18sp"
         android:drawableLeft="@drawable/ic_emergency"
         android:drawablePadding="3dip"
         android:text="@android:string/lockscreen_emergency_call"
         />
 
-    <!-- spacer above emergency call (doesn't fit in landscape...)-->
-    <!--View
-        android:layout_width="fill_parent"
-        android:layout_height="1dip"
-        android:layout_above="@id/emergencyCall"
-        android:layout_marginBottom="8dip"
-        android:background="@android:drawable/divider_horizontal_bright"/-->
 </LinearLayout>
diff --git a/core/res/res/layout/keyguard_screen_lock.xml b/core/res/res/layout/keyguard_screen_lock.xml
index fbbc1a4..952fc5d 100644
--- a/core/res/res/layout/keyguard_screen_lock.xml
+++ b/core/res/res/layout/keyguard_screen_lock.xml
@@ -36,8 +36,8 @@
         android:layout_marginBottom="15dip"
         android:layout_marginLeft="15dip"
         android:layout_marginRight="15dip"
-	android:paddingTop="20dip"
-	android:paddingBottom="20dip"
+        android:paddingTop="20dip"
+        android:paddingBottom="20dip"
         android:background="@android:drawable/popup_full_dark"
         >
 
@@ -59,13 +59,15 @@
                   android:layout_height="wrap_content"
                   android:gravity="center"
                   android:text="@android:string/lockscreen_missing_sim_message"
-                  android:textSize="22sp"/>
+                  android:textAppearance="?android:attr/textAppearanceLarge"/>
         <TextView android:id="@+id/headerSimBad2"
                   android:layout_width="fill_parent"
                   android:layout_height="wrap_content"
+                  android:layout_marginTop="7dip"
+                  android:layout_marginBottom="7dip"
                   android:gravity="center"
                   android:text="@android:string/lockscreen_missing_sim_instructions"
-                  android:textSize="20sp"/>
+                  android:textAppearance="?android:attr/textAppearanceSmall"/>
 
         <!-- spacer after carrier info / sim messages -->
         <View
@@ -203,17 +205,15 @@
         <!-- emergency call button shown when sim is missing or PUKd -->
         <Button
             android:id="@+id/emergencyCallButton"
-            android:layout_width="fill_parent"
+            android:layout_width="wrap_content"
             android:layout_height="wrap_content"
-            android:layout_marginLeft="5dip"
-            android:layout_marginRight="5dip"
             android:layout_marginBottom="5dip"
-            android:drawableTop="@drawable/ic_emergency"
+            android:layout_marginTop="5dip"
+            android:layout_gravity="center_horizontal"
+            android:drawableLeft="@drawable/ic_emergency"
             android:drawablePadding="3dip"
             android:text="@android:string/lockscreen_emergency_call"
-            android:textSize="14sp"
            />
 
-
     </LinearLayout>
 </LinearLayout>
diff --git a/core/res/res/layout/zoom_browser_accessory_buttons.xml b/core/res/res/layout/zoom_browser_accessory_buttons.xml
new file mode 100644
index 0000000..4bf2bdf
--- /dev/null
+++ b/core/res/res/layout/zoom_browser_accessory_buttons.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+-->
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+    <ImageView android:id="@+id/zoom_fit_page" 
+        android:background="@android:drawable/btn_browser_zoom_fit_page"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom|left"
+        android:layout_marginLeft="7dip"
+        />
+    <ImageView android:id="@+id/zoom_page_overview" 
+        android:background="@android:drawable/btn_browser_zoom_page_overview"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="bottom|right"
+        android:layout_marginRight="7dip"
+        />
+</merge>
diff --git a/core/res/res/layout/zoom_container.xml b/core/res/res/layout/zoom_container.xml
new file mode 100644
index 0000000..fc5cf3d
--- /dev/null
+++ b/core/res/res/layout/zoom_container.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License"); 
+** you may not use this file except in compliance with the License. 
+** You may obtain a copy of the License at 
+**
+**     http://www.apache.org/licenses/LICENSE-2.0 
+**
+** Unless required by applicable law or agreed to in writing, software 
+** distributed under the License is distributed on an "AS IS" BASIS, 
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+** See the License for the specific language governing permissions and 
+** limitations under the License.
+*/
+-->
+<merge xmlns:android="http://schemas.android.com/apk/res/android">
+    <ZoomControls android:id="@+id/zoomControls"
+        android:layout_gravity="bottom|center_horizontal"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        style="@style/ZoomControls"
+        android:background="@null"
+        />
+</merge>
diff --git a/core/res/res/layout/zoom_controls.xml b/core/res/res/layout/zoom_controls.xml
index 729af1b..95cf1d5 100644
--- a/core/res/res/layout/zoom_controls.xml
+++ b/core/res/res/layout/zoom_controls.xml
@@ -18,13 +18,13 @@
 */
 -->
 <merge xmlns:android="http://schemas.android.com/apk/res/android">
-    <ZoomButton android:id="@+id/zoomIn" 
-        android:background="@android:drawable/btn_plus"
+    <ZoomButton android:id="@+id/zoomOut" 
+        android:background="@android:drawable/btn_zoom_down" 
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         />
-    <ZoomButton android:id="@+id/zoomOut" 
-        android:background="@android:drawable/btn_minus" 
+    <ZoomButton android:id="@+id/zoomIn" 
+        android:background="@android:drawable/btn_zoom_up"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         />
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 5fa5f8d..899d109 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -586,7 +586,7 @@
         <!-- There is no specific action associated with this editor, let the
              editor come up with its own if it can.
              Corresponds to
-             {@link android.view.inputmethod.EditorInfo#IME_ACTION_UNSPECIFIED}. -->
+             {@link android.view.inputmethod.EditorInfo#IME_NULL}. -->
         <flag name="actionUnspecified" value="0x00000000" />
         <!-- This editor has no action associated with it.
              Corresponds to
@@ -595,28 +595,38 @@
         <!-- The action key performs a "go"
              operation to take the user to the target of the text they typed.
              Typically used, for example, when entering a URL.
+             Corresponds to
              {@link android.view.inputmethod.EditorInfo#IME_ACTION_GO}. -->
         <flag name="actionGo" value="0x00000002" />
         <!-- The action key performs a "search"
              operation, taking the user to the results of searching for the text
              the have typed (in whatever context is appropriate).
+             Corresponds to
              {@link android.view.inputmethod.EditorInfo#IME_ACTION_SEARCH}. -->
         <flag name="actionSearch" value="0x00000003" />
         <!-- The action key performs a "send"
              operation, delivering the text to its target.  This is typically used
              when composing a message.
+             Corresponds to
              {@link android.view.inputmethod.EditorInfo#IME_ACTION_SEND}. -->
         <flag name="actionSend" value="0x00000004" />
         <!-- The action key performs a "next"
              operation, taking the user to the next field that will accept text.
+             Corresponds to
              {@link android.view.inputmethod.EditorInfo#IME_ACTION_NEXT}. -->
         <flag name="actionNext" value="0x00000005" />
+        <!-- The action key performs a "done"
+             operation, closing the soft input method.
+             Corresponds to
+             {@link android.view.inputmethod.EditorInfo#IME_ACTION_DONE}. -->
+        <flag name="actionDone" value="0x00000006" />
         <!-- Used in conjunction with a custom action,
              this indicates that the action should not
              be available in-line as the same as a "enter" key.  Typically this is
              because the action has such a significant impact or is not recoverable
              enough that accidentally hitting it should be avoided, such as sending
              a message.
+             <p>Corresponds to
              {@link android.view.inputmethod.EditorInfo#IME_FLAG_NO_ENTER_ACTION}. -->
         <flag name="flagNoEnterAction" value="0x40000000" />
     </attr>
@@ -3115,23 +3125,23 @@
     </declare-styleable>
 
     <!-- =============================== -->
-    <!-- Gadget package class attributes -->
+    <!-- AppWidget package class attributes -->
     <!-- =============================== -->
 
-    <!-- Use <code>gadget-provider</code> as the root tag of the XML resource that
-         describes a gadget provider.  See TODO android.gadget package
+    <!-- Use <code>appwidget-provider</code> as the root tag of the XML resource that
+         describes an AppWidget provider.  See TODO android.appwidget package
          for more info.
      -->
-    <declare-styleable name="GadgetProviderInfo">
-        <!-- Minimum width of the gadget. -->
+    <declare-styleable name="AppWidgetProviderInfo">
+        <!-- Minimum width of the AppWidget. -->
         <attr name="minWidth"/>
-        <!-- Minimum height of the gadget. -->
+        <!-- Minimum height of the AppWidget. -->
         <attr name="minHeight"/>
-        <!-- Update period in milliseconds, or 0 if the gadget will update itself. -->
+        <!-- Update period in milliseconds, or 0 if the AppWidget will update itself. -->
         <attr name="updatePeriodMillis" format="integer" />
         <!-- A resource id of a layout. -->
         <attr name="initialLayout" format="reference" />
-        <!-- A class name in the gadget's package to be launched to configure.
+        <!-- A class name in the AppWidget's package to be launched to configure.
              If not supplied, then no activity will be launched. -->
         <attr name="configure" format="string" />
     </declare-styleable>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index cb63e17..761cedd 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1184,7 +1184,7 @@
     <!-- Title of the unlock screen that uses your Google login and password -->
     <string name="lockscreen_glogin_too_many_attempts">Too many pattern attempts!</string>
     <!-- In the unlock screen, message telling the user that they need to use their Google login and password to unlock the phone -->
-    <string name="lockscreen_glogin_instructions">To unlock,\nsign in with your Google account</string>
+    <string name="lockscreen_glogin_instructions">To unlock, sign in with your Google account</string>
     <!-- Hint caption for the username field when unlocking the phone using login and password -->
     <string name="lockscreen_glogin_username_hint">Username (email)</string>
     <!-- Hint caption for the password field when unlocking the phone using login and password -->
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 54eba62..ff8f8c2 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -144,6 +144,13 @@
         <item name="windowExitAnimation">@anim/search_bar_exit</item>
     </style>
 
+    <!-- Window animations that are applied to the zoom buttons overlay window.
+         {@hide Pending API council approval} -->
+    <style name="Animation.ZoomButtons">
+        <item name="windowEnterAnimation">@anim/fade_in</item>
+        <item name="windowExitAnimation">@anim/fade_out</item>
+    </style>
+
     <!-- Status Bar Styles -->
 
     <style name="TextAppearance.StatusBarTitle">