Merge "Fix issue #5180553: permission RECEIVE_BOOT_COMPLETED is not checked"
diff --git a/api/current.txt b/api/current.txt
index d377109..4332833 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -11431,7 +11431,7 @@
     method public android.net.NetworkInfo getActiveNetworkInfo();
     method public android.net.NetworkQuotaInfo getActiveNetworkQuotaInfo();
     method public android.net.NetworkInfo[] getAllNetworkInfo();
-    method public boolean getBackgroundDataSetting();
+    method public deprecated boolean getBackgroundDataSetting();
     method public android.net.NetworkInfo getNetworkInfo(int);
     method public int getNetworkPreference();
     method public static boolean isNetworkTypeValid(int);
@@ -17087,7 +17087,7 @@
     field public static final java.lang.String ALLOWED_GEOLOCATION_ORIGINS = "allowed_geolocation_origins";
     field public static final java.lang.String ALLOW_MOCK_LOCATION = "mock_location";
     field public static final java.lang.String ANDROID_ID = "android_id";
-    field public static final java.lang.String BACKGROUND_DATA = "background_data";
+    field public static final deprecated java.lang.String BACKGROUND_DATA = "background_data";
     field public static final java.lang.String BLUETOOTH_ON = "bluetooth_on";
     field public static final android.net.Uri CONTENT_URI;
     field public static final java.lang.String DATA_ROAMING = "data_roaming";
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 53fd50d..9c96883 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -21,6 +21,7 @@
 import android.annotation.SdkConstant;
 import android.annotation.SdkConstant.SdkConstantType;
 import android.os.Binder;
+import android.os.Build.VERSION_CODES;
 import android.os.RemoteException;
 
 import java.net.InetAddress;
@@ -503,16 +504,19 @@
      * <p>
      * All applications that have background services that use the network
      * should listen to {@link #ACTION_BACKGROUND_DATA_SETTING_CHANGED}.
+     * <p>
+     * As of {@link VERSION_CODES#ICE_CREAM_SANDWICH}, availability of
+     * background data depends on several combined factors, and this method will
+     * always return {@code true}. Instead, when background data is unavailable,
+     * {@link #getActiveNetworkInfo()} will now appear disconnected.
      *
      * @return Whether background data usage is allowed.
      */
+    @Deprecated
     public boolean getBackgroundDataSetting() {
-        try {
-            return mService.getBackgroundDataSetting();
-        } catch (RemoteException e) {
-            // Err on the side of safety
-            return false;
-        }
+        // assume that background data is allowed; final authority is
+        // NetworkInfo which may be blocked.
+        return true;
     }
 
     /**
@@ -525,11 +529,9 @@
      * @see #getBackgroundDataSetting()
      * @hide
      */
+    @Deprecated
     public void setBackgroundDataSetting(boolean allowBackgroundData) {
-        try {
-            mService.setBackgroundDataSetting(allowBackgroundData);
-        } catch (RemoteException e) {
-        }
+        // ignored
     }
 
     /**
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index f391200..1b95b60 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -63,10 +63,6 @@
 
     boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress);
 
-    boolean getBackgroundDataSetting();
-
-    void setBackgroundDataSetting(boolean allowBackgroundData);
-
     boolean getMobileDataEnabled();
 
     void setMobileDataEnabled(boolean enabled);
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index 78c9010..1029161 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -589,8 +589,6 @@
             mPreferenceManager.setOnPreferenceTreeClickListener(this);
         }
 
-        getListView().setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
-
         // see if we should show Back/Next buttons
         Intent intent = getIntent();
         if (intent.getBooleanExtra(EXTRA_PREFS_SHOW_BUTTON_BAR, false)) {
diff --git a/core/java/android/preference/PreferenceFragment.java b/core/java/android/preference/PreferenceFragment.java
index f6ba7f7..bdd858b 100644
--- a/core/java/android/preference/PreferenceFragment.java
+++ b/core/java/android/preference/PreferenceFragment.java
@@ -159,7 +159,6 @@
     @Override
     public void onActivityCreated(Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
-        getListView().setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
 
         if (mHavePrefs) {
             bindPreferences();
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index de06f20..554afd2 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3081,6 +3081,7 @@
          * Whether background data usage is allowed by the user. See
          * ConnectivityManager for more info.
          */
+        @Deprecated
         public static final String BACKGROUND_DATA = "background_data";
 
         /**
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 642aa22..77f6776 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -1807,7 +1807,9 @@
      * @hide
      */
     public void setProperty(String key, String value) {
-        mWebView.nativeSetProperty(key, value);
+        if (mWebView.nativeSetProperty(key, value)) {
+            mWebView.contentInvalidateAll();
+        }
     }
 
     /**
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 6374b47..5d776fd 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -9036,15 +9036,6 @@
     }
 
     /**
-     * Enable expanded tiles bound for smoother scrolling.
-     *
-     * @hide only used by the Browser
-     */
-    public void setExpandedTileBounds(boolean enabled) {
-        nativeSetExpandedTileBounds(enabled);
-    }
-
-    /**
      * Set the time to wait between passing touches to WebCore. See also the
      * TOUCH_SENT_INTERVAL member for further discussion.
      *
@@ -9273,7 +9264,6 @@
     static final int NO_LEFTEDGE = -1;
     native int nativeGetBlockLeftEdge(int x, int y, float scale);
 
-    private native void     nativeSetExpandedTileBounds(boolean enabled);
     private native void     nativeUseHardwareAccelSkia(boolean enabled);
 
     // Returns a pointer to the scrollable LayerAndroid at the given point.
@@ -9288,6 +9278,6 @@
      */
     private native boolean  nativeScrollLayer(int layer, int newX, int newY);
     private native int      nativeGetBackgroundColor();
-    native void     nativeSetProperty(String key, String value);
+    native boolean  nativeSetProperty(String key, String value);
     native String   nativeGetProperty(String key);
 }
diff --git a/core/java/android/widget/ActivityChooserView.java b/core/java/android/widget/ActivityChooserView.java
index 45d73af..6a84626 100644
--- a/core/java/android/widget/ActivityChooserView.java
+++ b/core/java/android/widget/ActivityChooserView.java
@@ -156,7 +156,7 @@
      * @param attrs A collection of attributes.
      */
     public ActivityChooserView(Context context, AttributeSet attrs) {
-        this(context, attrs, R.attr.actionButtonStyle);
+        this(context, attrs, 0);
     }
 
     /**
diff --git a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
index 5c42579..dd75925 100644
--- a/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ActionMenuPresenter.java
@@ -391,7 +391,6 @@
                 final boolean inGroup = seenGroups.get(groupId);
                 boolean isAction = (maxActions > 0 || inGroup) && widthLimit > 0 &&
                         (!mStrictWidthLimit || cellsRemaining > 0);
-                maxActions--;
 
                 if (isAction) {
                     View v = getItemView(item, mScrapActionButtonView, parent);
@@ -430,11 +429,15 @@
                     for (int j = 0; j < i; j++) {
                         MenuItemImpl areYouMyGroupie = visibleItems.get(j);
                         if (areYouMyGroupie.getGroupId() == groupId) {
+                            // Give back the action slot
+                            if (areYouMyGroupie.isActionButton()) maxActions++;
                             areYouMyGroupie.setIsActionButton(false);
                         }
                     }
                 }
 
+                if (isAction) maxActions--;
+
                 item.setIsActionButton(isAction);
             }
         }
diff --git a/core/java/com/android/internal/view/menu/MenuBuilder.java b/core/java/com/android/internal/view/menu/MenuBuilder.java
index 5e70e4c..5622b44 100644
--- a/core/java/com/android/internal/view/menu/MenuBuilder.java
+++ b/core/java/com/android/internal/view/menu/MenuBuilder.java
@@ -567,7 +567,7 @@
             }
         }
 
-        if (changedAtLeastOneItem) onItemsChanged(false);
+        if (changedAtLeastOneItem) onItemsChanged(true);
     }
 
     public void setGroupEnabled(int group, boolean enabled) {
@@ -929,6 +929,7 @@
      * 
      * @param structureChanged true if the menu structure changed,
      *                         false if only item properties changed.
+     *                         (Visibility is a structural property since it affects layout.)
      */
     void onItemsChanged(boolean structureChanged) {
         if (!mPreventDispatchingItemsChanged) {
@@ -971,7 +972,7 @@
     void onItemVisibleChanged(MenuItemImpl item) {
         // Notify of items being changed
         mIsVisibleItemsStale = true;
-        onItemsChanged(false);
+        onItemsChanged(true);
     }
     
     /**
@@ -981,7 +982,7 @@
     void onItemActionRequestChanged(MenuItemImpl item) {
         // Notify of items being changed
         mIsActionItemsStale = true;
-        onItemsChanged(false);
+        onItemsChanged(true);
     }
     
     ArrayList<MenuItemImpl> getVisibleItems() {
diff --git a/core/java/com/android/internal/view/menu/MenuItemImpl.java b/core/java/com/android/internal/view/menu/MenuItemImpl.java
index 8b53bb8..04147ab 100644
--- a/core/java/com/android/internal/view/menu/MenuItemImpl.java
+++ b/core/java/com/android/internal/view/menu/MenuItemImpl.java
@@ -585,7 +585,7 @@
     public MenuItem setActionProvider(ActionProvider actionProvider) {
         mActionView = null;
         mActionProvider = actionProvider;
-        mMenu.onItemsChanged(false);
+        mMenu.onItemsChanged(true); // Measurement can be changed
         return this;
     }
 
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 7baa412..792766b 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -1036,6 +1036,8 @@
                 } else if (centeredLeft + navWidth > menuLeft) {
                     hgravity = Gravity.RIGHT;
                 }
+            } else if (gravity == -1) {
+                hgravity = Gravity.LEFT;
             }
 
             int xpos = 0;
@@ -1051,8 +1053,14 @@
                     break;
             }
 
+            int vgravity = gravity & Gravity.VERTICAL_GRAVITY_MASK;
+
+            if (gravity == -1) {
+                vgravity = Gravity.CENTER_VERTICAL;
+            }
+
             int ypos = 0;
-            switch (gravity & Gravity.VERTICAL_GRAVITY_MASK) {
+            switch (vgravity) {
                 case Gravity.CENTER_VERTICAL:
                     final int paddedTop = getPaddingTop();
                     final int paddedBottom = mBottom - mTop - getPaddingBottom();
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index 45b7f27..b369efb 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -507,6 +507,7 @@
 #define EVENT_LOOP_EXIT 1
 #define EVENT_LOOP_ADD  2
 #define EVENT_LOOP_REMOVE 3
+#define EVENT_LOOP_WAKEUP 4
 
 dbus_bool_t dbusAddWatch(DBusWatch *watch, void *data) {
     native_data_t *nat = (native_data_t *)data;
@@ -551,6 +552,13 @@
     }
 }
 
+void dbusWakeup(void *data) {
+    native_data_t *nat = (native_data_t *)data;
+
+    char control = EVENT_LOOP_WAKEUP;
+    write(nat->controlFdW, &control, sizeof(char));
+}
+
 static void handleWatchAdd(native_data_t *nat) {
     DBusWatch *watch;
     int newFD;
@@ -634,6 +642,7 @@
 
     dbus_connection_set_watch_functions(nat->conn, dbusAddWatch,
             dbusRemoveWatch, dbusToggleWatch, ptr, NULL);
+    dbus_connection_set_wakeup_main_function(nat->conn, dbusWakeup, ptr, NULL);
 
     nat->running = true;
 
@@ -669,6 +678,11 @@
                         handleWatchRemove(nat);
                         break;
                     }
+                    case EVENT_LOOP_WAKEUP:
+                    {
+                        // noop
+                        break;
+                    }
                     }
                 }
             } else {
diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp
index b432d65..b8f2d6f 100644
--- a/core/jni/android_util_Binder.cpp
+++ b/core/jni/android_util_Binder.cpp
@@ -385,7 +385,8 @@
 {
 public:
     JavaDeathRecipient(JNIEnv* env, jobject object, const sp<DeathRecipientList>& list)
-        : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)), mList(list)
+        : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object)),
+          mObjectWeak(NULL), mList(list)
     {
         // These objects manage their own lifetimes so are responsible for final bookkeeping.
         // The list holds a strong reference to this object.
@@ -398,16 +399,23 @@
 
     void binderDied(const wp<IBinder>& who)
     {
-        JNIEnv* env = javavm_to_jnienv(mVM);
-
         LOGDEATH("Receiving binderDied() on JavaDeathRecipient %p\n", this);
+        if (mObject != NULL) {
+            JNIEnv* env = javavm_to_jnienv(mVM);
 
-        env->CallStaticVoidMethod(gBinderProxyOffsets.mClass,
-            gBinderProxyOffsets.mSendDeathNotice, mObject);
-        jthrowable excep = env->ExceptionOccurred();
-        if (excep) {
-            report_exception(env, excep,
-                "*** Uncaught exception returned from death notification!");
+            env->CallStaticVoidMethod(gBinderProxyOffsets.mClass,
+                    gBinderProxyOffsets.mSendDeathNotice, mObject);
+            jthrowable excep = env->ExceptionOccurred();
+            if (excep) {
+                report_exception(env, excep,
+                        "*** Uncaught exception returned from death notification!");
+            }
+
+            // Demote from strong ref to weak after binderDied() has been delivered,
+            // to allow the DeathRecipient and BinderProxy to be GC'd if no longer needed.
+            mObjectWeak = env->NewWeakGlobalRef(mObject);
+            env->DeleteGlobalRef(mObject);
+            mObject = NULL;
         }
     }
 
@@ -423,8 +431,17 @@
     }
 
     bool matches(jobject obj) {
+        bool result;
         JNIEnv* env = javavm_to_jnienv(mVM);
-        return env->IsSameObject(obj, mObject);
+
+        if (mObject != NULL) {
+            result = env->IsSameObject(obj, mObject);
+        } else {
+            jobject me = env->NewLocalRef(mObjectWeak);
+            result = env->IsSameObject(obj, me);
+            env->DeleteLocalRef(me);
+        }
+        return result;
     }
 
 protected:
@@ -433,12 +450,17 @@
         //LOGI("Removing death ref: recipient=%p\n", mObject);
         android_atomic_dec(&gNumDeathRefs);
         JNIEnv* env = javavm_to_jnienv(mVM);
-        env->DeleteGlobalRef(mObject);
+        if (mObject != NULL) {
+            env->DeleteGlobalRef(mObject);
+        } else {
+            env->DeleteWeakGlobalRef(mObjectWeak);
+        }
     }
 
 private:
-    JavaVM* const   mVM;
-    jobject const   mObject;
+    JavaVM* const mVM;
+    jobject mObject;
+    jweak mObjectWeak; // will be a weak ref to the same VM-side DeathRecipient after binderDied()
     wp<DeathRecipientList> mList;
 };
 
@@ -512,7 +534,7 @@
     if (val->checkSubclass(&gBinderOffsets)) {
         // One of our own!
         jobject object = static_cast<JavaBBinder*>(val.get())->object();
-        //printf("objectForBinder %p: it's our own %p!\n", val.get(), object);
+        LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
         return object;
     }
 
@@ -528,7 +550,7 @@
             LOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
             return res;
         }
-        LOGV("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
+        LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
         android_atomic_dec(&gNumProxyRefs);
         val->detachObject(&gBinderProxyOffsets);
         env->DeleteGlobalRef(object);
diff --git a/core/res/res/layout-sw600dp/preference_list_content.xml b/core/res/res/layout-sw600dp/preference_list_content.xml
index 5b67d71..08f6453 100644
--- a/core/res/res/layout-sw600dp/preference_list_content.xml
+++ b/core/res/res/layout-sw600dp/preference_list_content.xml
@@ -44,8 +44,11 @@
                 android:layout_width="match_parent"
                 android:layout_height="0px"
                 android:layout_weight="1"
-                android:paddingTop="16dp"
-                android:paddingBottom="16dp"
+                android:paddingLeft="@dimen/preference_screen_header_padding_side"
+                android:paddingRight="@dimen/preference_screen_header_padding_side"
+                android:paddingTop="@dimen/preference_screen_header_vertical_padding"
+                android:paddingBottom="@dimen/preference_screen_header_vertical_padding"
+                android:scrollbarStyle="@integer/preference_screen_header_scrollbarStyle"
                 android:drawSelectorOnTop="false"
                 android:cacheColorHint="@android:color/transparent"
                 android:listPreferredItemHeight="48dp"
diff --git a/core/res/res/layout/activity_chooser_view.xml b/core/res/res/layout/activity_chooser_view.xml
index 5d82a97..82e1f83 100644
--- a/core/res/res/layout/activity_chooser_view.xml
+++ b/core/res/res/layout/activity_chooser_view.xml
@@ -22,7 +22,8 @@
     android:layout_height="wrap_content"
     android:layout_gravity="center"
     android:gravity="center"
-    style="?android:attr/actionButtonStyle">
+    style="?android:attr/actionButtonStyle"
+    android:padding="0dip">
 
     <FrameLayout
         android:id="@+id/default_activity_button"
@@ -31,7 +32,7 @@
         android:layout_gravity="center"
         android:focusable="true"
         android:addStatesFromChildren="true"
-        android:background="?android:attr/selectableItemBackground">
+        android:background="?android:attr/actionBarItemBackground">
 
         <ImageView android:id="@+id/image"
             android:layout_width="32dip"
@@ -53,7 +54,7 @@
         android:layout_gravity="center"
         android:focusable="true"
         android:addStatesFromChildren="true"
-        android:background="?android:attr/selectableItemBackground">
+        android:background="?android:attr/actionBarItemBackground">
 
         <ImageView android:id="@+id/image"
             android:layout_width="32dip"
diff --git a/core/res/res/layout/breadcrumbs_in_fragment.xml b/core/res/res/layout/breadcrumbs_in_fragment.xml
index 98fffb7..9c12618 100644
--- a/core/res/res/layout/breadcrumbs_in_fragment.xml
+++ b/core/res/res/layout/breadcrumbs_in_fragment.xml
@@ -13,10 +13,10 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
+
 <!-- This layout disables breadcrumbs in the fragment area and causes PreferenceActivity to
     put the breadcrumbs in the action bar. -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:orientation="vertical"
-        android:layout_height="@dimen/preference_fragment_padding_side"
-        android:layout_width="match_parent">
-</LinearLayout>
\ No newline at end of file
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="0dip"
+    android:layout_height="0dip"
+    android:visibility="gone" />
diff --git a/core/res/res/layout/preference_list_content.xml b/core/res/res/layout/preference_list_content.xml
index 4e7981a..62181b5 100644
--- a/core/res/res/layout/preference_list_content.xml
+++ b/core/res/res/layout/preference_list_content.xml
@@ -44,8 +44,11 @@
                 android:layout_width="match_parent"
                 android:layout_height="0px"
                 android:layout_weight="1"
+                android:paddingLeft="@dimen/preference_screen_header_padding_side"
+                android:paddingRight="@dimen/preference_screen_header_padding_side"
                 android:paddingTop="@dimen/preference_screen_header_vertical_padding"
                 android:paddingBottom="@dimen/preference_screen_header_vertical_padding"
+                android:scrollbarStyle="@integer/preference_screen_header_scrollbarStyle"
                 android:drawSelectorOnTop="false"
                 android:cacheColorHint="@android:color/transparent"
                 android:listPreferredItemHeight="48dp"
diff --git a/core/res/res/layout/preference_list_fragment.xml b/core/res/res/layout/preference_list_fragment.xml
index 315f708..fdef4fc 100644
--- a/core/res/res/layout/preference_list_fragment.xml
+++ b/core/res/res/layout/preference_list_fragment.xml
@@ -32,11 +32,19 @@
         android:paddingBottom="@dimen/preference_fragment_padding_bottom"
         android:paddingLeft="@dimen/preference_fragment_padding_side"
         android:paddingRight="@dimen/preference_fragment_padding_side"
+        android:scrollbarStyle="@integer/preference_fragment_scrollbarStyle"
         android:clipToPadding="false"
         android:drawSelectorOnTop="false"
         android:cacheColorHint="@android:color/transparent"
         android:scrollbarAlwaysDrawVerticalTrack="true" />
 
+    <TextView android:id="@android:id/empty"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:padding="@dimen/preference_fragment_padding_side"
+        android:gravity="center"
+        android:visibility="gone" />
+
     <RelativeLayout android:id="@+id/button_bar"
         android:layout_height="wrap_content"
         android:layout_width="match_parent"
diff --git a/core/res/res/values-h720dp/dimens.xml b/core/res/res/values-h720dp/dimens.xml
index 37dee8e..7efe322 100644
--- a/core/res/res/values-h720dp/dimens.xml
+++ b/core/res/res/values-h720dp/dimens.xml
@@ -25,4 +25,10 @@
     <dimen name="preference_screen_top_margin">16dp</dimen>
     <!-- Preference activity bottom margin -->
     <dimen name="preference_screen_bottom_margin">16dp</dimen>
+
+    <dimen name="preference_screen_header_padding_side">0dip</dimen>
+
+    <integer name="preference_screen_header_scrollbarStyle">0x0</integer> <!-- insideOverlay -->
+    <integer name="preference_fragment_scrollbarStyle">0x0</integer> <!-- insideOverlay -->
+
 </resources>
diff --git a/core/res/res/values-w720dp/dimens.xml b/core/res/res/values-w720dp/dimens.xml
index 3d10103..c62c3f5 100644
--- a/core/res/res/values-w720dp/dimens.xml
+++ b/core/res/res/values-w720dp/dimens.xml
@@ -29,4 +29,9 @@
         This helps in aligning titles when some items have icons and some don't. When space is
         at a premium, we don't pre-allocate any space. -->
     <dimen name="preference_icon_minWidth">56dp</dimen>
+
+    <dimen name="preference_screen_header_padding_side">0dip</dimen>
+
+    <integer name="preference_screen_header_scrollbarStyle">0x0</integer> <!-- insideOverlay -->
+    <integer name="preference_fragment_scrollbarStyle">0x0</integer> <!-- insideOverlay -->
 </resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 40355e3..aa3397f 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -5264,9 +5264,9 @@
         <!-- Specifies a background drawable for the action bar. -->
         <attr name="background" />
         <!-- Specifies a background drawable for a second stacked row of the action bar. -->
-        <attr name="backgroundStacked" format="reference" />
+        <attr name="backgroundStacked" format="reference|color" />
         <!-- Specifies a background drawable for the bottom component of a split action bar. -->
-        <attr name="backgroundSplit" format="reference" />
+        <attr name="backgroundSplit" format="reference|color" />
         <!-- Specifies a layout for custom navigation. Overrides navigationMode. -->
         <attr name="customNavigationLayout" format="reference" />
         <!-- Specifies a fixed height. -->
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 8855645..83e86939 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -76,9 +76,9 @@
     <dimen name="multiwaveview_hit_radius">60dip</dimen>
 
     <!-- Preference activity side margins -->
-    <dimen name="preference_screen_side_margin">16dp</dimen>
+    <dimen name="preference_screen_side_margin">0dp</dimen>
     <!-- Preference activity side margins negative-->
-    <dimen name="preference_screen_side_margin_negative">16dp</dimen>
+    <dimen name="preference_screen_side_margin_negative">0dp</dimen>
     <!-- Preference activity top margin -->
     <dimen name="preference_screen_top_margin">0dp</dimen>
     <!-- Preference activity bottom margin -->
@@ -88,7 +88,7 @@
     <!-- Preference fragment padding, bottom -->
     <dimen name="preference_fragment_padding_bottom">0dp</dimen>
     <!-- Preference fragment padding, sides -->
-    <dimen name="preference_fragment_padding_side">0dp</dimen>
+    <dimen name="preference_fragment_padding_side">16dp</dimen>
     <!-- Weight of the left pane in a multi-pane preference layout. -->
     <integer name="preferences_left_pane_weight">4</integer>
     <!-- Weight of the right pane in a multi-pane preference layout. So the split is 40:60 -->
@@ -108,6 +108,11 @@
     <!-- Preference activity, vertical padding for the header list -->
     <dimen name="preference_screen_header_vertical_padding">0dp</dimen>
 
+    <dimen name="preference_screen_header_padding_side">16dip</dimen>
+    <integer name="preference_screen_header_scrollbarStyle">0x02000000</integer> <!-- outsideOverlay -->
+
+    <integer name="preference_fragment_scrollbarStyle">0x02000000</integer> <!-- outsideOverlay -->
+
     <dimen name="preference_item_padding_side">8dip</dimen>
     <dimen name="preference_item_padding_inner">8dip</dimen>
     <dimen name="preference_child_padding_side">16dip</dimen>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 128889c..6aff54e 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -3099,7 +3099,7 @@
     <!-- Notification title when mobile data usage has exceeded limit threshold, and has been disabled. [CHAR LIMIT=32] -->
     <string name="data_usage_mobile_limit_title">Mobile data disabled</string>
     <!-- Notification body when data usage has exceeded limit threshold, and has been disabled. [CHAR LIMIT=32] -->
-    <string name="data_usage_limit_body">tap to enable</string>
+    <string name="data_usage_limit_body">Touch to enable</string>
 
     <!-- Notification title when 2G-3G data usage has exceeded limit threshold. [CHAR LIMIT=32] -->
     <string name="data_usage_3g_limit_snoozed_title">2G-3G data limit exceeded</string>
@@ -3110,6 +3110,11 @@
     <!-- Notification body when data usage has exceeded limit threshold. [CHAR LIMIT=32] -->
     <string name="data_usage_limit_snoozed_body"><xliff:g id="size" example="3.8GB">%s</xliff:g> over specified limit</string>
 
+    <!-- Notification title when background data usage is limited. [CHAR LIMIT=32] -->
+    <string name="data_usage_restricted_title">Background data restricted</string>
+    <!-- Notification body when background data usage is limited. [CHAR LIMIT=32] -->
+    <string name="data_usage_restricted_body">Touch to remove restriction</string>
+
     <!-- SSL Certificate dialogs -->
     <!-- Title for an SSL Certificate dialog -->
     <string name="ssl_certificate">Security certificate</string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 6f2f1e5..94c6e41 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -2363,7 +2363,7 @@
 
     <style name="Widget.Holo.PreferenceFrameLayout">
         <item name="android:borderTop">0dip</item>
-        <item name="android:borderBottom">@dimen/preference_fragment_padding_side</item>
+        <item name="android:borderBottom">@dimen/preference_fragment_padding_bottom</item>
         <item name="android:borderLeft">@dimen/preference_fragment_padding_side</item>
         <item name="android:borderRight">@dimen/preference_fragment_padding_side</item>
     </style>
diff --git a/core/tests/coretests/src/android/provider/SettingsProviderTest.java b/core/tests/coretests/src/android/provider/SettingsProviderTest.java
index b82e698..3e96dc4 100644
--- a/core/tests/coretests/src/android/provider/SettingsProviderTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsProviderTest.java
@@ -20,11 +20,16 @@
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.database.Cursor;
 import android.net.Uri;
 import android.provider.Settings;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.MediumTest;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import java.util.List;
 
 /** Unit test for SettingsProvider. */
 public class SettingsProviderTest extends AndroidTestCase {
@@ -191,4 +196,49 @@
         assertEquals("test1,test2",
                 Settings.Secure.getString(r, Settings.Secure.LOCATION_PROVIDERS_ALLOWED));
      }
+
+     @SmallTest
+     public void testSettings() {
+        assertCanBeHandled(new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_ADD_ACCOUNT));
+        assertCanBeHandled(new Intent(Settings.ACTION_AIRPLANE_MODE_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_APN_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
+                .setData(Uri.parse("package:" + getContext().getPackageName())));
+        assertCanBeHandled(new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_APPLICATION_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_BLUETOOTH_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_DATE_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_DEVICE_INFO_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_DISPLAY_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_INPUT_METHOD_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_INTERNAL_STORAGE_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_LOCALE_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_MANAGE_ALL_APPLICATIONS_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_MANAGE_APPLICATIONS_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_MEMORY_CARD_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_NETWORK_OPERATOR_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_PRIVACY_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_QUICK_LAUNCH_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_SEARCH_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_SECURITY_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_SOUND_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_SYNC_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_SYSTEM_UPDATE_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_USER_DICTIONARY_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_WIFI_IP_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_WIFI_SETTINGS));
+        assertCanBeHandled(new Intent(Settings.ACTION_WIRELESS_SETTINGS));
+    }
+
+    private void assertCanBeHandled(final Intent intent) {
+        PackageManager packageManager = mContext.getPackageManager();
+        List<ResolveInfo> resolveInfoList = packageManager.queryIntentActivities(intent, 0);
+        assertNotNull(resolveInfoList);
+        // one or more activity can handle this intent.
+        assertTrue(resolveInfoList.size() > 0);
+    }
 }
diff --git a/include/surfaceflinger/ISurfaceComposer.h b/include/surfaceflinger/ISurfaceComposer.h
index dba98a3..6b31ca4 100644
--- a/include/surfaceflinger/ISurfaceComposer.h
+++ b/include/surfaceflinger/ISurfaceComposer.h
@@ -132,9 +132,10 @@
     virtual status_t turnElectronBeamOff(int32_t mode) = 0;
     virtual status_t turnElectronBeamOn(int32_t mode) = 0;
 
-    /* verify that an ISurface was created by SurfaceFlinger.
+    /* verify that an ISurfaceTexture was created by SurfaceFlinger.
      */
-    virtual bool authenticateSurface(const sp<ISurface>& surface) const = 0;
+    virtual bool authenticateSurfaceTexture(
+            const sp<ISurfaceTexture>& surface) const = 0;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index c1156d5..030a83e 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -31,6 +31,8 @@
 
 #include <ui/DisplayInfo.h>
 
+#include <gui/ISurfaceTexture.h>
+
 #include <utils/Log.h>
 
 // ---------------------------------------------------------------------------
@@ -166,35 +168,36 @@
         return reply.readInt32();
     }
 
-    virtual bool authenticateSurface(const sp<ISurface>& surface) const
+    virtual bool authenticateSurfaceTexture(
+            const sp<ISurfaceTexture>& surfaceTexture) const
     {
         Parcel data, reply;
         int err = NO_ERROR;
         err = data.writeInterfaceToken(
                 ISurfaceComposer::getInterfaceDescriptor());
         if (err != NO_ERROR) {
-            LOGE("ISurfaceComposer::authenticateSurface: error writing "
+            LOGE("ISurfaceComposer::authenticateSurfaceTexture: error writing "
                     "interface descriptor: %s (%d)", strerror(-err), -err);
             return false;
         }
-        err = data.writeStrongBinder(surface->asBinder());
+        err = data.writeStrongBinder(surfaceTexture->asBinder());
         if (err != NO_ERROR) {
-            LOGE("ISurfaceComposer::authenticateSurface: error writing strong "
-                    "binder to parcel: %s (%d)", strerror(-err), -err);
+            LOGE("ISurfaceComposer::authenticateSurfaceTexture: error writing "
+                    "strong binder to parcel: %s (%d)", strerror(-err), -err);
             return false;
         }
         err = remote()->transact(BnSurfaceComposer::AUTHENTICATE_SURFACE, data,
                 &reply);
         if (err != NO_ERROR) {
-            LOGE("ISurfaceComposer::authenticateSurface: error performing "
-                    "transaction: %s (%d)", strerror(-err), -err);
+            LOGE("ISurfaceComposer::authenticateSurfaceTexture: error "
+                    "performing transaction: %s (%d)", strerror(-err), -err);
             return false;
         }
         int32_t result = 0;
         err = reply.readInt32(&result);
         if (err != NO_ERROR) {
-            LOGE("ISurfaceComposer::authenticateSurface: error retrieving "
-                    "result: %s (%d)", strerror(-err), -err);
+            LOGE("ISurfaceComposer::authenticateSurfaceTexture: error "
+                    "retrieving result: %s (%d)", strerror(-err), -err);
             return false;
         }
         return result != 0;
@@ -291,8 +294,9 @@
         } break;
         case AUTHENTICATE_SURFACE: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
-            sp<ISurface> surface = interface_cast<ISurface>(data.readStrongBinder());
-            int32_t result = authenticateSurface(surface) ? 1 : 0;
+            sp<ISurfaceTexture> surfaceTexture =
+                    interface_cast<ISurfaceTexture>(data.readStrongBinder());
+            int32_t result = authenticateSurfaceTexture(surfaceTexture) ? 1 : 0;
             reply->writeInt32(result);
         } break;
         default:
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 2c70251..54d04aa 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -342,9 +342,6 @@
 
 int Surface::query(int what, int* value) const {
     switch (what) {
-    case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
-        *value = 1;
-        return NO_ERROR;
     case NATIVE_WINDOW_CONCRETE_TYPE:
         *value = NATIVE_WINDOW_SURFACE;
         return NO_ERROR;
diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp
index e91be84..5a35b4d 100644
--- a/libs/gui/SurfaceTextureClient.cpp
+++ b/libs/gui/SurfaceTextureClient.cpp
@@ -18,6 +18,8 @@
 //#define LOG_NDEBUG 0
 
 #include <gui/SurfaceTextureClient.h>
+#include <surfaceflinger/ISurfaceComposer.h>
+#include <surfaceflinger/SurfaceComposerClient.h>
 
 #include <utils/Log.h>
 
@@ -234,7 +236,15 @@
                 }
                 break;
             case NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER:
-                *value = 0;
+                {
+                    sp<ISurfaceComposer> composer(
+                            ComposerService::getComposerService());
+                    if (composer->authenticateSurfaceTexture(mSurfaceTexture)) {
+                        *value = 1;
+                    } else {
+                        *value = 0;
+                    }
+                }
                 return NO_ERROR;
             case NATIVE_WINDOW_CONCRETE_TYPE:
                 *value = NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT;
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 99242ab..f2673b3 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -59,6 +59,7 @@
 #include <cutils/properties.h>
 
 #define USE_SURFACE_ALLOC 1
+#define FRAME_DROP_FREQ 0
 
 namespace android {
 
@@ -548,7 +549,7 @@
     mVideoTimeUs = 0;
 
     mSeeking = NO_SEEK;
-    mSeekNotificationSent = false;
+    mSeekNotificationSent = true;
     mSeekTimeUs = 0;
 
     mUri.setTo("");
@@ -820,7 +821,12 @@
         return;
     }
 
-    if (mFlags & (LOOPING | AUTO_LOOPING)) {
+    if ((mFlags & LOOPING)
+            || ((mFlags & AUTO_LOOPING)
+                && (mAudioSink == NULL || mAudioSink->realtime()))) {
+        // Don't AUTO_LOOP if we're being recorded, since that cannot be
+        // turned off and recording would go on indefinitely.
+
         seekTo_l(0);
 
         if (mVideoSource != NULL) {
@@ -1204,7 +1210,6 @@
 
     if (mLastVideoTimeUs >= 0) {
         mSeeking = SEEK;
-        mSeekNotificationSent = true;
         mSeekTimeUs = mLastVideoTimeUs;
         modifyFlags((AT_EOS | AUDIO_AT_EOS | VIDEO_AT_EOS), CLEAR);
     }
@@ -1305,8 +1310,10 @@
 }
 
 void AwesomePlayer::onRTSPSeekDone() {
-    notifyListener_l(MEDIA_SEEK_COMPLETE);
-    mSeekNotificationSent = true;
+    if (!mSeekNotificationSent) {
+        notifyListener_l(MEDIA_SEEK_COMPLETE);
+        mSeekNotificationSent = true;
+    }
 }
 
 status_t AwesomePlayer::seekTo_l(int64_t timeUs) {
@@ -1518,14 +1525,29 @@
     }
 
     if (mVideoSource != NULL) {
-        Mutex::Autolock autoLock(mStatsLock);
-        TrackStat *stat = &mStats.mTracks.editItemAt(mStats.mVideoTrackIndex);
-
-        const char *component;
+        const char *componentName;
         CHECK(mVideoSource->getFormat()
-                ->findCString(kKeyDecoderComponent, &component));
+                ->findCString(kKeyDecoderComponent, &componentName));
 
-        stat->mDecoderName = component;
+        {
+            Mutex::Autolock autoLock(mStatsLock);
+            TrackStat *stat = &mStats.mTracks.editItemAt(mStats.mVideoTrackIndex);
+
+            stat->mDecoderName = componentName;
+        }
+
+        static const char *kPrefix = "OMX.Nvidia.";
+        static const char *kSuffix = ".decode";
+        static const size_t kSuffixLength = strlen(kSuffix);
+
+        size_t componentNameLength = strlen(componentName);
+
+        if (!strncmp(componentName, kPrefix, strlen(kPrefix))
+                && componentNameLength >= kSuffixLength
+                && !strcmp(&componentName[
+                    componentNameLength - kSuffixLength], kSuffix)) {
+            modifyFlags(SLOW_DECODER_HACK, SET);
+        }
     }
 
     return mVideoSource != NULL ? OK : UNKNOWN_ERROR;
@@ -1705,6 +1727,7 @@
 
     if (mFlags & FIRST_FRAME) {
         modifyFlags(FIRST_FRAME, CLEAR);
+        mSinceLastDropped = 0;
         mTimeSourceDeltaUs = ts->getRealTimeUs() - timeUs;
     }
 
@@ -1751,18 +1774,28 @@
 
         if (latenessUs > 40000) {
             // We're more than 40ms late.
-            LOGV("we're late by %lld us (%.2f secs), dropping frame",
+            LOGV("we're late by %lld us (%.2f secs)",
                  latenessUs, latenessUs / 1E6);
-            mVideoBuffer->release();
-            mVideoBuffer = NULL;
 
+            if (!(mFlags & SLOW_DECODER_HACK)
+                    || mSinceLastDropped > FRAME_DROP_FREQ)
             {
-                Mutex::Autolock autoLock(mStatsLock);
-                ++mStats.mNumVideoFramesDropped;
-            }
+                LOGV("we're late by %lld us (%.2f secs) dropping "
+                     "one after %d frames",
+                     latenessUs, latenessUs / 1E6, mSinceLastDropped);
 
-            postVideoEvent_l();
-            return;
+                mSinceLastDropped = 0;
+                mVideoBuffer->release();
+                mVideoBuffer = NULL;
+
+                {
+                    Mutex::Autolock autoLock(mStatsLock);
+                    ++mStats.mNumVideoFramesDropped;
+                }
+
+                postVideoEvent_l();
+                return;
+            }
         }
 
         if (latenessUs < -10000) {
@@ -1781,6 +1814,7 @@
     }
 
     if (mVideoRenderer != NULL) {
+        mSinceLastDropped++;
         mVideoRenderer->render(mVideoBuffer);
     }
 
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 95f2ae8..14476d3 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -141,6 +141,8 @@
 
         TEXT_RUNNING        = 0x10000,
         TEXTPLAYER_STARTED  = 0x20000,
+
+        SLOW_DECODER_HACK   = 0x40000,
     };
 
     mutable Mutex mLock;
@@ -181,6 +183,7 @@
 
     uint32_t mFlags;
     uint32_t mExtractorFlags;
+    uint32_t mSinceLastDropped;
 
     int64_t mTimeSourceDeltaUs;
     int64_t mVideoTimeUs;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 1e27233..a90eb3f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -59,13 +59,17 @@
         mNotification = notification;
         setContentDescription(notification);
 
-        final int outerBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_size);
-        final int imageBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_drawing_size);
-        final float scale = (float)imageBounds / (float)outerBounds;
-        setScaleX(scale);
-        setScaleY(scale);
-        final float alpha = res.getFraction(R.dimen.status_bar_icon_drawing_alpha, 1, 1);
-        setAlpha(alpha);
+        // We do not resize and scale system icons (on the right), only notification icons (on the
+        // left).
+        if (notification != null) {
+            final int outerBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_size);
+            final int imageBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_drawing_size);
+            final float scale = (float)imageBounds / (float)outerBounds;
+            setScaleX(scale);
+            setScaleY(scale);
+            final float alpha = res.getFraction(R.dimen.status_bar_icon_drawing_alpha, 1, 1);
+            setAlpha(alpha);
+        }
     }
 
     private static boolean streq(String a, String b) {
@@ -247,4 +251,9 @@
             }
         }
     }
+
+    public String toString() {
+        return "StatusBarIconView(slot=" + mSlot + " icon=" + mIcon 
+            + " notification=" + mNotification + ")";
+    }
 }
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 1edc351..68f6dcf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -91,6 +91,7 @@
     static final String TAG = "PhoneStatusBar";
     public static final boolean DEBUG = false;
     public static final boolean SPEW = false;
+    public static final boolean DUMPTRUCK = true; // extra dumpsys info
 
     // additional instrumentation for testing purposes; intended to be left on during development
     public static final boolean CHATTY = DEBUG || true;
@@ -316,8 +317,8 @@
         mPile = (ViewGroup)expanded.findViewById(R.id.latestItems);
         mExpandedContents = mPile; // was: expanded.findViewById(R.id.notificationLinearLayout);
         mNoNotificationsTitle = (TextView)expanded.findViewById(R.id.noNotificationsTitle);
-        mNoNotificationsTitle.setAlpha(0f);
-        mNoNotificationsTitle.setVisibility(View.VISIBLE);
+        mNoNotificationsTitle.setVisibility(View.GONE); // disabling for now
+
         mClearButton = expanded.findViewById(R.id.clear_all_button);
         mClearButton.setOnClickListener(mClearButtonListener);
         mClearButton.setAlpha(0f);
@@ -1026,6 +1027,7 @@
             mClearButton.setAlpha(clearable ? 1.0f : 0.0f);
         }
 
+        /*
         if (mNoNotificationsTitle.isShown()) {
             if (any != (mNoNotificationsTitle.getAlpha() == 0.0f)) {
                 ObjectAnimator a = ObjectAnimator.ofFloat(mNoNotificationsTitle, "alpha",
@@ -1037,6 +1039,7 @@
         } else {
             mNoNotificationsTitle.setAlpha(any ? 0.0f : 0.75f);
         }
+        */
     }
 
 
@@ -1697,26 +1700,28 @@
             pw.println("  mScrollView: " + viewInfo(mScrollView)
                     + " scroll " + mScrollView.getScrollX() + "," + mScrollView.getScrollY());
         }
-        /*
-        synchronized (mNotificationData) {
-            int N = mNotificationData.ongoingCount();
-            pw.println("  ongoingCount.size=" + N);
-            for (int i=0; i<N; i++) {
-                StatusBarNotification n = mNotificationData.getOngoing(i);
-                pw.println("    [" + i + "] key=" + n.key + " view=" + n.view);
-                pw.println("           data=" + n.data);
-            }
-            N = mNotificationData.latestCount();
-            pw.println("  ongoingCount.size=" + N);
-            for (int i=0; i<N; i++) {
-                StatusBarNotification n = mNotificationData.getLatest(i);
-                pw.println("    [" + i + "] key=" + n.key + " view=" + n.view);
-                pw.println("           data=" + n.data);
-            }
-        }
-        */
 
-        if (false) {
+        if (DUMPTRUCK) {
+            synchronized (mNotificationData) {
+                int N = mNotificationData.size();
+                pw.println("  notification icons: " + N);
+                for (int i=0; i<N; i++) {
+                    NotificationData.Entry e = mNotificationData.get(i);
+                    pw.println("    [" + i + "] key=" + e.key + " icon=" + e.icon);
+                    StatusBarNotification n = e.notification;
+                    pw.println("         pkg=" + n.pkg + " id=" + n.id + " priority=" + n.priority);
+                    pw.println("         notification=" + n.notification);
+                    pw.println("         tickerText=\"" + n.notification.tickerText + "\"");
+                }
+            }
+
+            int N = mStatusIcons.getChildCount();
+            pw.println("  system icons: " + N);
+            for (int i=0; i<N; i++) {
+                StatusBarIconView ic = (StatusBarIconView) mStatusIcons.getChildAt(i);
+                pw.println("    [" + i + "] icon=" + ic);
+            }
+            
             pw.println("see the logcat for a dump of the views we have created.");
             // must happen on ui thread
             mHandler.post(new Runnable() {
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index 9d360ac..4f6df36 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -23,7 +23,6 @@
 import com.android.internal.widget.multiwaveview.MultiWaveView;
 
 import android.app.ActivityManager;
-import android.content.ActivityNotFoundException;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Configuration;
@@ -46,6 +45,7 @@
  */
 class LockScreen extends LinearLayout implements KeyguardScreen {
 
+    private static final int ON_RESUME_PING_DELAY = 500; // delay first ping until the screen is on
     private static final boolean DBG = false;
     private static final String TAG = "LockScreen";
     private static final String ENABLE_MENU_KEY_FILE = "/data/local/enable_menu_key";
@@ -441,10 +441,16 @@
         mUnlockWidgetMethods.reset(false);
     }
 
+    private final Runnable mOnResumePing = new Runnable() {
+        public void run() {
+            mUnlockWidgetMethods.ping();
+        }
+    };
+
     /** {@inheritDoc} */
     public void onResume() {
         mStatusViewManager.onResume();
-        mUnlockWidgetMethods.ping();
+        postDelayed(mOnResumePing, ON_RESUME_PING_DELAY);
     }
 
     /** {@inheritDoc} */
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 73e4338..c580f08 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -386,8 +386,10 @@
                     // Ditch the menu created above
                     st.menu = null;
 
-                    // Don't show it in the action bar either
-                    mActionBar.setMenu(null, mActionMenuPresenterCallback);
+                    if (mActionBar != null) {
+                        // Don't show it in the action bar either
+                        mActionBar.setMenu(null, mActionMenuPresenterCallback);
+                    }
 
                     return false;
                 }
@@ -409,9 +411,11 @@
             }
 
             if (!cb.onPreparePanel(st.featureId, st.createdPanelView, st.menu)) {
-                // The app didn't want to show the menu for now but it still exists.
-                // Clear it out of the action bar.
-                mActionBar.setMenu(null, mActionMenuPresenterCallback);
+                if (mActionBar != null) {
+                    // The app didn't want to show the menu for now but it still exists.
+                    // Clear it out of the action bar.
+                    mActionBar.setMenu(null, mActionMenuPresenterCallback);
+                }
                 st.menu.startDispatchingItemsChanged();
                 return false;
             }
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 22ce484..1341dd4 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -163,8 +163,6 @@
     private boolean mTestMode;
     private static ConnectivityService sServiceInstance;
 
-    private AtomicBoolean mBackgroundDataEnabled = new AtomicBoolean(true);
-
     private INetworkManagementService mNetd;
     private INetworkPolicyManager mPolicyManager;
 
@@ -213,13 +211,6 @@
             MAX_NETWORK_STATE_TRACKER_EVENT + 5;
 
     /**
-     * used internally to set the background data preference
-     * arg1 = TRUE for enabled, FALSE for disabled
-     */
-    private static final int EVENT_SET_BACKGROUND_DATA =
-            MAX_NETWORK_STATE_TRACKER_EVENT + 6;
-
-    /**
      * used internally to set enable/disable cellular data
      * arg1 = ENBALED or DISABLED
      */
@@ -317,9 +308,6 @@
         handlerThread.start();
         mHandler = new MyHandler(handlerThread.getLooper());
 
-        mBackgroundDataEnabled.set(Settings.Secure.getInt(context.getContentResolver(),
-                Settings.Secure.BACKGROUND_DATA, 1) == 1);
-
         // setup our unique device name
         if (TextUtils.isEmpty(SystemProperties.get("net.hostname"))) {
             String id = Settings.Secure.getString(context.getContentResolver(),
@@ -1209,35 +1197,6 @@
     }
 
     /**
-     * @see ConnectivityManager#getBackgroundDataSetting()
-     */
-    public boolean getBackgroundDataSetting() {
-        return mBackgroundDataEnabled.get();
-    }
-
-    /**
-     * @see ConnectivityManager#setBackgroundDataSetting(boolean)
-     */
-    public void setBackgroundDataSetting(boolean allowBackgroundDataUsage) {
-        mContext.enforceCallingOrSelfPermission(
-                android.Manifest.permission.CHANGE_BACKGROUND_DATA_SETTING,
-                "ConnectivityService");
-
-        mBackgroundDataEnabled.set(allowBackgroundDataUsage);
-
-        mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_BACKGROUND_DATA,
-                (allowBackgroundDataUsage ? ENABLED : DISABLED), 0));
-    }
-
-    private void handleSetBackgroundData(boolean enabled) {
-        Settings.Secure.putInt(mContext.getContentResolver(),
-                Settings.Secure.BACKGROUND_DATA, enabled ? 1 : 0);
-        Intent broadcast = new Intent(
-                ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED);
-        mContext.sendBroadcast(broadcast);
-    }
-
-    /**
      * @see ConnectivityManager#getMobileDataEnabled()
      */
     public boolean getMobileDataEnabled() {
@@ -2273,12 +2232,6 @@
                     handleSetNetworkPreference(preference);
                     break;
                 }
-                case EVENT_SET_BACKGROUND_DATA:
-                {
-                    boolean enabled = (msg.arg1 == ENABLED);
-                    handleSetBackgroundData(enabled);
-                    break;
-                }
                 case EVENT_SET_MOBILE_DATA:
                 {
                     boolean enabled = (msg.arg1 == ENABLED);
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index 9c3d166..14d9665 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -89,6 +89,7 @@
 import android.os.Message;
 import android.os.RemoteCallbackList;
 import android.os.RemoteException;
+import android.provider.Settings;
 import android.telephony.TelephonyManager;
 import android.text.format.Formatter;
 import android.text.format.Time;
@@ -168,6 +169,12 @@
     private static final String ATTR_UID = "uid";
     private static final String ATTR_POLICY = "policy";
 
+    private static final String TAG_ALLOW_BACKGROUND = TAG + ":allowBackground";
+
+    // @VisibleForTesting
+    public static final String ACTION_ALLOW_BACKGROUND =
+            "com.android.server.action.ACTION_ALLOW_BACKGROUND";
+
     private static final long TIME_CACHE_MAX_AGE = DAY_IN_MILLIS;
 
     private static final int MSG_RULES_CHANGED = 0x1;
@@ -185,8 +192,8 @@
 
     private final Object mRulesLock = new Object();
 
-    private boolean mScreenOn;
-    private boolean mRestrictBackground;
+    private volatile boolean mScreenOn;
+    private volatile boolean mRestrictBackground;
 
     /** Defined network policies. */
     private HashMap<NetworkTemplate, NetworkPolicy> mNetworkPolicy = Maps.newHashMap();
@@ -265,6 +272,7 @@
 
             if (mRestrictBackground) {
                 updateRulesForRestrictBackgroundLocked();
+                updateNotificationsLocked();
             }
         }
 
@@ -309,6 +317,10 @@
         mContext.registerReceiver(
                 mStatsReceiver, statsFilter, READ_NETWORK_USAGE_HISTORY, mHandler);
 
+        // listen for restrict background changes from notifications
+        final IntentFilter allowFilter = new IntentFilter(ACTION_ALLOW_BACKGROUND);
+        mContext.registerReceiver(mAllowReceiver, allowFilter, MANAGE_NETWORK_POLICY, mHandler);
+
     }
 
     private IProcessObserver mProcessObserver = new IProcessObserver.Stub() {
@@ -402,6 +414,20 @@
     };
 
     /**
+     * Receiver that watches for {@link Notification} control of
+     * {@link #mRestrictBackground}.
+     */
+    private BroadcastReceiver mAllowReceiver = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            // on background handler thread, and verified MANAGE_NETWORK_POLICY
+            // permission above.
+
+            setRestrictBackground(false);
+        }
+    };
+
+    /**
      * Observer that watches for {@link INetworkManagementService} alerts.
      */
     private INetworkManagementEventObserver mAlertObserver = new NetworkAlertObserver() {
@@ -494,6 +520,13 @@
                 notifyUnderLimitLocked(policy.template);
             }
         }
+
+        // ongoing notification when restricting background data
+        if (mRestrictBackground) {
+            enqueueRestrictedNotification(TAG_ALLOW_BACKGROUND);
+        } else {
+            cancelNotification(TAG_ALLOW_BACKGROUND);
+        }
     }
 
     /**
@@ -614,16 +647,52 @@
     }
 
     /**
-     * Cancel any notification for combined {@link NetworkPolicy} and specific
-     * type, like {@link #TYPE_LIMIT}.
+     * Show ongoing notification to reflect that {@link #mRestrictBackground}
+     * has been enabled.
      */
-    private void cancelNotification(NetworkPolicy policy, int type) {
-        final String tag = buildNotificationTag(policy, type);
+    private void enqueueRestrictedNotification(String tag) {
+        final Resources res = mContext.getResources();
+        final Notification.Builder builder = new Notification.Builder(mContext);
+
+        final CharSequence title = res.getText(R.string.data_usage_restricted_title);
+        final CharSequence body = res.getString(R.string.data_usage_restricted_body);
+
+        builder.setOnlyAlertOnce(true);
+        builder.setOngoing(true);
+        builder.setSmallIcon(R.drawable.ic_menu_info_details);
+        builder.setTicker(title);
+        builder.setContentTitle(title);
+        builder.setContentText(body);
+
+        final Intent intent = buildAllowBackgroundDataIntent();
+        builder.setContentIntent(
+                PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
 
         // TODO: move to NotificationManager once we can mock it
         try {
             final String packageName = mContext.getPackageName();
-            mNotifManager.cancelNotificationWithTag(packageName, tag, 0x0);
+            final int[] idReceived = new int[1];
+            mNotifManager.enqueueNotificationWithTag(packageName, tag,
+                    0x0, builder.getNotification(), idReceived);
+        } catch (RemoteException e) {
+            Slog.w(TAG, "problem during enqueueNotification: " + e);
+        }
+    }
+
+    /**
+     * Cancel any notification for combined {@link NetworkPolicy} and specific
+     * type, like {@link #TYPE_LIMIT}.
+     */
+    private void cancelNotification(NetworkPolicy policy, int type) {
+        cancelNotification(buildNotificationTag(policy, type));
+    }
+
+    private void cancelNotification(String tag) {
+        // TODO: move to NotificationManager once we can mock it
+        try {
+            final String packageName = mContext.getPackageName();
+            mNotifManager.cancelNotificationWithTag(
+                    packageName, tag, 0x0);
         } catch (RemoteException e) {
             Slog.w(TAG, "problem during enqueueNotification: " + e);
         }
@@ -731,15 +800,9 @@
             final boolean hasLimit = policy.limitBytes != LIMIT_DISABLED;
             final boolean hasWarning = policy.warningBytes != WARNING_DISABLED;
 
-            if (hasLimit || hasWarning) {
-                final long quotaBytes;
-                if (hasLimit) {
-                    // remaining "quota" is based on usage in current cycle
-                    quotaBytes = Math.max(0, policy.limitBytes - total);
-                } else {
-                    // to track warning alert later, use a high quota
-                    quotaBytes = Long.MAX_VALUE;
-                }
+            if (hasLimit) {
+                // remaining "quota" is based on usage in current cycle
+                final long quotaBytes = Math.max(0, policy.limitBytes - total);
 
                 if (ifaces.length > 1) {
                     // TODO: switch to shared quota once NMS supports
@@ -754,16 +817,6 @@
                     }
                 }
             }
-
-            if (hasWarning) {
-                final long alertBytes = Math.max(0, policy.warningBytes - total);
-                for (String iface : ifaces) {
-                    removeInterfaceAlert(iface);
-                    if (alertBytes > 0) {
-                        setInterfaceAlert(iface, alertBytes);
-                    }
-                }
-            }
         }
 
         // remove quota on any trailing interfaces
@@ -839,11 +892,7 @@
                             mRestrictBackground = readBooleanAttribute(
                                     in, ATTR_RESTRICT_BACKGROUND);
                         } else {
-                            try {
-                                mRestrictBackground = !mConnManager.getBackgroundDataSetting();
-                            } catch (RemoteException e) {
-                                mRestrictBackground = false;
-                            }
+                            mRestrictBackground = false;
                         }
 
                     } else if (TAG_NETWORK_POLICY.equals(tag)) {
@@ -879,6 +928,7 @@
 
         } catch (FileNotFoundException e) {
             // missing policy is okay, probably first boot
+            upgradeLegacyBackgroundData();
         } catch (IOException e) {
             Slog.e(TAG, "problem reading network stats", e);
         } catch (XmlPullParserException e) {
@@ -888,6 +938,22 @@
         }
     }
 
+    /**
+     * Upgrade legacy background data flags, notifying listeners of one last
+     * change to always-true.
+     */
+    private void upgradeLegacyBackgroundData() {
+        mRestrictBackground = Settings.Secure.getInt(
+                mContext.getContentResolver(), Settings.Secure.BACKGROUND_DATA, 1) != 1;
+
+        // kick off one last broadcast if restricted
+        if (mRestrictBackground) {
+            final Intent broadcast = new Intent(
+                    ConnectivityManager.ACTION_BACKGROUND_DATA_SETTING_CHANGED);
+            mContext.sendBroadcast(broadcast);
+        }
+    }
+
     private void writePolicyLocked() {
         if (LOGV) Slog.v(TAG, "writePolicyLocked()");
 
@@ -1057,6 +1123,7 @@
         synchronized (mRulesLock) {
             mRestrictBackground = restrictBackground;
             updateRulesForRestrictBackgroundLocked();
+            updateNotificationsLocked();
             writePolicyLocked();
         }
     }
@@ -1420,6 +1487,10 @@
         return telephony.getSubscriberId();
     }
 
+    private static Intent buildAllowBackgroundDataIntent() {
+        return new Intent(ACTION_ALLOW_BACKGROUND);
+    }
+
     private static Intent buildNetworkOverLimitIntent(NetworkTemplate template) {
         final Intent intent = new Intent();
         intent.setComponent(new ComponentName(
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 0425fc3..64eaecc 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -133,6 +133,11 @@
     return sur;
 }
 
+wp<IBinder> Layer::getSurfaceTextureBinder() const
+{
+    return mSurfaceTexture->asBinder();
+}
+
 status_t Layer::setBuffers( uint32_t w, uint32_t h,
                             PixelFormat format, uint32_t flags)
 {
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index d3ddab4..5f0be80 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -74,6 +74,9 @@
     virtual bool isProtected() const;
     virtual void onRemoved();
 
+    // LayerBaseClient interface
+    virtual wp<IBinder> getSurfaceTextureBinder() const;
+
     // only for debugging
     inline const sp<FreezeLock>&  getFreezeLock() const { return mFreezeLock; }
 
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index e04c533..7bf73d9 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -544,6 +544,10 @@
     return mClientSurfaceBinder;
 }
 
+wp<IBinder> LayerBaseClient::getSurfaceTextureBinder() const {
+    return 0;
+}
+
 void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const
 {
     LayerBase::dump(result, buffer, SIZE);
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index faf71dd..a3d3644 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -288,6 +288,7 @@
 
             sp<ISurface> getSurface();
             wp<IBinder> getSurfaceBinder() const;
+            virtual wp<IBinder> getSurfaceTextureBinder() const;
 
     virtual sp<LayerBaseClient> getLayerBaseClient() const {
         return const_cast<LayerBaseClient*>(this); }
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index a68ab30..50afb3d 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -353,9 +353,10 @@
     mEventQueue.invalidate();
 }
 
-bool SurfaceFlinger::authenticateSurface(const sp<ISurface>& surface) const {
+bool SurfaceFlinger::authenticateSurfaceTexture(
+        const sp<ISurfaceTexture>& surfaceTexture) const {
     Mutex::Autolock _l(mStateLock);
-    sp<IBinder> surfBinder(surface->asBinder());
+    sp<IBinder> surfaceTextureBinder(surfaceTexture->asBinder());
 
     // Check the visible layer list for the ISurface
     const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
@@ -363,14 +364,17 @@
     for (size_t i=0 ; i<count ; i++) {
         const sp<LayerBase>& layer(currentLayers[i]);
         sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
-        if (lbc != NULL && lbc->getSurfaceBinder() == surfBinder) {
-            return true;
+        if (lbc != NULL) {
+            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
+            if (lbcBinder == surfaceTextureBinder) {
+                return true;
+            }
         }
     }
 
     // Check the layers in the purgatory.  This check is here so that if a
-    // Surface gets destroyed before all the clients are done using it, the
-    // error will not be reported as "surface XYZ is not authenticated", but
+    // SurfaceTexture gets destroyed before all the clients are done using it,
+    // the error will not be reported as "surface XYZ is not authenticated", but
     // will instead fail later on when the client tries to use the surface,
     // which should be reported as "surface XYZ returned an -ENODEV".  The
     // purgatorized layers are no less authentic than the visible ones, so this
@@ -379,8 +383,11 @@
     for (size_t i=0 ; i<purgatorySize ; i++) {
         const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
         sp<LayerBaseClient> lbc(layer->getLayerBaseClient());
-        if (lbc != NULL && lbc->getSurfaceBinder() == surfBinder) {
-            return true;
+        if (lbc != NULL) {
+            wp<IBinder> lbcBinder = lbc->getSurfaceTextureBinder();
+            if (lbcBinder == surfaceTextureBinder) {
+                return true;
+            }
         }
     }
 
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 89df0de..1738238 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -171,7 +171,7 @@
     virtual status_t                    freezeDisplay(DisplayID dpy, uint32_t flags);
     virtual status_t                    unfreezeDisplay(DisplayID dpy, uint32_t flags);
     virtual int                         setOrientation(DisplayID dpy, int orientation, uint32_t flags);
-    virtual bool                        authenticateSurface(const sp<ISurface>& surface) const;
+    virtual bool                        authenticateSurfaceTexture(const sp<ISurfaceTexture>& surface) const;
 
     virtual status_t captureScreen(DisplayID dpy,
             sp<IMemoryHeap>* heap,
diff --git a/tests/BiDiTests/res/layout/basic.xml b/tests/BiDiTests/res/layout/basic.xml
index e8f67a6..8a27213 100644
--- a/tests/BiDiTests/res/layout/basic.xml
+++ b/tests/BiDiTests/res/layout/basic.xml
@@ -34,6 +34,19 @@
                     android:textSize="32dip"
                     />
 
+            <TextView android:id="@+id/textview_default"
+                    android:layout_height="wrap_content"
+                    android:layout_width="wrap_content"
+                    android:textSize="32dip"
+                    android:text="@string/textview_default_text"
+            />
+
+            <EditText android:id="@+id/edittext_default"
+                      android:layout_height="wrap_content"
+                      android:layout_width="match_parent"
+                      android:textSize="32dip"
+                    />
+
             <TextView android:id="@+id/textview_ltr"
                       android:layout_height="wrap_content"
                       android:layout_width="wrap_content"
@@ -46,7 +59,6 @@
                       android:layout_width="match_parent"
                       android:textSize="32dip"
                       android:textDirection="ltr"
-                      android:text="@string/url"
                     />
 
             <TextView android:id="@+id/textview_rtl"
diff --git a/tests/BiDiTests/res/values/strings.xml b/tests/BiDiTests/res/values/strings.xml
index fde0ecf..b0809da 100644
--- a/tests/BiDiTests/res/values/strings.xml
+++ b/tests/BiDiTests/res/values/strings.xml
@@ -27,6 +27,7 @@
     <string name="textview_text">This is a text for a TextView</string>
     <string name="textview_ltr_text">This is a text for a LTR TextView</string>
     <string name="textview_rtl_text">This is a text for a RTL TextView</string>
+    <string name="textview_default_text">This is a text for a default TextView</string>
     <string name="edittext_text">mmmmmmmmmmmmmmmmmmmmmmmm</string>
     <string name="normal_text">Normal String</string>
     <string name="normal_long_text">mmmmmmmmmmmmmmmmmmmmmmmm</string>
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index daf53e0..178e7fd 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -1546,7 +1546,9 @@
     assets = new AaptAssets();
 
     // Set up the resource gathering in assets if we're going to generate
-    // dependency files
+    // dependency files. Every time we encounter a resource while slurping
+    // the tree, we'll add it to these stores so we have full resource paths
+    // to write to a dependency file.
     if (bundle->getGenDependencies()) {
         sp<FilePathStore> resPathStore = new FilePathStore;
         assets->setFullResPaths(resPathStore);
@@ -1577,15 +1579,20 @@
         goto bail;
     }
 
+    // If we've been asked to generate a dependency file, do that here
     if (bundle->getGenDependencies()) {
+        // If this is the packaging step, generate the dependency file next to
+        // the output apk (e.g. bin/resources.ap_.d)
         if (outputAPKFile) {
             dependencyFile = String8(outputAPKFile);
-            // Strip the extension and add new one
-            dependencyFile = dependencyFile.getBasePath();
+            // Add the .d extension to the dependency file.
             dependencyFile.append(".d");
         } else {
+            // Else if this is the R.java dependency generation step,
+            // generate the dependency file in the R.java package subdirectory
+            // e.g. gen/com/foo/app/R.java.d
             dependencyFile = String8(bundle->getRClassDir());
-            dependencyFile.appendPath("R.d");
+            dependencyFile.appendPath("R.java.d");
         }
         // Make sure we have a clean dependency file to start with
         fp = fopen(dependencyFile, "w");
@@ -1595,13 +1602,18 @@
     // Write out R.java constants
     if (assets->getPackage() == assets->getSymbolsPrivatePackage()) {
         if (bundle->getCustomPackage() == NULL) {
+            // Write the R.java file into the appropriate class directory
+            // e.g. gen/com/foo/app/R.java
             err = writeResourceSymbols(bundle, assets, assets->getPackage(), true);
-            // Copy R.java for libraries
+            // If we have library files, we're going to write our R.java file into
+            // the appropriate class directory for those libraries as well.
+            // e.g. gen/com/foo/app/lib/R.java
             if (bundle->getExtraPackages() != NULL) {
                 // Split on colon
                 String8 libs(bundle->getExtraPackages());
                 char* packageString = strtok(libs.lockBuffer(libs.length()), ":");
                 while (packageString != NULL) {
+                    // Write the R.java file out with the correct package name
                     err = writeResourceSymbols(bundle, assets, String8(packageString), true);
                     packageString = strtok(NULL, ":");
                 }
@@ -1640,6 +1652,10 @@
         }
     }
 
+    // If we've been asked to generate a dependency file, we need to finish up here.
+    // the writeResourceSymbols and writeAPK functions have already written the target
+    // half of the dependency file, now we need to write the prerequisites. (files that
+    // the R.java file or .ap_ file depend on)
     if (bundle->getGenDependencies()) {
         // Now that writeResourceSymbols or writeAPK has taken care of writing
         // the targets to our dependency file, we'll write the prereqs
@@ -1647,7 +1663,8 @@
         fprintf(fp, " : ");
         bool includeRaw = (outputAPKFile != NULL);
         err = writeDependencyPreReqs(bundle, assets, fp, includeRaw);
-        // Also manually add the AndroidManifeset since it's a non-asset
+        // Also manually add the AndroidManifeset since it's not under res/ or assets/
+        // and therefore was not added to our pathstores during slurping
         fprintf(fp, "%s \\\n", bundle->getAndroidManifestFile());
         fclose(fp);
     }
diff --git a/tools/aapt/Package.cpp b/tools/aapt/Package.cpp
index c9f6870..1e3efde 100644
--- a/tools/aapt/Package.cpp
+++ b/tools/aapt/Package.cpp
@@ -177,12 +177,17 @@
         }
     }
 
+    // If we've been asked to generate a dependency file for the .ap_ package,
+    // do so here
     if (bundle->getGenDependencies()) {
-        // Add this file to the dependency file
-        String8 dependencyFile = outputFile.getBasePath();
+        // The dependency file gets output to the same directory
+        // as the specified output file with an additional .d extension.
+        // e.g. bin/resources.ap_.d
+        String8 dependencyFile = outputFile;
         dependencyFile.append(".d");
 
         FILE* fp = fopen(dependencyFile.string(), "a");
+        // Add this file to the dependency file
         fprintf(fp, "%s \\\n", outputFile.string());
         fclose(fp);
     }
diff --git a/tools/aapt/Resource.cpp b/tools/aapt/Resource.cpp
index cb6484f..2e796a2 100644
--- a/tools/aapt/Resource.cpp
+++ b/tools/aapt/Resource.cpp
@@ -1958,10 +1958,12 @@
         }
         fclose(fp);
 
+        // If we were asked to generate a dependency file, we'll go ahead and add this R.java
+        // as a target in the dependency file right next to it.
         if (bundle->getGenDependencies()) {
             // Add this R.java to the dependency file
             String8 dependencyFile(bundle->getRClassDir());
-            dependencyFile.appendPath("R.d");
+            dependencyFile.appendPath("R.java.d");
 
             fp = fopen(dependencyFile.string(), "a");
             fprintf(fp,"%s \\\n", dest.string());
diff --git a/wifi/java/android/net/wifi/WifiNative.java b/wifi/java/android/net/wifi/WifiNative.java
index 3b043b3..bfc4d5e 100644
--- a/wifi/java/android/net/wifi/WifiNative.java
+++ b/wifi/java/android/net/wifi/WifiNative.java
@@ -203,70 +203,42 @@
 
     private native static boolean doBooleanCommand(String command);
 
-    //STOPSHIP: remove this after native interface works and replace all
-    //calls to doBooleanTempCommand() with doBooleanCommand()
-    private static boolean doBooleanTempCommand(String command) {
-        try {
-            String str = "/system/bin/wpa_cli " + command;
-            Log.e("WifiNative", "===> " + str);
-            Runtime.getRuntime()
-                .exec(str).waitFor();
-        } catch (Exception e) {
-            Log.e("WifiNative", "exception with doBooleanTempCommand");
-            return false;
-        }
-        return true;
-    }
-
-    private static String doStringTempCommand(String command) {
-        String lines[] = null;
-        try {
-            String str = "/system/bin/wpa_cli " + command;
-            Log.e("WifiNative", "===> " + str);
-            Process p = Runtime.getRuntime()
-                .exec(str);
-            InputStream in = p.getInputStream();
-            p.waitFor();
-            byte[] bytes=new byte[in.available()];
-            in.read(bytes);
-            String s = new String(bytes);
-            Log.e("WifiNative", "====> doString: " + s);
-            lines = s.split("\\r?\\n");
-        } catch (Exception e) {
-            Log.e("WifiNative", "exception with doBooleanTempCommand");
-            return null;
-        }
-        return lines[1];
-    }
-
     private native static int doIntCommand(String command);
 
     private native static String doStringCommand(String command);
 
+    public static boolean wpsPbc() {
+        return doBooleanCommand("WPS_PBC");
+    }
+
+    public static boolean wpsPin(String pin) {
+        return doBooleanCommand("WPS_PIN any " + pin);
+    }
+
     public static boolean p2pFind() {
-        return doBooleanTempCommand("p2p_find");
+        return doBooleanCommand("P2P_FIND");
     }
 
     public static boolean p2pFind(int timeout) {
         if (timeout <= 0) {
             return p2pFind();
         }
-        return doBooleanTempCommand("p2p_find " + timeout);
+        return doBooleanCommand("P2P_FIND " + timeout);
     }
 
     public static boolean p2pListen() {
-        return doBooleanTempCommand("p2p_listen");
+        return doBooleanCommand("P2P_LISTEN");
     }
 
     public static boolean p2pListen(int timeout) {
         if (timeout <= 0) {
             return p2pListen();
         }
-        return doBooleanTempCommand("p2p_listen " + timeout);
+        return doBooleanCommand("P2P_LISTEN " + timeout);
     }
 
     public static boolean p2pFlush() {
-        return doBooleanTempCommand("p2p_flush");
+        return doBooleanCommand("P2P_FLUSH");
     }
 
     /* p2p_connect <peer device address> <pbc|pin|PIN#> [label|display|keypad]
@@ -300,41 +272,36 @@
         if (config.isPersistent) args.add("persistent");
         if (config.joinExistingGroup) args.add("join");
 
-        args.add("go_intent=" + config.groupOwnerIntent);
+        int groupOwnerIntent = config.groupOwnerIntent;
+        if (groupOwnerIntent < 0 || groupOwnerIntent > 15) {
+            groupOwnerIntent = 3; //default value
+        }
+        args.add("go_intent=" + groupOwnerIntent);
         if (config.channel > 0) args.add("freq=" + config.channel);
 
-        String command = "p2p_connect ";
+        String command = "P2P_CONNECT ";
         for (String s : args) command += s + " ";
 
-        return doStringTempCommand(command);
+        return doStringCommand(command);
     }
 
     public static boolean p2pGroupAdd() {
-        return doBooleanTempCommand("p2p_group_add");
+        return doBooleanCommand("P2P_GROUP_ADD");
     }
 
     public static boolean p2pGroupRemove(String iface) {
         if (iface == null) return false;
-        return doBooleanTempCommand("p2p_group_remove " + iface);
+        return doBooleanCommand("P2P_GROUP_REMOVE " + iface);
     }
 
     public static boolean p2pReject(String deviceAddress) {
-        return doBooleanTempCommand("p2p_reject " + deviceAddress);
+        return doBooleanCommand("P2P_REJECT " + deviceAddress);
     }
 
     /* Invite a peer to a group */
     public static boolean p2pInvite(WifiP2pGroup group, String deviceAddress) {
         if (group == null || deviceAddress == null) return false;
-        return doBooleanTempCommand("p2p_invite group=" + group.getInterface()
+        return doBooleanCommand("P2P_INVITE group=" + group.getInterface()
                 + " peer=" + deviceAddress + " go_dev_addr=" + group.getOwner().deviceAddress);
     }
-
-    public static boolean p2pWpsPbc() {
-        return doBooleanTempCommand("wps_pbc");
-    }
-
-    public static boolean p2pWpsPin(String pin) {
-        return doBooleanTempCommand("wps_pin any " + pin);
-    }
-
 }
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
index fff5ee3..b77fd76 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pConfig.java
@@ -46,8 +46,10 @@
      * This is an integer value between 0 and 15 where 0 indicates the least
      * inclination to be a group owner and 15 indicates the highest inclination
      * to be a group owner.
+     *
+     * A value of -1 indicates the system can choose an appropriate value.
      */
-    public int groupOwnerIntent;
+    public int groupOwnerIntent = -1;
 
     public boolean isPersistent;
 
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index 176191e..49ce124 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -767,10 +767,10 @@
                     notifyP2pProvDiscPinRequest((WifiP2pDevice) message.obj);
                     break;
                 case WifiP2pManager.WPS_PBC:
-                    WifiNative.p2pWpsPbc();
+                    WifiNative.wpsPbc();
                     break;
                 case WifiP2pManager.WPS_PIN:
-                    WifiNative.p2pWpsPin((String) message.obj);
+                    WifiNative.wpsPin((String) message.obj);
                     break;
                 default:
                     return NOT_HANDLED;