Merge "Fix rendering issue with paths when the stroke width is 0"
diff --git a/Android.mk b/Android.mk
index 358bcc6..d4d9a33 100644
--- a/Android.mk
+++ b/Android.mk
@@ -382,8 +382,12 @@
 		            resources/samples/AccessibilityService "Accessibility Service" \
 		-samplecode $(sample_dir)/AccelerometerPlay \
 		            resources/samples/AccelerometerPlay "Accelerometer Play" \
-	  -samplecode $(sample_dir)/ApiDemos \
+		-samplecode $(sample_dir)/ApiDemos \
 		            resources/samples/ApiDemos "API Demos" \
+		-samplecode $(sample_dir)/Support4Demos \
+		            resources/samples/Support4Demos "API 4+ Support Demos" \
+		-samplecode $(sample_dir)/Support13Demos \
+		            resources/samples/Support13Demos "API 13+ Support Demos" \
 		-samplecode $(sample_dir)/BackupRestore \
 		            resources/samples/BackupRestore "Backup and Restore" \
 		-samplecode $(sample_dir)/BluetoothChat \
diff --git a/api/current.txt b/api/current.txt
index 8ba67c3..51c9348 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -218,6 +218,7 @@
     field public static final int alertDialogIcon = 16843605; // 0x1010355
     field public static final int alertDialogStyle = 16842845; // 0x101005d
     field public static final int alertDialogTheme = 16843529; // 0x1010309
+    field public static final int alignmentMode = 16843642; // 0x101037a
     field public static final int allContactsName = 16843468; // 0x10102cc
     field public static final int allowBackup = 16843392; // 0x1010280
     field public static final int allowClearUserData = 16842757; // 0x1010005
@@ -627,6 +628,8 @@
     field public static final int listDividerAlertDialog = 16843525; // 0x1010305
     field public static final int listPopupWindowStyle = 16843519; // 0x10102ff
     field public static final int listPreferredItemHeight = 16842829; // 0x101004d
+    field public static final int listPreferredItemHeightLarge = 16843670; // 0x1010396
+    field public static final int listPreferredItemHeightSmall = 16843671; // 0x1010397
     field public static final int listSelector = 16843003; // 0x10100fb
     field public static final int listSeparatorTextViewStyle = 16843272; // 0x1010208
     field public static final int listViewStyle = 16842868; // 0x1010074
@@ -636,7 +639,6 @@
     field public static final int loopViews = 16843527; // 0x1010307
     field public static final int manageSpaceActivity = 16842756; // 0x1010004
     field public static final int mapViewStyle = 16842890; // 0x101008a
-    field public static final int marginsIncludedInAlignment = 16843642; // 0x101037a
     field public static final int marqueeRepeatLimit = 16843293; // 0x101021d
     field public static final int max = 16843062; // 0x1010136
     field public static final int maxDate = 16843584; // 0x1010340
@@ -1374,6 +1376,7 @@
     field public static final int config_longAnimTime = 17694722; // 0x10e0002
     field public static final int config_mediumAnimTime = 17694721; // 0x10e0001
     field public static final int config_shortAnimTime = 17694720; // 0x10e0000
+    field public static final int status_bar_notification_info_maxnum = 17694723; // 0x10e0003
   }
 
   public static final class R.interpolator {
@@ -1460,6 +1463,7 @@
     field public static final int search_go = 17039372; // 0x104000c
     field public static final int selectAll = 17039373; // 0x104000d
     field public static final int selectTextMode = 17039382; // 0x1040016
+    field public static final int status_bar_notification_info_overflow = 17039383; // 0x1040017
     field public static final int unknownName = 17039374; // 0x104000e
     field public static final int untitled = 17039375; // 0x104000f
     field public static final int yes = 17039379; // 0x1040013
@@ -1632,6 +1636,7 @@
     field public static final int Widget_Holo_AutoCompleteTextView = 16973968; // 0x1030090
     field public static final int Widget_Holo_Button = 16973963; // 0x103008b
     field public static final int Widget_Holo_Button_Borderless = 16974050; // 0x10300e2
+    field public static final int Widget_Holo_Button_Borderless_Small = 16974107; // 0x103011b
     field public static final int Widget_Holo_Button_Inset = 16973965; // 0x103008d
     field public static final int Widget_Holo_Button_Small = 16973964; // 0x103008c
     field public static final int Widget_Holo_Button_Toggle = 16973966; // 0x103008e
@@ -1658,6 +1663,7 @@
     field public static final int Widget_Holo_Light_ActionMode = 16974047; // 0x10300df
     field public static final int Widget_Holo_Light_AutoCompleteTextView = 16974011; // 0x10300bb
     field public static final int Widget_Holo_Light_Button = 16974006; // 0x10300b6
+    field public static final int Widget_Holo_Light_Button_Borderless_Small = 16974108; // 0x103011c
     field public static final int Widget_Holo_Light_Button_Inset = 16974008; // 0x10300b8
     field public static final int Widget_Holo_Light_Button_Small = 16974007; // 0x10300b7
     field public static final int Widget_Holo_Light_Button_Toggle = 16974009; // 0x10300b9
@@ -2448,7 +2454,7 @@
     field public static final int RESULT_OK = -1; // 0xffffffff
   }
 
-  public class ActivityGroup extends android.app.Activity {
+  public deprecated class ActivityGroup extends android.app.Activity {
     ctor public ActivityGroup();
     ctor public ActivityGroup(boolean);
     method public android.app.Activity getCurrentActivity();
@@ -3237,7 +3243,7 @@
     method public abstract void onLoaderReset(android.content.Loader<D>);
   }
 
-  public class LocalActivityManager {
+  public deprecated class LocalActivityManager {
     ctor public LocalActivityManager(android.app.Activity, boolean);
     method public android.view.Window destroyActivity(java.lang.String, boolean);
     method public void dispatchCreate(android.os.Bundle);
@@ -3520,7 +3526,7 @@
     field public static final int START_STICKY_COMPATIBILITY = 0; // 0x0
   }
 
-  public class TabActivity extends android.app.ActivityGroup {
+  public deprecated class TabActivity extends android.app.ActivityGroup {
     ctor public TabActivity();
     method public android.widget.TabHost getTabHost();
     method public android.widget.TabWidget getTabWidget();
@@ -5804,6 +5810,7 @@
     method public abstract void setInstallerPackageName(java.lang.String, java.lang.String);
     field public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0; // 0x0
     field public static final int COMPONENT_ENABLED_STATE_DISABLED = 2; // 0x2
+    field public static final int COMPONENT_ENABLED_STATE_DISABLED_USER = 3; // 0x3
     field public static final int COMPONENT_ENABLED_STATE_ENABLED = 1; // 0x1
     field public static final int DONT_KILL_APP = 1; // 0x1
     field public static final java.lang.String FEATURE_AUDIO_LOW_LATENCY = "android.hardware.audio.low_latency";
@@ -15263,6 +15270,8 @@
     field public static final java.lang.String DIRECTORY_PARAM_KEY = "directory";
     field public static final java.lang.String INCLUDE_PROFILE = "include_profile";
     field public static final java.lang.String LIMIT_PARAM_KEY = "limit";
+    field public static final java.lang.String PRIMARY_ACCOUNT_NAME = "name_for_primary_account";
+    field public static final java.lang.String PRIMARY_ACCOUNT_TYPE = "type_for_primary_account";
   }
 
   public static final class ContactsContract.AggregationExceptions implements android.provider.BaseColumns {
@@ -15605,6 +15614,15 @@
   protected static abstract interface ContactsContract.DataColumnsWithJoins implements android.provider.BaseColumns android.provider.ContactsContract.ContactNameColumns android.provider.ContactsContract.ContactOptionsColumns android.provider.ContactsContract.ContactStatusColumns android.provider.ContactsContract.ContactsColumns android.provider.ContactsContract.DataColumns android.provider.ContactsContract.RawContactsColumns android.provider.ContactsContract.StatusColumns {
   }
 
+  public static final class ContactsContract.DataUsageFeedback {
+    ctor public ContactsContract.DataUsageFeedback();
+    field public static final android.net.Uri FEEDBACK_URI;
+    field public static final java.lang.String USAGE_TYPE = "type";
+    field public static final java.lang.String USAGE_TYPE_CALL = "call";
+    field public static final java.lang.String USAGE_TYPE_LONG_TEXT = "long_text";
+    field public static final java.lang.String USAGE_TYPE_SHORT_TEXT = "short_text";
+  }
+
   public static final class ContactsContract.Directory implements android.provider.BaseColumns {
     method public static void notifyDirectoryChange(android.content.ContentResolver);
     field public static final java.lang.String ACCOUNT_NAME = "accountName";
@@ -16673,6 +16691,7 @@
     method public static android.renderscript.Element U8_4(android.renderscript.RenderScript);
     method public static android.renderscript.Element createPixel(android.renderscript.RenderScript, android.renderscript.Element.DataType, android.renderscript.Element.DataKind);
     method public static android.renderscript.Element createVector(android.renderscript.RenderScript, android.renderscript.Element.DataType, int);
+    method public boolean isCompatible(android.renderscript.Element);
     method public boolean isComplex();
   }
 
@@ -17371,9 +17390,12 @@
     enum_constant public static final android.renderscript.Type.CubemapFace NEGATIVE_X;
     enum_constant public static final android.renderscript.Type.CubemapFace NEGATIVE_Y;
     enum_constant public static final android.renderscript.Type.CubemapFace NEGATIVE_Z;
-    enum_constant public static final android.renderscript.Type.CubemapFace POSITVE_X;
-    enum_constant public static final android.renderscript.Type.CubemapFace POSITVE_Y;
-    enum_constant public static final android.renderscript.Type.CubemapFace POSITVE_Z;
+    enum_constant public static final android.renderscript.Type.CubemapFace POSITIVE_X;
+    enum_constant public static final android.renderscript.Type.CubemapFace POSITIVE_Y;
+    enum_constant public static final android.renderscript.Type.CubemapFace POSITIVE_Z;
+    enum_constant public static final deprecated android.renderscript.Type.CubemapFace POSITVE_X;
+    enum_constant public static final deprecated android.renderscript.Type.CubemapFace POSITVE_Y;
+    enum_constant public static final deprecated android.renderscript.Type.CubemapFace POSITVE_Z;
   }
 
 }
@@ -23715,7 +23737,8 @@
     method public boolean getSavePassword();
     method public synchronized java.lang.String getSerifFontFamily();
     method public synchronized java.lang.String getStandardFontFamily();
-    method public synchronized android.webkit.WebSettings.TextSize getTextSize();
+    method public deprecated synchronized android.webkit.WebSettings.TextSize getTextSize();
+    method public synchronized int getTextZoom();
     method public deprecated synchronized boolean getUseDoubleTree();
     method public deprecated boolean getUseWebViewBackgroundForOverscrollBackground();
     method public synchronized boolean getUseWideViewPort();
@@ -23765,7 +23788,8 @@
     method public synchronized void setStandardFontFamily(java.lang.String);
     method public synchronized void setSupportMultipleWindows(boolean);
     method public void setSupportZoom(boolean);
-    method public synchronized void setTextSize(android.webkit.WebSettings.TextSize);
+    method public deprecated synchronized void setTextSize(android.webkit.WebSettings.TextSize);
+    method public synchronized void setTextZoom(int);
     method public deprecated synchronized void setUseDoubleTree(boolean);
     method public deprecated void setUseWebViewBackgroundForOverscrollBackground(boolean);
     method public synchronized void setUseWideViewPort(boolean);
@@ -23804,7 +23828,7 @@
     enum_constant public static final android.webkit.WebSettings.RenderPriority NORMAL;
   }
 
-  public static final class WebSettings.TextSize extends java.lang.Enum {
+  public static final deprecated class WebSettings.TextSize extends java.lang.Enum {
     method public static android.webkit.WebSettings.TextSize valueOf(java.lang.String);
     method public static final android.webkit.WebSettings.TextSize[] values();
     enum_constant public static final android.webkit.WebSettings.TextSize LARGER;
@@ -24775,21 +24799,23 @@
     ctor public GridLayout(android.content.Context);
     ctor public GridLayout(android.content.Context, android.util.AttributeSet, int);
     ctor public GridLayout(android.content.Context, android.util.AttributeSet);
+    method public int getAlignmentMode();
     method public int getColumnCount();
-    method public boolean getMarginsIncludedInAlignment();
     method public int getOrientation();
     method public int getRowCount();
     method public boolean getUseDefaultMargins();
     method public boolean isColumnOrderPreserved();
     method public boolean isRowOrderPreserved();
     method protected void onLayout(boolean, int, int, int, int);
+    method public void setAlignmentMode(int);
     method public void setColumnCount(int);
     method public void setColumnOrderPreserved(boolean);
-    method public void setMarginsIncludedInAlignment(boolean);
     method public void setOrientation(int);
     method public void setRowCount(int);
     method public void setRowOrderPreserved(boolean);
     method public void setUseDefaultMargins(boolean);
+    field public static final int ALIGN_BOUNDS = 0; // 0x0
+    field public static final int ALIGN_MARGINS = 1; // 0x1
     field public static final android.widget.GridLayout.Alignment BASELINE;
     field public static final android.widget.GridLayout.Alignment BOTTOM;
     field public static final android.widget.GridLayout.Alignment CENTER;
@@ -24802,9 +24828,10 @@
     field public static final int VERTICAL = 1; // 0x1
   }
 
-  public static abstract interface GridLayout.Alignment {
-    method public abstract int getAlignmentValue(android.view.View, int);
-    method public abstract int getSizeInCell(android.view.View, int, int);
+  public static abstract class GridLayout.Alignment {
+    ctor public GridLayout.Alignment();
+    method public abstract int getAlignmentValue(android.view.View, int, int);
+    method public int getSizeInCell(android.view.View, int, int, int);
   }
 
   public static class GridLayout.Group {
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index b0e4a86..e433079 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -120,6 +120,11 @@
             return;
         }
 
+        if ("disable-user".equals(op)) {
+            runSetEnabledSetting(PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER);
+            return;
+        }
+
         if ("setInstallLocation".equals(op)) {
             runSetInstallLocation();
             return;
@@ -970,6 +975,8 @@
                 return "enabled";
             case PackageManager.COMPONENT_ENABLED_STATE_DISABLED:
                 return "disabled";
+            case PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER:
+                return "disabled-user";
         }
         return "unknown";
     }
diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java
index cac06ec..3ec5edb 100644
--- a/core/java/android/app/ActionBar.java
+++ b/core/java/android/app/ActionBar.java
@@ -487,6 +487,12 @@
      * Create and return a new {@link Tab}.
      * This tab will not be included in the action bar until it is added.
      *
+     * <p>Very often tabs will be used to switch between {@link Fragment}
+     * objects.  Here is a typical implementation of such tabs:</p>
+     *
+     * {@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentTabs.java
+     *      complete}
+     *
      * @return A new Tab
      *
      * @see #addTab(Tab)
diff --git a/core/java/android/app/ActivityGroup.java b/core/java/android/app/ActivityGroup.java
index 5b04253..fbd78be 100644
--- a/core/java/android/app/ActivityGroup.java
+++ b/core/java/android/app/ActivityGroup.java
@@ -23,8 +23,13 @@
 import android.util.Log;
 
 /**
+ * @deprecated Use the new {@link Fragment} and {@link FragmentManager} APIs
+ * instead; these are also
+ * available on older platforms through the Android compatibility package.
+ *
  * A screen that contains and runs multiple embedded activities.
  */
+@Deprecated
 public class ActivityGroup extends Activity {
     private static final String TAG = "ActivityGroup";
     private static final String STATES_KEY = "android:states";
diff --git a/core/java/android/app/AlertDialog.java b/core/java/android/app/AlertDialog.java
index e83d104..7a465c1 100644
--- a/core/java/android/app/AlertDialog.java
+++ b/core/java/android/app/AlertDialog.java
@@ -890,7 +890,7 @@
         public AlertDialog create() {
             final AlertDialog dialog = new AlertDialog(P.mContext, mTheme, false);
             P.apply(dialog.mAlert);
-            dialog.setCancelable(P.mCancelable);
+            dialog.setCanceledOnTouchOutside(P.mCancelable);
             dialog.setOnCancelListener(P.mOnCancelListener);
             if (P.mOnKeyListener != null) {
                 dialog.setOnKeyListener(P.mOnKeyListener);
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 20dc792..94a4afa 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -52,6 +52,8 @@
 import android.media.AudioManager;
 import android.net.ConnectivityManager;
 import android.net.IConnectivityManager;
+import android.net.INetworkPolicyManager;
+import android.net.NetworkPolicyManager;
 import android.net.ThrottleManager;
 import android.net.IThrottleManager;
 import android.net.Uri;
@@ -339,6 +341,14 @@
                     return new LocationManager(ILocationManager.Stub.asInterface(b));
                 }});
 
+        registerService(NETWORK_POLICY_SERVICE, new ServiceFetcher() {
+            @Override
+            public Object createService(ContextImpl ctx) {
+                return new NetworkPolicyManager(INetworkPolicyManager.Stub.asInterface(
+                        ServiceManager.getService(NETWORK_POLICY_SERVICE)));
+            }
+        });
+
         registerService(NOTIFICATION_SERVICE, new ServiceFetcher() {
                 public Object createService(ContextImpl ctx) {
                     final Context outerContext = ctx.getOuterContext();
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index b88e5cf..28559cc 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -23,6 +23,7 @@
 import android.database.Cursor;
 import android.database.CursorWrapper;
 import android.net.ConnectivityManager;
+import android.net.NetworkPolicyManager;
 import android.net.Uri;
 import android.os.Environment;
 import android.os.ParcelFileDescriptor;
@@ -170,7 +171,6 @@
      */
     public final static int STATUS_FAILED = 1 << 4;
 
-
     /**
      * Value of COLUMN_ERROR_CODE when the download has completed with an error that doesn't fit
      * under any other error code.
@@ -249,6 +249,14 @@
     public final static int PAUSED_UNKNOWN = 4;
 
     /**
+     * Value of {@link #COLUMN_REASON} when the download has been paused because
+     * of {@link NetworkPolicyManager} controls on the requesting application.
+     *
+     * @hide
+     */
+    public final static int PAUSED_BY_POLICY = 5;
+
+    /**
      * Broadcast intent action sent by the download manager when a download completes.
      */
     public final static String ACTION_DOWNLOAD_COMPLETE = "android.intent.action.DOWNLOAD_COMPLETE";
@@ -796,6 +804,7 @@
                     parts.add(statusClause("=", Downloads.Impl.STATUS_WAITING_TO_RETRY));
                     parts.add(statusClause("=", Downloads.Impl.STATUS_WAITING_FOR_NETWORK));
                     parts.add(statusClause("=", Downloads.Impl.STATUS_QUEUED_FOR_WIFI));
+                    parts.add(statusClause("=", Downloads.Impl.STATUS_PAUSED_BY_POLICY));
                 }
                 if ((mStatusFlags & STATUS_SUCCESSFUL) != 0) {
                     parts.add(statusClause("=", Downloads.Impl.STATUS_SUCCESS));
@@ -1266,6 +1275,9 @@
                 case Downloads.Impl.STATUS_QUEUED_FOR_WIFI:
                     return PAUSED_QUEUED_FOR_WIFI;
 
+                case Downloads.Impl.STATUS_PAUSED_BY_POLICY:
+                    return PAUSED_BY_POLICY;
+
                 default:
                     return PAUSED_UNKNOWN;
             }
@@ -1321,6 +1333,7 @@
                 case Downloads.Impl.STATUS_WAITING_TO_RETRY:
                 case Downloads.Impl.STATUS_WAITING_FOR_NETWORK:
                 case Downloads.Impl.STATUS_QUEUED_FOR_WIFI:
+                case Downloads.Impl.STATUS_PAUSED_BY_POLICY:
                     return STATUS_PAUSED;
 
                 case Downloads.Impl.STATUS_SUCCESS:
diff --git a/core/java/android/app/LocalActivityManager.java b/core/java/android/app/LocalActivityManager.java
index c958e1b..0a6b804 100644
--- a/core/java/android/app/LocalActivityManager.java
+++ b/core/java/android/app/LocalActivityManager.java
@@ -28,12 +28,17 @@
 import java.util.Map;
 
 /**
- * Helper class for managing multiple running embedded activities in the same
+ * @deprecated Use the new {@link Fragment} and {@link FragmentManager} APIs
+ * instead; these are also
+ * available on older platforms through the Android compatibility package.
+ *
+ * <p>Helper class for managing multiple running embedded activities in the same
  * process. This class is not normally used directly, but rather created for
  * you as part of the {@link android.app.ActivityGroup} implementation.
  *
  * @see ActivityGroup
  */
+@Deprecated
 public class LocalActivityManager {
     private static final String TAG = "LocalActivityManager";
     private static final boolean localLOGV = false;
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index c9351af..170d2b5 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -929,15 +929,15 @@
             if (mContentInfo != null) {
                 contentView.setTextViewText(R.id.info, mContentInfo);
             } else if (mNumber > 0) {
-                if (mNumber > 999) {
-                    contentView.setTextViewText(R.id.info, "999+");
+                final int tooBig = mContext.getResources().getInteger(
+                        R.integer.status_bar_notification_info_maxnum);
+                if (mNumber > tooBig) {
+                    contentView.setTextViewText(R.id.info, mContext.getResources().getString(
+                                R.string.status_bar_notification_info_overflow));
                 } else {
                     NumberFormat f = NumberFormat.getIntegerInstance();
                     contentView.setTextViewText(R.id.info, f.format(mNumber));
                 }
-                contentView.setFloat(R.id.info, "setTextSize",
-                        mContext.getResources().getDimensionPixelSize(
-                            R.dimen.status_bar_content_number_size));
             } else {
                 contentView.setViewVisibility(R.id.info, View.GONE);
             }
diff --git a/core/java/android/app/TabActivity.java b/core/java/android/app/TabActivity.java
index 033fa0c..0fd0c2c 100644
--- a/core/java/android/app/TabActivity.java
+++ b/core/java/android/app/TabActivity.java
@@ -23,8 +23,34 @@
 import android.widget.TextView;
 
 /**
- * An activity that contains and runs multiple embedded activities or views.
+ * @deprecated New applications should use Fragments instead of this class;
+ * to continue to run on older devices, you can use the v4 support library
+ * which provides a version of the Fragment API that is compatible down to
+ * {@link android.os.Build.VERSION_CODES#DONUT}.
+ *
+ * <p>For apps developing against {@link android.os.Build.VERSION_CODES#HONEYCOMB}
+ * or later, tabs are typically presented in the UI using the new
+ * {@link ActionBar#newTab() ActionBar.newTab()} and
+ * related APIs for placing tabs within their action bar area.</p>
+ *
+ * <p>A replacement for TabActivity can also be implemented by directly using
+ * TabHost.  You will need to define a layout that correctly uses a TabHost
+ * with a TabWidget as well as an area in which to display your tab content.
+ * A typical example would be:</p>
+ *
+ * {@sample development/samples/Support4Demos/res/layout/fragment_tabs.xml complete}
+ *
+ * <p>The implementation needs to take over responsibility for switching
+ * the shown content when the user switches between tabs.
+ *
+ * {@sample development/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentTabs.java
+ *      complete}
+ *
+ * <p>Also see the <a href="{@docRoot}resources/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentTabsPager.html">
+ * Fragment Tabs Pager</a> sample for an example of using the support library's ViewPager to
+ * allow the user to swipe the content to switch between tabs.</p>
  */
+@Deprecated
 public class TabActivity extends ActivityGroup {
     private TabHost mTabHost;
     private String mDefaultTab = null;
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index c0a1d8e..454cb31 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -417,6 +417,12 @@
     public boolean enabled = true;
 
     /**
+     * For convenient access to the current enabled setting of this app.
+     * @hide
+     */
+    public int enabledSetting = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
+
+    /**
      * For convenient access to package's install location.
      * @hide
      */
@@ -508,6 +514,7 @@
         uid = orig.uid;
         targetSdkVersion = orig.targetSdkVersion;
         enabled = orig.enabled;
+        enabledSetting = orig.enabledSetting;
         installLocation = orig.installLocation;
         manageSpaceActivityName = orig.manageSpaceActivityName;
         descriptionRes = orig.descriptionRes;
@@ -544,6 +551,7 @@
         dest.writeInt(uid);
         dest.writeInt(targetSdkVersion);
         dest.writeInt(enabled ? 1 : 0);
+        dest.writeInt(enabledSetting);
         dest.writeInt(installLocation);
         dest.writeString(manageSpaceActivityName);
         dest.writeString(backupAgentName);
@@ -581,6 +589,7 @@
         uid = source.readInt();
         targetSdkVersion = source.readInt();
         enabled = source.readInt() != 0;
+        enabledSetting = source.readInt();
         installLocation = source.readInt();
         manageSpaceActivityName = source.readString();
         backupAgentName = source.readString();
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 1cd8ec0..dd684cd 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -224,11 +224,41 @@
      */
     public static final int SIGNATURE_UNKNOWN_PACKAGE = -4;
 
+    /**
+     * Flag for {@link #setApplicationEnabledSetting(String, int, int)}
+     * and {@link #setComponentEnabledSetting(ComponentName, int, int)}: This
+     * component or application is in its default enabled state (as specified
+     * in its manifest).
+     */
     public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0;
+
+    /**
+     * Flag for {@link #setApplicationEnabledSetting(String, int, int)}
+     * and {@link #setComponentEnabledSetting(ComponentName, int, int)}: This
+     * component or application has been explictily enabled, regardless of
+     * what it has specified in its manifest.
+     */
     public static final int COMPONENT_ENABLED_STATE_ENABLED = 1;
+
+    /**
+     * Flag for {@link #setApplicationEnabledSetting(String, int, int)}
+     * and {@link #setComponentEnabledSetting(ComponentName, int, int)}: This
+     * component or application has been explicitly disabled, regardless of
+     * what it has specified in its manifest.
+     */
     public static final int COMPONENT_ENABLED_STATE_DISABLED = 2;
 
     /**
+     * Flag for {@link #setApplicationEnabledSetting(String, int, int)} only: The
+     * user has explicitly disabled the application, regardless of what it has
+     * specified in its manifest.  Because this is due to the user's request,
+     * they may re-enable it if desired through the appropriate system UI.  This
+     * option currently <strong>can not</strong> be used with
+     * {@link #setComponentEnabledSetting(ComponentName, int, int)}.
+     */
+    public static final int COMPONENT_ENABLED_STATE_DISABLED_USER = 3;
+
+    /**
      * Flag parameter for {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} to
      * indicate that this package should be installed as forward locked, i.e. only the app itself
      * should have access to its code and non-resource assets.
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 31ad6e9..e927f6c 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -3128,9 +3128,11 @@
         }
         if (p.mSetEnabled == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
             ai.enabled = true;
-        } else if (p.mSetEnabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
+        } else if (p.mSetEnabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED
+                || p.mSetEnabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
             ai.enabled = false;
         }
+        ai.enabledSetting = p.mSetEnabled;
         return ai;
     }
 
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 1df3108..338e6c8 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -216,7 +216,9 @@
      *     {@link #getNumberOfCameras()}-1.
      * @return a new Camera object, connected, locked and ready for use.
      * @throws RuntimeException if connection to the camera service fails (for
-     *     example, if the camera is in use by another process).
+     *     example, if the camera is in use by another process or device policy
+     *     manager has disabled the camera).
+     * @see android.app.admin.DevicePolicyManager#getCameraDisabled(android.content.ComponentName)
      */
     public static Camera open(int cameraId) {
         return new Camera(cameraId);
diff --git a/core/java/android/net/MobileDataStateTracker.java b/core/java/android/net/MobileDataStateTracker.java
index 770f152..f3c863f 100644
--- a/core/java/android/net/MobileDataStateTracker.java
+++ b/core/java/android/net/MobileDataStateTracker.java
@@ -69,10 +69,6 @@
     private boolean mPrivateDnsRouteSet = false;
     private boolean mDefaultRouteSet = false;
 
-    // DEFAULT and HIPRI are the same connection.  If we're one of these we need to check if
-    // the other is also disconnected before we reset sockets
-    private boolean mIsDefaultOrHipri = false;
-
     private Handler mHandler;
     private AsyncChannel mDataConnectionTrackerAc;
     private Messenger mMessenger;
@@ -87,12 +83,6 @@
                 TelephonyManager.getDefault().getNetworkType(), tag,
                 TelephonyManager.getDefault().getNetworkTypeName());
         mApnType = networkTypeToApnType(netType);
-        if (netType == ConnectivityManager.TYPE_MOBILE ||
-                netType == ConnectivityManager.TYPE_MOBILE_HIPRI) {
-            mIsDefaultOrHipri = true;
-        }
-
-        mPhoneService = null;
     }
 
     /**
@@ -180,8 +170,6 @@
     }
 
     private class MobileDataStateReceiver extends BroadcastReceiver {
-        IConnectivityManager mConnectivityManager;
-
         @Override
         public void onReceive(Context context, Intent intent) {
             if (intent.getAction().equals(TelephonyIntents.
@@ -218,35 +206,6 @@
                             }
 
                             setDetailedState(DetailedState.DISCONNECTED, reason, apnName);
-                            boolean doReset = true;
-                            if (mIsDefaultOrHipri == true) {
-                                // both default and hipri must go down before we reset
-                                int typeToCheck = (Phone.APN_TYPE_DEFAULT.equals(mApnType) ?
-                                    ConnectivityManager.TYPE_MOBILE_HIPRI :
-                                    ConnectivityManager.TYPE_MOBILE);
-                                if (mConnectivityManager == null) {
-                                    IBinder b = ServiceManager.getService(
-                                            Context.CONNECTIVITY_SERVICE);
-                                    mConnectivityManager = IConnectivityManager.Stub.asInterface(b);
-                                }
-                                try {
-                                    if (mConnectivityManager != null) {
-                                        NetworkInfo info = mConnectivityManager.getNetworkInfo(
-                                                typeToCheck);
-                                        if (info.isConnected() == true) {
-                                            doReset = false;
-                                        }
-                                    }
-                                } catch (RemoteException e) {
-                                    // just go ahead with the reset
-                                    loge("Exception trying to contact ConnService: " + e);
-                                }
-                            }
-                            if (doReset && mLinkProperties != null) {
-                                String iface = mLinkProperties.getInterfaceName();
-                                if (iface != null) NetworkUtils.resetConnections(iface);
-                            }
-                            // TODO - check this
                             // can't do this here - ConnectivityService needs it to clear stuff
                             // it's ok though - just leave it to be refreshed next time
                             // we connect.
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index 538a06e..0d4d9a9 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -115,6 +115,20 @@
         }
     }
 
+    public void registerListener(INetworkPolicyListener listener) {
+        try {
+            mService.registerListener(listener);
+        } catch (RemoteException e) {
+        }
+    }
+
+    public void unregisterListener(INetworkPolicyListener listener) {
+        try {
+            mService.unregisterListener(listener);
+        } catch (RemoteException e) {
+        }
+    }
+
     /**
      * Compute the last cycle boundary for the given {@link NetworkPolicy}. For
      * example, if cycle day is 20th, and today is June 15th, it will return May
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index f17a6f2..b97ec19 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -59,6 +59,11 @@
     void setInterfaceConfig(String iface, in InterfaceConfiguration cfg);
 
     /**
+     * Clear all IP addresses on the specified interface
+     */
+    void clearInterfaceAddresses(String iface);
+
+    /**
      * Retrieves the network routes currently configured on the specified
      * interface
      */
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java
index b6d1594..74a376d 100644
--- a/core/java/android/preference/Preference.java
+++ b/core/java/android/preference/Preference.java
@@ -29,6 +29,7 @@
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.view.AbsSavedState;
+import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
@@ -956,6 +957,17 @@
             context.startActivity(mIntent);
         }
     }
+
+    /**
+     * Allows a Preference to intercept key events without having focus.
+     * For example, SeekBarPreference uses this to intercept +/- to adjust
+     * the progress.
+     * @return True if the Preference handled the key. Returns false by default.
+     * @hide
+     */
+    public boolean onKey(View v, int keyCode, KeyEvent event) {
+        return false;
+    }
     
     /**
      * Returns the {@link android.content.Context} of this Preference. 
diff --git a/core/java/android/preference/PreferenceFragment.java b/core/java/android/preference/PreferenceFragment.java
index 488919c..f6ba7f7 100644
--- a/core/java/android/preference/PreferenceFragment.java
+++ b/core/java/android/preference/PreferenceFragment.java
@@ -20,13 +20,14 @@
 import android.app.Fragment;
 import android.content.Intent;
 import android.content.SharedPreferences;
-import android.content.res.Configuration;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
+import android.view.KeyEvent;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.View.OnKeyListener;
 import android.widget.ListView;
 
 /**
@@ -350,6 +351,22 @@
                     "Your content must have a ListView whose id attribute is " +
                     "'android.R.id.list'");
         }
+        mList.setOnKeyListener(mListOnKeyListener);
         mHandler.post(mRequestFocus);
     }
+
+    private OnKeyListener mListOnKeyListener = new OnKeyListener() {
+
+        @Override
+        public boolean onKey(View v, int keyCode, KeyEvent event) {
+            Object selectedItem = mList.getSelectedItem();
+            if (selectedItem instanceof Preference) {
+                View selectedView = mList.getSelectedView();
+                return ((Preference)selectedItem).onKey(
+                        selectedView, keyCode, event);
+            }
+            return false;
+        }
+
+    };
 }
diff --git a/core/java/android/preference/SeekBarDialogPreference.java b/core/java/android/preference/SeekBarDialogPreference.java
new file mode 100644
index 0000000..0e89b16
--- /dev/null
+++ b/core/java/android/preference/SeekBarDialogPreference.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2007 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.preference;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.preference.DialogPreference;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.SeekBar;
+
+/**
+ * @hide
+ */
+public class SeekBarDialogPreference extends DialogPreference {
+    private static final String TAG = "SeekBarDialogPreference";
+
+    private Drawable mMyIcon;
+
+    public SeekBarDialogPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        setDialogLayoutResource(com.android.internal.R.layout.seekbar_dialog);
+        createActionButtons();
+
+        // Steal the XML dialogIcon attribute's value
+        mMyIcon = getDialogIcon();
+        setDialogIcon(null);
+    }
+
+    // Allow subclasses to override the action buttons
+    public void createActionButtons() {
+        setPositiveButtonText(android.R.string.ok);
+        setNegativeButtonText(android.R.string.cancel);
+    }
+
+    @Override
+    protected void onBindDialogView(View view) {
+        super.onBindDialogView(view);
+
+        final ImageView iconView = (ImageView) view.findViewById(android.R.id.icon);
+        if (mMyIcon != null) {
+            iconView.setImageDrawable(mMyIcon);
+        } else {
+            iconView.setVisibility(View.GONE);
+        }
+    }
+
+    protected static SeekBar getSeekBar(View dialogView) {
+        return (SeekBar) dialogView.findViewById(com.android.internal.R.id.seekbar);
+    }
+}
diff --git a/core/java/android/preference/SeekBarPreference.java b/core/java/android/preference/SeekBarPreference.java
index 037fb41..b8919c2 100644
--- a/core/java/android/preference/SeekBarPreference.java
+++ b/core/java/android/preference/SeekBarPreference.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007 The Android Open Source Project
+ * Copyright (C) 2011 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.
@@ -17,51 +17,226 @@
 package android.preference;
 
 import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.preference.DialogPreference;
+import android.content.res.TypedArray;
+import android.os.Parcel;
+import android.os.Parcelable;
 import android.util.AttributeSet;
+import android.view.KeyEvent;
 import android.view.View;
-import android.widget.ImageView;
 import android.widget.SeekBar;
+import android.widget.SeekBar.OnSeekBarChangeListener;
 
 /**
  * @hide
  */
-public class SeekBarPreference extends DialogPreference {
-    private static final String TAG = "SeekBarPreference";
+public class SeekBarPreference extends Preference
+        implements OnSeekBarChangeListener {
 
-    private Drawable mMyIcon;
+    private int mProgress;
+    private int mMax;
+    private boolean mTrackingTouch;
 
-    public SeekBarPreference(Context context, AttributeSet attrs) {
-        super(context, attrs);
-
-        setDialogLayoutResource(com.android.internal.R.layout.seekbar_dialog);
-        createActionButtons();
-
-        // Steal the XML dialogIcon attribute's value
-        mMyIcon = getDialogIcon();
-        setDialogIcon(null);
+    public SeekBarPreference(
+            Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        TypedArray a = context.obtainStyledAttributes(attrs,
+                com.android.internal.R.styleable.ProgressBar, defStyle, 0);
+        setMax(a.getInt(com.android.internal.R.styleable.ProgressBar_max, mMax));
+        a.recycle();
+        setLayoutResource(com.android.internal.R.layout.preference_widget_seekbar);
     }
 
-    // Allow subclasses to override the action buttons
-    public void createActionButtons() {
-        setPositiveButtonText(android.R.string.ok);
-        setNegativeButtonText(android.R.string.cancel);
+    public SeekBarPreference(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public SeekBarPreference(Context context) {
+        this(context, null);
     }
 
     @Override
-    protected void onBindDialogView(View view) {
-        super.onBindDialogView(view);
+    protected void onBindView(View view) {
+        super.onBindView(view);
+        SeekBar seekBar = (SeekBar) view.findViewById(
+                com.android.internal.R.id.seekbar);
+        seekBar.setOnSeekBarChangeListener(this);
+        seekBar.setMax(mMax);
+        seekBar.setProgress(mProgress);
+        seekBar.setEnabled(isEnabled());
+    }
 
-        final ImageView iconView = (ImageView) view.findViewById(android.R.id.icon);
-        if (mMyIcon != null) {
-            iconView.setImageDrawable(mMyIcon);
-        } else {
-            iconView.setVisibility(View.GONE);
+    @Override
+    public CharSequence getSummary() {
+        return null;
+    }
+
+    @Override
+    protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+        setProgress(restoreValue ? getPersistedInt(mProgress)
+                : (Integer) defaultValue);
+    }
+
+    @Override
+    public boolean onKey(View v, int keyCode, KeyEvent event) {
+        if (event.getAction() != KeyEvent.ACTION_UP) {
+            if (keyCode == KeyEvent.KEYCODE_PLUS
+                    || keyCode == KeyEvent.KEYCODE_EQUALS) {
+                setProgress(getProgress() + 1);
+                return true;
+            }
+            if (keyCode == KeyEvent.KEYCODE_MINUS) {
+                setProgress(getProgress() - 1);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    public void setMax(int max) {
+        if (max != mMax) {
+            mMax = max;
+            notifyChanged();
         }
     }
 
-    protected static SeekBar getSeekBar(View dialogView) {
-        return (SeekBar) dialogView.findViewById(com.android.internal.R.id.seekbar);
+    public void setProgress(int progress) {
+        setProgress(progress, true);
+    }
+
+    private void setProgress(int progress, boolean notifyChanged) {
+        if (progress > mMax) {
+            progress = mMax;
+        }
+        if (progress < 0) {
+            progress = 0;
+        }
+        if (progress != mProgress) {
+            mProgress = progress;
+            persistInt(progress);
+            if (notifyChanged) {
+                notifyChanged();
+            }
+        }
+    }
+
+    public int getProgress() {
+        return mProgress;
+    }
+
+    /**
+     * Persist the seekBar's progress value if callChangeListener
+     * returns true, otherwise set the seekBar's progress to the stored value
+     */
+    void syncProgress(SeekBar seekBar) {
+        int progress = seekBar.getProgress();
+        if (progress != mProgress) {
+            if (callChangeListener(progress)) {
+                setProgress(progress, false);
+            } else {
+                seekBar.setProgress(mProgress);
+            }
+        }
+    }
+
+    @Override
+    public void onProgressChanged(
+            SeekBar seekBar, int progress, boolean fromUser) {
+        if (fromUser && !mTrackingTouch) {
+            syncProgress(seekBar);
+        }
+    }
+
+    @Override
+    public void onStartTrackingTouch(SeekBar seekBar) {
+        mTrackingTouch = true;
+    }
+
+    @Override
+    public void onStopTrackingTouch(SeekBar seekBar) {
+        mTrackingTouch = false;
+        if (seekBar.getProgress() != mProgress) {
+            syncProgress(seekBar);
+        }
+    }
+
+    @Override
+    protected Parcelable onSaveInstanceState() {
+        /*
+         * Suppose a client uses this preference type without persisting. We
+         * must save the instance state so it is able to, for example, survive
+         * orientation changes.
+         */
+
+        final Parcelable superState = super.onSaveInstanceState();
+        if (isPersistent()) {
+            // No need to save instance state since it's persistent
+            return superState;
+        }
+
+        // Save the instance state
+        final SavedState myState = new SavedState(superState);
+        myState.progress = mProgress;
+        myState.max = mMax;
+        return myState;
+    }
+
+    @Override
+    protected void onRestoreInstanceState(Parcelable state) {
+        if (!state.getClass().equals(SavedState.class)) {
+            // Didn't save state for us in onSaveInstanceState
+            super.onRestoreInstanceState(state);
+            return;
+        }
+
+        // Restore the instance state
+        SavedState myState = (SavedState) state;
+        super.onRestoreInstanceState(myState.getSuperState());
+        mProgress = myState.progress;
+        mMax = myState.max;
+        notifyChanged();
+    }
+
+    /**
+     * SavedState, a subclass of {@link BaseSavedState}, will store the state
+     * of MyPreference, a subclass of Preference.
+     * <p>
+     * It is important to always call through to super methods.
+     */
+    private static class SavedState extends BaseSavedState {
+        int progress;
+        int max;
+
+        public SavedState(Parcel source) {
+            super(source);
+
+            // Restore the click counter
+            progress = source.readInt();
+            max = source.readInt();
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            super.writeToParcel(dest, flags);
+
+            // Save the click counter
+            dest.writeInt(progress);
+            dest.writeInt(max);
+        }
+
+        public SavedState(Parcelable superState) {
+            super(superState);
+        }
+
+        @SuppressWarnings("unused")
+        public static final Parcelable.Creator<SavedState> CREATOR =
+                new Parcelable.Creator<SavedState>() {
+            public SavedState createFromParcel(Parcel in) {
+                return new SavedState(in);
+            }
+
+            public SavedState[] newArray(int size) {
+                return new SavedState[size];
+            }
+        };
     }
 }
diff --git a/core/java/android/preference/VolumePreference.java b/core/java/android/preference/VolumePreference.java
index 3b12780..b48e8ce 100644
--- a/core/java/android/preference/VolumePreference.java
+++ b/core/java/android/preference/VolumePreference.java
@@ -38,19 +38,19 @@
 /**
  * @hide
  */
-public class VolumePreference extends SeekBarPreference implements 
+public class VolumePreference extends SeekBarDialogPreference implements
         PreferenceManager.OnActivityStopListener, View.OnKeyListener {
 
     private static final String TAG = "VolumePreference";
-    
+
     private int mStreamType;
 
     /** May be null if the dialog isn't visible. */
     private SeekBarVolumizer mSeekBarVolumizer;
-    
+
     public VolumePreference(Context context, AttributeSet attrs) {
         super(context, attrs);
-        
+
         TypedArray a = context.obtainStyledAttributes(attrs,
                 com.android.internal.R.styleable.VolumePreference, 0, 0);
         mStreamType = a.getInt(android.R.styleable.VolumePreference_streamType, 0);
@@ -64,7 +64,7 @@
     @Override
     protected void onBindDialogView(View view) {
         super.onBindDialogView(view);
-    
+
         final SeekBar seekBar = (SeekBar) view.findViewById(com.android.internal.R.id.seekbar);
         mSeekBarVolumizer = new SeekBarVolumizer(getContext(), seekBar, mStreamType);
 
@@ -105,7 +105,7 @@
     @Override
     protected void onDialogClosed(boolean positiveResult) {
         super.onDialogClosed(positiveResult);
-        
+
         if (!positiveResult && mSeekBarVolumizer != null) {
             mSeekBarVolumizer.revertVolume();
         }
@@ -222,16 +222,16 @@
 
         private Context mContext;
         private Handler mHandler = new Handler();
-    
+
         private AudioManager mAudioManager;
         private int mStreamType;
-        private int mOriginalStreamVolume; 
+        private int mOriginalStreamVolume;
         private Ringtone mRingtone;
-    
+
         private int mLastProgress = -1;
         private SeekBar mSeekBar;
         private int mVolumeBeforeMute = -1;
-        
+
         private ContentObserver mVolumeObserver = new ContentObserver(mHandler) {
             @Override
             public void onChange(boolean selfChange) {
@@ -263,7 +263,7 @@
             mOriginalStreamVolume = mAudioManager.getStreamVolume(mStreamType);
             seekBar.setProgress(mOriginalStreamVolume);
             seekBar.setOnSeekBarChangeListener(this);
-            
+
             mContext.getContentResolver().registerContentObserver(
                     System.getUriFor(System.VOLUME_SETTINGS[mStreamType]),
                     false, mVolumeObserver);
@@ -290,17 +290,17 @@
             mContext.getContentResolver().unregisterContentObserver(mVolumeObserver);
             mSeekBar.setOnSeekBarChangeListener(null);
         }
-        
+
         public void revertVolume() {
             mAudioManager.setStreamVolume(mStreamType, mOriginalStreamVolume, 0);
         }
-        
+
         public void onProgressChanged(SeekBar seekBar, int progress,
                 boolean fromTouch) {
             if (!fromTouch) {
                 return;
             }
-    
+
             postSetVolume(progress);
         }
 
@@ -310,7 +310,7 @@
             mHandler.removeCallbacks(this);
             mHandler.post(this);
         }
-    
+
         public void onStartTrackingTouch(SeekBar seekBar) {
         }
 
@@ -319,7 +319,7 @@
                 startSample();
             }
         }
-        
+
         public void run() {
             mAudioManager.setStreamVolume(mStreamType, mLastProgress, 0);
         }
@@ -334,7 +334,7 @@
                 mRingtone.play();
             }
         }
-    
+
         public void stopSample() {
             if (mRingtone != null) {
                 mRingtone.stop();
@@ -344,7 +344,7 @@
         public SeekBar getSeekBar() {
             return mSeekBar;
         }
-        
+
         public void changeVolumeBy(int amount) {
             mSeekBar.incrementProgressBy(amount);
             if (!isSamplePlaying()) {
diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java
index 3db1827..4368e31 100644
--- a/core/java/android/provider/CalendarContract.java
+++ b/core/java/android/provider/CalendarContract.java
@@ -476,7 +476,96 @@
      }
 
     /**
-     * Fields and helpers for interacting with Calendars.
+     * Constants and helpers for the Calendars table, which contains details for
+     * individual calendars. <h3>Operations</h3> All operations can be done
+     * either as an app or as a sync adapter. To perform an operation as a sync
+     * adapter {@link #CALLER_IS_SYNCADAPTER} should be set to true and
+     * {@link #ACCOUNT_NAME} and {@link #ACCOUNT_TYPE} must be set in the Uri
+     * parameters. See
+     * {@link Uri.Builder#appendQueryParameter(java.lang.String, java.lang.String)}
+     * for details on adding parameters. Sync adapters have write access to more
+     * columns but are restricted to a single account at a time. Calendars are
+     * designed to be primarily managed by a sync adapter and inserting new
+     * calendars should be done as a sync adapter. For the most part, apps
+     * should only update calendars (such as changing the color or display
+     * name). If a local calendar is required an app can do so by inserting as a
+     * sync adapter and using an {@link #ACCOUNT_TYPE} of
+     * {@link #ACCOUNT_TYPE_LOCAL} .
+     * <dl>
+     * <dt><b>Insert</b></dt>
+     * <dd>When inserting a new calendar the following fields must be included:
+     * <ul>
+     * <li>{@link #ACCOUNT_NAME}</li>
+     * <li>{@link #ACCOUNT_TYPE}</li>
+     * <li>{@link #NAME}</li>
+     * <li>{@link #CALENDAR_DISPLAY_NAME}</li>
+     * <li>{@link #CALENDAR_COLOR}</li>
+     * <li>{@link #CALENDAR_ACCESS_LEVEL}</li>
+     * <li>{@link #OWNER_ACCOUNT}</li>
+     * </ul>
+     * The following fields are not required when inserting a Calendar but are
+     * generally a good idea to include:
+     * <ul>
+     * <li>{@link #SYNC_EVENTS} set to 1</li>
+     * <li>{@link #CALENDAR_TIME_ZONE}</li>
+     * <li>{@link #ALLOWED_REMINDERS}</li>
+     * </ul>
+     * <dt><b>Update</b></dt>
+     * <dd>To perform an update on a calendar the {@link #_ID} of the calendar
+     * should be provided either as an appended id to the Uri (
+     * {@link ContentUris#withAppendedId}) or as the first selection item--the
+     * selection should start with "_id=?" and the first selectionArg should be
+     * the _id of the calendar. Calendars may also be updated using a selection
+     * without the id. In general, the {@link #ACCOUNT_NAME} and
+     * {@link #ACCOUNT_TYPE} should not be changed after a calendar is created
+     * as this can cause issues for sync adapters.
+     * <dt><b>Delete</b></dt>
+     * <dd>Calendars can be deleted either by the {@link #_ID} as an appended id
+     * on the Uri or using any standard selection. Deleting a calendar should
+     * generally be handled by a sync adapter as it will remove the calendar
+     * from the database and all associated data (aka events).</dd>
+     * <dt><b>Query</b></dt>
+     * <dd>Querying the Calendars table will get you all information about a set
+     * of calendars. There will be one row returned for each calendar that
+     * matches the query selection, or at most a single row if the {@link #_ID}
+     * is appended to the Uri.</dd>
+     * </dl>
+     * <h3>Calendar Columns</h3> The following Calendar columns are writable by
+     * both an app and a sync adapter.
+     * <ul>
+     * <li>{@link #NAME}</li>
+     * <li>{@link #CALENDAR_DISPLAY_NAME}</li>
+     * <li>{@link #CALENDAR_COLOR}</li>
+     * <li>{@link #VISIBLE}</li>
+     * <li>{@link #SYNC_EVENTS}</li>
+     * </ul>
+     * The following Calendars columns are writable only by a sync adapter
+     * <ul>
+     * <li>{@link #ACCOUNT_NAME}</li>
+     * <li>{@link #ACCOUNT_TYPE}</li>
+     * <li>{@link #_SYNC_ID}</li>
+     * <li>{@link #DIRTY}</li>
+     * <li>{@link #OWNER_ACCOUNT}</li>
+     * <li>{@link #MAX_REMINDERS}</li>
+     * <li>{@link #ALLOWED_REMINDERS}</li>
+     * <li>{@link #CAN_MODIFY_TIME_ZONE}</li>
+     * <li>{@link #CAN_ORGANIZER_RESPOND}</li>
+     * <li>{@link #CAN_PARTIALLY_UPDATE}</li>
+     * <li>{@link #CALENDAR_LOCATION}</li>
+     * <li>{@link #CALENDAR_TIME_ZONE}</li>
+     * <li>{@link #CALENDAR_ACCESS_LEVEL}</li>
+     * <li>{@link #DELETED}</li>
+     * <li>{@link #CAL_SYNC1}</li>
+     * <li>{@link #CAL_SYNC2}</li>
+     * <li>{@link #CAL_SYNC3}</li>
+     * <li>{@link #CAL_SYNC4}</li>
+     * <li>{@link #CAL_SYNC5}</li>
+     * <li>{@link #CAL_SYNC6}</li>
+     * <li>{@link #CAL_SYNC7}</li>
+     * <li>{@link #CAL_SYNC8}</li>
+     * <li>{@link #CAL_SYNC9}</li>
+     * <li>{@link #CAL_SYNC10}</li>
+     * </ul>
      */
     public static class Calendars implements BaseColumns, SyncColumns, CalendarsColumns {
         private static final String WHERE_DELETE_FOR_ACCOUNT = Calendars.ACCOUNT_NAME + "=?"
@@ -569,6 +658,7 @@
             DIRTY,
             OWNER_ACCOUNT,
             MAX_REMINDERS,
+            ALLOWED_REMINDERS,
             CAN_MODIFY_TIME_ZONE,
             CAN_ORGANIZER_RESPOND,
             CAN_PARTIALLY_UPDATE,
@@ -648,7 +738,21 @@
     }
 
     /**
-     * Fields and helpers for interacting with Attendees.
+     * Fields and helpers for interacting with Attendees. Each row of this table
+     * represents a single attendee or guest of an event. Calling
+     * {@link #query(ContentResolver, long)} will return a list of attendees for
+     * the event with the given eventId. Both apps and sync adapters may write
+     * to this table. There are six writable fields and all of them except
+     * {@link #ATTENDEE_NAME} must be included when inserting a new attendee.
+     * They are:
+     * <ul>
+     * <li>{@link #EVENT_ID}</li>
+     * <li>{@link #ATTENDEE_NAME}</li>
+     * <li>{@link #ATTENDEE_EMAIL}</li>
+     * <li>{@link #ATTENDEE_RELATIONSHIP}</li>
+     * <li>{@link #ATTENDEE_TYPE}</li>
+     * <li>{@link #ATTENDEE_STATUS}</li>
+     * </ul>
      */
     public static final class Attendees implements BaseColumns, AttendeesColumns, EventsColumns {
 
@@ -1238,7 +1342,106 @@
     }
 
     /**
-     * Fields and helpers for interacting with Events.
+     * Constants and helpers for the Events table, which contains details for
+     * individual events. <h3>Operations</h3> All operations can be done either
+     * as an app or as a sync adapter. To perform an operation as a sync adapter
+     * {@link #CALLER_IS_SYNCADAPTER} should be set to true and
+     * {@link #ACCOUNT_NAME} and {@link #ACCOUNT_TYPE} must be set in the Uri
+     * parameters. See
+     * {@link Uri.Builder#appendQueryParameter(java.lang.String, java.lang.String)}
+     * for details on adding parameters. Sync adapters have write access to more
+     * columns but are restricted to a single account at a time.
+     * <dl>
+     * <dt><b>Insert</b></dt>
+     * <dd>When inserting a new event the following fields must be included:
+     * <ul>
+     * <li>dtstart</li>
+     * <li>dtend -or- a (rrule or rdate) and a duration</li>
+     * <li>a calendar_id</li>
+     * </ul>
+     * There are also further requirements when inserting or updating an event.
+     * See the section on Writing to Events.</dd>
+     * <dt><b>Update</b></dt>
+     * <dd>To perform an update of an Event the {@link Events#_ID} of the event
+     * should be provided either as an appended id to the Uri (
+     * {@link ContentUris#withAppendedId}) or as the first selection item--the
+     * selection should start with "_id=?" and the first selectionArg should be
+     * the _id of the event. Updates may also be done using a selection and no
+     * id. Updating an event must respect the same rules as inserting and is
+     * further restricted in the fields that can be written. See the section on
+     * Writing to Events.</dd>
+     * <dt><b>Delete</b></dt>
+     * <dd>Events can be deleted either by the {@link Events#_ID} as an appended
+     * id on the Uri or using any standard selection. If an appended id is used
+     * a selection is not allowed. There are two versions of delete: as an app
+     * and as a sync adapter. An app delete will set the deleted column on an
+     * event and remove all instances of that event. A sync adapter delete will
+     * remove the event from the database and all associated data.</dd>
+     * <dt><b>Query</b></dt>
+     * <dd>Querying the Events table will get you all information about a set of
+     * events except their reminders, attendees, and extended properties. There
+     * will be one row returned for each event that matches the query selection,
+     * or at most a single row if the {@link Events#_ID} is appended to the Uri.
+     * Recurring events will only return a single row regardless of the number
+     * of times that event repeats.</dd>
+     * </dl>
+     * <h3>Writing to Events</h3> There are further restrictions on all Updates
+     * and Inserts in the Events table:
+     * <ul>
+     * <li>If allDay is set to 1 eventTimezone must be {@link Time#TIMEZONE_UTC}
+     * and the time must correspond to a midnight boundary.</li>
+     * <li>Exceptions are not allowed to recur. If rrule or rdate is not empty,
+     * original_id and original_sync_id must be empty.</li>
+     * <li>In general a calendar_id should not be modified after insertion. This
+     * is not explicitly forbidden but many sync adapters will not behave in an
+     * expected way if the calendar_id is modified.</li>
+     * </ul>
+     * The following Events columns are writable by both an app and a sync
+     * adapter.
+     * <ul>
+     * <li>{@link #CALENDAR_ID}</li>
+     * <li>{@link #ORGANIZER}</li>
+     * <li>{@link #TITLE}</li>
+     * <li>{@link #EVENT_LOCATION}</li>
+     * <li>{@link #DESCRIPTION}</li>
+     * <li>{@link #EVENT_COLOR}</li>
+     * <li>{@link #DTSTART}</li>
+     * <li>{@link #DTEND}</li>
+     * <li>{@link #EVENT_TIMEZONE}</li>
+     * <li>{@link #EVENT_END_TIMEZONE}</li>
+     * <li>{@link #DURATION}</li>
+     * <li>{@link #ALL_DAY}</li>
+     * <li>{@link #RRULE}</li>
+     * <li>{@link #RDATE}</li>
+     * <li>{@link #EXRULE}</li>
+     * <li>{@link #EXDATE}</li>
+     * <li>{@link #ORIGINAL_ID}</li>
+     * <li>{@link #ORIGINAL_SYNC_ID}</li>
+     * <li>{@link #ORIGINAL_INSTANCE_TIME}</li>
+     * <li>{@link #ORIGINAL_ALL_DAY}</li>
+     * <li>{@link #ACCESS_LEVEL}</li>
+     * <li>{@link #AVAILABILITY}</li>
+     * <li>{@link #GUESTS_CAN_MODIFY}</li>
+     * <li>{@link #GUESTS_CAN_INVITE_OTHERS}</li>
+     * <li>{@link #GUESTS_CAN_SEE_GUESTS}</li>
+     * </ul>
+     * The following Events columns are writable only by a sync adapter
+     * <ul>
+     * <li>{@link #DIRTY}</li>
+     * <li>{@link #_SYNC_ID}</li>
+     * <li>{@link #SYNC_DATA1}</li>
+     * <li>{@link #SYNC_DATA2}</li>
+     * <li>{@link #SYNC_DATA3}</li>
+     * <li>{@link #SYNC_DATA4}</li>
+     * <li>{@link #SYNC_DATA5}</li>
+     * <li>{@link #SYNC_DATA6}</li>
+     * <li>{@link #SYNC_DATA7}</li>
+     * <li>{@link #SYNC_DATA8}</li>
+     * <li>{@link #SYNC_DATA9}</li>
+     * <li>{@link #SYNC_DATA10}</li>
+     * </ul>
+     * The remaining columns are either updated by the provider only or are
+     * views into other tables and cannot be changed through the Events table.
      */
     public static final class Events implements BaseColumns, SyncColumns, EventsColumns,
             CalendarsColumns {
@@ -1350,7 +1553,8 @@
     /**
      * Fields and helpers for interacting with Instances. An instance is a
      * single occurrence of an event including time zone specific start and end
-     * days and minutes.
+     * days and minutes. The instances table is not writable and only provides a
+     * way to query event occurrences.
      */
     public static final class Instances implements BaseColumns, EventsColumns, CalendarsColumns {
 
@@ -1637,8 +1841,10 @@
 
     /**
      * A few Calendar globals are needed in the CalendarProvider for expanding
-     * the Instances table and these are all stored in the first (and only)
-     * row of the CalendarMetaData table.
+     * the Instances table and these are all stored in the first (and only) row
+     * of the CalendarMetaData table.
+     *
+     * @hide
      */
     protected interface CalendarMetaDataColumns {
         /**
@@ -1771,7 +1977,17 @@
     }
 
     /**
-     * Fields and helpers for accessing reminders for an event.
+     * Fields and helpers for accessing reminders for an event. Each row of this
+     * table represents a single reminder for an event. Calling
+     * {@link #query(ContentResolver, long)} will return a list of reminders for
+     * the event with the given eventId. Both apps and sync adapters may write
+     * to this table. There are three writable fields and all of them must be
+     * included when inserting a new reminder. They are:
+     * <ul>
+     * <li>{@link #EVENT_ID}</li>
+     * <li>{@link #MINUTES}</li>
+     * <li>{@link #METHOD}</li>
+     * </ul>
      */
     public static final class Reminders implements BaseColumns, RemindersColumns, EventsColumns {
         private static final String REMINDERS_WHERE = CalendarContract.Reminders.EVENT_ID + "=?";
@@ -1872,7 +2088,14 @@
 
     /**
      * Fields and helpers for accessing calendar alerts information. These
-     * fields are for tracking which alerts have been fired.
+     * fields are for tracking which alerts have been fired. Scheduled alarms
+     * will generate an intent using {@link #EVENT_REMINDER_ACTION}. Apps that
+     * receive this action may update the {@link #STATE} for the reminder when
+     * they have finished handling it. Apps that have their notifications
+     * disabled should not modify the table to ensure that they do not conflict
+     * with another app that is generating a notification. In general, apps
+     * should not need to write to this table directly except to update the
+     * state of a reminder.
      */
     public static final class CalendarAlerts implements BaseColumns,
             CalendarAlertsColumns, EventsColumns, CalendarsColumns {
@@ -2044,9 +2267,11 @@
 
         /**
          * Schedules an alarm intent with the system AlarmManager that will
-         * cause the Calendar provider to recheck alarms. This is used to wake
-         * the Calendar alarm handler when an alarm is expected or to do a
-         * periodic refresh of alarm data.
+         * notify listeners when a reminder should be fired. The provider will
+         * keep scheduled reminders up to date but apps may use this to
+         * implement snooze functionality without modifying the reminders table.
+         * Scheduled alarms will generate an intent using
+         * {@link #EVENT_REMINDER_ACTION}.
          *
          * @param context A context for referencing system resources
          * @param manager The AlarmManager to use or null
@@ -2136,7 +2361,13 @@
     /**
      * Fields for accessing the Extended Properties. This is a generic set of
      * name/value pairs for use by sync adapters or apps to add extra
-     * information to events.
+     * information to events. There are three writable columns and all three
+     * must be present when inserting a new value. They are:
+     * <ul>
+     * <li>{@link #EVENT_ID}</li>
+     * <li>{@link #NAME}</li>
+     * <li>{@link #VALUE}</li>
+     * </ul>
      */
    public static final class ExtendedProperties implements BaseColumns,
             ExtendedPropertiesColumns, EventsColumns {
@@ -2170,6 +2401,8 @@
 
     /**
      * Columns from the EventsRawTimes table
+     *
+     * @hide
      */
     protected interface EventsRawTimesColumns {
         /**
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 1816066..b5a11ab 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -163,14 +163,12 @@
      * obtaining possible recipients, letting the provider know which account is selected during
      * the composition. The provider may use the "primary account" information to optimize
      * the search result.
-     * @hide
      */
     public static final String PRIMARY_ACCOUNT_NAME = "name_for_primary_account";
 
     /**
      * A query parameter specifing a primary account. This parameter should be used with
      * {@link #PRIMARY_ACCOUNT_NAME}. See the doc in {@link #PRIMARY_ACCOUNT_NAME}.
-     * @hide
      */
     public static final String PRIMARY_ACCOUNT_TYPE = "type_for_primary_account";
 
@@ -6317,7 +6315,6 @@
      * boolean successful = resolver.update(uri, new ContentValues(), null, null) > 0;
      * </pre>
      * </p>
-     * @hide
      */
     public static final class DataUsageFeedback {
 
diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java
index 3c4bb79..0a8c3ca 100644
--- a/core/java/android/provider/Downloads.java
+++ b/core/java/android/provider/Downloads.java
@@ -17,6 +17,7 @@
 package android.provider;
 
 import android.app.DownloadManager;
+import android.net.NetworkPolicyManager;
 import android.net.Uri;
 
 /**
@@ -547,6 +548,14 @@
         }
 
         /**
+         * This download has been paused because requesting application has been
+         * blocked by {@link NetworkPolicyManager}.
+         *
+         * @hide
+         */
+        public static final int STATUS_PAUSED_BY_POLICY = 189;
+
+        /**
          * This download hasn't stated yet
          */
         public static final int STATUS_PENDING = 190;
diff --git a/core/java/android/util/LocaleUtil.java b/core/java/android/util/LocaleUtil.java
index e767a85..74a930f 100644
--- a/core/java/android/util/LocaleUtil.java
+++ b/core/java/android/util/LocaleUtil.java
@@ -67,17 +67,8 @@
             return TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE;
         }
 
-        final String localeWithSubtags = ICU.addLikelySubtags(locale.toString());
-        if (localeWithSubtags == null) return getLayoutDirectionFromFirstChar(locale);
-
-        // Need to check if we can extract the script subtag. For example, "Latn" in  "en_Latn_US"
-        if (localeWithSubtags.length() <= 7
-                || localeWithSubtags.charAt(2) != UNDERSCORE_CHAR
-                || localeWithSubtags.charAt(7) != UNDERSCORE_CHAR) {
-            return getLayoutDirectionFromFirstChar(locale);
-        }
-        // Extract the script subtag
-        final String scriptSubtag = localeWithSubtags.substring(3, 7);
+        final String scriptSubtag = ICU.getScript(ICU.addLikelySubtags(locale.toString()));
+        if (scriptSubtag == null) return getLayoutDirectionFromFirstChar(locale);
 
         if (scriptSubtag.equalsIgnoreCase(ARAB_SCRIPT_SUBTAG) ||
                 scriptSubtag.equalsIgnoreCase(HEBR_SCRIPT_SUBTAG)) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 591b765..1381b84 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8736,6 +8736,10 @@
         }
         jumpDrawablesToCurrentState();
         resolveLayoutDirection();
+        if (isFocused()) {
+            InputMethodManager imm = InputMethodManager.peekInstance();
+            imm.focusIn(this);
+        }
     }
 
     /**
diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java
index 9eddf23..a3de285 100644
--- a/core/java/android/view/ViewPropertyAnimator.java
+++ b/core/java/android/view/ViewPropertyAnimator.java
@@ -349,7 +349,7 @@
             }
         }
         mPendingAnimations.clear();
-        mView.getHandler().removeCallbacks(mAnimationStarter);
+        mView.removeCallbacks(mAnimationStarter);
     }
 
     /**
@@ -705,7 +705,7 @@
 
         NameValuesHolder nameValuePair = new NameValuesHolder(constantName, startValue, byValue);
         mPendingAnimations.add(nameValuePair);
-        mView.getHandler().removeCallbacks(mAnimationStarter);
+        mView.removeCallbacks(mAnimationStarter);
         mView.post(mAnimationStarter);
     }
 
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index c361a4a..761007f 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -59,6 +59,7 @@
      * NORMAL is 100%
      * LARGER is 150%
      * LARGEST is 200%
+     * @deprecated Use {@link WebSettings#setTextZoom(int)} and {@link WebSettings#getTextZoom()} instead.
      */
     public enum TextSize {
         SMALLEST(50),
@@ -158,7 +159,7 @@
     // know what they are.
     private LayoutAlgorithm mLayoutAlgorithm = LayoutAlgorithm.NARROW_COLUMNS;
     private Context         mContext;
-    private TextSize        mTextSize = TextSize.NORMAL;
+    private int             mTextSize = 100;
     private String          mStandardFontFamily = "sans-serif";
     private String          mFixedFontFamily = "monospace";
     private String          mSansSerifFontFamily = "sans-serif";
@@ -709,26 +710,61 @@
     }
 
     /**
-     * Set the text size of the page.
-     * @param t A TextSize value for increasing or decreasing the text.
-     * @see WebSettings.TextSize
+     * Set the text zoom of the page in percent. Default is 100.
+     * @param textZoom A percent value for increasing or decreasing the text.
      */
-    public synchronized void setTextSize(TextSize t) {
-        if (WebView.mLogEvent && mTextSize != t ) {
-            EventLog.writeEvent(EventLogTags.BROWSER_TEXT_SIZE_CHANGE,
-                    mTextSize.value, t.value);
+    public synchronized void setTextZoom(int textZoom) {
+        if (mTextSize != textZoom) {
+            if (WebView.mLogEvent) {
+                EventLog.writeEvent(EventLogTags.BROWSER_TEXT_SIZE_CHANGE,
+                        mTextSize, textZoom);
+            }
+            mTextSize = textZoom;
+            postSync();
         }
-        mTextSize = t;
-        postSync();
     }
 
     /**
-     * Get the text size of the page.
+     * Get the text zoom of the page in percent.
+     * @return A percent value describing the text zoom.
+     * @see setTextSizeZoom
+     */
+    public synchronized int getTextZoom() {
+        return mTextSize;
+    }
+
+    /**
+     * Set the text size of the page.
+     * @param t A TextSize value for increasing or decreasing the text.
+     * @see WebSettings.TextSize
+     * @deprecated Use {@link #setTextZoom(int)} instead
+     */
+    public synchronized void setTextSize(TextSize t) {
+        setTextZoom(t.value);
+    }
+
+    /**
+     * Get the text size of the page. If the text size was previously specified
+     * in percent using {@link #setTextZoom(int)}, this will return
+     * the closest matching {@link TextSize}.
      * @return A TextSize enum value describing the text size.
      * @see WebSettings.TextSize
+     * @deprecated Use {@link #getTextZoom()} instead
      */
     public synchronized TextSize getTextSize() {
-        return mTextSize;
+        TextSize closestSize = null;
+        int smallestDelta = Integer.MAX_VALUE;
+        for (TextSize size : TextSize.values()) {
+            int delta = Math.abs(mTextSize - size.value);
+            if (delta == 0) {
+                return size;
+            }
+            if (delta < smallestDelta) {
+                smallestDelta = delta;
+                closestSize = size;
+            }
+        }
+        return closestSize != null ? closestSize : TextSize.NORMAL;
     }
 
     /**
diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java
index 092c2f7..4a514bf 100644
--- a/core/java/android/widget/GridLayout.java
+++ b/core/java/android/widget/GridLayout.java
@@ -38,8 +38,6 @@
 import java.util.List;
 import java.util.Map;
 
-import static android.view.View.MeasureSpec.EXACTLY;
-import static android.view.View.MeasureSpec.UNSPECIFIED;
 import static java.lang.Math.max;
 import static java.lang.Math.min;
 
@@ -135,11 +133,44 @@
      */
     public static final int UNDEFINED = Integer.MIN_VALUE;
 
+    /**
+     * This constant is an {@link #setAlignmentMode(int) alignmentMode}.
+     * When the {@code alignmentMode} is set to {@link #ALIGN_BOUNDS}, alignment
+     * is made between the edges of each component's raw
+     * view boundary: i.e. the area delimited by the component's:
+     * {@link android.view.View#getTop() top},
+     * {@link android.view.View#getLeft() left},
+     * {@link android.view.View#getBottom() bottom} and
+     * {@link android.view.View#getRight() right} properties.
+     * <p>
+     * For example, when {@code GridLayout} is in {@link #ALIGN_BOUNDS} mode,
+     * children that belong to a row group that uses {@link #TOP} alignment will
+     * all return the same value when their {@link android.view.View#getTop()}
+     * method is called.
+     *
+     * @see #setAlignmentMode(int)
+     */
+    public static final int ALIGN_BOUNDS = 0;
+
+    /**
+     * This constant is an {@link #setAlignmentMode(int) alignmentMode}.
+     * When the {@code alignmentMode} is set to {@link #ALIGN_MARGINS},
+     * the bounds of each view are extended outwards, according
+     * to their margins, before the edges of the resulting rectangle are aligned.
+     * <p>
+     * For example, when {@code GridLayout} is in {@link #ALIGN_MARGINS} mode,
+     * the quantity {@code top - layoutParams.topMargin} is the same for all children that
+     * belong to a row group that uses {@link #TOP} alignment.
+     *
+     * @see #setAlignmentMode(int)
+     */
+    public static final int ALIGN_MARGINS = 1;
+
     // Misc constants
 
     private static final String TAG = GridLayout.class.getName();
     private static final boolean DEBUG = false;
-    private static final Paint GRID_PAINT = new Paint();
+    private static Paint GRID_PAINT;
     private static final double GOLDEN_RATIO = (1 + Math.sqrt(5)) / 2;
     private static final int MIN = 0;
     private static final int PRF = 1;
@@ -151,7 +182,7 @@
     private static final int DEFAULT_COUNT = UNDEFINED;
     private static final boolean DEFAULT_USE_DEFAULT_MARGINS = false;
     private static final boolean DEFAULT_ORDER_PRESERVED = false;
-    private static final boolean DEFAULT_MARGINS_INCLUDED = true;
+    private static final int DEFAULT_ALIGNMENT_MODE = ALIGN_MARGINS;
     // todo remove this
     private static final int DEFAULT_CONTAINER_MARGIN = 20;
 
@@ -161,14 +192,17 @@
     private static final int ROW_COUNT = styleable.GridLayout_rowCount;
     private static final int COLUMN_COUNT = styleable.GridLayout_columnCount;
     private static final int USE_DEFAULT_MARGINS = styleable.GridLayout_useDefaultMargins;
-    private static final int MARGINS_INCLUDED = styleable.GridLayout_marginsIncludedInAlignment;
+    private static final int ALIGNMENT_MODE = styleable.GridLayout_alignmentMode;
     private static final int ROW_ORDER_PRESERVED = styleable.GridLayout_rowOrderPreserved;
     private static final int COLUMN_ORDER_PRESERVED = styleable.GridLayout_columnOrderPreserved;
 
     // Static initialization
 
     static {
-        GRID_PAINT.setColor(Color.argb(50, 255, 255, 255));
+        if (DEBUG) {
+            GRID_PAINT = new Paint();
+            GRID_PAINT.setColor(Color.argb(50, 255, 255, 255));
+        }
     }
 
     // Instance variables
@@ -178,7 +212,7 @@
     private boolean mLayoutParamsValid = false;
     private int mOrientation = DEFAULT_ORIENTATION;
     private boolean mUseDefaultMargins = DEFAULT_USE_DEFAULT_MARGINS;
-    private boolean mMarginsIncludedInAlignment = DEFAULT_MARGINS_INCLUDED;
+    private int mAlignmentMode = DEFAULT_ALIGNMENT_MODE;
     private int mDefaultGravity = Gravity.NO_GRAVITY;
 
     /* package */ boolean accommodateBothMinAndMax = false;
@@ -189,10 +223,7 @@
      * {@inheritDoc}
      */
     public GridLayout(Context context) {
-        super(context);
-        if (DEBUG) {
-            setWillNotDraw(false);
-        }
+        this(context, null, 0);
     }
 
     /**
@@ -200,6 +231,9 @@
      */
     public GridLayout(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
+        if (DEBUG) {
+            setWillNotDraw(false);
+        }
         processAttributes(context, attrs);
     }
 
@@ -207,18 +241,17 @@
      * {@inheritDoc}
      */
     public GridLayout(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        processAttributes(context, attrs);
+        this(context, attrs, 0);
     }
 
     private void processAttributes(Context context, AttributeSet attrs) {
         TypedArray a = context.obtainStyledAttributes(attrs, styleable.GridLayout);
         try {
-            setRowCount(a.getInteger(ROW_COUNT, DEFAULT_COUNT));
-            setColumnCount(a.getInteger(COLUMN_COUNT, DEFAULT_COUNT));
-            mOrientation = a.getInteger(ORIENTATION, DEFAULT_ORIENTATION);
+            setRowCount(a.getInt(ROW_COUNT, DEFAULT_COUNT));
+            setColumnCount(a.getInt(COLUMN_COUNT, DEFAULT_COUNT));
+            mOrientation = a.getInt(ORIENTATION, DEFAULT_ORIENTATION);
             mUseDefaultMargins = a.getBoolean(USE_DEFAULT_MARGINS, DEFAULT_USE_DEFAULT_MARGINS);
-            mMarginsIncludedInAlignment = a.getBoolean(MARGINS_INCLUDED, DEFAULT_MARGINS_INCLUDED);
+            mAlignmentMode = a.getInt(ALIGNMENT_MODE, DEFAULT_ALIGNMENT_MODE);
             setRowOrderPreserved(a.getBoolean(ROW_ORDER_PRESERVED, DEFAULT_ORDER_PRESERVED));
             setColumnOrderPreserved(a.getBoolean(COLUMN_ORDER_PRESERVED, DEFAULT_ORDER_PRESERVED));
         } finally {
@@ -348,15 +381,15 @@
      * When {@code false}, the default value of all margins is zero.
      * <p>
      * When setting to {@code true}, consider setting the value of the
-     * {@link #setMarginsIncludedInAlignment(boolean) marginsIncludedInAlignment}
-     * property to {@code false}.
+     * {@link #setAlignmentMode(int) alignmentMode}
+     * property to {@link #ALIGN_BOUNDS}.
      * <p>
      * The default value of this property is {@code false}.
      *
      * @param useDefaultMargins use {@code true} to make GridLayout allocate default margins
      *
      * @see #getUseDefaultMargins()
-     * @see #setMarginsIncludedInAlignment(boolean)
+     * @see #setAlignmentMode(int)
      *
      * @see MarginLayoutParams#leftMargin
      * @see MarginLayoutParams#topMargin
@@ -371,36 +404,38 @@
     }
 
     /**
-     * Returns whether GridLayout aligns the edges of the view or the edges
-     * of the larger rectangle created by extending the view by its associated
-     * margins.
+     * Returns the alignment mode.
      *
-     * @see #setMarginsIncludedInAlignment(boolean)
+     * @return the alignment mode; either {@link #ALIGN_BOUNDS} or {@link #ALIGN_MARGINS}
      *
-     * @return {@code true} if alignment is between edges including margins
+     * @see #ALIGN_BOUNDS
+     * @see #ALIGN_MARGINS
      *
-     * @attr ref android.R.styleable#GridLayout_marginsIncludedInAlignment
+     * @see #setAlignmentMode(int)
+     *
+     * @attr ref android.R.styleable#GridLayout_alignmentMode
      */
-    public boolean getMarginsIncludedInAlignment() {
-        return mMarginsIncludedInAlignment;
+    public int getAlignmentMode() {
+        return mAlignmentMode;
     }
 
     /**
-     * When {@code true}, the bounds of a view are extended outwards according to its
-     * margins before the edges of the resulting rectangle are aligned.
-     * When {@code false}, alignment occurs between the bounds of the view - i.e.
-     * {@link #LEFT} alignment means align the left edges of the view.
+     * Sets the alignment mode to be used for all of the alignments between the
+     * children of this container.
      * <p>
-     * The default value of this property is {@code true}.
+     * The default value of this property is {@link #ALIGN_MARGINS}.
      *
-     * @param marginsIncludedInAlignment {@code true} if alignment between edges includes margins
+     * @param alignmentMode either {@link #ALIGN_BOUNDS} or {@link #ALIGN_MARGINS}
      *
-     * @see #getMarginsIncludedInAlignment()
+     * @see #ALIGN_BOUNDS
+     * @see #ALIGN_MARGINS
      *
-     * @attr ref android.R.styleable#GridLayout_marginsIncludedInAlignment
+     * @see #getAlignmentMode()
+     *
+     * @attr ref android.R.styleable#GridLayout_alignmentMode
      */
-    public void setMarginsIncludedInAlignment(boolean marginsIncludedInAlignment) {
-        mMarginsIncludedInAlignment = marginsIncludedInAlignment;
+    public void setAlignmentMode(int alignmentMode) {
+        mAlignmentMode = alignmentMode;
         requestLayout();
     }
 
@@ -723,43 +758,6 @@
 
     // Measurement
 
-    private static int getChildMeasureSpec2(int spec, int padding, int childDimension) {
-        int resultSize;
-        int resultMode;
-
-        if (childDimension >= 0) {
-            resultSize = childDimension;
-            resultMode = EXACTLY;
-        } else {
-            /*
-            using the following lines would replicate the logic of ViewGroup.getChildMeasureSpec()
-
-            int specMode = MeasureSpec.getMode(spec);
-            int specSize = MeasureSpec.getSize(spec);
-            int size = Math.max(0, specSize - padding);
-
-            resultSize = size;
-            resultMode = (specMode == EXACTLY && childDimension == LayoutParams.WRAP_CONTENT) ?
-                    AT_MOST : specMode;
-            */
-            resultSize = 0;
-            resultMode = UNSPECIFIED;
-        }
-        return MeasureSpec.makeMeasureSpec(resultSize, resultMode);
-    }
-
-    @Override
-    protected void measureChild(View child, int parentWidthSpec, int parentHeightSpec) {
-        ViewGroup.LayoutParams lp = child.getLayoutParams();
-
-        int childWidthMeasureSpec = getChildMeasureSpec2(parentWidthSpec,
-                mPaddingLeft + mPaddingRight, lp.width);
-        int childHeightMeasureSpec = getChildMeasureSpec2(parentHeightSpec,
-                mPaddingTop + mPaddingBottom, lp.height);
-
-        child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
-    }
-
     @Override
     protected void onMeasure(int widthSpec, int heightSpec) {
         measureChildren(widthSpec, heightSpec);
@@ -782,7 +780,7 @@
 
     private int getMeasurementIncludingMargin(View c, boolean horizontal, int measurementType) {
         int result = getMeasurement(c, horizontal, measurementType);
-        if (mMarginsIncludedInAlignment) {
+        if (mAlignmentMode == ALIGN_MARGINS) {
             int leadingMargin = getMargin(c, true, horizontal);
             int trailingMargin = getMargin(c, false, horizontal);
             return result + leadingMargin + trailingMargin;
@@ -844,8 +842,8 @@
             int pWidth = getMeasurement(view, true, PRF);
             int pHeight = getMeasurement(view, false, PRF);
 
-            Alignment hAlignment = columnGroup.alignment;
-            Alignment vAlignment = rowGroup.alignment;
+            Alignment hAlign = columnGroup.alignment;
+            Alignment vAlign = rowGroup.alignment;
 
             int dx, dy;
 
@@ -853,22 +851,23 @@
             Bounds rowBounds = mVerticalAxis.getGroupBounds().getValue(i);
 
             // Gravity offsets: the location of the alignment group relative to its cell group.
-            int c2ax = protect(hAlignment.getAlignmentValue(null, cellWidth - colBounds.size()));
-            int c2ay = protect(vAlignment.getAlignmentValue(null, cellHeight - rowBounds.size()));
+            int type = PRF;
+            int c2ax = protect(hAlign.getAlignmentValue(null, cellWidth - colBounds.size(), type));
+            int c2ay = protect(vAlign.getAlignmentValue(null, cellHeight - rowBounds.size(), type));
 
-            if (mMarginsIncludedInAlignment) {
+            if (mAlignmentMode == ALIGN_MARGINS) {
                 int leftMargin = getMargin(view, true, true);
                 int topMargin = getMargin(view, true, false);
                 int rightMargin = getMargin(view, false, true);
                 int bottomMargin = getMargin(view, false, false);
 
                 // Same calculation as getMeasurementIncludingMargin()
-                int measuredWidth = leftMargin + pWidth + rightMargin;
-                int measuredHeight = topMargin + pHeight + bottomMargin;
+                int mWidth = leftMargin + pWidth + rightMargin;
+                int mHeight = topMargin + pHeight + bottomMargin;
 
                 // Alignment offsets: the location of the view relative to its alignment group.
-                int a2vx = colBounds.before - hAlignment.getAlignmentValue(view, measuredWidth);
-                int a2vy = rowBounds.before - vAlignment.getAlignmentValue(view, measuredHeight);
+                int a2vx = colBounds.before - hAlign.getAlignmentValue(view, mWidth, type);
+                int a2vy = rowBounds.before - vAlign.getAlignmentValue(view, mHeight, type);
 
                 dx = c2ax + a2vx + leftMargin;
                 dy = c2ay + a2vy + topMargin;
@@ -877,15 +876,15 @@
                 cellHeight -= topMargin + bottomMargin;
             } else {
                 // Alignment offsets: the location of the view relative to its alignment group.
-                int a2vx = colBounds.before - hAlignment.getAlignmentValue(view, pWidth);
-                int a2vy = rowBounds.before - vAlignment.getAlignmentValue(view, pHeight);
+                int a2vx = colBounds.before - hAlign.getAlignmentValue(view, pWidth, type);
+                int a2vy = rowBounds.before - vAlign.getAlignmentValue(view, pHeight, type);
 
                 dx = c2ax + a2vx;
                 dy = c2ay + a2vy;
             }
 
-            int width = hAlignment.getSizeInCell(view, pWidth, cellWidth);
-            int height = vAlignment.getSizeInCell(view, pHeight, cellHeight);
+            int width = hAlign.getSizeInCell(view, pWidth, cellWidth, type);
+            int height = vAlign.getSizeInCell(view, pHeight, cellHeight, type);
 
             int cx = paddingLeft + x1 + dx;
             int cy = paddingTop + y1 + dy;
@@ -1003,7 +1002,7 @@
 
                 int size = getMeasurementIncludingMargin(c, horizontal, PRF);
                 // todo test this works correctly when the returned value is UNDEFINED
-                int before = g.alignment.getAlignmentValue(c, size);
+                int before = g.alignment.getAlignmentValue(c, size, PRF);
                 bounds.include(before, size - before);
             }
         }
@@ -1107,9 +1106,6 @@
             return result;
         }
 
-        /*
-        Topological sort.
-         */
         private Arc[] topologicalSort(final Arc[] arcs, int start) {
         // todo ensure the <start> vertex is added in edge cases
             final List<Arc> result = new ArrayList<Arc>();
@@ -1358,7 +1354,7 @@
         private int getLocationIncludingMargin(View view, boolean leading, int index) {
             int location = locations[index];
             int margin;
-            if (!mMarginsIncludedInAlignment) {
+            if (mAlignmentMode != ALIGN_MARGINS) {
                 margin = (leading ? leadingMargins : trailingMargins)[index];
             } else {
                 margin = 0;
@@ -1370,7 +1366,7 @@
             Arrays.fill(a, MIN_VALUE);
             a[0] = 0;
             solve(getArcs(), a);
-            if (!mMarginsIncludedInAlignment) {
+            if (mAlignmentMode != ALIGN_MARGINS) {
                 addMargins();
             }
         }
@@ -1459,6 +1455,7 @@
             spanSizes = null;
             leadingMargins = null;
             trailingMargins = null;
+            arcs = null;
             minima = null;
             weights = null;
             locations = null;
@@ -1750,16 +1747,16 @@
         private void init(Context context, AttributeSet attrs, int defaultGravity) {
             TypedArray a = context.obtainStyledAttributes(attrs, styleable.GridLayout_Layout);
             try {
-                int gravity = a.getInteger(GRAVITY, defaultGravity);
+                int gravity = a.getInt(GRAVITY, defaultGravity);
 
-                int column = a.getInteger(COLUMN, DEFAULT_COLUMN);
-                int columnSpan = a.getInteger(COLUMN_SPAN, DEFAULT_SPAN_SIZE);
+                int column = a.getInt(COLUMN, DEFAULT_COLUMN);
+                int columnSpan = a.getInt(COLUMN_SPAN, DEFAULT_SPAN_SIZE);
                 Interval hSpan = new Interval(column, column + columnSpan);
                 this.columnGroup = new Group(hSpan, getColumnAlignment(gravity, width));
                 this.columnWeight = a.getFloat(COLUMN_WEIGHT, getDefaultWeight(width));
 
-                int row = a.getInteger(ROW, DEFAULT_ROW);
-                int rowSpan = a.getInteger(ROW_SPAN, DEFAULT_SPAN_SIZE);
+                int row = a.getInt(ROW, DEFAULT_ROW);
+                int rowSpan = a.getInt(ROW_SPAN, DEFAULT_SPAN_SIZE);
                 Interval vSpan = new Interval(row, row + rowSpan);
                 this.rowGroup = new Group(vSpan, getRowAlignment(gravity, height));
                 this.rowWeight = a.getFloat(ROW_WEIGHT, getDefaultWeight(height));
@@ -2156,57 +2153,63 @@
      * {@link Group#alignment alignment}. Overall placement of the view in the cell
      * group is specified by the two alignments which act along each axis independently.
      * <p>
-     * An Alignment implementation must define the {@link #getAlignmentValue(View, int)}
+     * An Alignment implementation must define {@link #getAlignmentValue(View, int, int)},
      * to return the appropriate value for the type of alignment being defined.
      * The enclosing algorithms position the children
-     * so that the values returned from the alignment
+     * so that the locations defined by the alignment values
      * are the same for all of the views in a group.
      * <p>
      *  The GridLayout class defines the most common alignments used in general layout:
      * {@link #TOP}, {@link #LEFT}, {@link #BOTTOM}, {@link #RIGHT}, {@link #CENTER}, {@link
      * #BASELINE} and {@link #FILL}.
      */
-    public static interface Alignment {
+    public static abstract class Alignment {
         /**
          * Returns an alignment value. In the case of vertical alignments the value
          * returned should indicate the distance from the top of the view to the
          * alignment location.
          * For horizontal alignments measurement is made from the left edge of the component.
          *
-         * @param view     the view to which this alignment should be applied
-         * @param viewSize the measured size of the view
-         * @return         the alignment value
+         * @param view              the view to which this alignment should be applied
+         * @param viewSize          the measured size of the view
+         * @param measurementType   The type of measurement that should be made. This feature
+         *                          is currently unused as GridLayout only supports one
+         *                          type of measurement: {@link View#measure(int, int)}.
+         *
+         * @return                  the alignment value
          */
-        public int getAlignmentValue(View view, int viewSize);
+        public abstract int getAlignmentValue(View view, int viewSize, int measurementType);
 
         /**
          * Returns the size of the view specified by this alignment.
          * In the case of vertical alignments this method should return a height; for
          * horizontal alignments this method should return the width.
+         * <p>
+         * The default implementation returns {@code viewSize}.
          *
-         * @param view     the view to which this alignment should be applied
-         * @param viewSize the measured size of the view
-         * @param cellSize the size of the cell into which this view will be placed
-         * @return         the aligned size
+         * @param view              the view to which this alignment should be applied
+         * @param viewSize          the measured size of the view
+         * @param cellSize          the size of the cell into which this view will be placed
+         * @param measurementType   The type of measurement that should be made. This feature
+         *                          is currently unused as GridLayout only supports one
+         *                          type of measurement: {@link View#measure(int, int)}.
+         *
+         * @return                  the aligned size
          */
-        public int getSizeInCell(View view, int viewSize, int cellSize);
-    }
-
-    private static abstract class AbstractAlignment implements Alignment {
-        public int getSizeInCell(View view, int viewSize, int cellSize) {
+        public int getSizeInCell(View view, int viewSize, int cellSize, int measurementType) {
             return viewSize;
         }
     }
 
-    private static final Alignment LEADING = new AbstractAlignment() {
-        public int getAlignmentValue(View view, int viewSize) {
+    private static final Alignment LEADING = new Alignment() {
+        public int getAlignmentValue(View view, int viewSize, int measurementType) {
             return 0;
         }
 
     };
 
-    private static final Alignment TRAILING = new AbstractAlignment() {
-        public int getAlignmentValue(View view, int viewSize) {
+    private static final Alignment TRAILING = new Alignment() {
+        public int getAlignmentValue(View view, int viewSize, int measurementType) {
             return viewSize;
         }
     };
@@ -2240,8 +2243,8 @@
      * This constant may be used in both {@link LayoutParams#rowGroup rowGroups} and {@link
      * LayoutParams#columnGroup columnGroups}.
      */
-    public static final Alignment CENTER = new AbstractAlignment() {
-        public int getAlignmentValue(View view, int viewSize) {
+    public static final Alignment CENTER = new Alignment() {
+        public int getAlignmentValue(View view, int viewSize, int measurementType) {
             return viewSize >> 1;
         }
     };
@@ -2253,8 +2256,8 @@
      *
      * @see View#getBaseline()
      */
-    public static final Alignment BASELINE = new AbstractAlignment() {
-        public int getAlignmentValue(View view, int height) {
+    public static final Alignment BASELINE = new Alignment() {
+        public int getAlignmentValue(View view, int viewSize, int measurementType) {
             if (view == null) {
                 return UNDEFINED;
             }
@@ -2274,12 +2277,13 @@
      * {@link LayoutParams#columnGroup columnGroups}.
      */
     public static final Alignment FILL = new Alignment() {
-        public int getAlignmentValue(View view, int viewSize) {
+        public int getAlignmentValue(View view, int viewSize, int measurementType) {
             return UNDEFINED;
         }
 
-        public int getSizeInCell(View view, int viewSize, int cellSize) {
+        @Override
+        public int getSizeInCell(View view, int viewSize, int cellSize, int measurementType) {
             return cellSize;
         }
     };
-}
\ No newline at end of file
+}
diff --git a/core/java/android/widget/Space.java b/core/java/android/widget/Space.java
index d98b937..d7b2ec2 100644
--- a/core/java/android/widget/Space.java
+++ b/core/java/android/widget/Space.java
@@ -72,4 +72,35 @@
     public void setLayoutParams(ViewGroup.LayoutParams params) {
         super.setLayoutParams(params);
     }
+
+    /**
+     * Compare to: {@link View#getDefaultSize(int, int)}
+     * If mode is AT_MOST, return the child size instead of the parent size
+     * (unless it is too big).
+     */
+    private static int getDefaultSize2(int size, int measureSpec) {
+        int result = size;
+        int specMode = MeasureSpec.getMode(measureSpec);
+        int specSize = MeasureSpec.getSize(measureSpec);
+
+        switch (specMode) {
+            case MeasureSpec.UNSPECIFIED:
+                result = size;
+                break;
+            case MeasureSpec.AT_MOST:
+                result = Math.min(size, specSize);
+                break;
+            case MeasureSpec.EXACTLY:
+                result = specSize;
+                break;
+        }
+        return result;
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        setMeasuredDimension(
+                getDefaultSize2(getSuggestedMinimumWidth(), widthMeasureSpec),
+                getDefaultSize2(getSuggestedMinimumHeight(), heightMeasureSpec));
+    }
 }
diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java
index 71a7a52..8d6caa1 100644
--- a/core/java/com/android/internal/app/AlertController.java
+++ b/core/java/com/android/internal/app/AlertController.java
@@ -575,9 +575,13 @@
         params.weight = 0.5f;
         button.setLayoutParams(params);
         View leftSpacer = mWindow.findViewById(R.id.leftSpacer);
-        leftSpacer.setVisibility(View.VISIBLE);
+        if (leftSpacer != null) {
+            leftSpacer.setVisibility(View.VISIBLE);
+        }
         View rightSpacer = mWindow.findViewById(R.id.rightSpacer);
-        rightSpacer.setVisibility(View.VISIBLE);
+        if (rightSpacer != null) {
+            rightSpacer.setVisibility(View.VISIBLE);
+        }
     }
 
     private void setBackground(LinearLayout topPanel, LinearLayout contentPanel,
diff --git a/core/java/com/android/internal/net/VpnConfig.java b/core/java/com/android/internal/net/VpnConfig.java
index 18d9ec4..773be5b 100644
--- a/core/java/com/android/internal/net/VpnConfig.java
+++ b/core/java/com/android/internal/net/VpnConfig.java
@@ -16,8 +16,12 @@
 
 package com.android.internal.net;
 
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
 import android.os.Parcel;
 import android.os.Parcelable;
+import android.os.SystemClock;
 
 /**
  * A simple container used to carry information in VpnBuilder, VpnDialogs,
@@ -27,6 +31,30 @@
  */
 public class VpnConfig implements Parcelable {
 
+    public static final String ACTION_VPN_REVOKED = "android.net.vpn.action.REVOKED";
+
+    public static void enforceCallingPackage(String packageName) {
+        if (!"com.android.vpndialogs".equals(packageName)) {
+            throw new SecurityException("Unauthorized Caller");
+        }
+    }
+
+    public static Intent getIntentForConfirmation() {
+        Intent intent = new Intent();
+        intent.setClassName("com.android.vpndialogs", "com.android.vpndialogs.ConfirmDialog");
+        return intent;
+    }
+
+    public static PendingIntent getIntentForNotification(Context context, VpnConfig config) {
+        config.startTime = SystemClock.elapsedRealtime();
+        Intent intent = new Intent();
+        intent.setClassName("com.android.vpndialogs", "com.android.vpndialogs.ManageDialog");
+        intent.putExtra("config", config);
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_HISTORY |
+                Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
+        return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
+    }
+
     public String packageName;
     public String sessionName;
     public String interfaceName;
diff --git a/core/java/com/android/internal/util/HanziToPinyin.java b/core/java/com/android/internal/util/HanziToPinyin.java
deleted file mode 100644
index 6a4adaa..0000000
--- a/core/java/com/android/internal/util/HanziToPinyin.java
+++ /dev/null
@@ -1,495 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.util;
-
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.text.Collator;
-import java.util.ArrayList;
-import java.util.Locale;
-
-/**
- * An object to convert Chinese character to its corresponding pinyin string.
- * For characters with multiple possible pinyin string, only one is selected
- * according to collator. Polyphone is not supported in this implementation.
- * This class is implemented to achieve the best runtime performance and minimum
- * runtime resources with tolerable sacrifice of accuracy. This implementation
- * highly depends on zh_CN ICU collation data and must be always synchronized with
- * ICU.
- */
-public class HanziToPinyin {
-    private static final String TAG = "HanziToPinyin";
-
-    private static final char[] UNIHANS = {
-            '\u5416', '\u54ce', '\u5b89', '\u80ae', '\u51f9', '\u516b', '\u63b0', '\u6273',
-            '\u90a6', '\u52f9', '\u9642', '\u5954', '\u4f3b', '\u7680', '\u782d', '\u706c',
-            '\u618b', '\u6c43', '\u51ab', '\u7676', '\u5cec', '\u5693', '\u5072', '\u53c2',
-            '\u4ed3', '\u64a1', '\u518a', '\u5d7e', '\u564c', '\u6260', '\u62c6', '\u8fbf',
-            '\u4f25', '\u6284', '\u8f66', '\u62bb', '\u9637', '\u5403', '\u5145', '\u62bd',
-            '\u51fa', '\u640b', '\u5ddb', '\u5205', '\u5439', '\u65fe', '\u8e14', '\u5472',
-            '\u4ece', '\u51d1', '\u7c97', '\u6c46', '\u5d14', '\u90a8', '\u6413', '\u5491',
-            '\u5446', '\u4e39', '\u5f53', '\u5200', '\u6074', '\u6265', '\u706f', '\u4efe',
-            '\u55f2', '\u6541', '\u5201', '\u7239', '\u4e01', '\u4e1f', '\u4e1c', '\u543a',
-            '\u5262', '\u8011', '\u5796', '\u5428', '\u591a', '\u59b8', '\u5940', '\u97a5',
-            '\u800c', '\u53d1', '\u5e06', '\u531a', '\u98de', '\u5206', '\u4e30', '\u8985',
-            '\u4ecf', '\u57ba', '\u7d11', '\u592b', '\u7324', '\u65ee', '\u4f85', '\u5e72',
-            '\u5188', '\u768b', '\u6208', '\u7ed9', '\u6839', '\u63ef', '\u55bc', '\u55f0',
-            '\u5de5', '\u52fe', '\u4f30', '\u9e39', '\u4e56', '\u5173', '\u5149', '\u5f52',
-            '\u4e28', '\u8b34', '\u5459', '\u598e', '\u548d', '\u4f44', '\u592f', '\u8320',
-            '\u8bc3', '\u9ed2', '\u62eb', '\u4ea8', '\u53ff', '\u9f41', '\u4e4e', '\u82b1',
-            '\u6000', '\u6b22', '\u5ddf', '\u7070', '\u660f', '\u5419', '\u4e0c', '\u52a0',
-            '\u620b', '\u6c5f', '\u827d', '\u9636', '\u5dfe', '\u5755', '\u5182', '\u4e29',
-            '\u51e5', '\u59e2', '\u5658', '\u519b', '\u5494', '\u5f00', '\u938e', '\u5ffc',
-            '\u5c3b', '\u533c', '\u808e', '\u52a5', '\u7a7a', '\u62a0', '\u625d', '\u5938',
-            '\u84af', '\u5bbd', '\u5321', '\u4e8f', '\u5764', '\u6269', '\u62c9', '\u4f86',
-            '\u5170', '\u5577', '\u635e', '\u4ec2', '\u96f7', '\u8137', '\u68f1', '\u695e',
-            '\u550e', '\u4fe9', '\u5afe', '\u826f', '\u8e7d', '\u57d3', '\u53b8', '\u62ce',
-            '\u6e9c', '\u9f99', '\u5a04', '\u565c', '\u5b6a', '\u62a1', '\u9831', '\u5988',
-            '\u57cb', '\u989f', '\u7264', '\u732b', '\u5445', '\u95e8', '\u6c13', '\u54aa',
-            '\u5b80', '\u55b5', '\u4e5c', '\u6c11', '\u540d', '\u8c2c', '\u6478', '\u725f',
-            '\u6bcd', '\u62cf', '\u8149', '\u56e1', '\u56d4', '\u5b6c', '\u8bb7', '\u5a1e',
-            '\u5ae9', '\u80fd', '\u92b0', '\u62c8', '\u5a18', '\u9e1f', '\u634f', '\u56dc',
-            '\u5b81', '\u599e', '\u519c', '\u7fba', '\u5974', '\u597b', '\u9ec1', '\u90cd',
-            '\u5662', '\u8bb4', '\u5991', '\u62cd', '\u7705', '\u6c78', '\u629b', '\u5478',
-            '\u55b7', '\u5309', '\u4e76', '\u7247', '\u527d', '\u6c15', '\u59d8', '\u4e52',
-            '\u948b', '\u5256', '\u4ec6', '\u4e03', '\u6390', '\u5343', '\u545b', '\u6084',
-            '\u5207', '\u4eb2', '\u9751', '\u5b86', '\u74d7', '\u533a', '\u5cd1', '\u7094',
-            '\u590b', '\u5465', '\u7a63', '\u835b', '\u60f9', '\u4eba', '\u6254', '\u65e5',
-            '\u620e', '\u53b9', '\u909a', '\u5827', '\u6875', '\u95f0', '\u633c', '\u4ee8',
-            '\u6be2', '\u4e09', '\u6852', '\u63bb', '\u8272', '\u68ee', '\u50e7', '\u6740',
-            '\u7b5b', '\u5c71', '\u4f24', '\u5f30', '\u5962', '\u7533', '\u5347', '\u5c38',
-            '\u53ce', '\u4e66', '\u5237', '\u8870', '\u95e9', '\u53cc', '\u8c01', '\u542e',
-            '\u8bf4', '\u53b6', '\u5fea', '\u51c1', '\u82cf', '\u72fb', '\u590a', '\u5b59',
-            '\u5506', '\u4ed6', '\u5b61', '\u574d', '\u6c64', '\u5932', '\u5fd1', '\u81af',
-            '\u5254', '\u5929', '\u65eb', '\u6017', '\u5385', '\u70b5', '\u5077', '\u51f8',
-            '\u6e4d', '\u63a8', '\u541e', '\u8bac', '\u52b8', '\u6b6a', '\u5f2f', '\u5c23',
-            '\u5371', '\u6637', '\u7fc1', '\u631d', '\u4e4c', '\u5915', '\u5477', '\u4ed9',
-            '\u4e61', '\u7071', '\u4e9b', '\u5fc3', '\u5174', '\u51f6', '\u4f11', '\u620c',
-            '\u5405', '\u75b6', '\u7025', '\u4e2b', '\u54bd', '\u592e', '\u5e7a', '\u503b',
-            '\u4e00', '\u4e5a', '\u5e94', '\u5537', '\u4f63', '\u4f18', '\u7ea1', '\u56e6',
-            '\u66f0', '\u8480', '\u5e00', '\u707d', '\u5142', '\u7242', '\u50ae', '\u556b',
-            '\u9c61', '\u600e', '\u66fd', '\u5412', '\u635a', '\u6cbe', '\u5f20', '\u4f4b',
-            '\u8707', '\u8d1e', '\u9eee', '\u4e4b', '\u4e2d', '\u5dde', '\u6731', '\u6293',
-            '\u62fd', '\u4e13', '\u5986', '\u96b9', '\u5b92', '\u5353', '\u4ed4', '\u5b97',
-            '\u90b9', '\u79df', '\u5297', '\u55fa', '\u5c0a', '\u6628',
-        };
-    private final static byte[][] PINYINS = {
-            {65, 00, 00, 00, 00, 00, }, {65, 73, 00, 00, 00, 00, },
-            {65, 78, 00, 00, 00, 00, }, {65, 78, 71, 00, 00, 00, },
-            {65, 79, 00, 00, 00, 00, }, {66, 65, 00, 00, 00, 00, },
-            {66, 65, 73, 00, 00, 00, }, {66, 65, 78, 00, 00, 00, },
-            {66, 65, 78, 71, 00, 00, }, {66, 65, 79, 00, 00, 00, },
-            {66, 69, 73, 00, 00, 00, }, {66, 69, 78, 00, 00, 00, },
-            {66, 69, 78, 71, 00, 00, }, {66, 73, 00, 00, 00, 00, },
-            {66, 73, 65, 78, 00, 00, }, {66, 73, 65, 79, 00, 00, },
-            {66, 73, 69, 00, 00, 00, }, {66, 73, 78, 00, 00, 00, },
-            {66, 73, 78, 71, 00, 00, }, {66, 79, 00, 00, 00, 00, },
-            {66, 85, 00, 00, 00, 00, }, {67, 65, 00, 00, 00, 00, },
-            {67, 65, 73, 00, 00, 00, }, {67, 65, 78, 00, 00, 00, },
-            {67, 65, 78, 71, 00, 00, }, {67, 65, 79, 00, 00, 00, },
-            {67, 69, 00, 00, 00, 00, }, {67, 69, 78, 00, 00, 00, },
-            {67, 69, 78, 71, 00, 00, }, {67, 72, 65, 00, 00, 00, },
-            {67, 72, 65, 73, 00, 00, }, {67, 72, 65, 78, 00, 00, },
-            {67, 72, 65, 78, 71, 00, }, {67, 72, 65, 79, 00, 00, },
-            {67, 72, 69, 00, 00, 00, }, {67, 72, 69, 78, 00, 00, },
-            {67, 72, 69, 78, 71, 00, }, {67, 72, 73, 00, 00, 00, },
-            {67, 72, 79, 78, 71, 00, }, {67, 72, 79, 85, 00, 00, },
-            {67, 72, 85, 00, 00, 00, }, {67, 72, 85, 65, 73, 00, },
-            {67, 72, 85, 65, 78, 00, }, {67, 72, 85, 65, 78, 71, },
-            {67, 72, 85, 73, 00, 00, }, {67, 72, 85, 78, 00, 00, },
-            {67, 72, 85, 79, 00, 00, }, {67, 73, 00, 00, 00, 00, },
-            {67, 79, 78, 71, 00, 00, }, {67, 79, 85, 00, 00, 00, },
-            {67, 85, 00, 00, 00, 00, }, {67, 85, 65, 78, 00, 00, },
-            {67, 85, 73, 00, 00, 00, }, {67, 85, 78, 00, 00, 00, },
-            {67, 85, 79, 00, 00, 00, }, {68, 65, 00, 00, 00, 00, },
-            {68, 65, 73, 00, 00, 00, }, {68, 65, 78, 00, 00, 00, },
-            {68, 65, 78, 71, 00, 00, }, {68, 65, 79, 00, 00, 00, },
-            {68, 69, 00, 00, 00, 00, }, {68, 69, 78, 00, 00, 00, },
-            {68, 69, 78, 71, 00, 00, }, {68, 73, 00, 00, 00, 00, },
-            {68, 73, 65, 00, 00, 00, }, {68, 73, 65, 78, 00, 00, },
-            {68, 73, 65, 79, 00, 00, }, {68, 73, 69, 00, 00, 00, },
-            {68, 73, 78, 71, 00, 00, }, {68, 73, 85, 00, 00, 00, },
-            {68, 79, 78, 71, 00, 00, }, {68, 79, 85, 00, 00, 00, },
-            {68, 85, 00, 00, 00, 00, }, {68, 85, 65, 78, 00, 00, },
-            {68, 85, 73, 00, 00, 00, }, {68, 85, 78, 00, 00, 00, },
-            {68, 85, 79, 00, 00, 00, }, {69, 00, 00, 00, 00, 00, },
-            {69, 78, 00, 00, 00, 00, }, {69, 78, 71, 00, 00, 00, },
-            {69, 82, 00, 00, 00, 00, }, {70, 65, 00, 00, 00, 00, },
-            {70, 65, 78, 00, 00, 00, }, {70, 65, 78, 71, 00, 00, },
-            {70, 69, 73, 00, 00, 00, }, {70, 69, 78, 00, 00, 00, },
-            {70, 69, 78, 71, 00, 00, }, {70, 73, 65, 79, 00, 00, },
-            {70, 79, 00, 00, 00, 00, }, {70, 85, 00, 00, 00, 00, },
-            {70, 79, 85, 00, 00, 00, }, {70, 85, 00, 00, 00, 00, },
-            {71, 85, 73, 00, 00, 00, }, {71, 65, 00, 00, 00, 00, },
-            {71, 65, 73, 00, 00, 00, }, {71, 65, 78, 00, 00, 00, },
-            {71, 65, 78, 71, 00, 00, }, {71, 65, 79, 00, 00, 00, },
-            {71, 69, 00, 00, 00, 00, }, {71, 69, 73, 00, 00, 00, },
-            {71, 69, 78, 00, 00, 00, }, {71, 69, 78, 71, 00, 00, },
-            {74, 73, 69, 00, 00, 00, }, {71, 69, 00, 00, 00, 00, },
-            {71, 79, 78, 71, 00, 00, }, {71, 79, 85, 00, 00, 00, },
-            {71, 85, 00, 00, 00, 00, }, {71, 85, 65, 00, 00, 00, },
-            {71, 85, 65, 73, 00, 00, }, {71, 85, 65, 78, 00, 00, },
-            {71, 85, 65, 78, 71, 00, }, {71, 85, 73, 00, 00, 00, },
-            {71, 85, 78, 00, 00, 00, }, {71, 85, 65, 78, 00, 00, },
-            {71, 85, 79, 00, 00, 00, }, {72, 65, 00, 00, 00, 00, },
-            {72, 65, 73, 00, 00, 00, }, {72, 65, 78, 00, 00, 00, },
-            {72, 65, 78, 71, 00, 00, }, {72, 65, 79, 00, 00, 00, },
-            {72, 69, 00, 00, 00, 00, }, {72, 69, 73, 00, 00, 00, },
-            {72, 69, 78, 00, 00, 00, }, {72, 69, 78, 71, 00, 00, },
-            {72, 79, 78, 71, 00, 00, }, {72, 79, 85, 00, 00, 00, },
-            {72, 85, 00, 00, 00, 00, }, {72, 85, 65, 00, 00, 00, },
-            {72, 85, 65, 73, 00, 00, }, {72, 85, 65, 78, 00, 00, },
-            {72, 85, 65, 78, 71, 00, }, {72, 85, 73, 00, 00, 00, },
-            {72, 85, 78, 00, 00, 00, }, {72, 85, 79, 00, 00, 00, },
-            {74, 73, 00, 00, 00, 00, }, {74, 73, 65, 00, 00, 00, },
-            {74, 73, 65, 78, 00, 00, }, {74, 73, 65, 78, 71, 00, },
-            {74, 73, 65, 79, 00, 00, }, {74, 73, 69, 00, 00, 00, },
-            {74, 73, 78, 00, 00, 00, }, {74, 73, 78, 71, 00, 00, },
-            {74, 73, 79, 78, 71, 00, }, {74, 73, 85, 00, 00, 00, },
-            {74, 85, 00, 00, 00, 00, }, {74, 85, 65, 78, 00, 00, },
-            {74, 85, 69, 00, 00, 00, }, {74, 85, 78, 00, 00, 00, },
-            {75, 65, 00, 00, 00, 00, }, {75, 65, 73, 00, 00, 00, },
-            {75, 65, 78, 00, 00, 00, }, {75, 65, 78, 71, 00, 00, },
-            {75, 65, 79, 00, 00, 00, }, {75, 69, 00, 00, 00, 00, },
-            {75, 69, 78, 00, 00, 00, }, {75, 69, 78, 71, 00, 00, },
-            {75, 79, 78, 71, 00, 00, }, {75, 79, 85, 00, 00, 00, },
-            {75, 85, 00, 00, 00, 00, }, {75, 85, 65, 00, 00, 00, },
-            {75, 85, 65, 73, 00, 00, }, {75, 85, 65, 78, 00, 00, },
-            {75, 85, 65, 78, 71, 00, }, {75, 85, 73, 00, 00, 00, },
-            {75, 85, 78, 00, 00, 00, }, {75, 85, 79, 00, 00, 00, },
-            {76, 65, 00, 00, 00, 00, }, {76, 65, 73, 00, 00, 00, },
-            {76, 65, 78, 00, 00, 00, }, {76, 65, 78, 71, 00, 00, },
-            {76, 65, 79, 00, 00, 00, }, {76, 69, 00, 00, 00, 00, },
-            {76, 69, 73, 00, 00, 00, }, {76, 73, 00, 00, 00, 00, },
-            {76, 73, 78, 71, 00, 00, }, {76, 69, 78, 71, 00, 00, },
-            {76, 73, 00, 00, 00, 00, }, {76, 73, 65, 00, 00, 00, },
-            {76, 73, 65, 78, 00, 00, }, {76, 73, 65, 78, 71, 00, },
-            {76, 73, 65, 79, 00, 00, }, {76, 73, 69, 00, 00, 00, },
-            {76, 73, 78, 00, 00, 00, }, {76, 73, 78, 71, 00, 00, },
-            {76, 73, 85, 00, 00, 00, }, {76, 79, 78, 71, 00, 00, },
-            {76, 79, 85, 00, 00, 00, }, {76, 85, 00, 00, 00, 00, },
-            {76, 85, 65, 78, 00, 00, }, {76, 85, 78, 00, 00, 00, },
-            {76, 85, 79, 00, 00, 00, }, {77, 65, 00, 00, 00, 00, },
-            {77, 65, 73, 00, 00, 00, }, {77, 65, 78, 00, 00, 00, },
-            {77, 65, 78, 71, 00, 00, }, {77, 65, 79, 00, 00, 00, },
-            {77, 69, 73, 00, 00, 00, }, {77, 69, 78, 00, 00, 00, },
-            {77, 69, 78, 71, 00, 00, }, {77, 73, 00, 00, 00, 00, },
-            {77, 73, 65, 78, 00, 00, }, {77, 73, 65, 79, 00, 00, },
-            {77, 73, 69, 00, 00, 00, }, {77, 73, 78, 00, 00, 00, },
-            {77, 73, 78, 71, 00, 00, }, {77, 73, 85, 00, 00, 00, },
-            {77, 79, 00, 00, 00, 00, }, {77, 79, 85, 00, 00, 00, },
-            {77, 85, 00, 00, 00, 00, }, {78, 65, 00, 00, 00, 00, },
-            {78, 65, 73, 00, 00, 00, }, {78, 65, 78, 00, 00, 00, },
-            {78, 65, 78, 71, 00, 00, }, {78, 65, 79, 00, 00, 00, },
-            {78, 69, 00, 00, 00, 00, }, {78, 69, 73, 00, 00, 00, },
-            {78, 69, 78, 00, 00, 00, }, {78, 69, 78, 71, 00, 00, },
-            {78, 73, 00, 00, 00, 00, }, {78, 73, 65, 78, 00, 00, },
-            {78, 73, 65, 78, 71, 00, }, {78, 73, 65, 79, 00, 00, },
-            {78, 73, 69, 00, 00, 00, }, {78, 73, 78, 00, 00, 00, },
-            {78, 73, 78, 71, 00, 00, }, {78, 73, 85, 00, 00, 00, },
-            {78, 79, 78, 71, 00, 00, }, {78, 79, 85, 00, 00, 00, },
-            {78, 85, 00, 00, 00, 00, }, {78, 85, 65, 78, 00, 00, },
-            {78, 85, 78, 00, 00, 00, }, {78, 85, 79, 00, 00, 00, },
-            {79, 00, 00, 00, 00, 00, }, {79, 85, 00, 00, 00, 00, },
-            {80, 65, 00, 00, 00, 00, }, {80, 65, 73, 00, 00, 00, },
-            {80, 65, 78, 00, 00, 00, }, {80, 65, 78, 71, 00, 00, },
-            {80, 65, 79, 00, 00, 00, }, {80, 69, 73, 00, 00, 00, },
-            {80, 69, 78, 00, 00, 00, }, {80, 69, 78, 71, 00, 00, },
-            {80, 73, 00, 00, 00, 00, }, {80, 73, 65, 78, 00, 00, },
-            {80, 73, 65, 79, 00, 00, }, {80, 73, 69, 00, 00, 00, },
-            {80, 73, 78, 00, 00, 00, }, {80, 73, 78, 71, 00, 00, },
-            {80, 79, 00, 00, 00, 00, }, {80, 79, 85, 00, 00, 00, },
-            {80, 85, 00, 00, 00, 00, }, {81, 73, 00, 00, 00, 00, },
-            {81, 73, 65, 00, 00, 00, }, {81, 73, 65, 78, 00, 00, },
-            {81, 73, 65, 78, 71, 00, }, {81, 73, 65, 79, 00, 00, },
-            {81, 73, 69, 00, 00, 00, }, {81, 73, 78, 00, 00, 00, },
-            {81, 73, 78, 71, 00, 00, }, {81, 73, 79, 78, 71, 00, },
-            {81, 73, 85, 00, 00, 00, }, {81, 85, 00, 00, 00, 00, },
-            {81, 85, 65, 78, 00, 00, }, {81, 85, 69, 00, 00, 00, },
-            {81, 85, 78, 00, 00, 00, }, {82, 65, 78, 00, 00, 00, },
-            {82, 65, 78, 71, 00, 00, }, {82, 65, 79, 00, 00, 00, },
-            {82, 69, 00, 00, 00, 00, }, {82, 69, 78, 00, 00, 00, },
-            {82, 69, 78, 71, 00, 00, }, {82, 73, 00, 00, 00, 00, },
-            {82, 79, 78, 71, 00, 00, }, {82, 79, 85, 00, 00, 00, },
-            {82, 85, 00, 00, 00, 00, }, {82, 85, 65, 78, 00, 00, },
-            {82, 85, 73, 00, 00, 00, }, {82, 85, 78, 00, 00, 00, },
-            {82, 85, 79, 00, 00, 00, }, {83, 65, 00, 00, 00, 00, },
-            {83, 65, 73, 00, 00, 00, }, {83, 65, 78, 00, 00, 00, },
-            {83, 65, 78, 71, 00, 00, }, {83, 65, 79, 00, 00, 00, },
-            {83, 69, 00, 00, 00, 00, }, {83, 69, 78, 00, 00, 00, },
-            {83, 69, 78, 71, 00, 00, }, {83, 72, 65, 00, 00, 00, },
-            {83, 72, 65, 73, 00, 00, }, {83, 72, 65, 78, 00, 00, },
-            {83, 72, 65, 78, 71, 00, }, {83, 72, 65, 79, 00, 00, },
-            {83, 72, 69, 00, 00, 00, }, {83, 72, 69, 78, 00, 00, },
-            {83, 72, 69, 78, 71, 00, }, {83, 72, 73, 00, 00, 00, },
-            {83, 72, 79, 85, 00, 00, }, {83, 72, 85, 00, 00, 00, },
-            {83, 72, 85, 65, 00, 00, }, {83, 72, 85, 65, 73, 00, },
-            {83, 72, 85, 65, 78, 00, }, {83, 72, 85, 65, 78, 71, },
-            {83, 72, 85, 73, 00, 00, }, {83, 72, 85, 78, 00, 00, },
-            {83, 72, 85, 79, 00, 00, }, {83, 73, 00, 00, 00, 00, },
-            {83, 79, 78, 71, 00, 00, }, {83, 79, 85, 00, 00, 00, },
-            {83, 85, 00, 00, 00, 00, }, {83, 85, 65, 78, 00, 00, },
-            {83, 85, 73, 00, 00, 00, }, {83, 85, 78, 00, 00, 00, },
-            {83, 85, 79, 00, 00, 00, }, {84, 65, 00, 00, 00, 00, },
-            {84, 65, 73, 00, 00, 00, }, {84, 65, 78, 00, 00, 00, },
-            {84, 65, 78, 71, 00, 00, }, {84, 65, 79, 00, 00, 00, },
-            {84, 69, 00, 00, 00, 00, }, {84, 69, 78, 71, 00, 00, },
-            {84, 73, 00, 00, 00, 00, }, {84, 73, 65, 78, 00, 00, },
-            {84, 73, 65, 79, 00, 00, }, {84, 73, 69, 00, 00, 00, },
-            {84, 73, 78, 71, 00, 00, }, {84, 79, 78, 71, 00, 00, },
-            {84, 79, 85, 00, 00, 00, }, {84, 85, 00, 00, 00, 00, },
-            {84, 85, 65, 78, 00, 00, }, {84, 85, 73, 00, 00, 00, },
-            {84, 85, 78, 00, 00, 00, }, {84, 85, 79, 00, 00, 00, },
-            {87, 65, 00, 00, 00, 00, }, {87, 65, 73, 00, 00, 00, },
-            {87, 65, 78, 00, 00, 00, }, {87, 65, 78, 71, 00, 00, },
-            {87, 69, 73, 00, 00, 00, }, {87, 69, 78, 00, 00, 00, },
-            {87, 69, 78, 71, 00, 00, }, {87, 79, 00, 00, 00, 00, },
-            {87, 85, 00, 00, 00, 00, }, {88, 73, 00, 00, 00, 00, },
-            {88, 73, 65, 00, 00, 00, }, {88, 73, 65, 78, 00, 00, },
-            {88, 73, 65, 78, 71, 00, }, {88, 73, 65, 79, 00, 00, },
-            {88, 73, 69, 00, 00, 00, }, {88, 73, 78, 00, 00, 00, },
-            {88, 73, 78, 71, 00, 00, }, {88, 73, 79, 78, 71, 00, },
-            {88, 73, 85, 00, 00, 00, }, {88, 85, 00, 00, 00, 00, },
-            {88, 85, 65, 78, 00, 00, }, {88, 85, 69, 00, 00, 00, },
-            {88, 85, 78, 00, 00, 00, }, {89, 65, 00, 00, 00, 00, },
-            {89, 65, 78, 00, 00, 00, }, {89, 65, 78, 71, 00, 00, },
-            {89, 65, 79, 00, 00, 00, }, {89, 69, 00, 00, 00, 00, },
-            {89, 73, 00, 00, 00, 00, }, {89, 73, 78, 00, 00, 00, },
-            {89, 73, 78, 71, 00, 00, }, {89, 79, 00, 00, 00, 00, },
-            {89, 79, 78, 71, 00, 00, }, {89, 79, 85, 00, 00, 00, },
-            {89, 85, 00, 00, 00, 00, }, {89, 85, 65, 78, 00, 00, },
-            {89, 85, 69, 00, 00, 00, }, {89, 85, 78, 00, 00, 00, },
-            {90, 65, 00, 00, 00, 00, }, {90, 65, 73, 00, 00, 00, },
-            {90, 65, 78, 00, 00, 00, }, {90, 65, 78, 71, 00, 00, },
-            {90, 65, 79, 00, 00, 00, }, {90, 69, 00, 00, 00, 00, },
-            {90, 69, 73, 00, 00, 00, }, {90, 69, 78, 00, 00, 00, },
-            {90, 69, 78, 71, 00, 00, }, {90, 72, 65, 00, 00, 00, },
-            {90, 72, 65, 73, 00, 00, }, {90, 72, 65, 78, 00, 00, },
-            {90, 72, 65, 78, 71, 00, }, {90, 72, 65, 79, 00, 00, },
-            {90, 72, 69, 00, 00, 00, }, {90, 72, 69, 78, 00, 00, },
-            {90, 72, 69, 78, 71, 00, }, {90, 72, 73, 00, 00, 00, },
-            {90, 72, 79, 78, 71, 00, }, {90, 72, 79, 85, 00, 00, },
-            {90, 72, 85, 00, 00, 00, }, {90, 72, 85, 65, 00, 00, },
-            {90, 72, 85, 65, 73, 00, }, {90, 72, 85, 65, 78, 00, },
-            {90, 72, 85, 65, 78, 71, }, {90, 72, 85, 73, 00, 00, },
-            {90, 72, 85, 78, 00, 00, }, {90, 72, 85, 79, 00, 00, },
-            {90, 73, 00, 00, 00, 00, }, {90, 79, 78, 71, 00, 00, },
-            {90, 79, 85, 00, 00, 00, }, {90, 85, 00, 00, 00, 00, },
-            {90, 85, 65, 78, 00, 00, }, {90, 85, 73, 00, 00, 00, },
-            {90, 85, 78, 00, 00, 00, }, {90, 85, 79, 00, 00, 00, },
-
-        };
-
-    /** First and last Chinese character with known Pinyin according to zh collation */
-    private static final String FIRST_PINYIN_UNIHAN =  "\u5416";
-    private static final String LAST_PINYIN_UNIHAN =  "\u5497";
-    /** The first Chinese character in Unicode block */
-    private static final char FIRST_UNIHAN = '\u3400';
-    private static final Collator COLLATOR = Collator.getInstance(Locale.CHINA);
-
-    private static HanziToPinyin sInstance;
-    private final boolean mHasChinaCollator;
-
-    public static class Token {
-        /**
-         * Separator between target string for each source char
-         */
-        public static final String SEPARATOR = " ";
-
-        public static final int LATIN = 1;
-        public static final int PINYIN = 2;
-        public static final int UNKNOWN = 3;
-
-        public Token() {
-        }
-
-        public Token(int type, String source, String target) {
-            this.type = type;
-            this.source = source;
-            this.target = target;
-        }
-        /**
-         * Type of this token, ASCII, PINYIN or UNKNOWN.
-         */
-        public int type;
-        /**
-         * Original string before translation.
-         */
-        public String source;
-        /**
-         * Translated string of source. For Han, target is corresponding Pinyin.
-         * Otherwise target is original string in source.
-         */
-        public String target;
-    }
-
-    protected HanziToPinyin(boolean hasChinaCollator) {
-        mHasChinaCollator = hasChinaCollator;
-    }
-
-    public static HanziToPinyin getInstance() {
-        synchronized(HanziToPinyin.class) {
-            if (sInstance != null) {
-                return sInstance;
-            }
-            // Check if zh_CN collation data is available
-            final Locale locale[] = Collator.getAvailableLocales();
-            for (int i = 0; i < locale.length; i++) {
-                if (locale[i].equals(Locale.CHINA)) {
-                    sInstance = new HanziToPinyin(true);
-                    return sInstance;
-                }
-            }
-            Log.w(TAG, "There is no Chinese collator, HanziToPinyin is disabled");
-            sInstance = new HanziToPinyin(false);
-            return sInstance;
-        }
-    }
-
-    private Token getToken(char character) {
-        Token token = new Token();
-        final String letter = Character.toString(character);
-        token.source = letter;
-        int offset = -1;
-        int cmp;
-        if (character < 256) {
-            token.type = Token.LATIN;
-            token.target = letter;
-            return token;
-        } else if (character < FIRST_UNIHAN) {
-            token.type = Token.UNKNOWN;
-            token.target = letter;
-            return token;
-        } else {
-            cmp = COLLATOR.compare(letter, FIRST_PINYIN_UNIHAN);
-            if (cmp < 0) {
-                token.type = Token.UNKNOWN;
-                token.target = letter;
-                return token;
-            } else if (cmp == 0) {
-                token.type = Token.PINYIN;
-                offset = 0;
-            } else {
-                cmp = COLLATOR.compare(letter, LAST_PINYIN_UNIHAN);
-                if (cmp > 0) {
-                    token.type = Token.UNKNOWN;
-                    token.target = letter;
-                    return token;
-                } else if (cmp == 0) {
-                    token.type = Token.PINYIN;
-                    offset = UNIHANS.length - 1;
-                }
-            }
-        }
-
-        token.type = Token.PINYIN;
-        if (offset < 0) {
-            int begin = 0;
-            int end = UNIHANS.length - 1;
-            while (begin <= end) {
-                offset = (begin + end) / 2;
-                final String unihan = Character.toString(UNIHANS[offset]);
-                cmp = COLLATOR.compare(letter, unihan);
-                if (cmp == 0) {
-                    break;
-                } else if (cmp > 0) {
-                    begin = offset + 1;
-                } else {
-                    end = offset - 1;
-                }
-            }
-        }
-        if (cmp < 0) {
-            offset--;
-        }
-        StringBuilder pinyin = new StringBuilder();
-        for (int j = 0; j < PINYINS[offset].length && PINYINS[offset][j] != 0; j++) {
-            pinyin.append((char)PINYINS[offset][j]);
-        }
-        token.target = pinyin.toString();
-        return token;
-    }
-
-    /**
-     * Convert the input to a array of tokens. The sequence of ASCII or Unknown
-     * characters without space will be put into a Token, One Hanzi character 
-     * which has pinyin will be treated as a Token.
-     * If these is no China collator, the empty token array is returned.
-     */
-    public ArrayList<Token> get(final String input) {
-        ArrayList<Token> tokens = new ArrayList<Token>();
-        if (!mHasChinaCollator || TextUtils.isEmpty(input)) {
-            // return empty tokens.
-            return tokens;
-        }
-        final int inputLength = input.length();
-        final StringBuilder sb = new StringBuilder();
-        int tokenType = Token.LATIN;
-        // Go through the input, create a new token when
-        // a. Token type changed
-        // b. Get the Pinyin of current charater.
-        // c. current character is space.
-        for (int i = 0; i < inputLength; i++) {
-            final char character = input.charAt(i);
-            if (character == ' ') {
-                if (sb.length() > 0) {
-                    addToken(sb, tokens, tokenType);
-                }
-            } else if (character < 256) {
-                if (tokenType != Token.LATIN && sb.length() > 0) {
-                    addToken(sb, tokens, tokenType);
-                }
-                tokenType = Token.LATIN;
-                sb.append(character);
-            } else if (character < FIRST_UNIHAN) {
-                if (tokenType != Token.UNKNOWN && sb.length() > 0) {
-                    addToken(sb, tokens, tokenType);
-                }
-                tokenType = Token.UNKNOWN;
-                sb.append(character);
-            } else {
-                Token t = getToken(character);
-                if (t.type == Token.PINYIN) {
-                    if (sb.length() > 0) {
-                        addToken(sb, tokens, tokenType);
-                    }
-                    tokens.add(t);
-                    tokenType = Token.PINYIN;
-                } else {
-                    if (tokenType != t.type && sb.length() > 0) {
-                        addToken(sb, tokens, tokenType);
-                    }
-                    tokenType = t.type;
-                    sb.append(character);
-                }
-            }
-        }
-        if (sb.length() > 0) {
-            addToken(sb, tokens, tokenType);
-        }
-        return tokens;
-    }
-
-    private void addToken(final StringBuilder sb, final ArrayList<Token> tokens,
-            final int tokenType) {
-        String str = sb.toString();
-        tokens.add(new Token(tokenType, str, str));
-        sb.setLength(0);
-    }
-
-}
diff --git a/core/java/com/android/internal/view/menu/ListMenuPresenter.java b/core/java/com/android/internal/view/menu/ListMenuPresenter.java
index f8d24a3..cc09927 100644
--- a/core/java/com/android/internal/view/menu/ListMenuPresenter.java
+++ b/core/java/com/android/internal/view/menu/ListMenuPresenter.java
@@ -177,7 +177,9 @@
 
     public void restoreHierarchyState(Bundle inState) {
         SparseArray<Parcelable> viewStates = inState.getSparseParcelableArray(VIEWS_TAG);
-        ((View) mMenuView).restoreHierarchyState(viewStates);
+        if (viewStates != null) {
+            ((View) mMenuView).restoreHierarchyState(viewStates);
+        }
     }
 
     private class MenuAdapter extends BaseAdapter {
diff --git a/core/java/com/android/internal/widget/DialogTitle.java b/core/java/com/android/internal/widget/DialogTitle.java
index 125d2c5..cd165dc 100644
--- a/core/java/com/android/internal/widget/DialogTitle.java
+++ b/core/java/com/android/internal/widget/DialogTitle.java
@@ -54,15 +54,19 @@
                 if (ellipsisCount > 0) {
                     setSingleLine(false);
                     
-                    TypedArray a = mContext.obtainStyledAttributes(
-                            android.R.style.TextAppearance_Medium,
-                            android.R.styleable.TextAppearance);
+                    TypedArray a = mContext.obtainStyledAttributes(null,
+                            android.R.styleable.TextAppearance,
+                            android.R.attr.textAppearanceMedium,
+                            android.R.style.TextAppearance_Medium);
                     final int textSize = a.getDimensionPixelSize(
                             android.R.styleable.TextAppearance_textSize,
                             (int) (20 * getResources().getDisplayMetrics().density));
+                    final int textColor = a.getColor(
+                            android.R.styleable.TextAppearance_textColor, 0xffffffff);
 
                     // textSize is already expressed in pixels
                     setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
+                    setTextColor(textColor);
                     setMaxLines(2);
                     super.onMeasure(widthMeasureSpec, heightMeasureSpec);      
                 }
diff --git a/core/res/res/drawable-hdpi/dialog_bottom_holo_dark.9.png b/core/res/res/drawable-hdpi/dialog_bottom_holo_dark.9.png
index 32c2c97..5225a81 100644
--- a/core/res/res/drawable-hdpi/dialog_bottom_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/dialog_bottom_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_bottom_holo_light.9.png b/core/res/res/drawable-hdpi/dialog_bottom_holo_light.9.png
index f1cba06..2e7e973 100644
--- a/core/res/res/drawable-hdpi/dialog_bottom_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/dialog_bottom_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_full_holo_dark.9.png b/core/res/res/drawable-hdpi/dialog_full_holo_dark.9.png
index 08b163a..4591627 100644
--- a/core/res/res/drawable-hdpi/dialog_full_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/dialog_full_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_full_holo_light.9.png b/core/res/res/drawable-hdpi/dialog_full_holo_light.9.png
index 77ec017..9cf1826 100644
--- a/core/res/res/drawable-hdpi/dialog_full_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/dialog_full_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_middle_holo_dark.9.png b/core/res/res/drawable-hdpi/dialog_middle_holo_dark.9.png
index 029f186..a47ef40 100644
--- a/core/res/res/drawable-hdpi/dialog_middle_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/dialog_middle_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_middle_holo_light.9.png b/core/res/res/drawable-hdpi/dialog_middle_holo_light.9.png
index ee1054ef..9b50c73 100644
--- a/core/res/res/drawable-hdpi/dialog_middle_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/dialog_middle_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_top_holo_dark.9.png b/core/res/res/drawable-hdpi/dialog_top_holo_dark.9.png
index acbd7cf..a0d36de 100644
--- a/core/res/res/drawable-hdpi/dialog_top_holo_dark.9.png
+++ b/core/res/res/drawable-hdpi/dialog_top_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/dialog_top_holo_light.9.png b/core/res/res/drawable-hdpi/dialog_top_holo_light.9.png
index b7ddbb4..805b9567 100644
--- a/core/res/res/drawable-hdpi/dialog_top_holo_light.9.png
+++ b/core/res/res/drawable-hdpi/dialog_top_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_bottom_holo_dark.9.png b/core/res/res/drawable-mdpi/dialog_bottom_holo_dark.9.png
index cc66804..a0bd4e3 100644
--- a/core/res/res/drawable-mdpi/dialog_bottom_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/dialog_bottom_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_bottom_holo_light.9.png b/core/res/res/drawable-mdpi/dialog_bottom_holo_light.9.png
index bc734c8..12abcd2 100644
--- a/core/res/res/drawable-mdpi/dialog_bottom_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/dialog_bottom_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_full_holo_dark.9.png b/core/res/res/drawable-mdpi/dialog_full_holo_dark.9.png
index 8603e93..adb8104 100644
--- a/core/res/res/drawable-mdpi/dialog_full_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/dialog_full_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_full_holo_light.9.png b/core/res/res/drawable-mdpi/dialog_full_holo_light.9.png
index 65a318c..d7c6bbf 100644
--- a/core/res/res/drawable-mdpi/dialog_full_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/dialog_full_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_middle_holo_dark.9.png b/core/res/res/drawable-mdpi/dialog_middle_holo_dark.9.png
index e39a472..42cfc52 100644
--- a/core/res/res/drawable-mdpi/dialog_middle_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/dialog_middle_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_middle_holo_light.9.png b/core/res/res/drawable-mdpi/dialog_middle_holo_light.9.png
index ec06c17d..9a08e15 100644
--- a/core/res/res/drawable-mdpi/dialog_middle_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/dialog_middle_holo_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_top_holo_dark.9.png b/core/res/res/drawable-mdpi/dialog_top_holo_dark.9.png
index 32c49f2..5d86b2a 100644
--- a/core/res/res/drawable-mdpi/dialog_top_holo_dark.9.png
+++ b/core/res/res/drawable-mdpi/dialog_top_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/dialog_top_holo_light.9.png b/core/res/res/drawable-mdpi/dialog_top_holo_light.9.png
index 7a2bf8d..ad22f5b 100644
--- a/core/res/res/drawable-mdpi/dialog_top_holo_light.9.png
+++ b/core/res/res/drawable-mdpi/dialog_top_holo_light.9.png
Binary files differ
diff --git a/core/res/res/layout/alert_dialog_holo.xml b/core/res/res/layout/alert_dialog_holo.xml
index 8ee91ca..1a3573e 100644
--- a/core/res/res/layout/alert_dialog_holo.xml
+++ b/core/res/res/layout/alert_dialog_holo.xml
@@ -32,12 +32,10 @@
         android:orientation="vertical">
         <ImageView android:id="@+id/titleDividerTop"
             android:layout_width="match_parent"
-            android:layout_height="4dip"
+            android:layout_height="1dip"
             android:visibility="gone"
             android:scaleType="fitXY"
             android:gravity="fill_horizontal"
-            android:paddingLeft="16dip"
-            android:paddingRight="16dip"
             android:src="@android:drawable/divider_strong_holo" />
         <LinearLayout android:id="@+id/title_template"
             android:layout_width="match_parent"
@@ -45,15 +43,16 @@
             android:orientation="horizontal"
             android:gravity="center_vertical|left"
             android:minHeight="@dimen/alert_dialog_title_height"
-            android:layout_marginLeft="32dip"
-            android:layout_marginRight="32dip">
+            android:layout_marginLeft="16dip"
+            android:layout_marginRight="16dip">
             <ImageView android:id="@+id/icon"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
-                android:paddingRight="16dip"
+                android:paddingRight="8dip"
                 android:src="@null" />
             <com.android.internal.widget.DialogTitle android:id="@+id/alertTitle"
-                style="?android:attr/textAppearanceMedium"
+                style="?android:attr/textAppearanceLarge"
+                android:textColor="@android:color/holo_blue"
                 android:singleLine="true"
                 android:ellipsize="end"
                 android:layout_width="match_parent"
@@ -61,12 +60,10 @@
         </LinearLayout>
         <ImageView android:id="@+id/titleDivider"
             android:layout_width="match_parent"
-            android:layout_height="4dip"
+            android:layout_height="1dip"
             android:visibility="gone"
             android:scaleType="fitXY"
             android:gravity="fill_horizontal"
-            android:paddingLeft="16dip"
-            android:paddingRight="16dip"
             android:src="@android:drawable/divider_strong_holo" />
         <!-- If the client uses a customTitle, it will be added here. -->
     </LinearLayout>
@@ -79,10 +76,6 @@
         <ScrollView android:id="@+id/scrollView"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:layout_marginLeft="16dip"
-            android:layout_marginRight="16dip"
-            android:paddingTop="32dip"
-            android:paddingBottom="32dip"
             android:clipToPadding="false">
             <TextView android:id="@+id/message"
                 style="?android:attr/textAppearanceMedium"
@@ -99,11 +92,7 @@
         android:layout_weight="1">
         <FrameLayout android:id="@+android:id/custom"
             android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:paddingTop="8dip"
-            android:paddingBottom="8dip"
-            android:paddingLeft="32dip"
-            android:paddingRight="32dip" />
+            android:layout_height="wrap_content" />
     </FrameLayout>
 
     <LinearLayout android:id="@+id/buttonPanel"
@@ -113,27 +102,21 @@
         android:orientation="vertical"
         android:divider="?android:attr/dividerHorizontal"
         android:showDividers="beginning"
-        android:dividerPadding="16dip">
+        android:dividerPadding="0dip">
         <LinearLayout
             style="?android:attr/buttonBarStyle"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
             android:orientation="horizontal"
-            android:paddingLeft="2dip"
-            android:paddingRight="2dip"
+            android:layoutDirection="locale"
             android:measureWithLargestChild="true">
-            <LinearLayout android:id="@+id/leftSpacer"
-                android:layout_weight="0.25"
-                android:layout_width="0dip"
-                android:layout_height="wrap_content"
-                android:orientation="horizontal"
-                android:visibility="gone" />
-            <Button android:id="@+id/button1"
+            <Button android:id="@+id/button2"
                 android:layout_width="0dip"
                 android:layout_gravity="left"
                 android:layout_weight="1"
                 android:maxLines="2"
                 style="?android:attr/buttonBarButtonStyle"
+                android:textSize="14sp"
                 android:minHeight="@dimen/alert_dialog_button_bar_height"
                 android:layout_height="wrap_content" />
             <Button android:id="@+id/button3"
@@ -142,22 +125,18 @@
                 android:layout_weight="1"
                 android:maxLines="2"
                 style="?android:attr/buttonBarButtonStyle"
+                android:textSize="14sp"
                 android:minHeight="@dimen/alert_dialog_button_bar_height"
                 android:layout_height="wrap_content" />
-            <Button android:id="@+id/button2"
+            <Button android:id="@+id/button1"
                 android:layout_width="0dip"
                 android:layout_gravity="right"
                 android:layout_weight="1"
                 android:maxLines="2"
                 android:minHeight="@dimen/alert_dialog_button_bar_height"
                 style="?android:attr/buttonBarButtonStyle"
+                android:textSize="14sp"
                 android:layout_height="wrap_content" />
-            <LinearLayout android:id="@+id/rightSpacer"
-                android:layout_width="0dip"
-                android:layout_weight="0.25"
-                android:layout_height="wrap_content"
-                android:orientation="horizontal"
-                android:visibility="gone" />
         </LinearLayout>
      </LinearLayout>
 </LinearLayout>
diff --git a/core/res/res/layout/dialog_custom_title_holo.xml b/core/res/res/layout/dialog_custom_title_holo.xml
index 74b6070..5261553 100644
--- a/core/res/res/layout/dialog_custom_title_holo.xml
+++ b/core/res/res/layout/dialog_custom_title_holo.xml
@@ -23,18 +23,16 @@
     android:fitsSystemWindows="true">
     <FrameLayout android:id="@android:id/title_container"
         android:layout_width="match_parent"
-        android:layout_height="60dip"
+        android:layout_height="@dimen/alert_dialog_title_height"
         android:layout_weight="0"
         android:gravity="center_vertical|left"
         style="?android:attr/windowTitleBackgroundStyle">
     </FrameLayout>
     <ImageView android:id="@+id/titleDivider"
             android:layout_width="match_parent"
-            android:layout_height="4dip"
+            android:layout_height="1dip"
             android:scaleType="fitXY"
             android:gravity="fill_horizontal"
-            android:paddingLeft="16dip"
-            android:paddingRight="16dip"
             android:src="@android:drawable/divider_strong_holo" />
     <FrameLayout
         android:layout_width="match_parent" android:layout_height="wrap_content"
diff --git a/core/res/res/layout/dialog_title_holo.xml b/core/res/res/layout/dialog_title_holo.xml
index 534dd8d..400ef60 100644
--- a/core/res/res/layout/dialog_title_holo.xml
+++ b/core/res/res/layout/dialog_title_holo.xml
@@ -26,17 +26,15 @@
     <TextView android:id="@android:id/title" style="?android:attr/windowTitleStyle"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:minHeight="60dip"
-        android:paddingLeft="32dip"
-        android:paddingRight="32dip"
+        android:minHeight="@android:dimen/alert_dialog_title_height"
+        android:paddingLeft="16dip"
+        android:paddingRight="16dip"
         android:gravity="center_vertical|left" />
     <ImageView android:id="@+id/titleDivider"
             android:layout_width="match_parent"
-            android:layout_height="4dip"
+            android:layout_height="1dip"
             android:scaleType="fitXY"
             android:gravity="fill_horizontal"
-            android:paddingLeft="16dip"
-            android:paddingRight="16dip"
             android:src="@android:drawable/divider_strong_holo" />
     <FrameLayout
         android:layout_width="match_parent" android:layout_height="wrap_content"
diff --git a/core/res/res/layout/dialog_title_icons_holo.xml b/core/res/res/layout/dialog_title_icons_holo.xml
index a3cd3af..f780ab0 100644
--- a/core/res/res/layout/dialog_title_icons_holo.xml
+++ b/core/res/res/layout/dialog_title_icons_holo.xml
@@ -28,16 +28,16 @@
         android:layout_height="wrap_content"
         android:orientation="horizontal"
         android:gravity="center_vertical"
-        android:minHeight="60dip"
-        android:paddingLeft="32dip"
-        android:paddingRight="32dip">
+        android:minHeight="@android:dimen/alert_dialog_title_height"
+        android:paddingLeft="16dip"
+        android:paddingRight="16dip">
         <ImageView android:id="@+id/left_icon"
             android:layout_width="32dip"
             android:layout_height="32dip"
             android:scaleType="fitCenter"
             android:layout_marginRight="8dip" />
         <TextView android:id="@android:id/title"
-		style="?android:attr/windowTitleStyle"
+            style="?android:attr/windowTitleStyle"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_weight="0" />
@@ -50,11 +50,9 @@
 
     <ImageView android:id="@+id/titleDivider"
             android:layout_width="match_parent"
-            android:layout_height="4dip"
+            android:layout_height="1dip"
             android:scaleType="fitXY"
             android:gravity="fill_horizontal"
-            android:paddingLeft="16dip"
-            android:paddingRight="16dip"
             android:src="@android:drawable/divider_strong_holo" />
 
     <FrameLayout
diff --git a/core/res/res/layout/preference_widget_seekbar.xml b/core/res/res/layout/preference_widget_seekbar.xml
new file mode 100644
index 0000000..e4cf86d
--- /dev/null
+++ b/core/res/res/layout/preference_widget_seekbar.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<!-- Layout for a Preference in a PreferenceActivity. The
+     Preference is able to place a specific widget for its particular
+     type in the "widget_frame" layout. -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:gravity="center_vertical"
+    android:paddingRight="?android:attr/scrollbarSize">
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="match_parent"
+        android:gravity="center"
+        android:minWidth="@dimen/preference_icon_minWidth"
+        android:orientation="horizontal">
+        <ImageView
+            android:id="@+android:id/icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:minWidth="48dp"
+            />
+    </LinearLayout>
+
+    <RelativeLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_marginLeft="16dip"
+        android:layout_marginRight="8dip"
+        android:layout_marginTop="6dip"
+        android:layout_marginBottom="6dip"
+        android:layout_weight="1">
+
+        <TextView android:id="@+android:id/title"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:singleLine="true"
+            android:textAppearance="?android:attr/textAppearanceMedium"
+            android:ellipsize="marquee"
+            android:fadingEdge="horizontal" />
+
+        <TextView android:id="@+android:id/summary"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_below="@android:id/title"
+            android:layout_alignLeft="@android:id/title"
+            android:textAppearance="?android:attr/textAppearanceSmall"
+            android:textColor="?android:attr/textColorSecondary"
+            android:maxLines="4" />
+
+        <!-- Preference should place its actual preference widget here. -->
+        <LinearLayout android:id="@+android:id/widget_frame"
+            android:layout_width="wrap_content"
+            android:layout_height="match_parent"
+            android:layout_below="@android:id/summary"
+            android:layout_alignLeft="@android:id/title"
+            android:minWidth="@dimen/preference_widget_width"
+            android:gravity="center"
+            android:orientation="vertical" />
+
+        <SeekBar android:id="@+android:id/seekbar"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:layout_below="@android:id/summary"
+            android:layout_toRightOf="@android:id/widget_frame"
+            android:layout_alignParentRight="true" />
+
+    </RelativeLayout>
+
+</LinearLayout>
diff --git a/core/res/res/layout/select_dialog_holo.xml b/core/res/res/layout/select_dialog_holo.xml
index 7c95693..06a5d96 100644
--- a/core/res/res/layout/select_dialog_holo.xml
+++ b/core/res/res/layout/select_dialog_holo.xml
@@ -27,9 +27,6 @@
     android:id="@+android:id/select_dialog_listview"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:layout_marginTop="5dip"
-    android:paddingLeft="16dip"
-    android:paddingRight="16dip"
     android:cacheColorHint="@null"
     android:divider="?android:attr/listDividerAlertDialog"
     android:scrollbars="vertical"
diff --git a/core/res/res/layout/select_dialog_item_holo.xml b/core/res/res/layout/select_dialog_item_holo.xml
index 396092e..0c700cf 100644
--- a/core/res/res/layout/select_dialog_item_holo.xml
+++ b/core/res/res/layout/select_dialog_item_holo.xml
@@ -26,7 +26,7 @@
     android:id="@android:id/text1"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:minHeight="?android:attr/listPreferredItemHeightSmall"
     android:textAppearance="?android:attr/textAppearanceMedium"
     android:textColor="?android:attr/textColorAlertDialogListItem"
     android:gravity="center_vertical"
diff --git a/core/res/res/layout/select_dialog_multichoice_holo.xml b/core/res/res/layout/select_dialog_multichoice_holo.xml
index 8027035..683151c 100644
--- a/core/res/res/layout/select_dialog_multichoice_holo.xml
+++ b/core/res/res/layout/select_dialog_multichoice_holo.xml
@@ -18,7 +18,7 @@
     android:id="@android:id/text1"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:minHeight="?android:attr/listPreferredItemHeightSmall"
     android:textAppearance="?android:attr/textAppearanceMedium"
     android:textColor="?android:attr/textColorAlertDialogListItem"
     android:gravity="center_vertical"
diff --git a/core/res/res/layout/select_dialog_singlechoice_holo.xml b/core/res/res/layout/select_dialog_singlechoice_holo.xml
index cab519f..52782d0 100644
--- a/core/res/res/layout/select_dialog_singlechoice_holo.xml
+++ b/core/res/res/layout/select_dialog_singlechoice_holo.xml
@@ -18,7 +18,7 @@
     android:id="@android:id/text1"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
-    android:minHeight="?android:attr/listPreferredItemHeight"
+    android:minHeight="?android:attr/listPreferredItemHeightSmall"
     android:textAppearance="?android:attr/textAppearanceMedium"
     android:textColor="?android:attr/textColorAlertDialogListItem"
     android:gravity="center_vertical"
diff --git a/core/res/res/layout/status_bar_latest_event_content.xml b/core/res/res/layout/status_bar_latest_event_content.xml
index 676c38b..0dc6741 100644
--- a/core/res/res/layout/status_bar_latest_event_content.xml
+++ b/core/res/res/layout/status_bar_latest_event_content.xml
@@ -1,4 +1,5 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/status_bar_latest_event_content"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
     >
@@ -8,41 +9,9 @@
         android:background="@drawable/notify_panel_notification_icon_bg"
         android:scaleType="center"
         />
-    <LinearLayout
-        android:layout_width="0dp"
+    <include layout="@layout/status_bar_latest_event_content_large_icon" 
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_gravity="center_vertical"
-        android:layout_weight="1"
-        android:orientation="vertical"
-        android:paddingLeft="16dp"
-        >
-        <TextView android:id="@+id/title"
-            android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:singleLine="true"
-            android:ellipsize="marquee"
-            android:fadingEdge="horizontal"
-            android:layout_marginBottom="-3dp"
-            />
-        <TextView android:id="@+id/text"
-            android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:layout_weight="1"
-            android:layout_marginTop="-2dp"
-            android:singleLine="true"
-            android:ellipsize="marquee"
-            android:fadingEdge="horizontal"
-            />
-    </LinearLayout>
-    <TextView android:id="@+id/info"
-        android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:singleLine="true"
-        android:gravity="center_vertical"
-        android:paddingLeft="8dp"
+        android:layout_gravity="center"
         />
 </LinearLayout>
-
diff --git a/core/res/res/layout/status_bar_latest_event_content_large_icon.xml b/core/res/res/layout/status_bar_latest_event_content_large_icon.xml
index ebdaaa3..d937392 100644
--- a/core/res/res/layout/status_bar_latest_event_content_large_icon.xml
+++ b/core/res/res/layout/status_bar_latest_event_content_large_icon.xml
@@ -1,50 +1,65 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@+id/status_bar_latest_event_content_large_icon"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
+    android:layout_height="wrap_content"
+    android:layout_gravity="center"
+    android:orientation="vertical"
+    android:paddingLeft="8dp"
+    android:paddingRight="8dp"
     >
-    <LinearLayout
-        android:layout_width="0dp"
+    <TextView android:id="@+id/title"
+        android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:layout_gravity="center_vertical"
-        android:layout_weight="1"
-        android:orientation="vertical"
-        android:paddingLeft="16dp"
+        android:singleLine="true"
+        android:ellipsize="marquee"
+        android:fadingEdge="horizontal"
+        />
+    <TextView android:id="@+id/text2"
+        android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:layout_marginTop="-2dp"
+        android:layout_marginBottom="-2dp"
+        android:singleLine="true"
+        android:fadingEdge="horizontal"
+        android:ellipsize="marquee"
+        android:visibility="gone"
+        android:alpha="0.7"
+        />
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:alpha="0.7"
         >
-        <TextView android:id="@+id/title"
-            android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:singleLine="true"
-            android:ellipsize="marquee"
-            android:fadingEdge="horizontal"
-            android:layout_marginBottom="-3dp"
-            />
         <TextView android:id="@+id/text"
             android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
-            android:layout_width="match_parent"
+            android:layout_width="0dp"
             android:layout_height="wrap_content"
             android:layout_weight="1"
-            android:layout_marginTop="-2dp"
+            android:layout_gravity="center"
             android:singleLine="true"
             android:ellipsize="marquee"
             android:fadingEdge="horizontal"
             />
+        <TextView android:id="@+id/info"
+            android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:layout_weight="0"
+            android:singleLine="true"
+            android:gravity="center"
+            android:paddingLeft="8dp"
+            />
+        <ImageView android:id="@+id/icon"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center"
+            android:layout_weight="0"
+            android:scaleType="center"
+            android:paddingLeft="8dp"
+            />
     </LinearLayout>
-    <TextView android:id="@+id/info"
-        android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info"
-        android:layout_width="wrap_content"
-        android:layout_height="match_parent"
-        android:singleLine="true"
-        android:gravity="center_vertical"
-        android:paddingLeft="4dp"
-        android:paddingRight="4dp"
-        />
-    <ImageView android:id="@+id/icon"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_gravity="bottom"
-        android:layout_marginBottom="13dip"
-        android:scaleType="center"
-        />
 </LinearLayout>
-
diff --git a/core/res/res/values-h720dp/dimens.xml b/core/res/res/values-h720dp/dimens.xml
index c09cb5b..37dee8e 100644
--- a/core/res/res/values-h720dp/dimens.xml
+++ b/core/res/res/values-h720dp/dimens.xml
@@ -17,8 +17,6 @@
 */
 -->
 <resources>
-    <!-- Dialog title height -->
-    <dimen name="alert_dialog_title_height">54dip</dimen>
     <!-- Dialog button bar height -->
     <dimen name="alert_dialog_button_bar_height">54dip</dimen>
     <!-- Preference fragment padding, bottom -->
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index f17a272..b87e99e 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -190,6 +190,8 @@
     <string name="permdesc_receiveSms" msgid="6298292335965966117">"Aplikaciji omogućuje primanje i obradu SMS poruka. Zlonamjerne aplikacije mogu pratiti vaše poruke ili ih izbrisati prije nego što ih vi vidite."</string>
     <string name="permlab_receiveMms" msgid="8894700916188083287">"primanje MMS-a"</string>
     <string name="permdesc_receiveMms" msgid="4563346832000174373">"Aplikaciji omogućuje primanje i obradu MMS poruka. Zlonamjerne aplikacije mogu pratiti vaše poruke ili ih izbrisati prije nego što ih vi vidite."</string>
+    <string name="permlab_receiveEmergencyBroadcast" msgid="1803477660846288089">"primanje hitnih odašiljanja"</string>
+    <string name="permdesc_receiveEmergencyBroadcast" msgid="7118393393716546131">"Omogućuje aplikaciji primanje i obradu poruka hitnih odašiljanja. Ta je dozvola dostupna samo aplikacijama sustava."</string>
     <string name="permlab_sendSms" msgid="5600830612147671529">"slanje SMS poruka"</string>
     <string name="permdesc_sendSms" msgid="1946540351763502120">"Aplikaciji omogućuje slanje SMS poruka. Zlonamjerne aplikacije mogu stvarati troškove slanjem poruka bez vaše potvrde."</string>
     <string name="permlab_readSms" msgid="4085333708122372256">"čitanje SMS-a ili MMS-a"</string>
diff --git a/core/res/res/values-sw600dp/styles.xml b/core/res/res/values-sw600dp/styles.xml
index 7515c98..645db13 100644
--- a/core/res/res/values-sw600dp/styles.xml
+++ b/core/res/res/values-sw600dp/styles.xml
@@ -15,27 +15,6 @@
 -->
 
 <resources>
-    <!-- Status Bar Styles -->
-
-    <style name="TextAppearance.StatusBar">
-        <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
-    </style>
-    <style name="TextAppearance.StatusBar.Ticker">
-    </style>
-    <style name="TextAppearance.StatusBar.Title">
-        <item name="android:textStyle">bold</item>
-    </style>
-
-    <style name="TextAppearance.StatusBar.Icon">
-    </style>
-    <style name="TextAppearance.StatusBar.EventContent">
-        <item name="android:textColor">#ff999999</item>
-        <item name="android:textSize">14sp</item>
-    </style>
-    <style name="TextAppearance.StatusBar.EventContent.Title">
-        <item name="android:textColor">?android:attr/textColorPrimary</item>
-    </style>
-
     <style name="TextAppearance.Holo.Widget.TabWidget">
         <item name="android:textSize">18sp</item>
         <item name="android:textStyle">normal</item>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 9c25ace..a59af1a 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -202,9 +202,14 @@
 
         <!-- The preferred list item height. -->
         <attr name="listPreferredItemHeight" format="dimension" />
-        <!-- The drawable for the list divider. -->
+        <!-- A smaller, sleeker list item height. -->
+        <attr name="listPreferredItemHeightSmall" format="dimension" />
+        <!-- A larger, more robust list item height. -->
+        <attr name="listPreferredItemHeightLarge" format="dimension" />
         <!-- The list item height for search results. @hide -->
         <attr name="searchResultListItemHeight" format="dimension" />
+
+        <!-- The drawable for the list divider. -->
         <attr name="listDivider" format="reference" />
         <!-- The list divider used in alert dialogs. -->
         <attr name="listDividerAlertDialog" format="reference" />
@@ -1206,6 +1211,16 @@
         <enum name="vertical" value="1" />
     </attr>
 
+    <!-- Alignment constants. -->
+    <attr name="alignmentMode">
+        <!-- Align the bounds of the children.
+        See {@link android.widget.GridLayout#ALIGN_BOUNDS}. -->
+        <enum name="alignBounds" value="0" />
+        <!-- Align the margins of the children.
+        See {@link android.widget.GridLayout#ALIGN_MARGINS}. -->
+        <enum name="alignMargins" value="1" />
+    </attr>
+
     <!-- ========================== -->
     <!-- Key Codes                  -->
     <!-- ========================== -->
@@ -2541,12 +2556,12 @@
         The default value is false.
         See {@link android.widget.GridLayout#setUseDefaultMargins(boolean)}.-->
         <attr name="useDefaultMargins" format="boolean" />
-        <!-- When set to true, causes alignment to take place between the outer
-        boundary of a view, as defined by its margins. When set to false,
+        <!-- When set to alignMargins, causes alignment to take place between the outer
+        boundary of a view, as defined by its margins. When set to alignBounds,
         causes alignment to take place between the edges of the view.
-        The default is true.
-        See {@link android.widget.GridLayout#setMarginsIncludedInAlignment(boolean)}.-->
-        <attr name="marginsIncludedInAlignment" format="boolean" />
+        The default is alignMargins.
+        See {@link android.widget.GridLayout#setAlignmentMode(int)}.-->
+        <attr name="alignmentMode" />
         <!-- When set to true, forces row boundaries to appear in the same order
         as row indices.
         The default is false.
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 6529fe1..e76c0e5 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -148,5 +148,14 @@
 
     <color name="group_button_dialog_pressed_holo_light">#ffffffff</color>
     <color name="group_button_dialog_focused_holo_light">#4699cc00</color>
+
+    <!-- General purpose colors for Holo-themed elements -->
+    <eat-comment />
+
+    <!-- A Holo shade of blue -->
+    <color name="holo_blue">#ff6699ff</color>
+    <!-- A Holo shade of green -->
+    <color name="holo_green">#ff99cc00</color>
+
 </resources>
 
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index e6dfc03..4deb8ca 100755
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -82,7 +82,7 @@
     <!-- The maximum width we would prefer dialogs to be.  0 if there is no
          maximum (let them grow as large as the screen).  Actual values are
          specified for -large and -xlarge configurations. -->
-    <dimen name="config_prefDialogWidth">0px</dimen>
+    <dimen name="config_prefDialogWidth">320dp</dimen>
     
     <!-- Whether dialogs should close automatically when the user touches outside
          of them.  This should not normally be modified. -->
@@ -642,4 +642,10 @@
              -SourcePortDestPort-SourcePortDestPort-OMADM PDU
          If false, not supported. -->
     <bool name="config_duplicate_port_omadm_wappush">false</bool>
+
+    <!-- Maximum numerical value that will be shown in a status bar
+         notification icon or in the notification itself. Will be replaced
+         with @string/status_bar_notification_info_overflow when shown in the
+         UI. -->
+    <integer name="status_bar_notification_info_maxnum">999</integer>
 </resources>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index df22f15..0725c2f 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -111,7 +111,7 @@
     <dimen name="search_view_text_min_width">160dip</dimen>
 
     <!-- Dialog title height -->
-    <dimen name="alert_dialog_title_height">48dip</dimen>
+    <dimen name="alert_dialog_title_height">64dip</dimen>
     <!-- Dialog button bar height -->
     <dimen name="alert_dialog_button_bar_height">48dip</dimen>
 
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 17b23da..e02496c 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1733,7 +1733,7 @@
   <public type="attr" name="columnCount" />
   <public type="attr" name="columnOrderPreserved" />
   <public type="attr" name="useDefaultMargins" />
-  <public type="attr" name="marginsIncludedInAlignment" />
+  <public type="attr" name="alignmentMode" />
 
   <public type="attr" name="layout_row" />
   <public type="attr" name="layout_rowSpan" />
@@ -1766,5 +1766,13 @@
   <public type="attr" name="feedbackCount" />
   <public type="attr" name="verticalOffset" />
   <public type="attr" name="horizontalOffset" />
+  <public type="attr" name="listPreferredItemHeightLarge" />
+  <public type="attr" name="listPreferredItemHeightSmall" />
+
+  <public type="style" name="Widget.Holo.Button.Borderless.Small" />
+  <public type="style" name="Widget.Holo.Light.Button.Borderless.Small" />
+
+  <public type="integer" name="status_bar_notification_info_maxnum" />
+  <public type="string" name="status_bar_notification_info_overflow" />
 
 </resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 879892e..d9e7dac 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -339,10 +339,12 @@
     <!-- status message in phone options dialog for when airplane mode is off -->
     <string name="global_actions_airplane_mode_off_status">Airplane mode is OFF</string>
 
-    <!-- Text to use when the number in a notification info is too large (> 100).  Most likely does not need
-    to be translated.  We do this so, for example, if the user has tens of thousands of unread
-    emails, the whole notification isn't taken over by the number. [CHAR LIMIT=5] -->
-    <string name="status_bar_notification_info_overflow">100+</string>
+    <!-- Text to use when the number in a notification info is too large
+         (greater than status_bar_notification_info_maxnum, defined in
+         values/config.xml) and must be truncated. May need to be localized
+         for most appropriate textual indicator of "more than X".
+         [CHAR LIMIT=4] -->
+    <string name="status_bar_notification_info_overflow">999+</string>
 
     <!-- Displayed to the user to tell them that they have started up the phone in "safe mode" -->
     <string name="safeMode">Safe mode</string>
@@ -1790,6 +1792,9 @@
     <string name="lockscreen_missing_sim_instructions">Please insert a SIM card.</string>
     <!-- Shown in the lock screen to ask the user to insert a SIM card when sim is missing or not readable. -->
     <string name="lockscreen_missing_sim_instructions_long">The SIM card is missing or not readable. Please insert a SIM card.</string>
+    <!-- Shown in the lock screen to inform the user to SIM card is permanently disabled. -->
+    <string name="lockscreen_permanent_disabled_sim_instructions">Your SIM card is permanently disabled.\n
+    Please contact your wireless service provider to obtain another SIM card.</string>
 
     <!-- Shown in the lock screen when there is emergency calls only mode. -->
     <string name="emergency_calls_only" msgid="2485604591272668370">Emergency calls only</string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 19b05c9..72a5797 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -227,15 +227,15 @@
     <style name="TextAppearance.StatusBar.Icon">
     </style>
     <style name="TextAppearance.StatusBar.EventContent">
-        <item name="android:textColor">#ff999999</item>
-        <item name="android:textSize">14sp</item>
+        <item name="android:textColor">?android:attr/textColorPrimary</item>
+        <item name="android:textSize">13sp</item>
     </style>
     <style name="TextAppearance.StatusBar.EventContent.Title">
-        <item name="android:textColor">?android:attr/textColorPrimary</item>
+        <item name="android:textSize">16sp</item>
+        <item name="android:textStyle">bold</item>
     </style>
     <style name="TextAppearance.StatusBar.EventContent.Info">
-        <item name="android:textAppearance">?android:attr/textAppearanceLarge</item>
-        <item name="android:textColor">#ff272727</item>
+        <item name="android:textSize">13sp</item>
     </style>
 
     <style name="TextAppearance.Small.CalendarViewWeekDayView">
@@ -1321,7 +1321,8 @@
     </style>
 
     <style name="TextAppearance.Holo.DialogWindowTitle">
-        <item name="android:textSize">18sp</item>
+        <item name="android:textSize">22sp</item>
+        <item name="android:textColor">@android:color/holo_blue</item>
     </style>
 
     <style name="TextAppearance.Holo.CalendarViewWeekDayView" parent="TextAppearance.Small.CalendarViewWeekDayView">
@@ -1419,7 +1420,8 @@
     </style>
 
     <style name="TextAppearance.Holo.Light.DialogWindowTitle">
-        <item name="android:textSize">18sp</item>
+        <item name="android:textSize">22sp</item>
+        <item name="android:textColor">@android:color/holo_blue</item>
     </style>
 
     <style name="TextAppearance.Holo.Light.CalendarViewWeekDayView" parent="TextAppearance.Small.CalendarViewWeekDayView">
@@ -1448,6 +1450,12 @@
 
     <style name="Widget.Holo.Button.Borderless">
         <item name="android:background">?android:attr/selectableItemBackground</item>
+        <item name="android:paddingLeft">4dip</item>
+        <item name="android:paddingRight">4dip</item>
+    </style>
+
+    <style name="Widget.Holo.Button.Borderless.Small">
+        <item name="android:textSize">14sp</item>
     </style>
 
     <style name="Widget.Holo.Button.Small">
@@ -1488,6 +1496,7 @@
 
     <style name="Holo.ButtonBar.AlertDialog">
         <item name="android:background">@null</item>
+        <item name="android:dividerPadding">0dp</item>
     </style>
 
     <style name="Widget.Holo.TextView" parent="Widget.TextView">
@@ -1864,6 +1873,12 @@
 
     <style name="Widget.Holo.Light.Button.Borderless">
         <item name="android:background">?android:attr/selectableItemBackground</item>
+        <item name="android:paddingLeft">4dip</item>
+        <item name="android:paddingRight">4dip</item>
+    </style>
+
+    <style name="Widget.Holo.Light.Button.Borderless.Small">
+        <item name="android:textSize">14sp</item>
     </style>
 
     <style name="Widget.Holo.Light.Button.Small">
@@ -1891,6 +1906,7 @@
 
     <style name="Holo.Light.ButtonBar.AlertDialog">
         <item name="android:background">@null</item>
+        <item name="android:dividerPadding">0dp</item>
     </style>
 
     <style name="Holo.Light.SegmentedButton" parent="SegmentedButton">
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 5f77dc5..2ab2c04 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -95,7 +95,9 @@
 
         <!-- List attributes -->
         <item name="listPreferredItemHeight">64dip</item>
-        <item name="dropdownListPreferredItemHeight">64dip</item>
+        <item name="listPreferredItemHeightSmall">?android:attr/listPreferredItemHeight</item>
+        <item name="listPreferredItemHeightLarge">?android:attr/listPreferredItemHeight</item>
+        <item name="dropdownListPreferredItemHeight">?android:attr/listPreferredItemHeight</item>
 
         <!-- @hide -->
         <item name="searchResultListItemHeight">58dip</item>
@@ -861,7 +863,9 @@
 
         <!-- List attributes -->
         <item name="listPreferredItemHeight">64dip</item>
-        <item name="dropdownListPreferredItemHeight">48dip</item>
+        <item name="listPreferredItemHeightSmall">48dip</item>
+        <item name="listPreferredItemHeightLarge">80dip</item>
+        <item name="dropdownListPreferredItemHeight">?android:attr/listPreferredItemHeightSmall</item>
 
         <!-- @hide -->
         <item name="searchResultListItemHeight">58dip</item>
@@ -1150,7 +1154,9 @@
 
         <!-- List attributes -->
         <item name="listPreferredItemHeight">64dip</item>
-        <item name="dropdownListPreferredItemHeight">48dip</item>
+        <item name="listPreferredItemHeightSmall">48dip</item>
+        <item name="listPreferredItemHeightLarge">80dip</item>
+        <item name="dropdownListPreferredItemHeight">?android:attr/listPreferredItemHeightSmall</item>
 
         <!-- @hide -->
         <item name="searchResultListItemHeight">58dip</item>
@@ -1411,6 +1417,7 @@
         <item name="android:colorBackgroundCacheHint">@null</item>
 
         <item name="android:buttonBarStyle">@android:style/Holo.ButtonBar.AlertDialog</item>
+        <item name="borderlessButtonStyle">@android:style/Widget.Holo.Button.Borderless.Small</item>
         
         <item name="textAppearance">@android:style/TextAppearance.Holo</item>
         <item name="textAppearanceInverse">@android:style/TextAppearance.Holo.Inverse</item>
@@ -1420,7 +1427,7 @@
          a regular dialog. -->
     <style name="Theme.Holo.Dialog.MinWidth">
         <item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
-        <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_major</item>
+        <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
     </style>
 
     <!-- Variation of Theme.Holo.Dialog that does not include a title bar. -->
@@ -1433,7 +1440,7 @@
          a regular dialog. -->
     <style name="Theme.Holo.Dialog.NoActionBar.MinWidth">
         <item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
-        <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_major</item>
+        <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
     </style>
 
     <!-- Variation of Theme.Holo.Dialog that does not include a frame (or background).
@@ -1460,7 +1467,7 @@
         <item name="windowTitleStyle">@android:style/DialogWindowTitle.Holo</item>
         <item name="windowContentOverlay">@null</item>
         <item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
-        <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_major</item>
+        <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
     </style>
 
     <!-- Theme for a window that will be displayed either full-screen on
@@ -1499,6 +1506,7 @@
         <item name="android:colorBackgroundCacheHint">@null</item>
 
         <item name="android:buttonBarStyle">@android:style/Holo.Light.ButtonBar.AlertDialog</item>
+        <item name="borderlessButtonStyle">@android:style/Widget.Holo.Light.Button.Borderless.Small</item>
 
         <item name="textAppearance">@android:style/TextAppearance.Holo.Light</item>
         <item name="textAppearanceInverse">@android:style/TextAppearance.Holo.Light.Inverse</item>
@@ -1508,7 +1516,7 @@
          a regular dialog. -->
     <style name="Theme.Holo.Light.Dialog.MinWidth">
         <item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
-        <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_major</item>
+        <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
     </style>
 
     <!-- Variation of Theme.Holo.Light.Dialog that does not include a title bar. -->
@@ -1521,7 +1529,7 @@
          a regular dialog. -->
     <style name="Theme.Holo.Light.Dialog.NoActionBar.MinWidth">
         <item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
-        <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_major</item>
+        <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
     </style>
 
     <!-- Theme for a window that will be displayed either full-screen on
@@ -1547,7 +1555,7 @@
         <item name="windowTitleStyle">@android:style/DialogWindowTitle.Holo.Light</item>
         <item name="windowContentOverlay">@null</item>
         <item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
-        <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_major</item>
+        <item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
     </style>
 
     <!-- Default holographic (dark) for windows that want to have the user's selected
diff --git a/core/tests/coretests/src/android/util/LocaleUtilTest.java b/core/tests/coretests/src/android/util/LocaleUtilTest.java
index 5aa99c1..203781f 100644
--- a/core/tests/coretests/src/android/util/LocaleUtilTest.java
+++ b/core/tests/coretests/src/android/util/LocaleUtilTest.java
@@ -18,14 +18,12 @@
 
 import java.util.Locale;
 
-import android.content.res.Configuration;
 import android.test.AndroidTestCase;
 import dalvik.annotation.TestLevel;
 import dalvik.annotation.TestTargetNew;
 
-import static android.util.LocaleUtil.TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE;
 import static android.util.LocaleUtil.TEXT_LAYOUT_DIRECTION_LTR_DO_NOT_USE;
-import static android.util.LocaleUtil.TEXT_LAYOUT_DIRECTION_RTL_DO_NOT_USE;
+import static android.util.LocaleUtil.TEXT_LAYOUT_DIRECTION_UNDEFINED_DO_NOT_USE;
 
 public class LocaleUtilTest extends AndroidTestCase {
 
diff --git a/core/tests/coretests/src/com/android/internal/util/HanziToPinyinTest.java b/core/tests/coretests/src/com/android/internal/util/HanziToPinyinTest.java
deleted file mode 100644
index 36dee70..0000000
--- a/core/tests/coretests/src/com/android/internal/util/HanziToPinyinTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.util;
-
-import java.text.Collator;
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.Locale;
-
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
-
-import com.android.internal.util.HanziToPinyin;
-import com.android.internal.util.HanziToPinyin.Token;
-
-import junit.framework.TestCase;
-
-public class HanziToPinyinTest extends TestCase {
-    private final static String ONE_HANZI = "\u675C";
-    private final static String TWO_HANZI = "\u675C\u9D51";
-    private final static String ASSIC = "test";
-    private final static String ONE_UNKNOWN = "\uFF71";
-    private final static String MISC = "test\u675C   Test with space\uFF71\uFF71\u675C";
-
-    @SmallTest
-    public void testGetToken() throws Exception {
-        if (!Arrays.asList(Collator.getAvailableLocales()).contains(Locale.CHINA)) {
-            return;
-        }
-        ArrayList<Token> tokens = HanziToPinyin.getInstance().get(ONE_HANZI);
-        assertEquals(tokens.size(), 1);
-        assertEquals(tokens.get(0).type, Token.PINYIN);
-        assertTrue(tokens.get(0).target.equalsIgnoreCase("DU"));
-
-        tokens = HanziToPinyin.getInstance().get(TWO_HANZI);
-        assertEquals(tokens.size(), 2);
-        assertEquals(tokens.get(0).type, Token.PINYIN);
-        assertEquals(tokens.get(1).type, Token.PINYIN);
-        assertTrue(tokens.get(0).target.equalsIgnoreCase("DU"));
-        assertTrue(tokens.get(1).target.equalsIgnoreCase("JUAN"));
-
-        tokens = HanziToPinyin.getInstance().get(ASSIC);
-        assertEquals(tokens.size(), 1);
-        assertEquals(tokens.get(0).type, Token.LATIN);
-
-        tokens = HanziToPinyin.getInstance().get(ONE_UNKNOWN);
-        assertEquals(tokens.size(), 1);
-        assertEquals(tokens.get(0).type, Token.UNKNOWN);
-
-        tokens = HanziToPinyin.getInstance().get(MISC);
-        assertEquals(tokens.size(), 7);
-        assertEquals(tokens.get(0).type, Token.LATIN);
-        assertEquals(tokens.get(1).type, Token.PINYIN);
-        assertEquals(tokens.get(2).type, Token.LATIN);
-        assertEquals(tokens.get(3).type, Token.LATIN);
-        assertEquals(tokens.get(4).type, Token.LATIN);
-        assertEquals(tokens.get(5).type, Token.UNKNOWN);
-        assertEquals(tokens.get(6).type, Token.PINYIN);
-    }
-}
diff --git a/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js
index 77aee46..097d004 100644
--- a/docs/html/resources/resources-data.js
+++ b/docs/html/resources/resources-data.js
@@ -407,6 +407,26 @@
     }
   },
   {
+    tags: ['sample', 'layout', 'ui', 'fragment', 'loader', 'new'],
+    path: 'samples/Support4Demos/index.html',
+    title: {
+      en: 'API 4+ Support Demos'
+    },
+    description: {
+      en: 'A variety of small applications that demonstrate the use of the helper classes in the Android API 4+ Support Library (classes which work down to API level 4 or version 1.6 of the platform).'
+    }
+  },
+  {
+    tags: ['sample', 'layout', 'ui', 'new'],
+    path: 'samples/Support13Demos/index.html',
+    title: {
+      en: 'API 13+ Support Demos'
+    },
+    description: {
+      en: 'A variety of small applications that demonstrate the use of the helper classes in the Android API 13+ Support Library (classes which work down to API level 13 or version 3.2 of the platform).'
+    }
+  },
+  {
     tags: ['sample', 'data', 'newfeature', 'accountsync'],
     path: 'samples/BackupRestore/index.html',
     title: {
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index a63abb9..eeab9b4 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -606,9 +606,9 @@
      */
     public void copy1DRangeFrom(int off, int count, Allocation data, int dataOff) {
         mRS.nAllocationData2D(getID(), off, 0,
-                              0, Type.CubemapFace.POSITVE_X.mID,
+                              0, Type.CubemapFace.POSITIVE_X.mID,
                               count, 1, data.getID(), dataOff, 0,
-                              0, Type.CubemapFace.POSITVE_X.mID);
+                              0, Type.CubemapFace.POSITIVE_X.mID);
     }
 
     private void validate2DRange(int xoff, int yoff, int w, int h) {
@@ -675,9 +675,9 @@
         mRS.validate();
         validate2DRange(xoff, yoff, w, h);
         mRS.nAllocationData2D(getID(), xoff, yoff,
-                              0, Type.CubemapFace.POSITVE_X.mID,
+                              0, Type.CubemapFace.POSITIVE_X.mID,
                               w, h, data.getID(), dataXoff, dataYoff,
-                              0, Type.CubemapFace.POSITVE_X.mID);
+                              0, Type.CubemapFace.POSITIVE_X.mID);
     }
 
     /**
@@ -1048,15 +1048,15 @@
         Allocation cubemap = Allocation.createTyped(rs, t, mips, usage);
 
         AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap);
-        adapter.setFace(Type.CubemapFace.POSITVE_X);
+        adapter.setFace(Type.CubemapFace.POSITIVE_X);
         adapter.copyFrom(xpos);
         adapter.setFace(Type.CubemapFace.NEGATIVE_X);
         adapter.copyFrom(xneg);
-        adapter.setFace(Type.CubemapFace.POSITVE_Y);
+        adapter.setFace(Type.CubemapFace.POSITIVE_Y);
         adapter.copyFrom(ypos);
         adapter.setFace(Type.CubemapFace.NEGATIVE_Y);
         adapter.copyFrom(yneg);
-        adapter.setFace(Type.CubemapFace.POSITVE_Z);
+        adapter.setFace(Type.CubemapFace.POSITIVE_Z);
         adapter.copyFrom(zpos);
         adapter.setFace(Type.CubemapFace.NEGATIVE_Z);
         adapter.copyFrom(zneg);
diff --git a/graphics/java/android/renderscript/AllocationAdapter.java b/graphics/java/android/renderscript/AllocationAdapter.java
index 07a1f5d..61f2e1f 100644
--- a/graphics/java/android/renderscript/AllocationAdapter.java
+++ b/graphics/java/android/renderscript/AllocationAdapter.java
@@ -33,7 +33,7 @@
     private Allocation mAlloc;
 
     private int mSelectedLOD = 0;
-    private Type.CubemapFace mSelectedFace = Type.CubemapFace.POSITVE_X;
+    private Type.CubemapFace mSelectedFace = Type.CubemapFace.POSITIVE_X;
 
     AllocationAdapter(int id, RenderScript rs, Allocation alloc) {
         super(id, rs, null, alloc.mUsage);
diff --git a/graphics/java/android/renderscript/Element.java b/graphics/java/android/renderscript/Element.java
index 0c1ad2a..5a72dbe 100644
--- a/graphics/java/android/renderscript/Element.java
+++ b/graphics/java/android/renderscript/Element.java
@@ -32,8 +32,8 @@
  * <p>Complex elements contain a list of sub-elements and names that
  * represents a structure of data. The fields can be accessed by name
  * from a script or shader. The memory layout is defined and ordered. Data
- * alignment is determinied by the most basic primitive type. i.e. a float4
- * vector will be alligned to sizeof(float) and not sizeof(float4).  The
+ * alignment is determined by the most basic primitive type. i.e. a float4
+ * vector will be aligned to sizeof(float) and not sizeof(float4). The
  * ordering of elements in memory will be the order in which they were added
  * with each component aligned as necessary. No re-ordering will be done.</p>
  *
@@ -584,6 +584,33 @@
     }
 
     /**
+     * Check if the current Element is compatible with another Element.
+     * Primitive Elements are compatible if they share the same underlying
+     * size and type (i.e. U8 is compatible with A_8). User-defined Elements
+     * must be equal in order to be compatible. This requires strict name
+     * equivalence for all sub-Elements (in addition to structural equivalence).
+     *
+     * @param e The Element to check compatibility with.
+     *
+     * @return boolean true if the Elements are compatible, otherwise false.
+     */
+    public boolean isCompatible(Element e) {
+        // Try strict BaseObj equality to start with.
+        if (this.equals(e)) {
+            return true;
+        }
+
+        // Ignore mKind because it is allowed to be different (user vs. pixel).
+        // We also ignore mNormalized because it can be different. The mType
+        // field must be non-null since we require name equivalence for
+        // user-created Elements.
+        return ((mSize == e.mSize) &&
+                (mType != null) &&
+                (mType == e.mType) &&
+                (mVectorSize == e.mVectorSize));
+    }
+
+    /**
      * Builder class for producing complex elements with matching field and name
      * pairs.  The builder starts empty.  The order in which elements are added
      * is retained for the layout in memory.
diff --git a/graphics/java/android/renderscript/Type.java b/graphics/java/android/renderscript/Type.java
index b39d2e4..f88af8b 100644
--- a/graphics/java/android/renderscript/Type.java
+++ b/graphics/java/android/renderscript/Type.java
@@ -46,12 +46,18 @@
     Element mElement;
 
     public enum CubemapFace {
-        POSITVE_X (0),
+        POSITIVE_X (0),
         NEGATIVE_X (1),
-        POSITVE_Y (2),
+        POSITIVE_Y (2),
         NEGATIVE_Y (3),
-        POSITVE_Z (4),
-        NEGATIVE_Z (5);
+        POSITIVE_Z (4),
+        NEGATIVE_Z (5),
+        @Deprecated
+        POSITVE_X (0),
+        @Deprecated
+        POSITVE_Y (2),
+        @Deprecated
+        POSITVE_Z (4);
 
         int mID;
         CubemapFace(int id) {
diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp
index a4c5b36..519b40e 100644
--- a/libs/gui/tests/SurfaceTextureClient_test.cpp
+++ b/libs/gui/tests/SurfaceTextureClient_test.cpp
@@ -590,7 +590,7 @@
 
 // This test verifies that the buffer format can be queried immediately after
 // it is set.
-TEST_F(SurfaceTextureClientTest, DISABLED_QueryFormatAfterSettingWorks) {
+TEST_F(SurfaceTextureClientTest, QueryFormatAfterSettingWorks) {
     sp<ANativeWindow> anw(mSTC);
     int fmts[] = {
         // RGBA_8888 should not come first, as it's the default
diff --git a/libs/gui/tests/SurfaceTexture_test.cpp b/libs/gui/tests/SurfaceTexture_test.cpp
index 50af3bb..f6cefa6 100644
--- a/libs/gui/tests/SurfaceTexture_test.cpp
+++ b/libs/gui/tests/SurfaceTexture_test.cpp
@@ -542,11 +542,7 @@
     EXPECT_TRUE(checkPixel(36, 22, 155,  29,   0, 255));
 }
 
-// XXX: This test is disabled because it it currently broken on all devices to
-// which I have access.  Some of the checkPixel calls are not correct because
-// I just copied them from the npot test above and haven't bothered to figure
-// out the correct values.
-TEST_F(SurfaceTextureGLTest, DISABLED_TexturingFromCpuFilledYV12BufferPow2) {
+TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferPow2) {
     const int texWidth = 64;
     const int texHeight = 64;
 
@@ -576,18 +572,18 @@
 
     drawTexture();
 
-    EXPECT_TRUE(checkPixel( 0,  0, 255, 127, 255, 255));
-    EXPECT_TRUE(checkPixel(63,  0,   0, 133,   0, 255));
+    EXPECT_TRUE(checkPixel( 0,  0,   0, 133,   0, 255));
+    EXPECT_TRUE(checkPixel(63,  0, 255, 127, 255, 255));
     EXPECT_TRUE(checkPixel(63, 63,   0, 133,   0, 255));
     EXPECT_TRUE(checkPixel( 0, 63, 255, 127, 255, 255));
 
-    EXPECT_TRUE(checkPixel(22, 19, 247,  70, 255, 255));
-    EXPECT_TRUE(checkPixel(45, 11, 209,  32, 235, 255));
-    EXPECT_TRUE(checkPixel(52, 12, 100, 255,  73, 255));
-    EXPECT_TRUE(checkPixel( 7, 32, 155,   0, 118, 255));
-    EXPECT_TRUE(checkPixel(31, 54, 148,  71, 110, 255));
-    EXPECT_TRUE(checkPixel(29, 28, 255, 127, 255, 255));
-    EXPECT_TRUE(checkPixel(36, 41, 155,  29,   0, 255));
+    EXPECT_TRUE(checkPixel(22, 19, 100, 255,  74, 255));
+    EXPECT_TRUE(checkPixel(45, 11, 100, 255,  74, 255));
+    EXPECT_TRUE(checkPixel(52, 12, 155,   0, 181, 255));
+    EXPECT_TRUE(checkPixel( 7, 32, 150, 237, 170, 255));
+    EXPECT_TRUE(checkPixel(31, 54,   0,  71, 117, 255));
+    EXPECT_TRUE(checkPixel(29, 28,   0, 133,   0, 255));
+    EXPECT_TRUE(checkPixel(36, 41, 100, 232, 255, 255));
 }
 
 TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferWithCrop) {
diff --git a/libs/rs/Android.mk b/libs/rs/Android.mk
index 9fabf8d..d9cc6b6 100644
--- a/libs/rs/Android.mk
+++ b/libs/rs/Android.mk
@@ -119,6 +119,7 @@
 	driver/rsdBcc.cpp \
 	driver/rsdCore.cpp \
 	driver/rsdFrameBuffer.cpp \
+	driver/rsdFrameBufferObj.cpp \
 	driver/rsdGL.cpp \
 	driver/rsdMesh.cpp \
 	driver/rsdMeshObj.cpp \
diff --git a/libs/rs/driver/rsdAllocation.cpp b/libs/rs/driver/rsdAllocation.cpp
index 8bfc185..01a0cf6 100644
--- a/libs/rs/driver/rsdAllocation.cpp
+++ b/libs/rs/driver/rsdAllocation.cpp
@@ -19,6 +19,7 @@
 #include "rsdBcc.h"
 #include "rsdRuntime.h"
 #include "rsdAllocation.h"
+#include "rsdFrameBufferObj.h"
 
 #include "rsAllocation.h"
 
@@ -244,6 +245,9 @@
     if (alloc->mHal.state.usageFlags & ~RS_ALLOCATION_USAGE_SCRIPT) {
         drv->uploadDeferred = true;
     }
+
+    drv->readBackFBO = NULL;
+
     return true;
 }
 
@@ -269,6 +273,10 @@
         free(drv->mallocPtr);
         drv->mallocPtr = NULL;
     }
+    if (drv->readBackFBO != NULL) {
+        delete drv->readBackFBO;
+        drv->readBackFBO = NULL;
+    }
     free(drv);
     alloc->mHal.drv = NULL;
 }
@@ -292,13 +300,52 @@
     }
 }
 
+static void rsdAllocationSyncFromFBO(const Context *rsc, const Allocation *alloc) {
+    if (!alloc->getIsScript()) {
+        return; // nothing to sync
+    }
+
+    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+    RsdFrameBufferObj *lastFbo = dc->gl.currentFrameBuffer;
+
+    DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
+    if (!drv->textureID && !drv->renderTargetID) {
+        return; // nothing was rendered here yet, so nothing to sync
+    }
+    if (drv->readBackFBO == NULL) {
+        drv->readBackFBO = new RsdFrameBufferObj();
+        drv->readBackFBO->setColorTarget(drv, 0);
+        drv->readBackFBO->setDimensions(alloc->getType()->getDimX(),
+                                        alloc->getType()->getDimY());
+    }
+
+    // Bind the framebuffer object so we can read back from it
+    drv->readBackFBO->setActive(rsc);
+
+    // Do the readback
+    glReadPixels(0, 0, alloc->getType()->getDimX(), alloc->getType()->getDimY(),
+                 drv->glFormat, drv->glType, alloc->getPtr());
+
+    // Revert framebuffer to its original
+    lastFbo->setActive(rsc);
+}
 
 
 void rsdAllocationSyncAll(const Context *rsc, const Allocation *alloc,
                          RsAllocationUsageType src) {
     DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
 
-    if (!drv->uploadDeferred) {
+    if (src == RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET) {
+        if(!alloc->getIsRenderTarget()) {
+            rsc->setError(RS_ERROR_FATAL_DRIVER,
+                          "Attempting to sync allocation from render target, "
+                          "for non-render target allocation");
+        } else if (alloc->getType()->getElement()->getKind() != RS_KIND_PIXEL_RGBA) {
+            rsc->setError(RS_ERROR_FATAL_DRIVER, "Cannot only sync from RGBA"
+                                                 "render target");
+        } else {
+            rsdAllocationSyncFromFBO(rsc, alloc);
+        }
         return;
     }
 
@@ -382,7 +429,40 @@
                                const android::renderscript::Allocation *dstAlloc,
                                uint32_t dstXoff, uint32_t dstLod, uint32_t count,
                                const android::renderscript::Allocation *srcAlloc,
-                               uint32_t srcXoff, uint32_t srcLod){
+                               uint32_t srcXoff, uint32_t srcLod) {
+}
+
+uint8_t *getOffsetPtr(const android::renderscript::Allocation *alloc,
+                      uint32_t xoff, uint32_t yoff, uint32_t lod,
+                      RsAllocationCubemapFace face) {
+    uint8_t *ptr = static_cast<uint8_t *>(alloc->getPtr());
+    ptr += alloc->getType()->getLODOffset(lod, xoff, yoff);
+
+    if (face != 0) {
+        uint32_t totalSizeBytes = alloc->getType()->getSizeBytes();
+        uint32_t faceOffset = totalSizeBytes / 6;
+        ptr += faceOffset * (uint32_t)face;
+    }
+    return ptr;
+}
+
+
+void rsdAllocationData2D_alloc_script(const android::renderscript::Context *rsc,
+                                      const android::renderscript::Allocation *dstAlloc,
+                                      uint32_t dstXoff, uint32_t dstYoff, uint32_t dstLod,
+                                      RsAllocationCubemapFace dstFace, uint32_t w, uint32_t h,
+                                      const android::renderscript::Allocation *srcAlloc,
+                                      uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod,
+                                      RsAllocationCubemapFace srcFace) {
+    uint32_t elementSize = dstAlloc->getType()->getElementSizeBytes();
+    for (uint32_t i = 0; i < h; i ++) {
+        uint8_t *dstPtr = getOffsetPtr(dstAlloc, dstXoff, dstYoff + i, dstLod, dstFace);
+        uint8_t *srcPtr = getOffsetPtr(srcAlloc, srcXoff, srcYoff + i, srcLod, srcFace);
+        memcpy(dstPtr, srcPtr, w * elementSize);
+
+        LOGE("COPIED dstXoff(%u), dstYoff(%u), dstLod(%u), dstFace(%u), w(%u), h(%u), srcXoff(%u), srcYoff(%u), srcLod(%u), srcFace(%u)",
+             dstXoff, dstYoff, dstLod, dstFace, w, h, srcXoff, srcYoff, srcLod, srcFace);
+    }
 }
 
 void rsdAllocationData2D_alloc(const android::renderscript::Context *rsc,
@@ -392,6 +472,14 @@
                                const android::renderscript::Allocation *srcAlloc,
                                uint32_t srcXoff, uint32_t srcYoff, uint32_t srcLod,
                                RsAllocationCubemapFace srcFace) {
+    if (!dstAlloc->getIsScript() && !srcAlloc->getIsScript()) {
+        rsc->setError(RS_ERROR_FATAL_DRIVER, "Non-script allocation copies not "
+                                             "yet implemented.");
+        return;
+    }
+    rsdAllocationData2D_alloc_script(rsc, dstAlloc, dstXoff, dstYoff,
+                                     dstLod, dstFace, w, h, srcAlloc,
+                                     srcXoff, srcYoff, srcLod, srcFace);
 }
 
 void rsdAllocationData3D_alloc(const android::renderscript::Context *rsc,
diff --git a/libs/rs/driver/rsdAllocation.h b/libs/rs/driver/rsdAllocation.h
index 7555c4a..4fc4419 100644
--- a/libs/rs/driver/rsdAllocation.h
+++ b/libs/rs/driver/rsdAllocation.h
@@ -23,6 +23,8 @@
 #include <GLES/gl.h>
 #include <GLES2/gl2.h>
 
+class RsdFrameBufferObj;
+
 struct DrvAllocation {
     // Is this a legal structure to be used as a texture source.
     // Initially this will require 1D or 2D and color data
@@ -42,8 +44,9 @@
     GLenum glType;
     GLenum glFormat;
 
-
     bool uploadDeferred;
+
+    RsdFrameBufferObj * readBackFBO;
 };
 
 GLenum rsdTypeToGLType(RsDataType t);
diff --git a/libs/rs/driver/rsdFrameBuffer.cpp b/libs/rs/driver/rsdFrameBuffer.cpp
index ce72b5d..8c1b12d 100644
--- a/libs/rs/driver/rsdFrameBuffer.cpp
+++ b/libs/rs/driver/rsdFrameBuffer.cpp
@@ -17,6 +17,7 @@
 
 #include "rsdCore.h"
 #include "rsdFrameBuffer.h"
+#include "rsdFrameBufferObj.h"
 #include "rsdAllocation.h"
 
 #include "rsContext.h"
@@ -28,133 +29,70 @@
 using namespace android;
 using namespace android::renderscript;
 
-struct DrvFrameBuffer {
-    GLuint mFBOId;
-};
-
-void checkError(const Context *rsc) {
-    GLenum status;
-    status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
-    switch (status) {
-    case GL_FRAMEBUFFER_COMPLETE:
-        break;
-    case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
-        rsc->setError(RS_ERROR_BAD_VALUE,
-                      "Unable to set up render Target: RFRAMEBUFFER_INCOMPLETE_ATTACHMENT");
-        break;
-    case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
-        rsc->setError(RS_ERROR_BAD_VALUE,
-                      "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
-        break;
-    case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
-        rsc->setError(RS_ERROR_BAD_VALUE,
-                      "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS");
-        break;
-    case GL_FRAMEBUFFER_UNSUPPORTED:
-        rsc->setError(RS_ERROR_BAD_VALUE,
-                      "Unable to set up render Target: GL_FRAMEBUFFER_UNSUPPORTED");
-        break;
-    }
-}
-
-
 void setDepthAttachment(const Context *rsc, const FBOCache *fb) {
-    if (fb->mHal.state.depthTarget.get() != NULL) {
-        DrvAllocation *drv = (DrvAllocation *)fb->mHal.state.depthTarget->mHal.drv;
+    RsdFrameBufferObj *fbo = (RsdFrameBufferObj*)fb->mHal.drv;
 
-        if (drv->textureID) {
-            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
-                                   GL_TEXTURE_2D, drv->textureID, 0);
-        } else {
-            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
-                                      GL_RENDERBUFFER, drv->renderTargetID);
+    DrvAllocation *depth = NULL;
+    if (fb->mHal.state.depthTarget.get() != NULL) {
+        depth = (DrvAllocation *)fb->mHal.state.depthTarget->mHal.drv;
+
+        if (depth->uploadDeferred) {
+            rsdAllocationSyncAll(rsc, fb->mHal.state.depthTarget.get(),
+                                 RS_ALLOCATION_USAGE_SCRIPT);
         }
-    } else {
-        // Reset last attachment
-        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
-        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
     }
+    fbo->setDepthTarget(depth);
 }
 
 void setColorAttachment(const Context *rsc, const FBOCache *fb) {
+    RsdFrameBufferObj *fbo = (RsdFrameBufferObj*)fb->mHal.drv;
     // Now attach color targets
     for (uint32_t i = 0; i < fb->mHal.state.colorTargetsCount; i ++) {
-        uint32_t texID = 0;
+        DrvAllocation *color = NULL;
         if (fb->mHal.state.colorTargets[i].get() != NULL) {
-            DrvAllocation *drv = (DrvAllocation *)fb->mHal.state.colorTargets[i]->mHal.drv;
+            color = (DrvAllocation *)fb->mHal.state.colorTargets[i]->mHal.drv;
 
-            if (drv->textureID) {
-                glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
-                                       GL_TEXTURE_2D, drv->textureID, 0);
-            } else {
-                glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
-                                          GL_RENDERBUFFER, drv->renderTargetID);
+            if (color->uploadDeferred) {
+                rsdAllocationSyncAll(rsc, fb->mHal.state.colorTargets[i].get(),
+                                     RS_ALLOCATION_USAGE_SCRIPT);
             }
-        } else {
-            // Reset last attachment
-            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
-                                      GL_RENDERBUFFER, 0);
-            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
-                                   GL_TEXTURE_2D, 0, 0);
         }
+        fbo->setColorTarget(color, i);
     }
 }
 
-bool renderToFramebuffer(const FBOCache *fb) {
-    if (fb->mHal.state.depthTarget.get() != NULL) {
-        return false;
-    }
-
-    for (uint32_t i = 0; i < fb->mHal.state.colorTargetsCount; i ++) {
-        if (fb->mHal.state.colorTargets[i].get() != NULL) {
-            return false;
-        }
-    }
-    return true;
-}
-
-
 bool rsdFrameBufferInit(const Context *rsc, const FBOCache *fb) {
-    DrvFrameBuffer *drv = (DrvFrameBuffer *)calloc(1, sizeof(DrvFrameBuffer));
-    if (drv == NULL) {
+    RsdFrameBufferObj *fbo = new RsdFrameBufferObj();
+    if (fbo == NULL) {
         return false;
     }
-    fb->mHal.drv = drv;
-    drv->mFBOId = 0;
+    fb->mHal.drv = fbo;
+
+    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
+    dc->gl.currentFrameBuffer = fbo;
 
     return true;
 }
 
 void rsdFrameBufferSetActive(const Context *rsc, const FBOCache *fb) {
-    DrvFrameBuffer *drv = (DrvFrameBuffer *)fb->mHal.drv;
+    setDepthAttachment(rsc, fb);
+    setColorAttachment(rsc, fb);
 
-    bool framebuffer = renderToFramebuffer(fb);
-    if (!framebuffer) {
-        if(drv->mFBOId == 0) {
-            glGenFramebuffers(1, &drv->mFBOId);
-        }
-        glBindFramebuffer(GL_FRAMEBUFFER, drv->mFBOId);
-
-        setDepthAttachment(rsc, fb);
-        setColorAttachment(rsc, fb);
-
-        glViewport(0, 0, fb->mHal.state.colorTargets[0]->getType()->getDimX(),
-                         fb->mHal.state.colorTargets[0]->getType()->getDimY());
-
-        checkError(rsc);
-    } else {
-        glBindFramebuffer(GL_FRAMEBUFFER, 0);
-        glViewport(0, 0, rsc->getWidth(), rsc->getHeight());
+    RsdFrameBufferObj *fbo = (RsdFrameBufferObj *)fb->mHal.drv;
+    if (fb->mHal.state.colorTargets[0].get()) {
+        fbo->setDimensions(fb->mHal.state.colorTargets[0]->getType()->getDimX(),
+                           fb->mHal.state.colorTargets[0]->getType()->getDimY());
+    } else if (fb->mHal.state.depthTarget.get()) {
+        fbo->setDimensions(fb->mHal.state.depthTarget->getType()->getDimX(),
+                           fb->mHal.state.depthTarget->getType()->getDimY());
     }
+
+    fbo->setActive(rsc);
 }
 
 void rsdFrameBufferDestroy(const Context *rsc, const FBOCache *fb) {
-    DrvFrameBuffer *drv = (DrvFrameBuffer *)fb->mHal.drv;
-    if(drv->mFBOId != 0) {
-        glDeleteFramebuffers(1, &drv->mFBOId);
-    }
-
-    free(fb->mHal.drv);
+    RsdFrameBufferObj *fbo = (RsdFrameBufferObj *)fb->mHal.drv;
+    delete fbo;
     fb->mHal.drv = NULL;
 }
 
diff --git a/libs/rs/driver/rsdFrameBufferObj.cpp b/libs/rs/driver/rsdFrameBufferObj.cpp
new file mode 100644
index 0000000..145bf34
--- /dev/null
+++ b/libs/rs/driver/rsdFrameBufferObj.cpp
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+
+#include "rsdFrameBufferObj.h"
+#include "rsdAllocation.h"
+
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+
+using namespace android;
+using namespace android::renderscript;
+
+RsdFrameBufferObj::RsdFrameBufferObj() {
+    mFBOId = 0;
+    mWidth = 0;
+    mHeight = 0;
+    mColorTargetsCount = 1;
+    mColorTargets = new DrvAllocation*[mColorTargetsCount];
+    for (uint32_t i = 0; i < mColorTargetsCount; i ++) {
+        mColorTargets[i] = 0;
+    }
+    mDepthTarget = NULL;
+    mDirty = true;
+}
+
+RsdFrameBufferObj::~RsdFrameBufferObj() {
+    if(mFBOId != 0) {
+        glDeleteFramebuffers(1, &mFBOId);
+    }
+    delete [] mColorTargets;
+}
+
+void RsdFrameBufferObj::checkError(const Context *rsc) {
+    GLenum status;
+    status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
+    switch (status) {
+    case GL_FRAMEBUFFER_COMPLETE:
+        break;
+    case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
+        rsc->setError(RS_ERROR_BAD_VALUE,
+                      "Unable to set up render Target: RFRAMEBUFFER_INCOMPLETE_ATTACHMENT");
+        break;
+    case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
+        rsc->setError(RS_ERROR_BAD_VALUE,
+                      "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
+        break;
+    case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
+        rsc->setError(RS_ERROR_BAD_VALUE,
+                      "Unable to set up render Target: GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS");
+        break;
+    case GL_FRAMEBUFFER_UNSUPPORTED:
+        rsc->setError(RS_ERROR_BAD_VALUE,
+                      "Unable to set up render Target: GL_FRAMEBUFFER_UNSUPPORTED");
+        break;
+    }
+}
+
+
+void RsdFrameBufferObj::setDepthAttachment() {
+    if (mDepthTarget != NULL) {
+        if (mDepthTarget->textureID) {
+            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+                                   GL_TEXTURE_2D, mDepthTarget->textureID, 0);
+        } else {
+            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
+                                      GL_RENDERBUFFER, mDepthTarget->renderTargetID);
+        }
+    } else {
+        // Reset last attachment
+        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0);
+        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
+    }
+}
+
+void RsdFrameBufferObj::setColorAttachment() {
+    // Now attach color targets
+    for (uint32_t i = 0; i < mColorTargetsCount; i ++) {
+        if (mColorTargets[i] != NULL) {
+            if (mColorTargets[i]->textureID) {
+                glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
+                                       GL_TEXTURE_2D, mColorTargets[i]->textureID, 0);
+            } else {
+                glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
+                                          GL_RENDERBUFFER, mColorTargets[i]->renderTargetID);
+            }
+        } else {
+            // Reset last attachment
+            glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
+                                      GL_RENDERBUFFER, 0);
+            glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + i,
+                                   GL_TEXTURE_2D, 0, 0);
+        }
+    }
+}
+
+bool RsdFrameBufferObj::renderToFramebuffer() {
+    if (mDepthTarget != NULL) {
+        return false;
+    }
+
+    for (uint32_t i = 0; i < mColorTargetsCount; i ++) {
+        if (mColorTargets[i] != NULL) {
+            return false;
+        }
+    }
+    return true;
+}
+
+void RsdFrameBufferObj::setActive(const Context *rsc) {
+    bool framebuffer = renderToFramebuffer();
+    if (!framebuffer) {
+        if(mFBOId == 0) {
+            glGenFramebuffers(1, &mFBOId);
+        }
+        glBindFramebuffer(GL_FRAMEBUFFER, mFBOId);
+
+        if (mDirty) {
+            setDepthAttachment();
+            setColorAttachment();
+            mDirty = false;
+        }
+
+        glViewport(0, 0, mWidth, mHeight);
+        checkError(rsc);
+    } else {
+        glBindFramebuffer(GL_FRAMEBUFFER, 0);
+        glViewport(0, 0, rsc->getWidth(), rsc->getHeight());
+    }
+}
diff --git a/libs/rs/driver/rsdFrameBufferObj.h b/libs/rs/driver/rsdFrameBufferObj.h
new file mode 100644
index 0000000..c6e7deb
--- /dev/null
+++ b/libs/rs/driver/rsdFrameBufferObj.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _RSD_FRAMEBUFFER_OBJ_H_
+#define _RSD_FRAMEBUFFER_OBJ_H_
+
+#include <rsContext.h>
+
+class DrvAllocation;
+
+class RsdFrameBufferObj {
+public:
+    RsdFrameBufferObj();
+    ~RsdFrameBufferObj();
+
+    void setActive(const android::renderscript::Context *rsc);
+    void setColorTarget(DrvAllocation *color, uint32_t index) {
+        mColorTargets[index] = color;
+        mDirty = true;
+    }
+    void setDepthTarget(DrvAllocation *depth) {
+        mDepthTarget = depth;
+        mDirty = true;
+    }
+    void setDimensions(uint32_t width, uint32_t height) {
+        mWidth = width;
+        mHeight = height;
+    }
+protected:
+    uint32_t mFBOId;
+    DrvAllocation **mColorTargets;
+    uint32_t mColorTargetsCount;
+    DrvAllocation *mDepthTarget;
+
+    uint32_t mWidth;
+    uint32_t mHeight;
+
+    bool mDirty;
+
+    bool renderToFramebuffer();
+    void checkError(const android::renderscript::Context *rsc);
+    void setColorAttachment();
+    void setDepthAttachment();
+};
+
+#endif //_RSD_FRAMEBUFFER_STATE_H_
diff --git a/libs/rs/driver/rsdGL.cpp b/libs/rs/driver/rsdGL.cpp
index a70589b..3ff03b4 100644
--- a/libs/rs/driver/rsdGL.cpp
+++ b/libs/rs/driver/rsdGL.cpp
@@ -39,6 +39,7 @@
 #include "rsContext.h"
 #include "rsdShaderCache.h"
 #include "rsdVertexArray.h"
+#include "rsdFrameBufferObj.h"
 
 using namespace android;
 using namespace android::renderscript;
@@ -294,6 +295,7 @@
     dc->gl.shaderCache = new RsdShaderCache();
     dc->gl.vertexArrayState = new RsdVertexArrayState();
     dc->gl.vertexArrayState->init(dc->gl.gl.maxVertexAttribs);
+    dc->gl.currentFrameBuffer = NULL;
 
     LOGV("initGLThread end %p", rsc);
     return true;
diff --git a/libs/rs/driver/rsdGL.h b/libs/rs/driver/rsdGL.h
index 01c8438..0d5b7e7 100644
--- a/libs/rs/driver/rsdGL.h
+++ b/libs/rs/driver/rsdGL.h
@@ -22,6 +22,7 @@
 
 class RsdShaderCache;
 class RsdVertexArrayState;
+class RsdFrameBufferObj;
 
 typedef void (* InvokeFunc_t)(void);
 typedef void (*WorkerCallback_t)(void *usr, uint32_t idx);
@@ -68,6 +69,7 @@
     uint32_t height;
     RsdShaderCache *shaderCache;
     RsdVertexArrayState *vertexArrayState;
+    RsdFrameBufferObj *currentFrameBuffer;
 } RsdGL;
 
 
diff --git a/libs/rs/driver/rsdMeshObj.cpp b/libs/rs/driver/rsdMeshObj.cpp
index c220ac1..4315c0d 100644
--- a/libs/rs/driver/rsdMeshObj.cpp
+++ b/libs/rs/driver/rsdMeshObj.cpp
@@ -138,7 +138,10 @@
 
     for (uint32_t ct=0; ct < mRSMesh->mHal.state.vertexBuffersCount; ct++) {
         const Allocation *alloc = mRSMesh->mHal.state.vertexBuffers[ct].get();
-        rsdAllocationSyncAll(rsc, alloc, RS_ALLOCATION_USAGE_SCRIPT);
+        DrvAllocation *drv = (DrvAllocation *)alloc->mHal.drv;
+        if (drv->uploadDeferred) {
+            rsdAllocationSyncAll(rsc, alloc, RS_ALLOCATION_USAGE_SCRIPT);
+        }
     }
 
     // update attributes with either buffer information or data ptr based on their current state
@@ -163,7 +166,9 @@
     const Allocation *idxAlloc = prim->mIndexBuffer.get();
     if (idxAlloc) {
         DrvAllocation *drvAlloc = (DrvAllocation *)idxAlloc->mHal.drv;
-        rsdAllocationSyncAll(rsc, idxAlloc, RS_ALLOCATION_USAGE_SCRIPT);
+        if (drvAlloc->uploadDeferred) {
+            rsdAllocationSyncAll(rsc, idxAlloc, RS_ALLOCATION_USAGE_SCRIPT);
+        }
 
         if (drvAlloc->bufferID) {
             glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, drvAlloc->bufferID);
diff --git a/libs/rs/driver/rsdRuntimeStubs.cpp b/libs/rs/driver/rsdRuntimeStubs.cpp
index bd8b3c3..25302aa 100644
--- a/libs/rs/driver/rsdRuntimeStubs.cpp
+++ b/libs/rs/driver/rsdRuntimeStubs.cpp
@@ -95,6 +95,8 @@
                                      Allocation *srcAlloc,
                                      uint32_t srcOff, uint32_t srcMip) {
     GET_TLS();
+    rsrAllocationCopy1DRange(rsc, dstAlloc, dstOff, dstMip, count,
+                             srcAlloc, srcOff, srcMip);
 }
 
 static void SC_AllocationCopy2DRange(Allocation *dstAlloc,
@@ -105,6 +107,11 @@
                                      uint32_t srcXoff, uint32_t srcYoff,
                                      uint32_t srcMip, uint32_t srcFace) {
     GET_TLS();
+    rsrAllocationCopy2DRange(rsc, dstAlloc,
+                             dstXoff, dstYoff, dstMip, dstFace,
+                             width, height,
+                             srcAlloc,
+                             srcXoff, srcYoff, srcMip, srcFace);
 }
 
 
diff --git a/libs/rs/rsFBOCache.cpp b/libs/rs/rsFBOCache.cpp
index 6960ef2..c5c64c2 100644
--- a/libs/rs/rsFBOCache.cpp
+++ b/libs/rs/rsFBOCache.cpp
@@ -80,16 +80,6 @@
         return;
     }
 
-    if (mHal.state.depthTarget.get() != NULL) {
-        mHal.state.depthTarget->syncAll(rsc, RS_ALLOCATION_USAGE_SCRIPT);
-    }
-
-    for (uint32_t i = 0; i < mHal.state.colorTargetsCount; i ++) {
-        if (mHal.state.colorTargets[i].get() != NULL) {
-            mHal.state.colorTargets[i]->syncAll(rsc, RS_ALLOCATION_USAGE_SCRIPT);
-        }
-    }
-
     rsc->mHal.funcs.framebuffer.setActive(rsc, this);
 
     mDirty = false;
diff --git a/media/libeffects/factory/EffectsFactory.c b/media/libeffects/factory/EffectsFactory.c
index b0e8585..a3e76d9 100644
--- a/media/libeffects/factory/EffectsFactory.c
+++ b/media/libeffects/factory/EffectsFactory.c
@@ -257,7 +257,7 @@
     }
 
     // create effect in library
-    l->desc->create_effect(uuid, sessionId, ioId, &itfe);
+    ret = l->desc->create_effect(uuid, sessionId, ioId, &itfe);
     if (ret != 0) {
         LOGW("EffectCreate() library %s: could not create fx %s, error %d", l->name, d->name, ret);
         goto exit;
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_row.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_notification_row.xml
deleted file mode 100644
index 93085d7..0000000
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_row.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="@dimen/notification_height"
-    >
-
-    <ImageButton
-        android:id="@+id/veto"
-        android:layout_width="48dp"
-        android:layout_height="match_parent"
-        android:layout_centerVertical="true"
-        android:layout_alignParentRight="true"
-        android:src="@drawable/status_bar_veto"
-        android:scaleType="center"
-        android:background="@null"
-        android:paddingRight="8dp"
-        android:paddingLeft="8dp"
-        />
-
-    <ImageView
-        android:id="@+id/large_icon"
-        android:layout_width="@android:dimen/notification_large_icon_width"
-        android:layout_height="@android:dimen/notification_large_icon_height"
-        android:layout_alignParentTop="true"
-        android:layout_alignParentLeft="true"
-        android:scaleType="center"
-        />
-
-    <com.android.systemui.statusbar.LatestItemView android:id="@+id/content"
-        android:layout_width="match_parent"
-        android:layout_height="64dp"
-        android:layout_alignParentTop="true"
-        android:layout_toRightOf="@id/large_icon"
-        android:layout_toLeftOf="@id/veto"
-        android:focusable="true"
-        android:clickable="true"
-        />
-
-    <View
-        android:layout_width="match_parent"
-        android:layout_height="1dp"
-        android:layout_alignParentBottom="true"
-        android:background="@android:drawable/divider_horizontal_dark"
-        />
-
-</RelativeLayout>
diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml
index 93085d7..aff6a6e 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml
@@ -9,6 +9,7 @@
         android:layout_height="match_parent"
         android:layout_centerVertical="true"
         android:layout_alignParentRight="true"
+        android:layout_marginRight="-80dp"
         android:src="@drawable/status_bar_veto"
         android:scaleType="center"
         android:background="@null"
@@ -30,7 +31,7 @@
         android:layout_height="64dp"
         android:layout_alignParentTop="true"
         android:layout_toRightOf="@id/large_icon"
-        android:layout_toLeftOf="@id/veto"
+        android:layout_alignParentRight="true"
         android:focusable="true"
         android:clickable="true"
         />
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index dbfbe11..d9d9c06 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -29,6 +29,8 @@
 import android.view.ViewDebug;
 import android.widget.FrameLayout;
 
+import java.text.NumberFormat;
+
 import com.android.internal.statusbar.StatusBarIcon;
 
 import com.android.systemui.R;
@@ -180,7 +182,18 @@
     }
 
     void placeNumber() {
-        final String str = mNumberText = Integer.toString(mIcon.number);
+        final String str;
+        final int tooBig = mContext.getResources().getInteger(
+                android.R.integer.status_bar_notification_info_maxnum);
+        if (mIcon.number > tooBig) {
+            str = mContext.getResources().getString(
+                        android.R.string.status_bar_notification_info_overflow);
+        } else {
+            NumberFormat f = NumberFormat.getIntegerInstance();
+            str = f.format(mIcon.number);
+        }
+        mNumberText = str;
+
         final int w = getWidth();
         final int h = getHeight();
         final Rect r = new Rect();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
index b5ea7b2..981fb24 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NotificationRowLayout.java
@@ -52,11 +52,16 @@
 
     private static final boolean ANIMATE_LAYOUT = true;
 
+    private static final boolean CLEAR_IF_SWIPED_FAR_ENOUGH = true;
+    
+    private static final boolean CONSTRAIN_SWIPE_ON_PERMANENT = true;
+
     private static final int APPEAR_ANIM_LEN = SLOW_ANIMATIONS ? 5000 : 250;
     private static final int DISAPPEAR_ANIM_LEN = APPEAR_ANIM_LEN;
     private static final int SNAP_ANIM_LEN = SLOW_ANIMATIONS ? 1000 : 250;
 
     private static final float SWIPE_ESCAPE_VELOCITY = 1500f;
+    private static final float SWIPE_ANIM_VELOCITY_MIN = 1000f;
 
     Rect mTmpRect = new Rect();
     int mNumRows = 0;
@@ -149,6 +154,21 @@
         }
         return mSlidingChild != null;
     }
+
+    protected boolean canBeCleared(View v) {
+        final View veto = v.findViewById(R.id.veto);
+        return (veto != null && veto.getVisibility() != View.GONE);
+    }
+
+    protected boolean clear(View v) {
+        final View veto = v.findViewById(R.id.veto);
+        if (veto != null && veto.getVisibility() != View.GONE) {
+            veto.performClick();
+            return true;
+        }
+        return false;
+    }
+
     @Override
     public boolean onTouchEvent(MotionEvent ev) {
         final int action = ev.getAction();
@@ -159,7 +179,13 @@
                 case MotionEvent.ACTION_MOVE:
                     mVT.addMovement(ev);
 
-                    mSlidingChild.setTranslationX(ev.getX() - mInitialTouchX);
+                    float delta = (ev.getX() - mInitialTouchX);
+                    if (CONSTRAIN_SWIPE_ON_PERMANENT && !canBeCleared(mSlidingChild)) {
+                        delta = Math.copySign(
+                                    Math.min(Math.abs(delta),
+                                    mSlidingChild.getMeasuredWidth() * 0.2f), delta);
+                    }
+                    mSlidingChild.setTranslationX(delta);
                     break;
                 case MotionEvent.ACTION_UP:
                 case MotionEvent.ACTION_CANCEL:
@@ -168,14 +194,13 @@
                     if (DEBUG) Slog.d(TAG, "exit velocity: " + mVT.getXVelocity());
                     boolean restore = true;
                     mLiftoffVelocity = mVT.getXVelocity();
-                    if (Math.abs(mLiftoffVelocity) > SWIPE_ESCAPE_VELOCITY) {
-                        // flingadingy
+                    if (Math.abs(mLiftoffVelocity) > SWIPE_ESCAPE_VELOCITY
+                        || (CLEAR_IF_SWIPED_FAR_ENOUGH && 
+                            (mSlidingChild.getTranslationX() * 2) > mSlidingChild.getMeasuredWidth()))
+                    {
 
-                        View veto = mSlidingChild.findViewById(R.id.veto);
-                        if (veto != null && veto.getVisibility() == View.VISIBLE) {
-                            veto.performClick();
-                            restore = false;
-                        }
+                        // flingadingy
+                        restore = ! clear(mSlidingChild);
                     }
                     if (restore) {
                         // snappity
@@ -230,7 +255,8 @@
             child.setPivotY(0);
 
             final float velocity = (mSlidingChild == child) 
-                    ? mLiftoffVelocity : SWIPE_ESCAPE_VELOCITY;
+                    ? Math.min(mLiftoffVelocity, SWIPE_ANIM_VELOCITY_MIN)
+                    : SWIPE_ESCAPE_VELOCITY;
             final TimeAnimator zoom = new TimeAnimator();
             zoom.setTimeListener(new TimeAnimator.TimeListener() {
                 @Override
diff --git a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
index f1da49d..ba3f344 100644
--- a/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
+++ b/packages/VpnDialogs/src/com/android/vpndialogs/ManageDialog.java
@@ -35,16 +35,16 @@
 import android.widget.ImageView;
 import android.widget.TextView;
 
+import com.android.internal.net.VpnConfig;
+
 import java.io.DataInputStream;
 import java.io.FileInputStream;
 
-public class ManageDialog extends Activity implements
+public class ManageDialog extends Activity implements Handler.Callback,
         DialogInterface.OnClickListener, DialogInterface.OnDismissListener {
     private static final String TAG = "VpnManage";
 
-    private String mPackageName;
-    private String mInterfaceName;
-    private long mStartTime;
+    private VpnConfig mConfig;
 
     private IConnectivityManager mService;
 
@@ -53,28 +53,23 @@
     private TextView mDataTransmitted;
     private TextView mDataReceived;
 
-    private Updater mUpdater;
+    private Handler mHandler;
 
     @Override
     protected void onResume() {
         super.onResume();
         try {
-            Intent intent = getIntent();
-            // TODO: Move constants into VpnBuilder.
-            mPackageName = intent.getStringExtra("packageName");
-            mInterfaceName = intent.getStringExtra("interfaceName");
-            mStartTime = intent.getLongExtra("startTime", 0);
+            mConfig = getIntent().getParcelableExtra("config");
 
             mService = IConnectivityManager.Stub.asInterface(
                     ServiceManager.getService(Context.CONNECTIVITY_SERVICE));
 
             PackageManager pm = getPackageManager();
-            ApplicationInfo app = pm.getApplicationInfo(mPackageName, 0);
+            ApplicationInfo app = pm.getApplicationInfo(mConfig.packageName, 0);
 
             View view = View.inflate(this, R.layout.manage, null);
-            String session = intent.getStringExtra("session");
-            if (session != null) {
-                ((TextView) view.findViewById(R.id.session)).setText(session);
+            if (mConfig.sessionName != null) {
+                ((TextView) view.findViewById(R.id.session)).setText(mConfig.sessionName);
             }
             mDuration = (TextView) view.findViewById(R.id.duration);
             mDataTransmitted = (TextView) view.findViewById(R.id.data_transmitted);
@@ -84,15 +79,21 @@
                     .setIcon(app.loadIcon(pm))
                     .setTitle(app.loadLabel(pm))
                     .setView(view)
-                    .setPositiveButton(R.string.configure, this)
                     .setNeutralButton(R.string.disconnect, this)
                     .setNegativeButton(android.R.string.cancel, this)
                     .create();
+
+            if (mConfig.configureActivity != null) {
+                mDialog.setButton(DialogInterface.BUTTON_POSITIVE,
+                        getText(R.string.configure), this);
+            }
             mDialog.setOnDismissListener(this);
             mDialog.show();
 
-            mUpdater = new Updater();
-            mUpdater.sendEmptyMessage(0);
+            if (mHandler == null) {
+                mHandler = new Handler(this);
+            }
+            mHandler.sendEmptyMessage(0);
         } catch (Exception e) {
             Log.e(TAG, "onResume", e);
             finish();
@@ -112,14 +113,15 @@
     public void onClick(DialogInterface dialog, int which) {
         try {
             if (which == AlertDialog.BUTTON_POSITIVE) {
-                Intent intent = new Intent(Intent.ACTION_MAIN);
-                intent.setPackage(mPackageName);
+                Intent intent = new Intent();
+                intent.setClassName(mConfig.packageName, mConfig.configureActivity);
                 startActivity(intent);
             } else if (which == AlertDialog.BUTTON_NEUTRAL) {
-                mService.prepareVpn(mPackageName);
+                mService.prepareVpn("");
             }
         } catch (Exception e) {
             Log.e(TAG, "onClick", e);
+            finish();
         }
     }
 
@@ -128,30 +130,30 @@
         finish();
     }
 
-    private class Updater extends Handler {
-        public void handleMessage(Message message) {
-            removeMessages(0);
+    @Override
+    public boolean handleMessage(Message message) {
+        mHandler.removeMessages(0);
 
-            if (mDialog.isShowing()) {
-                if (mStartTime != 0) {
-                    long seconds = (SystemClock.elapsedRealtime() - mStartTime) / 1000;
-                    mDuration.setText(String.format("%02d:%02d:%02d",
-                            seconds / 3600, seconds / 60 % 60, seconds % 60));
-                }
-
-                String[] numbers = getStatistics();
-                if (numbers != null) {
-                    // [1] and [2] are received data in bytes and packets.
-                    mDataReceived.setText(getString(R.string.data_value_format,
-                            numbers[1], numbers[2]));
-
-                    // [9] and [10] are transmitted data in bytes and packets.
-                    mDataTransmitted.setText(getString(R.string.data_value_format,
-                            numbers[9], numbers[10]));
-                }
-                sendEmptyMessageDelayed(0, 1000);
+        if (mDialog.isShowing()) {
+            if (mConfig.startTime != 0) {
+                long seconds = (SystemClock.elapsedRealtime() - mConfig.startTime) / 1000;
+                mDuration.setText(String.format("%02d:%02d:%02d",
+                        seconds / 3600, seconds / 60 % 60, seconds % 60));
             }
+
+            String[] numbers = getStatistics();
+            if (numbers != null) {
+                // [1] and [2] are received data in bytes and packets.
+                mDataReceived.setText(getString(R.string.data_value_format,
+                        numbers[1], numbers[2]));
+
+                // [9] and [10] are transmitted data in bytes and packets.
+                mDataTransmitted.setText(getString(R.string.data_value_format,
+                        numbers[9], numbers[10]));
+            }
+            mHandler.sendEmptyMessageDelayed(0, 1000);
         }
+        return true;
     }
 
     private String[] getStatistics() {
@@ -159,7 +161,7 @@
         try {
             // See dev_seq_printf_stats() in net/core/dev.c.
             in = new DataInputStream(new FileInputStream("/proc/net/dev"));
-            String prefix = mInterfaceName + ':';
+            String prefix = mConfig.interfaceName + ':';
 
             while (true) {
                 String line = in.readLine().trim();
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
index 72209f6..f385a23 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
@@ -114,7 +114,15 @@
             }
             String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE);
             if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
-                this.simState = IccCard.State.ABSENT;
+                final String absentReason = intent
+                    .getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON);
+
+                if (IccCard.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
+                        absentReason)) {
+                    this.simState = IccCard.State.PERM_DISABLED;
+                } else {
+                    this.simState = IccCard.State.ABSENT;
+                }
             } else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
                 this.simState = IccCard.State.READY;
             } else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
index 8a60098..8ba235b 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardViewMediator.java
@@ -580,7 +580,9 @@
             final boolean provisioned = mUpdateMonitor.isDeviceProvisioned();
             final IccCard.State state = mUpdateMonitor.getSimState();
             final boolean lockedOrMissing = state.isPinLocked()
-                    || ((state == IccCard.State.ABSENT) && requireSim);
+                    || ((state == IccCard.State.ABSENT
+                            || state == IccCard.State.PERM_DISABLED)
+                            && requireSim);
 
             if (!lockedOrMissing && !provisioned) {
                 if (DEBUG) Log.d(TAG, "doKeyguard: not showing because device isn't provisioned"
@@ -687,12 +689,15 @@
 
         switch (simState) {
             case ABSENT:
+            case PERM_DISABLED:
                 // only force lock screen in case of missing sim if user hasn't
                 // gone through setup wizard
                 if (!mUpdateMonitor.isDeviceProvisioned()) {
                     if (!isShowing()) {
-                        if (DEBUG) Log.d(TAG, "INTENT_VALUE_ICC_ABSENT and keygaurd isn't showing, we need "
-                             + "to show the keyguard since the device isn't provisioned yet.");
+                        if (DEBUG) Log.d(TAG, "INTENT_VALUE_ICC_ABSENT "
+                                + "or PERM_DISABLED and keygaurd isn't showing,"
+                                + " we need to show the keyguard since the "
+                                + "device isn't provisioned yet.");
                         doKeyguard();
                     } else {
                         resetStateLocked();
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
index 874acd0..eea30407 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardView.java
@@ -181,7 +181,8 @@
     private boolean stuckOnLockScreenBecauseSimMissing() {
         return mRequiresSim
                 && (!mUpdateMonitor.isDeviceProvisioned())
-                && (mUpdateMonitor.getSimState() == IccCard.State.ABSENT);
+                && (mUpdateMonitor.getSimState() == IccCard.State.ABSENT ||
+                    mUpdateMonitor.getSimState() == IccCard.State.PERM_DISABLED);
     }
 
     /**
diff --git a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java
index ed5a058..19adb3e 100644
--- a/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java
+++ b/policy/src/com/android/internal/policy/impl/LockPatternKeyguardViewProperties.java
@@ -55,8 +55,10 @@
 
     private boolean isSimPinSecure() {
         final IccCard.State simState = mUpdateMonitor.getSimState();
-        return (simState == IccCard.State.PIN_REQUIRED || simState == IccCard.State.PUK_REQUIRED
-            || simState == IccCard.State.ABSENT);
+        return (simState == IccCard.State.PIN_REQUIRED
+                || simState == IccCard.State.PUK_REQUIRED
+                || simState == IccCard.State.ABSENT
+                || simState == IccCard.State.PERM_DISABLED);
     }
 
 }
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index 08f9ebb..8b7a61e 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -129,7 +129,12 @@
         /**
          * The sim card is locked.
          */
-        SimLocked(true);
+        SimLocked(true),
+
+        /**
+         * The sim card is permanently disabled due to puk unlock failure
+         */
+        SimPermDisabled(false);
 
         private final boolean mShowStatusLines;
 
@@ -503,7 +508,9 @@
      */
     private Status getCurrentStatus(IccCard.State simState) {
         boolean missingAndNotProvisioned = (!mUpdateMonitor.isDeviceProvisioned()
-                && simState == IccCard.State.ABSENT);
+                && (simState == IccCard.State.ABSENT
+                        || simState == IccCard.State.PERM_DISABLED));
+
         if (missingAndNotProvisioned) {
             return Status.SimMissingLocked;
         }
@@ -521,6 +528,8 @@
                 return Status.SimPukLocked;
             case READY:
                 return Status.Normal;
+            case PERM_DISABLED:
+                return Status.SimPermDisabled;
             case UNKNOWN:
                 return Status.SimMissing;
         }
@@ -595,6 +604,18 @@
                 enableUnlock(); // do not need to show the e-call button; user may unlock
                 break;
 
+            case SimPermDisabled:
+                // text
+                mStatusView.setCarrierText(R.string.lockscreen_missing_sim_message_short);
+                mScreenLocked.setText(
+                        R.string.lockscreen_permanent_disabled_sim_instructions);
+
+                // layout
+                mScreenLocked.setVisibility(View.VISIBLE);
+                mLockPatternUtils.updateEmergencyCallText(mEmergencyCallText);
+                enableUnlock(); // do not need to show the e-call button; user may unlock
+                break;
+
             case SimMissingLocked:
                 // text
                 mStatusView.setCarrierText(
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 385448f..07855d9 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -16,8 +16,7 @@
 
 package com.android.server;
 
-import static android.Manifest.permission.READ_PHONE_STATE;
-import static android.Manifest.permission.UPDATE_DEVICE_STATS;
+import static android.Manifest.permission.MANAGE_NETWORK_POLICY;
 import static android.net.ConnectivityManager.isNetworkTypeValid;
 import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
 import static android.net.NetworkPolicyManager.RULE_REJECT_PAID;
@@ -1142,8 +1141,7 @@
         @Override
         public void onRulesChanged(int uid, int uidRules) {
             // only someone like NPMS should only be calling us
-            // TODO: create permission for modifying data policy
-            mContext.enforceCallingOrSelfPermission(UPDATE_DEVICE_STATS, TAG);
+            mContext.enforceCallingOrSelfPermission(MANAGE_NETWORK_POLICY, TAG);
 
             if (LOGD_RULES) {
                 Slog.d(TAG, "onRulesChanged(uid=" + uid + ", uidRules=" + uidRules + ")");
@@ -1267,8 +1265,30 @@
             }
         }
         intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION, mDefaultInetConditionPublished);
+
+        // Reset interface if no other connections are using the same interface
+        boolean doReset = true;
+        LinkProperties linkProperties = mNetTrackers[prevNetType].getLinkProperties();
+        if (linkProperties != null) {
+            String oldIface = linkProperties.getInterfaceName();
+            if (TextUtils.isEmpty(oldIface) == false) {
+                for (NetworkStateTracker networkStateTracker : mNetTrackers) {
+                    if (networkStateTracker == null) continue;
+                    NetworkInfo networkInfo = networkStateTracker.getNetworkInfo();
+                    if (networkInfo.isConnected() && networkInfo.getType() != prevNetType) {
+                        LinkProperties l = networkStateTracker.getLinkProperties();
+                        if (l == null) continue;
+                        if (oldIface.equals(l.getInterfaceName())) {
+                            doReset = false;
+                            break;
+                        }
+                    }
+                }
+            }
+        }
+
         // do this before we broadcast the change
-        handleConnectivityChange(prevNetType);
+        handleConnectivityChange(prevNetType, doReset);
 
         sendStickyBroadcast(intent);
         /*
@@ -1490,7 +1510,7 @@
         }
         thisNet.setTeardownRequested(false);
         updateNetworkSettings(thisNet);
-        handleConnectivityChange(type);
+        handleConnectivityChange(type, false);
         sendConnectedBroadcast(info);
     }
 
@@ -1500,7 +1520,7 @@
      * according to which networks are connected, and ensuring that the
      * right routing table entries exist.
      */
-    private void handleConnectivityChange(int netType) {
+    private void handleConnectivityChange(int netType, boolean doReset) {
         /*
          * If a non-default network is enabled, add the host routes that
          * will allow it's DNS servers to be accessed.
@@ -1540,6 +1560,17 @@
                 removePrivateDnsRoutes(mNetTrackers[netType]);
             }
         }
+
+        if (doReset) {
+            LinkProperties linkProperties = mNetTrackers[netType].getLinkProperties();
+            if (linkProperties != null) {
+                String iface = linkProperties.getInterfaceName();
+                if (TextUtils.isEmpty(iface) == false) {
+                    if (DBG) log("resetConnections(" + iface + ")");
+                    NetworkUtils.resetConnections(iface);
+                }
+            }
+        }
     }
 
     private void addPrivateDnsRoutes(NetworkStateTracker nt) {
@@ -1965,7 +1996,7 @@
                     break;
                 case NetworkStateTracker.EVENT_CONFIGURATION_CHANGED:
                     info = (NetworkInfo) msg.obj;
-                    handleConnectivityChange(info.getType());
+                    handleConnectivityChange(info.getType(), true);
                     break;
                 case EVENT_CLEAR_NET_TRANSITION_WAKELOCK:
                     String causedBy = null;
diff --git a/services/java/com/android/server/NetworkManagementService.java b/services/java/com/android/server/NetworkManagementService.java
index 2190b30..bb0c671 100644
--- a/services/java/com/android/server/NetworkManagementService.java
+++ b/services/java/com/android/server/NetworkManagementService.java
@@ -311,6 +311,18 @@
         }
     }
 
+    /* TODO: This is right now a IPv4 only function. Works for wifi which loses its
+       IPv6 addresses on interface down, but we need to do full clean up here */
+    public void clearInterfaceAddresses(String iface) throws IllegalStateException {
+         String cmd = String.format("interface clearaddrs %s", iface);
+        try {
+            mConnector.doCommand(cmd);
+        } catch (NativeDaemonConnectorException e) {
+            throw new IllegalStateException(
+                    "Unable to communicate with native daemon to interface clearallips - " + e);
+        }
+    }
+
     public void addRoute(String interfaceName, RouteInfo route) {
         modifyRoute(interfaceName, ADD, route);
     }
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index ec59da6..a9dfb22 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -441,6 +441,14 @@
             if (oldService != null) {
                 tryRemoveServiceLocked(oldService);
             }
+            // This API is intended for testing so enable accessibility to make
+            // sure clients can start poking with the window content.
+            Settings.Secure.putInt(mContext.getContentResolver(),
+                    Settings.Secure.ACCESSIBILITY_ENABLED, 1);
+            // Also disable all accessibility services to avoid interference
+            // with the tests.
+            Settings.Secure.putString(mContext.getContentResolver(),
+                    Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES, "");
         }
         AccessibilityServiceInfo accessibilityServiceInfo = new AccessibilityServiceInfo();
         accessibilityServiceInfo.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index f1098a8..4ec71c1 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1933,6 +1933,9 @@
             int debugFlags = 0;
             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
+                // Also turn on CheckJNI for debuggable apps. It's quite
+                // awkward to turn on otherwise.
+                debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
             }
             // Run the app in safe mode if its manifest requests so or the
             // system is booted in safe mode.
diff --git a/services/java/com/android/server/connectivity/Vpn.java b/services/java/com/android/server/connectivity/Vpn.java
index 372ba85..035a6679 100644
--- a/services/java/com/android/server/connectivity/Vpn.java
+++ b/services/java/com/android/server/connectivity/Vpn.java
@@ -18,7 +18,6 @@
 
 import android.app.Notification;
 import android.app.NotificationManager;
-import android.app.PendingIntent;
 import android.content.Context;
 import android.content.Intent;
 import android.content.pm.ApplicationInfo;
@@ -64,29 +63,40 @@
      * @return The name of the current prepared package.
      */
     public synchronized String prepare(String packageName) {
-
-        // TODO: Check if the caller is VpnDialogs.
-
+        // Return the current prepared package if the new one is null.
         if (packageName == null) {
             return mPackageName;
         }
 
-        // Check the permission of the given application.
+        // Check the permission of the caller.
         PackageManager pm = mContext.getPackageManager();
-        if (pm.checkPermission(VPN, packageName) != PackageManager.PERMISSION_GRANTED) {
+        VpnConfig.enforceCallingPackage(pm.getNameForUid(Binder.getCallingUid()));
+
+        // Check the permission of the given package.
+        if (packageName.isEmpty()) {
+            packageName = null;
+        } else if (pm.checkPermission(VPN, packageName) != PackageManager.PERMISSION_GRANTED) {
             throw new SecurityException(packageName + " does not have " + VPN);
         }
 
         // Reset the interface and hide the notification.
         if (mInterfaceName != null) {
             nativeReset(mInterfaceName);
-            mInterfaceName = null;
+            mCallback.restore();
             hideNotification();
-            // TODO: Send out a broadcast.
+            mInterfaceName = null;
         }
 
+        // Notify the package being revoked.
+        if (mPackageName != null) {
+            Intent intent = new Intent(VpnConfig.ACTION_VPN_REVOKED);
+            intent.setPackage(mPackageName);
+            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+            mContext.sendBroadcast(intent);
+        }
+
+        Log.i(TAG, "Switched from " + mPackageName + " to " + packageName);
         mPackageName = packageName;
-        Log.i(TAG, "Prepared for " + packageName);
         return mPackageName;
     }
 
@@ -118,10 +128,10 @@
         try {
             app = pm.getApplicationInfo(mPackageName, 0);
         } catch (Exception e) {
-            throw new SecurityException("Not prepared");
+            return null;
         }
         if (Binder.getCallingUid() != app.uid) {
-            throw new SecurityException("Not prepared");
+            return null;
         }
 
         // Create and configure the interface.
@@ -148,7 +158,9 @@
         String dnsServers = (config.dnsServers == null) ? "" : config.dnsServers.trim();
         mCallback.override(dnsServers.isEmpty() ? null : dnsServers.split(" "));
 
-        showNotification(pm, app, config.sessionName);
+        config.packageName = mPackageName;
+        config.interfaceName = mInterfaceName;
+        showNotification(pm, app, config);
         return descriptor;
     }
 
@@ -169,7 +181,7 @@
         }
     }
 
-    private void showNotification(PackageManager pm, ApplicationInfo app, String sessionName) {
+    private void showNotification(PackageManager pm, ApplicationInfo app, VpnConfig config) {
         NotificationManager nm = (NotificationManager)
                 mContext.getSystemService(Context.NOTIFICATION_SERVICE);
 
@@ -190,20 +202,9 @@
             // Load the label.
             String label = app.loadLabel(pm).toString();
 
-            // Build the intent.
-            // TODO: move these into VpnBuilder.
-            Intent intent = new Intent();
-            intent.setClassName("com.android.vpndialogs",
-                    "com.android.vpndialogs.ManageDialog");
-            intent.putExtra("packageName", mPackageName);
-            intent.putExtra("interfaceName", mInterfaceName);
-            intent.putExtra("session", sessionName);
-            intent.putExtra("startTime", android.os.SystemClock.elapsedRealtime());
-            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
-
             // Build the notification.
-            String text = (sessionName == null) ? mContext.getString(R.string.vpn_text) :
-                    mContext.getString(R.string.vpn_text_long, sessionName);
+            String text = (config.sessionName == null) ? mContext.getString(R.string.vpn_text) :
+                    mContext.getString(R.string.vpn_text_long, config.sessionName);
             long identity = Binder.clearCallingIdentity();
             Notification notification = new Notification.Builder(mContext)
                     .setSmallIcon(R.drawable.vpn_connected)
@@ -211,7 +212,7 @@
                     .setTicker(mContext.getString(R.string.vpn_ticker, label))
                     .setContentTitle(mContext.getString(R.string.vpn_title, label))
                     .setContentText(text)
-                    .setContentIntent(PendingIntent.getActivity(mContext, 0, intent, 0))
+                    .setContentIntent(VpnConfig.getIntentForNotification(mContext, config))
                     .setDefaults(Notification.DEFAULT_ALL)
                     .setOngoing(true)
                     .getNotification();
diff --git a/services/java/com/android/server/net/NetworkPolicyManagerService.java b/services/java/com/android/server/net/NetworkPolicyManagerService.java
index dac0044..9cbe82d 100644
--- a/services/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -747,6 +747,9 @@
 
     @Override
     public void registerListener(INetworkPolicyListener listener) {
+        // TODO: create permission for observing network policy
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+
         mListeners.register(listener);
 
         synchronized (mRulesLock) {
@@ -767,6 +770,9 @@
 
     @Override
     public void unregisterListener(INetworkPolicyListener listener) {
+        // TODO: create permission for observing network policy
+        mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+
         mListeners.unregister(listener);
     }
 
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index f762123..0a84bc7 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -225,7 +225,9 @@
         mContext.unregisterReceiver(mShutdownReceiver);
 
         writeNetworkStatsLocked();
-        writeUidStatsLocked();
+        if (mUidStatsLoaded) {
+            writeUidStatsLocked();
+        }
         mNetworkStats.clear();
         mUidStats.clear();
         mUidStatsLoaded = false;
@@ -442,7 +444,9 @@
             if (persistDelta.rx[index] > persistThreshold
                     || persistDelta.tx[index] > persistThreshold) {
                 writeNetworkStatsLocked();
-                writeUidStatsLocked();
+                if (mUidStatsLoaded) {
+                    writeUidStatsLocked();
+                }
                 mLastNetworkPersist = networkStats;
                 break;
             }
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index e1fbe1c..5a9dae9 100644
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -18,6 +18,7 @@
 
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
 
 import com.android.internal.app.IMediaContainerService;
@@ -7048,7 +7049,8 @@
             final String packageName, String className, int newState, final int flags) {
         if (!(newState == COMPONENT_ENABLED_STATE_DEFAULT
               || newState == COMPONENT_ENABLED_STATE_ENABLED
-              || newState == COMPONENT_ENABLED_STATE_DISABLED)) {
+              || newState == COMPONENT_ENABLED_STATE_DISABLED
+              || newState == COMPONENT_ENABLED_STATE_DISABLED_USER)) {
             throw new IllegalArgumentException("Invalid new component state: "
                     + newState);
         }
diff --git a/services/java/com/android/server/pm/Settings.java b/services/java/com/android/server/pm/Settings.java
index 2720bf8..5ed7988 100644
--- a/services/java/com/android/server/pm/Settings.java
+++ b/services/java/com/android/server/pm/Settings.java
@@ -18,6 +18,7 @@
 
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
+import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
 import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
 
 import com.android.internal.util.FastXmlSerializer;
@@ -1912,6 +1913,7 @@
             return false;
         }
         if (packageSettings.enabled == COMPONENT_ENABLED_STATE_DISABLED
+                || packageSettings.enabled == COMPONENT_ENABLED_STATE_DISABLED_USER
                 || (packageSettings.pkg != null && !packageSettings.pkg.applicationInfo.enabled
                         && packageSettings.enabled == COMPONENT_ENABLED_STATE_DEFAULT)) {
             return false;
diff --git a/services/jni/com_android_server_connectivity_Vpn.cpp b/services/jni/com_android_server_connectivity_Vpn.cpp
index 206df25..ae7fbfe 100644
--- a/services/jni/com_android_server_connectivity_Vpn.cpp
+++ b/services/jni/com_android_server_connectivity_Vpn.cpp
@@ -55,6 +55,7 @@
 {
     int tun = open("/dev/tun", O_RDWR);
     int inet4 = socket(AF_INET, SOCK_DGRAM, 0);
+    int flags;
 
     ifreq ifr4;
     memset(&ifr4, 0, sizeof(ifr4));
@@ -86,6 +87,13 @@
         goto error;
     }
 
+    // Make it non-blocking.
+    flags = fcntl(tun, F_GETFL, 0);
+    if (flags == -1 || fcntl(tun, F_SETFL, flags | O_NONBLOCK)) {
+        LOGE("Cannot set non-blocking on %s: %s", ifr4.ifr_name, strerror(errno));
+        goto error;
+    }
+
     strcpy(name, ifr4.ifr_name);
     *index = ifr4.ifr_ifindex;
     close(inet4);
diff --git a/services/tests/servicestests/AndroidManifest.xml b/services/tests/servicestests/AndroidManifest.xml
index 151fde7..ee5f3f5 100644
--- a/services/tests/servicestests/AndroidManifest.xml
+++ b/services/tests/servicestests/AndroidManifest.xml
@@ -28,6 +28,7 @@
     <uses-permission android:name="android.permission.MANAGE_APP_TOKENS" />
     <uses-permission android:name="android.permission.MANAGE_NETWORK_POLICY" />
     <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" />
+    <uses-permission android:name="android.permission.CONNECTIVITY_INTERNAL" />
 
     <application>
         <uses-library android:name="android.test.runner" />
diff --git a/telephony/java/com/android/internal/telephony/IccCard.java b/telephony/java/com/android/internal/telephony/IccCard.java
index 5d8fc78..02617c8 100644
--- a/telephony/java/com/android/internal/telephony/IccCard.java
+++ b/telephony/java/com/android/internal/telephony/IccCard.java
@@ -84,6 +84,9 @@
     static public final String INTENT_VALUE_LOCKED_ON_PUK = "PUK";
     /* NETWORK means ICC is locked on NETWORK PERSONALIZATION */
     static public final String INTENT_VALUE_LOCKED_NETWORK = "NETWORK";
+    /* PERM_DISABLED means ICC is permanently disabled due to puk fails */
+    static public final String INTENT_VALUE_ABSENT_ON_PERM_DISABLED = "PERM_DISABLED";
+
 
     protected static final int EVENT_ICC_LOCKED_OR_ABSENT = 1;
     private static final int EVENT_GET_ICC_STATUS_DONE = 2;
@@ -112,7 +115,8 @@
         PUK_REQUIRED,
         NETWORK_LOCKED,
         READY,
-        NOT_READY;
+        NOT_READY,
+        PERM_DISABLED;
 
         public boolean isPinLocked() {
             return ((this == PIN_REQUIRED) || (this == PUK_REQUIRED));
@@ -120,7 +124,8 @@
 
         public boolean iccCardExist() {
             return ((this == PIN_REQUIRED) || (this == PUK_REQUIRED)
-                    || (this == NETWORK_LOCKED) || (this == READY));
+                    || (this == NETWORK_LOCKED) || (this == READY)
+                    || (this == PERM_DISABLED));
         }
     }
 
@@ -416,6 +421,7 @@
         boolean transitionedIntoPinLocked;
         boolean transitionedIntoAbsent;
         boolean transitionedIntoNetworkLocked;
+        boolean transitionedIntoPermBlocked;
         boolean isIccCardRemoved;
         boolean isIccCardAdded;
 
@@ -434,6 +440,8 @@
         transitionedIntoAbsent = (oldState != State.ABSENT && newState == State.ABSENT);
         transitionedIntoNetworkLocked = (oldState != State.NETWORK_LOCKED
                 && newState == State.NETWORK_LOCKED);
+        transitionedIntoPermBlocked = (oldState != State.PERM_DISABLED
+                && newState == State.PERM_DISABLED);
         isIccCardRemoved = (oldState != null &&
                         oldState.iccCardExist() && newState == State.ABSENT);
         isIccCardAdded = (oldState == State.ABSENT &&
@@ -454,6 +462,10 @@
             mNetworkLockedRegistrants.notifyRegistrants();
             broadcastIccStateChangedIntent(INTENT_VALUE_ICC_LOCKED,
                   INTENT_VALUE_LOCKED_NETWORK);
+        } else if (transitionedIntoPermBlocked) {
+            if (mDbg) log("Notify SIM permanently disabled.");
+            broadcastIccStateChangedIntent(INTENT_VALUE_ICC_ABSENT,
+                    INTENT_VALUE_ABSENT_ON_PERM_DISABLED);
         }
 
         if (isIccCardRemoved) {
@@ -762,6 +774,9 @@
         }
 
         // check if PIN required
+        if (app.pin1.isPermBlocked()) {
+            return IccCard.State.PERM_DISABLED;
+        }
         if (app.app_state.isPinRequired()) {
             return IccCard.State.PIN_REQUIRED;
         }
diff --git a/telephony/java/com/android/internal/telephony/IccCardApplication.java b/telephony/java/com/android/internal/telephony/IccCardApplication.java
index 434c484..abb740e 100644
--- a/telephony/java/com/android/internal/telephony/IccCardApplication.java
+++ b/telephony/java/com/android/internal/telephony/IccCardApplication.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony;
 
+import com.android.internal.telephony.IccCardStatus.PinState;
+
 
 /**
  * See also RIL_AppStatus in include/telephony/ril.h
@@ -104,8 +106,8 @@
     public String         app_label;
     // applicable to USIM and CSIM
     public int            pin1_replaced;
-    public int            pin1;
-    public int            pin2;
+    public PinState            pin1;
+    public PinState            pin2;
 
     AppType AppTypeFromRILInt(int type) {
         AppType newType;
@@ -177,6 +179,33 @@
         return newSubState;
     }
 
+    PinState PinStateFromRILInt(int state) {
+        PinState newPinState;
+        switch(state) {
+            case 0:
+                newPinState = PinState.PINSTATE_UNKNOWN;
+                break;
+            case 1:
+                newPinState = PinState.PINSTATE_ENABLED_NOT_VERIFIED;
+                break;
+            case 2:
+                newPinState = PinState.PINSTATE_ENABLED_VERIFIED;
+                break;
+            case 3:
+                newPinState = PinState.PINSTATE_DISABLED;
+                break;
+            case 4:
+                newPinState = PinState.PINSTATE_ENABLED_BLOCKED;
+                break;
+            case 5:
+                newPinState = PinState.PINSTATE_ENABLED_PERM_BLOCKED;
+                break;
+            default:
+                throw new RuntimeException("Unrecognized RIL_PinState: " + state);
+        }
+        return newPinState;
+    }
+
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
@@ -185,6 +214,12 @@
         if (app_state == AppState.APPSTATE_SUBSCRIPTION_PERSO) {
             sb.append(",").append(perso_substate);
         }
+        if (app_type == AppType.APPTYPE_CSIM ||
+                app_type == AppType.APPTYPE_USIM ||
+                app_type == AppType.APPTYPE_ISIM) {
+            sb.append(",pin1=").append(pin1);
+            sb.append(",pin2=").append(pin2);
+        }
         sb.append("}");
         return sb.toString();
     }
diff --git a/telephony/java/com/android/internal/telephony/IccCardStatus.java b/telephony/java/com/android/internal/telephony/IccCardStatus.java
index e9de922..c751a21 100644
--- a/telephony/java/com/android/internal/telephony/IccCardStatus.java
+++ b/telephony/java/com/android/internal/telephony/IccCardStatus.java
@@ -42,7 +42,19 @@
         PINSTATE_ENABLED_VERIFIED,
         PINSTATE_DISABLED,
         PINSTATE_ENABLED_BLOCKED,
-        PINSTATE_ENABLED_PERM_BLOCKED
+        PINSTATE_ENABLED_PERM_BLOCKED;
+
+        boolean isPermBlocked() {
+            return this == PINSTATE_ENABLED_PERM_BLOCKED;
+        }
+
+        boolean isPinRequired() {
+            return this == PINSTATE_ENABLED_NOT_VERIFIED;
+        }
+
+        boolean isPukRequired() {
+            return this == PINSTATE_ENABLED_BLOCKED;
+        }
     }
 
     private CardState  mCardState;
diff --git a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java b/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java
index 5fef6de..9763265 100644
--- a/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java
+++ b/telephony/java/com/android/internal/telephony/IccSmsInterfaceManager.java
@@ -112,7 +112,7 @@
      */
     public void sendText(String destAddr, String scAddr,
             String text, PendingIntent sentIntent, PendingIntent deliveryIntent) {
-        mPhone.getContext().enforceCallingPermission(
+        mPhone.getContext().enforceCallingOrSelfPermission(
                 "android.permission.SEND_SMS",
                 "Sending SMS message");
         if (Log.isLoggable("SMS", Log.VERBOSE)) {
diff --git a/telephony/java/com/android/internal/telephony/RIL.java b/telephony/java/com/android/internal/telephony/RIL.java
index 572bbaa..76f1ab7 100644
--- a/telephony/java/com/android/internal/telephony/RIL.java
+++ b/telephony/java/com/android/internal/telephony/RIL.java
@@ -2924,8 +2924,8 @@
             ca.aid            = p.readString();
             ca.app_label      = p.readString();
             ca.pin1_replaced  = p.readInt();
-            ca.pin1           = p.readInt();
-            ca.pin2           = p.readInt();
+            ca.pin1           = ca.PinStateFromRILInt(p.readInt());
+            ca.pin2           = ca.PinStateFromRILInt(p.readInt());
             status.addApplication(ca);
         }
         return status;
diff --git a/tests/BiDiTests/res/layout/view_padding.xml b/tests/BiDiTests/res/layout/view_padding.xml
new file mode 100644
index 0000000..1652d04
--- /dev/null
+++ b/tests/BiDiTests/res/layout/view_padding.xml
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/view_padding"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent">
+
+    <FrameLayout android:layout_width="match_parent"
+                 android:layout_height="match_parent">
+
+        <FrameLayout
+                android:layout_width="300dp"
+                android:layout_height="300dp"
+                android:layout_gravity="top|left"
+                android:background="#FF888888"
+                android:paddingTop="20dip"
+                android:paddingLeft="40dip"
+                android:paddingBottom="30dip"
+                android:paddingRight="50dip">
+
+            <FrameLayout
+                    android:layout_width="100dp"
+                    android:layout_height="100dp"
+                    android:layout_gravity="top|left"
+                    android:background="#FF0000FF">
+            </FrameLayout>
+
+            <FrameLayout
+                    android:layout_width="100dp"
+                    android:layout_height="100dp"
+                    android:layout_gravity="bottom|right"
+                    android:background="#FF00FF00">
+            </FrameLayout>
+        </FrameLayout>
+
+        <FrameLayout
+                android:layout_width="300dp"
+                android:layout_height="300dp"
+                android:layout_gravity="top|center_horizontal"
+                android:background="#FF888888"
+                android:paddingTop="20dip"
+                android:paddingLeft="40dip"
+                android:paddingBottom="30dip"
+                android:paddingRight="50dip"
+                android:layoutDirection="inherit">
+
+            <FrameLayout
+                    android:layout_width="100dp"
+                    android:layout_height="100dp"
+                    android:layout_gravity="top|left"
+                    android:background="#FF0000FF">
+            </FrameLayout>
+
+            <FrameLayout
+                    android:layout_width="100dp"
+                    android:layout_height="100dp"
+                    android:layout_gravity="bottom|right"
+                    android:background="#FF00FF00">
+            </FrameLayout>
+        </FrameLayout>
+
+        <FrameLayout
+                android:layout_width="300dp"
+                android:layout_height="300dp"
+                android:layout_gravity="top|right"
+                android:background="#FF888888"
+                android:paddingTop="20dip"
+                android:paddingLeft="40dip"
+                android:paddingBottom="30dip"
+                android:paddingRight="50dip"
+                android:layoutDirection="ltr">
+
+            <FrameLayout
+                    android:layout_width="100dp"
+                    android:layout_height="100dp"
+                    android:layout_gravity="top|left"
+                    android:background="#FF0000FF">
+            </FrameLayout>
+
+            <FrameLayout
+                    android:layout_width="100dp"
+                    android:layout_height="100dp"
+                    android:layout_gravity="bottom|right"
+                    android:background="#FF00FF00">
+            </FrameLayout>
+        </FrameLayout>
+
+        <FrameLayout
+                android:layout_width="300dp"
+                android:layout_height="300dp"
+                android:layout_gravity="bottom|left"
+                android:background="#FF888888"
+                android:paddingTop="20dip"
+                android:paddingLeft="40dip"
+                android:paddingBottom="30dip"
+                android:paddingRight="50dip"
+                android:layoutDirection="rtl">
+
+            <FrameLayout
+                    android:layout_width="100dp"
+                    android:layout_height="100dp"
+                    android:layout_gravity="top|left"
+                    android:background="#FF0000FF">
+            </FrameLayout>
+
+            <FrameLayout
+                    android:layout_width="100dp"
+                    android:layout_height="100dp"
+                    android:layout_gravity="bottom|right"
+                    android:background="#FF00FF00">
+            </FrameLayout>
+        </FrameLayout>
+
+        <FrameLayout
+                android:layout_width="300dp"
+                android:layout_height="300dp"
+                android:layout_gravity="bottom|center_horizontal"
+                android:background="#FF888888"
+                android:paddingTop="20dip"
+                android:paddingLeft="40dip"
+                android:paddingBottom="30dip"
+                android:paddingRight="50dip"
+                android:layoutDirection="locale">
+
+            <FrameLayout
+                    android:layout_width="100dp"
+                    android:layout_height="100dp"
+                    android:layout_gravity="top|left"
+                    android:background="#FF0000FF">
+            </FrameLayout>
+
+            <FrameLayout
+                    android:layout_width="100dp"
+                    android:layout_height="100dp"
+                    android:layout_gravity="bottom|right"
+                    android:background="#FF00FF00">
+            </FrameLayout>
+        </FrameLayout>
+
+    </FrameLayout>
+
+</FrameLayout>
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java
index a3a0041..0bed7ce 100644
--- a/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestActivity.java
@@ -119,6 +119,8 @@
         addItem(result, "Table RTL", BiDiTestTableLayoutRtl.class, R.id.table_layout_rtl);
         addItem(result, "Table LOC", BiDiTestTableLayoutLocale.class, R.id.table_layout_locale);
 
+        addItem(result, "ViewPadding", BiDiTestViewPadding.class, R.id.view_padding);
+
         return result;
     }
 }
\ No newline at end of file
diff --git a/tests/BiDiTests/src/com/android/bidi/BiDiTestViewPadding.java b/tests/BiDiTests/src/com/android/bidi/BiDiTestViewPadding.java
new file mode 100644
index 0000000..6bb410a
--- /dev/null
+++ b/tests/BiDiTests/src/com/android/bidi/BiDiTestViewPadding.java
@@ -0,0 +1,17 @@
+// Copyright 2011 Google Inc. All Rights Reserved.
+package com.android.bidi;
+
+import android.app.Fragment;
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+public class BiDiTestViewPadding extends Fragment {
+
+    @Override
+    public View onCreateView(LayoutInflater inflater, ViewGroup container,
+            Bundle savedInstanceState) {
+        return inflater.inflate(R.layout.view_padding, container, false);
+    }
+}
diff --git a/tests/GridLayoutTest/res/layout/grid3.xml b/tests/GridLayoutTest/res/layout/grid3.xml
index 5cdacf7..ba911c2 100644
--- a/tests/GridLayoutTest/res/layout/grid3.xml
+++ b/tests/GridLayoutTest/res/layout/grid3.xml
@@ -21,7 +21,7 @@
         android:layout_height="match_parent"
 
         android:useDefaultMargins="true"
-        android:marginsIncludedInAlignment="false"
+        android:alignmentMode="alignBounds"
 
         android:columnCount="4"
         >
diff --git a/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java b/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java
index 32365d7..e010a00 100644
--- a/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java
+++ b/tests/GridLayoutTest/src/com/android/test/layout/Activity2.java
@@ -36,7 +36,7 @@
     public static View create(Context context) {
         GridLayout vg = new GridLayout(context);
         vg.setUseDefaultMargins(true);
-        vg.setMarginsIncludedInAlignment(false);
+        vg.setAlignmentMode(ALIGN_BOUNDS);
 
         Group row1 = new Group(1, CENTER);
         Group row2 = new Group(2, CENTER);
diff --git a/tests/RenderScriptTests/FBOTest/AndroidManifest.xml b/tests/RenderScriptTests/FBOTest/AndroidManifest.xml
index c2e0cc6..788e856 100644
--- a/tests/RenderScriptTests/FBOTest/AndroidManifest.xml
+++ b/tests/RenderScriptTests/FBOTest/AndroidManifest.xml
@@ -3,11 +3,20 @@
     package="com.android.fbotest">
     <application android:label="_FBOTest">
         <activity android:name="FBOTest"
+                  android:label="FBO Base Test"
                   android:theme="@android:style/Theme.Black.NoTitleBar">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
-        </activity>        
+        </activity>
+        <activity android:name="FBOSync"
+                  android:label="FBO Sync Test"
+                  android:theme="@android:style/Theme.Black.NoTitleBar">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
     </application>
 </manifest>
diff --git a/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/FBOSync.java b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/FBOSync.java
new file mode 100644
index 0000000..d30ad7e
--- /dev/null
+++ b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/FBOSync.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2011 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.fbotest;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScript;
+
+import android.app.Activity;
+import android.content.res.Configuration;
+import android.content.Intent;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.provider.Settings.System;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.MenuInflater;
+import android.view.Window;
+import android.widget.Button;
+import android.widget.ListView;
+import android.net.Uri;
+
+import java.lang.Runtime;
+
+public class FBOSync extends Activity {
+
+    private FBOSyncView mView;
+
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        // Create our Preview view and set it as the content of our
+        // Activity
+        mView = new FBOSyncView(this);
+        setContentView(mView);
+    }
+
+    @Override
+    protected void onResume() {
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onResume();
+        mView.resume();
+    }
+
+    @Override
+    protected void onPause() {
+        // Ideally a game should implement onResume() and onPause()
+        // to take appropriate action when the activity looses focus
+        super.onPause();
+        mView.pause();
+    }
+}
+
diff --git a/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/FBOSyncRS.java b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/FBOSyncRS.java
new file mode 100644
index 0000000..57a117c
--- /dev/null
+++ b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/FBOSyncRS.java
@@ -0,0 +1,213 @@
+/*
+ * Copyright (C) 2011 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.fbotest;
+
+import java.io.Writer;
+
+import android.content.res.Resources;
+import android.renderscript.*;
+import android.renderscript.Element.DataType;
+import android.renderscript.Element.DataKind;
+import android.renderscript.ProgramStore.DepthFunc;
+import android.renderscript.Type.Builder;
+import android.util.Log;
+
+
+public class FBOSyncRS {
+
+    public FBOSyncRS() {
+    }
+
+    public void init(RenderScriptGL rs, Resources res) {
+        mRS = rs;
+        mRes = res;
+        initRS();
+    }
+
+    public void surfaceChanged() {
+        mRS.getWidth();
+        mRS.getHeight();
+    }
+
+    private Resources mRes;
+    private RenderScriptGL mRS;
+    private Sampler mSampler;
+    private ProgramStore mPSBackground;
+    private ProgramFragment mPFBackground;
+    private ProgramVertex mPVBackground;
+    private ProgramVertexFixedFunction.Constants mPVA;
+
+    private Allocation mGridImage;
+    private Allocation mOffscreen;
+    private Allocation mOffscreenDepth;
+    private Allocation mAllocPV;
+    private Allocation mReadBackTest;
+
+    private Font mItalic;
+    private Allocation mTextAlloc;
+
+    private ScriptField_MeshInfo mMeshes;
+    private ScriptC_fbosync mScript;
+
+
+    public void onActionDown(float x, float y) {
+        mScript.invoke_onActionDown(x, y);
+    }
+
+    public void onActionScale(float scale) {
+        mScript.invoke_onActionScale(scale);
+    }
+
+    public void onActionMove(float x, float y) {
+        mScript.invoke_onActionMove(x, y);
+    }
+
+    private void initPFS() {
+        ProgramStore.Builder b = new ProgramStore.Builder(mRS);
+
+        b.setDepthFunc(ProgramStore.DepthFunc.LESS);
+        b.setDitherEnabled(false);
+        b.setDepthMaskEnabled(true);
+        mPSBackground = b.create();
+
+        mScript.set_gPFSBackground(mPSBackground);
+    }
+
+    private void initPF() {
+        Sampler.Builder bs = new Sampler.Builder(mRS);
+        bs.setMinification(Sampler.Value.LINEAR);
+        bs.setMagnification(Sampler.Value.LINEAR);
+        bs.setWrapS(Sampler.Value.CLAMP);
+        bs.setWrapT(Sampler.Value.CLAMP);
+        mSampler = bs.create();
+
+        ProgramFragmentFixedFunction.Builder b = new ProgramFragmentFixedFunction.Builder(mRS);
+        b.setTexture(ProgramFragmentFixedFunction.Builder.EnvMode.REPLACE,
+                     ProgramFragmentFixedFunction.Builder.Format.RGBA, 0);
+        mPFBackground = b.create();
+        mPFBackground.bindSampler(mSampler, 0);
+
+        mScript.set_gPFBackground(mPFBackground);
+    }
+
+    private void initPV() {
+        ProgramVertexFixedFunction.Builder pvb = new ProgramVertexFixedFunction.Builder(mRS);
+        mPVBackground = pvb.create();
+
+        mPVA = new ProgramVertexFixedFunction.Constants(mRS);
+        ((ProgramVertexFixedFunction)mPVBackground).bindConstants(mPVA);
+
+        mScript.set_gPVBackground(mPVBackground);
+    }
+
+    private void loadImage() {
+        mGridImage = Allocation.createFromBitmapResource(mRS, mRes, R.drawable.robot,
+                                                         Allocation.MipmapControl.MIPMAP_ON_SYNC_TO_TEXTURE,
+                                                         Allocation.USAGE_GRAPHICS_TEXTURE);
+        mScript.set_gTGrid(mGridImage);
+    }
+
+    private void initTextAllocation(String fileName) {
+        String allocString = "Displaying file: " + fileName;
+        mTextAlloc = Allocation.createFromString(mRS, allocString, Allocation.USAGE_SCRIPT);
+        mScript.set_gTextAlloc(mTextAlloc);
+    }
+
+    private void initMeshes(FileA3D model) {
+        int numEntries = model.getIndexEntryCount();
+        int numMeshes = 0;
+        for (int i = 0; i < numEntries; i ++) {
+            FileA3D.IndexEntry entry = model.getIndexEntry(i);
+            if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) {
+                numMeshes ++;
+            }
+        }
+
+        if (numMeshes > 0) {
+            mMeshes = new ScriptField_MeshInfo(mRS, numMeshes);
+
+            for (int i = 0; i < numEntries; i ++) {
+                FileA3D.IndexEntry entry = model.getIndexEntry(i);
+                if (entry != null && entry.getEntryType() == FileA3D.EntryType.MESH) {
+                    Mesh mesh = entry.getMesh();
+                    mMeshes.set_mMesh(i, mesh, false);
+                    mMeshes.set_mNumIndexSets(i, mesh.getPrimitiveCount(), false);
+                }
+            }
+            mMeshes.copyAll();
+        } else {
+            throw new RSRuntimeException("No valid meshes in file");
+        }
+
+        mScript.bind_gMeshes(mMeshes);
+        mScript.invoke_updateMeshInfo();
+    }
+
+    public void loadA3DFile(String path) {
+        FileA3D model = FileA3D.createFromFile(mRS, path);
+        initMeshes(model);
+        initTextAllocation(path);
+    }
+
+    private void initRS() {
+
+        mScript = new ScriptC_fbosync(mRS, mRes, R.raw.fbosync);
+
+        initPFS();
+        initPF();
+        initPV();
+
+        loadImage();
+
+        Type.Builder b = new Type.Builder(mRS, Element.RGBA_8888(mRS));
+        b.setX(512).setY(512);
+        mOffscreen = Allocation.createTyped(mRS,
+                                            b.create(),
+                                            Allocation.USAGE_SCRIPT |
+                                            Allocation.USAGE_GRAPHICS_TEXTURE |
+                                            Allocation.USAGE_GRAPHICS_RENDER_TARGET);
+        mScript.set_gOffscreen(mOffscreen);
+
+        mReadBackTest = Allocation.createTyped(mRS,
+                                               b.create(),
+                                               Allocation.USAGE_SCRIPT |
+                                               Allocation.USAGE_GRAPHICS_TEXTURE);
+        mScript.set_gReadBackTest(mReadBackTest);
+
+        b = new Type.Builder(mRS,
+                             Element.createPixel(mRS, DataType.UNSIGNED_16,
+                             DataKind.PIXEL_DEPTH));
+        b.setX(512).setY(512);
+        mOffscreenDepth = Allocation.createTyped(mRS,
+                                                 b.create(),
+                                                 Allocation.USAGE_GRAPHICS_RENDER_TARGET);
+        mScript.set_gOffscreenDepth(mOffscreenDepth);
+
+        FileA3D model = FileA3D.createFromResource(mRS, mRes, R.raw.robot);
+        initMeshes(model);
+
+        mItalic = Font.create(mRS, mRes, "serif", Font.Style.ITALIC, 8);
+        mScript.set_gItalic(mItalic);
+
+        initTextAllocation("R.raw.robot");
+
+        mRS.bindRootScript(mScript);
+    }
+}
+
+
+
diff --git a/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/FBOSyncView.java b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/FBOSyncView.java
new file mode 100644
index 0000000..6a85628
--- /dev/null
+++ b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/FBOSyncView.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2011 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.fbotest;
+
+import android.renderscript.RSSurfaceView;
+import android.renderscript.RenderScriptGL;
+
+import android.content.Context;
+import android.view.MotionEvent;
+import android.view.SurfaceHolder;
+import android.view.ScaleGestureDetector;
+import android.util.Log;
+
+public class FBOSyncView extends RSSurfaceView {
+
+    private RenderScriptGL mRS;
+    private FBOSyncRS mRender;
+
+    private ScaleGestureDetector mScaleDetector;
+
+    private static final int INVALID_POINTER_ID = -1;
+    private int mActivePointerId = INVALID_POINTER_ID;
+
+    public FBOSyncView(Context context) {
+        super(context);
+        ensureRenderScript();
+        mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
+    }
+
+    private void ensureRenderScript() {
+        if (mRS == null) {
+            RenderScriptGL.SurfaceConfig sc = new RenderScriptGL.SurfaceConfig();
+            sc.setDepth(16, 24);
+            mRS = createRenderScriptGL(sc);
+            mRender = new FBOSyncRS();
+            mRender.init(mRS, getResources());
+        }
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        ensureRenderScript();
+    }
+
+    @Override
+    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
+        super.surfaceChanged(holder, format, w, h);
+        mRender.surfaceChanged();
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        mRender = null;
+        if (mRS != null) {
+            mRS = null;
+            destroyRenderScriptGL();
+        }
+    }
+
+    public void loadA3DFile(String path) {
+        mRender.loadA3DFile(path);
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        mScaleDetector.onTouchEvent(ev);
+
+        boolean ret = false;
+        float x = ev.getX();
+        float y = ev.getY();
+
+        final int action = ev.getAction();
+
+        switch (action & MotionEvent.ACTION_MASK) {
+        case MotionEvent.ACTION_DOWN: {
+            mRender.onActionDown(x, y);
+            mActivePointerId = ev.getPointerId(0);
+            ret = true;
+            break;
+        }
+        case MotionEvent.ACTION_MOVE: {
+            if (!mScaleDetector.isInProgress()) {
+                mRender.onActionMove(x, y);
+            }
+            mRender.onActionDown(x, y);
+            ret = true;
+            break;
+        }
+
+        case MotionEvent.ACTION_UP: {
+            mActivePointerId = INVALID_POINTER_ID;
+            break;
+        }
+
+        case MotionEvent.ACTION_CANCEL: {
+            mActivePointerId = INVALID_POINTER_ID;
+            break;
+        }
+
+        case MotionEvent.ACTION_POINTER_UP: {
+            final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
+                    >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+            final int pointerId = ev.getPointerId(pointerIndex);
+            if (pointerId == mActivePointerId) {
+                // This was our active pointer going up. Choose a new
+                // active pointer and adjust accordingly.
+                final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
+                x = ev.getX(newPointerIndex);
+                y = ev.getY(newPointerIndex);
+                mRender.onActionDown(x, y);
+                mActivePointerId = ev.getPointerId(newPointerIndex);
+            }
+            break;
+        }
+        }
+
+        return ret;
+    }
+
+    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
+        @Override
+        public boolean onScale(ScaleGestureDetector detector) {
+            mRender.onActionScale(detector.getScaleFactor());
+            return true;
+        }
+    }
+}
+
+
diff --git a/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbosync.rs b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbosync.rs
new file mode 100644
index 0000000..b77ccb4
--- /dev/null
+++ b/tests/RenderScriptTests/FBOTest/src/com/android/fbotest/fbosync.rs
@@ -0,0 +1,233 @@
+// Copyright (C) 2011 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.
+
+#pragma version(1)
+
+#pragma rs java_package_name(com.android.fbotest)
+
+#include "rs_graphics.rsh"
+
+rs_program_vertex gPVBackground;
+rs_program_fragment gPFBackground;
+
+rs_allocation gTGrid;
+
+rs_program_store gPFSBackground;
+
+rs_font gItalic;
+rs_allocation gTextAlloc;
+
+rs_allocation gOffscreen;
+rs_allocation gOffscreenDepth;
+rs_allocation gReadBackTest;
+
+typedef struct MeshInfo {
+    rs_mesh mMesh;
+    int mNumIndexSets;
+    float3 bBoxMin;
+    float3 bBoxMax;
+} MeshInfo_t;
+
+MeshInfo_t *gMeshes;
+
+static float3 gLookAt;
+
+static float gRotateX;
+static float gRotateY;
+static float gZoom;
+
+static float gLastX;
+static float gLastY;
+
+void onActionDown(float x, float y) {
+    gLastX = x;
+    gLastY = y;
+}
+
+void onActionScale(float scale) {
+
+    gZoom *= 1.0f / scale;
+    gZoom = max(0.1f, min(gZoom, 500.0f));
+}
+
+void onActionMove(float x, float y) {
+    float dx = gLastX - x;
+    float dy = gLastY - y;
+
+    if (fabs(dy) <= 2.0f) {
+        dy = 0.0f;
+    }
+    if (fabs(dx) <= 2.0f) {
+        dx = 0.0f;
+    }
+
+    gRotateY -= dx;
+    if (gRotateY > 360) {
+        gRotateY -= 360;
+    }
+    if (gRotateY < 0) {
+        gRotateY += 360;
+    }
+
+    gRotateX -= dy;
+    gRotateX = min(gRotateX, 80.0f);
+    gRotateX = max(gRotateX, -80.0f);
+
+    gLastX = x;
+    gLastY = y;
+}
+
+void init() {
+    gRotateX = 0.0f;
+    gRotateY = 0.0f;
+    gZoom = 50.0f;
+    gLookAt = 0.0f;
+}
+
+void updateMeshInfo() {
+    rs_allocation allMeshes = rsGetAllocation(gMeshes);
+    int size = rsAllocationGetDimX(allMeshes);
+    gLookAt = 0.0f;
+    float minX, minY, minZ, maxX, maxY, maxZ;
+    for (int i = 0; i < size; i++) {
+        MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i);
+        rsgMeshComputeBoundingBox(info->mMesh,
+                                  &minX, &minY, &minZ,
+                                  &maxX, &maxY, &maxZ);
+        info->bBoxMin = (minX, minY, minZ);
+        info->bBoxMax = (maxX, maxY, maxZ);
+        gLookAt += (info->bBoxMin + info->bBoxMax)*0.5f;
+    }
+    gLookAt = gLookAt / (float)size;
+}
+
+static void renderAllMeshes() {
+    rs_allocation allMeshes = rsGetAllocation(gMeshes);
+    int size = rsAllocationGetDimX(allMeshes);
+    gLookAt = 0.0f;
+    float minX, minY, minZ, maxX, maxY, maxZ;
+    for (int i = 0; i < size; i++) {
+        MeshInfo_t *info = (MeshInfo_t*)rsGetElementAt(allMeshes, i);
+        rsgDrawMesh(info->mMesh);
+    }
+}
+
+static void drawDescription() {
+    uint width = rsgGetWidth();
+    uint height = rsgGetHeight();
+    int left = 0, right = 0, top = 0, bottom = 0;
+
+    rsgBindFont(gItalic);
+
+    rsgMeasureText(gTextAlloc, &left, &right, &top, &bottom);
+    rsgDrawText(gTextAlloc, 2 -left, height - 2 + bottom);
+}
+
+static void renderOffscreen(bool useDepth) {
+
+    rsgBindColorTarget(gOffscreen, 0);
+    if (useDepth) {
+        rsgBindDepthTarget(gOffscreenDepth);
+        rsgClearDepth(1.0f);
+    } else {
+        rsgClearDepthTarget();
+    }
+    rsgClearColor(0.8f, 0.0f, 0.0f, 1.0f);
+
+    rsgBindProgramVertex(gPVBackground);
+    rs_matrix4x4 proj;
+    float aspect = (float)rsAllocationGetDimX(gOffscreen) / (float)rsAllocationGetDimY(gOffscreen);
+    rsMatrixLoadPerspective(&proj, 30.0f, aspect, 1.0f, 100.0f);
+    rsgProgramVertexLoadProjectionMatrix(&proj);
+
+    rsgBindProgramFragment(gPFBackground);
+    rsgBindProgramStore(gPFSBackground);
+    rsgBindTexture(gPFBackground, 0, gTGrid);
+
+    rs_matrix4x4 matrix;
+    rsMatrixLoadIdentity(&matrix);
+    // Position our models on the screen
+    rsMatrixTranslate(&matrix, gLookAt.x, gLookAt.y, gLookAt.z - gZoom);
+    rsMatrixRotate(&matrix, gRotateX, 1.0f, 0.0f, 0.0f);
+    rsMatrixRotate(&matrix, gRotateY, 0.0f, 1.0f, 0.0f);
+    rsgProgramVertexLoadModelMatrix(&matrix);
+
+    renderAllMeshes();
+
+    // Render into the frambuffer
+    rsgClearAllRenderTargets();
+}
+
+static void drawOffscreenResult(int posX, int posY, rs_allocation texture) {
+    // display the result
+    rs_matrix4x4 proj, matrix;
+    rsMatrixLoadOrtho(&proj, 0, rsgGetWidth(), rsgGetHeight(), 0, -500, 500);
+    rsgProgramVertexLoadProjectionMatrix(&proj);
+    rsMatrixLoadIdentity(&matrix);
+    rsgProgramVertexLoadModelMatrix(&matrix);
+    rsgBindTexture(gPFBackground, 0, texture);
+    float startX = posX, startY = posY;
+    float width = 256, height = 256;
+    rsgDrawQuadTexCoords(startX, startY, 0, 0, 1,
+                         startX, startY + height, 0, 0, 0,
+                         startX + width, startY + height, 0, 1, 0,
+                         startX + width, startY, 0, 1, 1);
+}
+
+int root(void) {
+
+    rsgClearColor(1.0f, 1.0f, 1.0f, 1.0f);
+    rsgClearDepth(1.0f);
+
+    renderOffscreen(true);
+    drawOffscreenResult(0, 0, gOffscreen);
+
+
+    uint32_t w = rsAllocationGetDimX(gOffscreen);
+    uint32_t h = rsAllocationGetDimY(gOffscreen);
+    uint32_t numElements = w*h;
+
+    rsgAllocationSyncAll(gOffscreen, RS_ALLOCATION_USAGE_GRAPHICS_RENDER_TARGET);
+
+    rsAllocationCopy2DRange(gReadBackTest, 0, 0, 0,
+                            RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X, w, h,
+                            gOffscreen, 0, 0, 0, RS_ALLOCATION_CUBEMAP_FACE_POSITIVE_X);
+
+    rsgAllocationSyncAll(gReadBackTest);
+    drawOffscreenResult(0, 300, gReadBackTest);
+
+    rsgBindProgramVertex(gPVBackground);
+    rs_matrix4x4 proj;
+    float aspect = (float)rsgGetWidth() / (float)rsgGetHeight();
+    rsMatrixLoadPerspective(&proj, 30.0f, aspect, 1.0f, 100.0f);
+    rsgProgramVertexLoadProjectionMatrix(&proj);
+
+    rsgBindProgramFragment(gPFBackground);
+    rsgBindProgramStore(gPFSBackground);
+    rsgBindTexture(gPFBackground, 0, gTGrid);
+
+    rs_matrix4x4 matrix;
+    rsMatrixLoadIdentity(&matrix);
+    // Position our models on the screen
+    rsMatrixTranslate(&matrix, gLookAt.x, gLookAt.y, gLookAt.z - gZoom);
+    rsMatrixRotate(&matrix, gRotateX, 1.0f, 0.0f, 0.0f);
+    rsMatrixRotate(&matrix, gRotateY, 0.0f, 1.0f, 0.0f);
+    rsgProgramVertexLoadModelMatrix(&matrix);
+
+    renderAllMeshes();
+
+    drawDescription();
+
+    return 0;
+}
diff --git a/tests/StatusBar/res/drawable-hdpi/emo_im_kissing.png b/tests/StatusBar/res/drawable-hdpi/emo_im_kissing.png
new file mode 100644
index 0000000..0a8f0d7
--- /dev/null
+++ b/tests/StatusBar/res/drawable-hdpi/emo_im_kissing.png
Binary files differ
diff --git a/tests/StatusBar/res/drawable-hdpi/notification0.png b/tests/StatusBar/res/drawable-hdpi/notification0.png
new file mode 100644
index 0000000..6d2612e
--- /dev/null
+++ b/tests/StatusBar/res/drawable-hdpi/notification0.png
Binary files differ
diff --git a/tests/StatusBar/res/drawable-hdpi/notification1.png b/tests/StatusBar/res/drawable-hdpi/notification1.png
new file mode 100644
index 0000000..ce9009c
--- /dev/null
+++ b/tests/StatusBar/res/drawable-hdpi/notification1.png
Binary files differ
diff --git a/tests/StatusBar/res/drawable-hdpi/notification2.png b/tests/StatusBar/res/drawable-hdpi/notification2.png
new file mode 100644
index 0000000..772d70a
--- /dev/null
+++ b/tests/StatusBar/res/drawable-hdpi/notification2.png
Binary files differ
diff --git a/tests/StatusBar/res/drawable-hdpi/notification3.png b/tests/StatusBar/res/drawable-hdpi/notification3.png
new file mode 100644
index 0000000..61127ee
--- /dev/null
+++ b/tests/StatusBar/res/drawable-hdpi/notification3.png
Binary files differ
diff --git a/tests/StatusBar/res/drawable-hdpi/notification4.png b/tests/StatusBar/res/drawable-hdpi/notification4.png
new file mode 100644
index 0000000..40b7d55
--- /dev/null
+++ b/tests/StatusBar/res/drawable-hdpi/notification4.png
Binary files differ
diff --git a/tests/StatusBar/res/drawable-hdpi/notification5.png b/tests/StatusBar/res/drawable-hdpi/notification5.png
new file mode 100644
index 0000000..e89903a
--- /dev/null
+++ b/tests/StatusBar/res/drawable-hdpi/notification5.png
Binary files differ
diff --git a/tests/StatusBar/res/drawable-hdpi/notification6.png b/tests/StatusBar/res/drawable-hdpi/notification6.png
new file mode 100644
index 0000000..e0878f5
--- /dev/null
+++ b/tests/StatusBar/res/drawable-hdpi/notification6.png
Binary files differ
diff --git a/tests/StatusBar/res/drawable-hdpi/notification7.png b/tests/StatusBar/res/drawable-hdpi/notification7.png
new file mode 100644
index 0000000..49397ca
--- /dev/null
+++ b/tests/StatusBar/res/drawable-hdpi/notification7.png
Binary files differ
diff --git a/tests/StatusBar/res/drawable-hdpi/notification8.png b/tests/StatusBar/res/drawable-hdpi/notification8.png
new file mode 100644
index 0000000..763b048
--- /dev/null
+++ b/tests/StatusBar/res/drawable-hdpi/notification8.png
Binary files differ
diff --git a/tests/StatusBar/res/drawable-hdpi/notification9.png b/tests/StatusBar/res/drawable-hdpi/notification9.png
new file mode 100644
index 0000000..c3c3771
--- /dev/null
+++ b/tests/StatusBar/res/drawable-hdpi/notification9.png
Binary files differ
diff --git a/tests/StatusBar/res/drawable-hdpi/notificationx.png b/tests/StatusBar/res/drawable-hdpi/notificationx.png
new file mode 100644
index 0000000..7267286
--- /dev/null
+++ b/tests/StatusBar/res/drawable-hdpi/notificationx.png
Binary files differ
diff --git a/tests/StatusBar/res/drawable-hdpi/pineapple.png b/tests/StatusBar/res/drawable-hdpi/pineapple.png
new file mode 100644
index 0000000..e62d3c8
--- /dev/null
+++ b/tests/StatusBar/res/drawable-hdpi/pineapple.png
Binary files differ
diff --git a/tests/StatusBar/res/drawable-hdpi/pineapple2.png b/tests/StatusBar/res/drawable-hdpi/pineapple2.png
new file mode 100644
index 0000000..54146a8
--- /dev/null
+++ b/tests/StatusBar/res/drawable-hdpi/pineapple2.png
Binary files differ
diff --git a/tests/StatusBar/res/layout/notification_builder_test.xml b/tests/StatusBar/res/layout/notification_builder_test.xml
index 3c37a73..e1199c7 100644
--- a/tests/StatusBar/res/layout/notification_builder_test.xml
+++ b/tests/StatusBar/res/layout/notification_builder_test.xml
@@ -1,224 +1,220 @@
 <?xml version="1.0" encoding="utf-8"?>
-<LinearLayout
-        xmlns:android="http://schemas.android.com/apk/res/android"
+<ScrollView
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:orientation="horizontal"
-        android:paddingLeft="40dp"
-        android:paddingTop="12dp"
-        android:paddingRight="24dp"
-        android:paddingBottom="12dp"
+        xmlns:android="http://schemas.android.com/apk/res/android"
         >
-
     <LinearLayout
-            android:layout_width="220sp"
+            android:layout_width="match_parent"
             android:layout_height="match_parent"
-            android:layout_marginRight="24dp"
-            android:orientation="vertical"
+            android:orientation="horizontal"
             >
+
         <LinearLayout
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:orientation="horizontal"
+                android:layout_width="120dp"
+                android:layout_height="match_parent"
+                android:orientation="vertical"
                 >
+            <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    >
+                <Button
+                        style="@style/IdButton.Minus"
+                        android:id="@+id/clear_1"
+                        />
+                <TextView
+                        style="@style/IdTitle"
+                        android:text="1"
+                        />
+                <Button
+                        style="@style/IdButton.Plus"
+                        android:id="@+id/notify_1"
+                        />
+            </LinearLayout>
+            <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    >
+                <Button
+                        style="@style/IdButton.Minus"
+                        android:id="@+id/clear_2"
+                        />
+                <TextView
+                        style="@style/IdTitle"
+                        android:text="2"
+                        />
+                <Button
+                        style="@style/IdButton.Plus"
+                        android:id="@+id/notify_2"
+                        />
+            </LinearLayout>
+            <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    >
+                <Button
+                        style="@style/IdButton.Minus"
+                        android:id="@+id/clear_3"
+                        />
+                <TextView
+                        style="@style/IdTitle"
+                        android:text="3"
+                        />
+                <Button
+                        style="@style/IdButton.Plus"
+                        android:id="@+id/notify_3"
+                        />
+            </LinearLayout>
+            <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    >
+                <Button
+                        style="@style/IdButton.Minus"
+                        android:id="@+id/clear_4"
+                        />
+                <TextView
+                        style="@style/IdTitle"
+                        android:text="4"
+                        />
+                <Button
+                        style="@style/IdButton.Plus"
+                        android:id="@+id/notify_4"
+                        />
+            </LinearLayout>
+            <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    >
+                <Button
+                        style="@style/IdButton.Minus"
+                        android:id="@+id/clear_5"
+                        />
+                <TextView
+                        style="@style/IdTitle"
+                        android:text="5"
+                        />
+                <Button
+                        style="@style/IdButton.Plus"
+                        android:id="@+id/notify_5"
+                        />
+            </LinearLayout>
+            <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    >
+                <Button
+                        style="@style/IdButton.Minus"
+                        android:id="@+id/clear_6"
+                        />
+                <TextView
+                        style="@style/IdTitle"
+                        android:text="6"
+                        />
+                <Button
+                        style="@style/IdButton.Plus"
+                        android:id="@+id/notify_6"
+                        />
+            </LinearLayout>
+            <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    >
+                <Button
+                        style="@style/IdButton.Minus"
+                        android:id="@+id/clear_7"
+                        />
+                <TextView
+                        style="@style/IdTitle"
+                        android:text="7"
+                        />
+                <Button
+                        style="@style/IdButton.Plus"
+                        android:id="@+id/notify_7"
+                        />
+            </LinearLayout>
+            <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    >
+                <Button
+                        style="@style/IdButton.Minus"
+                        android:id="@+id/clear_8"
+                        />
+                <TextView
+                        style="@style/IdTitle"
+                        android:text="8"
+                        />
+                <Button
+                        style="@style/IdButton.Plus"
+                        android:id="@+id/notify_8"
+                        />
+            </LinearLayout>
+            <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    >
+                <Button
+                        style="@style/IdButton.Minus"
+                        android:id="@+id/clear_9"
+                        />
+                <TextView
+                        style="@style/IdTitle"
+                        android:text="9"
+                        />
+                <Button
+                        style="@style/IdButton.Plus"
+                        android:id="@+id/notify_9"
+                        />
+            </LinearLayout>
+            <LinearLayout
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:orientation="horizontal"
+                    >
+                <Button
+                        style="@style/IdButton.Minus"
+                        android:id="@+id/clear_10"
+                        />
+                <TextView
+                        style="@style/IdTitle"
+                        android:text="10"
+                        />
+                <Button
+                        style="@style/IdButton.Plus"
+                        android:id="@+id/notify_10"
+                        />
+            </LinearLayout>
+
             <Button
-                    style="@style/IdButton.Minus"
-                    android:id="@+id/clear_1"
-                    />
-            <TextView
-                    style="@style/IdTitle"
-                    android:text="1"
+                    android:id="@+id/clear_all"
+                    android:textAppearance="?android:attr/textAppearanceSmall"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:layout_marginTop="12dp"
+                    android:layout_marginBottom="12dp"
+                    android:text="Clear All"
                     />
             <Button
-                    style="@style/IdButton.Plus"
-                    android:id="@+id/notify_1"
+                    android:id="@+id/ten"
+                    android:textAppearance="?android:attr/textAppearanceSmall"
+                    android:layout_width="match_parent"
+                    android:layout_height="wrap_content"
+                    android:text="Ten notifications"
                     />
-        </LinearLayout>
-        <LinearLayout
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:orientation="horizontal"
-                >
-            <Button
-                    style="@style/IdButton.Minus"
-                    android:id="@+id/clear_2"
-                    />
-            <TextView
-                    style="@style/IdTitle"
-                    android:text="2"
-                    />
-            <Button
-                    style="@style/IdButton.Plus"
-                    android:id="@+id/notify_2"
-                    />
-        </LinearLayout>
-        <LinearLayout
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:orientation="horizontal"
-                >
-            <Button
-                    style="@style/IdButton.Minus"
-                    android:id="@+id/clear_3"
-                    />
-            <TextView
-                    style="@style/IdTitle"
-                    android:text="3"
-                    />
-            <Button
-                    style="@style/IdButton.Plus"
-                    android:id="@+id/notify_3"
-                    />
-        </LinearLayout>
-        <LinearLayout
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:orientation="horizontal"
-                >
-            <Button
-                    style="@style/IdButton.Minus"
-                    android:id="@+id/clear_4"
-                    />
-            <TextView
-                    style="@style/IdTitle"
-                    android:text="4"
-                    />
-            <Button
-                    style="@style/IdButton.Plus"
-                    android:id="@+id/notify_4"
-                    />
-        </LinearLayout>
-        <LinearLayout
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:orientation="horizontal"
-                >
-            <Button
-                    style="@style/IdButton.Minus"
-                    android:id="@+id/clear_5"
-                    />
-            <TextView
-                    style="@style/IdTitle"
-                    android:text="5"
-                    />
-            <Button
-                    style="@style/IdButton.Plus"
-                    android:id="@+id/notify_5"
-                    />
-        </LinearLayout>
-        <LinearLayout
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:orientation="horizontal"
-                >
-            <Button
-                    style="@style/IdButton.Minus"
-                    android:id="@+id/clear_6"
-                    />
-            <TextView
-                    style="@style/IdTitle"
-                    android:text="6"
-                    />
-            <Button
-                    style="@style/IdButton.Plus"
-                    android:id="@+id/notify_6"
-                    />
-        </LinearLayout>
-        <LinearLayout
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:orientation="horizontal"
-                >
-            <Button
-                    style="@style/IdButton.Minus"
-                    android:id="@+id/clear_7"
-                    />
-            <TextView
-                    style="@style/IdTitle"
-                    android:text="7"
-                    />
-            <Button
-                    style="@style/IdButton.Plus"
-                    android:id="@+id/notify_7"
-                    />
-        </LinearLayout>
-        <LinearLayout
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:orientation="horizontal"
-                >
-            <Button
-                    style="@style/IdButton.Minus"
-                    android:id="@+id/clear_8"
-                    />
-            <TextView
-                    style="@style/IdTitle"
-                    android:text="8"
-                    />
-            <Button
-                    style="@style/IdButton.Plus"
-                    android:id="@+id/notify_8"
-                    />
-        </LinearLayout>
-        <LinearLayout
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:orientation="horizontal"
-                >
-            <Button
-                    style="@style/IdButton.Minus"
-                    android:id="@+id/clear_9"
-                    />
-            <TextView
-                    style="@style/IdTitle"
-                    android:text="9"
-                    />
-            <Button
-                    style="@style/IdButton.Plus"
-                    android:id="@+id/notify_9"
-                    />
-        </LinearLayout>
-        <LinearLayout
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:orientation="horizontal"
-                >
-            <Button
-                    style="@style/IdButton.Minus"
-                    android:id="@+id/clear_10"
-                    />
-            <TextView
-                    style="@style/IdTitle"
-                    android:text="10"
-                    />
-            <Button
-                    style="@style/IdButton.Plus"
-                    android:id="@+id/notify_10"
-                    />
+                    
         </LinearLayout>
 
-        <Button
-                android:id="@+id/clear_all"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:layout_marginTop="12dp"
-                android:layout_marginBottom="12dp"
-                android:text="Clear All"
-                />
-        <Button
-                android:id="@+id/ten"
-                android:layout_width="match_parent"
-                android:layout_height="wrap_content"
-                android:text="Ten notifications"
-                />
-                
-    </LinearLayout>
-
-    <ScrollView
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_weight="1"
-            >
         <LinearLayout
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
@@ -818,7 +814,6 @@
 
 
         </LinearLayout>
-    </ScrollView>
+    </LinearLayout>
 
-
-</LinearLayout>
+</ScrollView>
diff --git a/tests/StatusBar/res/values-sw600dp/styles.xml b/tests/StatusBar/res/values-sw600dp/styles.xml
new file mode 100644
index 0000000..f29847c
--- /dev/null
+++ b/tests/StatusBar/res/values-sw600dp/styles.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<resources>
+    <style name="IdTitle">
+        <item name="android:textAppearance">?android:attr/textAppearanceLarge</item>
+        <item name="android:layout_width">30sp</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:gravity">center</item>
+        <item name="android:textStyle">bold</item>
+    </style>
+
+    <style name="IdButton">
+        <item name="android:textAppearance">?android:attr/textAppearanceLarge</item>
+        <item name="android:layout_width">0dp</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_weight">1</item>
+        <item name="android:layout_marginRight">8dp</item>
+        <item name="android:layout_marginLeft">8dp</item>
+        <item name="android:textStyle">bold</item>
+    </style>
+
+    <style name="IdButton.Minus">
+        <item name="android:text">-</item>
+    </style>
+
+    <style name="IdButton.Plus">
+        <item name="android:text">+</item>
+    </style>
+
+    <style name="FieldTitle">
+        <item name="android:textAppearance">?android:attr/textAppearanceLarge</item>
+        <item name="android:layout_width">208sp</item>
+        <item name="android:layout_height">wrap_content</item>
+    </style>
+
+    <style name="FieldContents">
+        <item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
+        <item name="android:layout_width">wrap_content</item>
+        <item name="android:layout_height">wrap_content</item>
+        <item name="android:layout_marginRight">20dp</item>
+    </style>
+
+    <style name="FieldContents.Disabled">
+        <item name="android:clickable">false</item>
+        <item name="android:visibility">gone</item>
+    </style>
+
+</resources>
+
+
diff --git a/tests/StatusBar/res/values/styles.xml b/tests/StatusBar/res/values/styles.xml
index e051efd..103a25a 100644
--- a/tests/StatusBar/res/values/styles.xml
+++ b/tests/StatusBar/res/values/styles.xml
@@ -16,21 +16,23 @@
 <resources>
 
     <style name="IdTitle">
-        <item name="android:textAppearance">?android:attr/textAppearanceLarge</item>
-        <item name="android:layout_width">30sp</item>
+        <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
+        <item name="android:layout_width">20sp</item>
         <item name="android:layout_height">wrap_content</item>
         <item name="android:gravity">center</item>
         <item name="android:textStyle">bold</item>
     </style>
 
     <style name="IdButton">
-        <item name="android:textAppearance">?android:attr/textAppearanceLarge</item>
-        <item name="android:layout_width">0dp</item>
+        <item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
+        <item name="android:layout_width">10dp</item>
         <item name="android:layout_height">wrap_content</item>
         <item name="android:layout_weight">1</item>
-        <item name="android:layout_marginRight">8dp</item>
-        <item name="android:layout_marginLeft">8dp</item>
         <item name="android:textStyle">bold</item>
+        <item name="android:layout_marginLeft">1dp</item>
+        <item name="android:layout_marginRight">1dp</item>
+        <item name="android:paddingLeft">6dp</item>
+        <item name="android:paddingRight">6dp</item>
     </style>
 
     <style name="IdButton.Minus">
@@ -42,16 +44,16 @@
     </style>
 
     <style name="FieldTitle">
-        <item name="android:textAppearance">?android:attr/textAppearanceLarge</item>
-        <item name="android:layout_width">208sp</item>
+        <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
+        <item name="android:layout_width">wrap_content</item>
         <item name="android:layout_height">wrap_content</item>
     </style>
 
     <style name="FieldContents">
-        <item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
+        <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
         <item name="android:layout_width">wrap_content</item>
         <item name="android:layout_height">wrap_content</item>
-        <item name="android:layout_marginRight">20dp</item>
+        <item name="android:layout_marginRight">4dp</item>
     </style>
 
     <style name="FieldContents.Disabled">
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 223b1fa..7852197 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -291,6 +291,27 @@
     return value.data;
 }
 
+static int32_t getResolvedIntegerAttribute(const ResTable* resTable, const ResXMLTree& tree,
+        uint32_t attrRes, String8* outError, int32_t defValue = -1)
+{
+    ssize_t idx = indexOfAttribute(tree, attrRes);
+    if (idx < 0) {
+        return defValue;
+    }
+    Res_value value;
+    if (tree.getAttributeValue(idx, &value) != NO_ERROR) {
+        if (value.dataType == Res_value::TYPE_REFERENCE) {
+            resTable->resolveReference(&value, 0);
+        }
+        if (value.dataType < Res_value::TYPE_FIRST_INT
+                || value.dataType > Res_value::TYPE_LAST_INT) {
+            if (outError != NULL) *outError = "attribute is not an integer value";
+            return defValue;
+        }
+    }
+    return value.data;
+}
+
 static String8 getResolvedAttribute(const ResTable* resTable, const ResXMLTree& tree,
         uint32_t attrRes, String8* outError)
 {
@@ -320,11 +341,12 @@
 // These are attribute resource constants for the platform, as found
 // in android.R.attr
 enum {
+    LABEL_ATTR = 0x01010001,
+    ICON_ATTR = 0x01010002,
     NAME_ATTR = 0x01010003,
     VERSION_CODE_ATTR = 0x0101021b,
     VERSION_NAME_ATTR = 0x0101021c,
-    LABEL_ATTR = 0x01010001,
-    ICON_ATTR = 0x01010002,
+    SCREEN_ORIENTATION_ATTR = 0x0101001e,
     MIN_SDK_VERSION_ATTR = 0x0101020c,
     MAX_SDK_VERSION_ATTR = 0x01010271,
     REQ_TOUCH_SCREEN_ATTR = 0x01010227,
@@ -634,6 +656,8 @@
             bool reqDistinctMultitouchFeature = false;
             bool specScreenPortraitFeature = false;
             bool specScreenLandscapeFeature = false;
+            bool reqScreenPortraitFeature = false;
+            bool reqScreenLandscapeFeature = false;
             // 2.2 also added some other features that apps can request, but that
             // have no corresponding permission, so we cannot implement any
             // back-compatibility heuristic for them. The below are thus unnecessary
@@ -1022,6 +1046,18 @@
                             fprintf(stderr, "ERROR getting 'android:icon' attribute: %s\n", error.string());
                             goto bail;
                         }
+
+                        int32_t orien = getResolvedIntegerAttribute(&res, tree,
+                                SCREEN_ORIENTATION_ATTR, &error);
+                        if (error == "") {
+                            if (orien == 0 || orien == 6 || orien == 8) {
+                                // Requests landscape, sensorLandscape, or reverseLandscape.
+                                reqScreenLandscapeFeature = true;
+                            } else if (orien == 1 || orien == 7 || orien == 9) {
+                                // Requests portrait, sensorPortrait, or reversePortrait.
+                                reqScreenPortraitFeature = true;
+                            }
+                        }
                     } else if (tag == "uses-library") {
                         String8 libraryName = getAttribute(tree, NAME_ATTR, &error);
                         if (error != "") {
@@ -1182,12 +1218,16 @@
             }
 
             // Landscape/portrait-related compatibility logic
-            if (!specScreenLandscapeFeature && !specScreenPortraitFeature && (targetSdk < 13)) {
-                // If app has not specified whether it requires portrait or landscape
-                // and is targeting an API before Honeycomb MR2, then assume it requires
-                // both.
-                printf("uses-feature:'android.hardware.screen.portrait'\n");
-                printf("uses-feature:'android.hardware.screen.landscape'\n");
+            if (!specScreenLandscapeFeature && !specScreenPortraitFeature) {
+                // If the app has specified any activities in its manifest
+                // that request a specific orientation, then assume that
+                // orientation is required.
+                if (reqScreenLandscapeFeature) {
+                    printf("uses-feature:'android.hardware.screen.landscape'\n");
+                }
+                if (reqScreenPortraitFeature) {
+                    printf("uses-feature:'android.hardware.screen.portrait'\n");
+                }
             }
 
             if (hasMainActivity) {
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 7380fc1..47fa68e 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -25,11 +25,11 @@
 import com.android.ide.common.rendering.api.StyleResourceValue;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.BridgeConstants;
+import com.android.layoutlib.bridge.impl.ParserFactory;
 import com.android.layoutlib.bridge.impl.Stack;
 import com.android.resources.ResourceType;
 import com.android.util.Pair;
 
-import org.kxml2.io.KXmlParser;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -206,6 +206,9 @@
      * @param parser the parser to add.
      */
     public void pushParser(BridgeXmlBlockParser parser) {
+        if (ParserFactory.LOG_PARSER) {
+            System.out.println("PUSH " + parser.getParser().toString());
+        }
         mParserStack.push(parser);
     }
 
@@ -213,7 +216,10 @@
      * Removes the parser at the top of the stack
      */
     public void popParser() {
-        mParserStack.pop();
+        BridgeXmlBlockParser parser = mParserStack.pop();
+        if (ParserFactory.LOG_PARSER) {
+            System.out.println("POPD " + parser.getParser().toString());
+        }
     }
 
     /**
@@ -346,9 +352,7 @@
                 // we need to create a pull parser around the layout XML file, and then
                 // give that to our XmlBlockParser
                 try {
-                    KXmlParser parser = new KXmlParser();
-                    parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
-                    parser.setInput(new FileInputStream(xml), "UTF-8"); //$NON-NLS-1$);
+                    XmlPullParser parser = ParserFactory.create(xml);
 
                     // set the resource ref to have correct view cookies
                     mBridgeInflater.setResourceReference(resource);
@@ -687,25 +691,25 @@
      */
     private BridgeTypedArray createStyleBasedTypedArray(StyleResourceValue style, int[] attrs)
             throws Resources.NotFoundException {
-        AtomicBoolean frameworkAttributes = new AtomicBoolean();
-        AtomicReference<String> attrName = new AtomicReference<String>();
-        TreeMap<Integer, String> styleNameMap = searchAttrs(attrs, frameworkAttributes, attrName);
 
         BridgeTypedArray ta = ((BridgeResources) mSystemResources).newTypeArray(attrs.length,
-                style.isFramework(), frameworkAttributes.get(), attrName.get());
+                false, true, null);
 
-        // loop through all the values in the style map, and init the TypedArray with
-        // the style we got from the dynamic id
-        for (Entry<Integer, String> styleAttribute : styleNameMap.entrySet()) {
-            int index = styleAttribute.getKey().intValue();
+        // for each attribute, get its name so that we can search it in the style
+        for (int i = 0 ; i < attrs.length ; i++) {
+            Pair<ResourceType, String> resolvedResource = Bridge.resolveResourceId(attrs[i]);
+            if (resolvedResource != null) {
+                String attrName = resolvedResource.getSecond();
+                // look for the value in the given style
+                ResourceValue resValue = mRenderResources.findItemInStyle(style, attrName);
 
-            String name = styleAttribute.getValue();
+                if (resValue != null) {
+                    // resolve it to make sure there are no references left.
+                    ta.bridgeSetValue(i, attrName, mRenderResources.resolveResValue(resValue));
 
-            // get the value from the style, or its parent styles.
-            ResourceValue resValue = mRenderResources.findItemInStyle(style, name);
-
-            // resolve it to make sure there are no references left.
-            ta.bridgeSetValue(index, name, mRenderResources.resolveResValue(resValue));
+                    resValue = mRenderResources.resolveResValue(resValue);
+                }
+            }
         }
 
         ta.sealArray();
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java
index 7c90a31..4a6393d 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java
@@ -22,10 +22,10 @@
 import com.android.ide.common.rendering.api.ResourceReference;
 import com.android.ide.common.rendering.api.ResourceValue;
 import com.android.layoutlib.bridge.Bridge;
+import com.android.layoutlib.bridge.impl.ParserFactory;
 import com.android.resources.ResourceType;
 import com.android.util.Pair;
 
-import org.kxml2.io.KXmlParser;
 import org.xmlpull.v1.XmlPullParser;
 
 import android.content.Context;
@@ -36,7 +36,6 @@
 import android.view.ViewGroup;
 
 import java.io.File;
-import java.io.FileInputStream;
 
 /**
  * Custom implementation of {@link LayoutInflater} to handle custom views.
@@ -175,9 +174,7 @@
                 File f = new File(value.getValue());
                 if (f.isFile()) {
                     try {
-                        KXmlParser parser = new KXmlParser();
-                        parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
-                        parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$
+                        XmlPullParser parser = ParserFactory.create(f);
 
                         BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(
                                 parser, bridgeContext, false);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java
index d0b90fb..1756496 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeResources.java
@@ -21,12 +21,12 @@
 import com.android.ide.common.rendering.api.ResourceValue;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.BridgeConstants;
+import com.android.layoutlib.bridge.impl.ParserFactory;
 import com.android.layoutlib.bridge.impl.ResourceHelper;
 import com.android.ninepatch.NinePatch;
 import com.android.resources.ResourceType;
 import com.android.util.Pair;
 
-import org.kxml2.io.KXmlParser;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -131,14 +131,16 @@
                 platformStyleable, styleableName);
     }
 
-    private ResourceValue getResourceValue(int id, boolean[] platformResFlag_out) {
+    private Pair<String, ResourceValue> getResourceValue(int id, boolean[] platformResFlag_out) {
         // first get the String related to this id in the framework
         Pair<ResourceType, String> resourceInfo = Bridge.resolveResourceId(id);
 
         if (resourceInfo != null) {
             platformResFlag_out[0] = true;
-            return mContext.getRenderResources().getFrameworkResource(
-                    resourceInfo.getFirst(), resourceInfo.getSecond());
+            String attributeName = resourceInfo.getSecond();
+
+            return Pair.of(attributeName, mContext.getRenderResources().getFrameworkResource(
+                    resourceInfo.getFirst(), attributeName));
         }
 
         // didn't find a match in the framework? look in the project.
@@ -147,8 +149,10 @@
 
             if (resourceInfo != null) {
                 platformResFlag_out[0] = false;
-                return mContext.getRenderResources().getProjectResource(
-                        resourceInfo.getFirst(), resourceInfo.getSecond());
+                String attributeName = resourceInfo.getSecond();
+
+                return Pair.of(attributeName, mContext.getRenderResources().getProjectResource(
+                        resourceInfo.getFirst(), attributeName));
             }
         }
 
@@ -157,10 +161,10 @@
 
     @Override
     public Drawable getDrawable(int id) throws NotFoundException {
-        ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
 
         if (value != null) {
-            return ResourceHelper.getDrawable(value, mContext);
+            return ResourceHelper.getDrawable(value.getSecond(), mContext);
         }
 
         // id was not found or not resolved. Throw a NotFoundException.
@@ -172,11 +176,11 @@
 
     @Override
     public int getColor(int id) throws NotFoundException {
-        ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
 
         if (value != null) {
             try {
-                return ResourceHelper.getColor(value.getValue());
+                return ResourceHelper.getColor(value.getSecond().getValue());
             } catch (NumberFormatException e) {
                 Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT, e.getMessage(), e,
                         null /*data*/);
@@ -193,10 +197,11 @@
 
     @Override
     public ColorStateList getColorStateList(int id) throws NotFoundException {
-        ResourceValue resValue = getResourceValue(id, mPlatformResourceFlag);
+        Pair<String, ResourceValue> resValue = getResourceValue(id, mPlatformResourceFlag);
 
         if (resValue != null) {
-            ColorStateList stateList = ResourceHelper.getColorStateList(resValue, mContext);
+            ColorStateList stateList = ResourceHelper.getColorStateList(resValue.getSecond(),
+                    mContext);
             if (stateList != null) {
                 return stateList;
             }
@@ -211,10 +216,10 @@
 
     @Override
     public CharSequence getText(int id) throws NotFoundException {
-        ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
 
         if (value != null) {
-            return value.getValue();
+            return value.getSecond().getValue();
         }
 
         // id was not found or not resolved. Throw a NotFoundException.
@@ -226,9 +231,10 @@
 
     @Override
     public XmlResourceParser getLayout(int id) throws NotFoundException {
-        ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+        Pair<String, ResourceValue> v = getResourceValue(id, mPlatformResourceFlag);
 
-        if (value != null) {
+        if (v != null) {
+            ResourceValue value = v.getSecond();
             XmlPullParser parser = null;
 
             try {
@@ -243,9 +249,7 @@
                     if (xml.isFile()) {
                         // we need to create a pull parser around the layout XML file, and then
                         // give that to our XmlBlockParser
-                        parser = new KXmlParser();
-                        parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
-                        parser.setInput(new FileInputStream(xml), "UTF-8"); //$NON-NLS-1$);
+                        parser = ParserFactory.create(xml);
                     }
                 }
 
@@ -271,9 +275,10 @@
 
     @Override
     public XmlResourceParser getAnimation(int id) throws NotFoundException {
-        ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+        Pair<String, ResourceValue> v = getResourceValue(id, mPlatformResourceFlag);
 
-        if (value != null) {
+        if (v != null) {
+            ResourceValue value = v.getSecond();
             XmlPullParser parser = null;
 
             try {
@@ -281,9 +286,7 @@
                 if (xml.isFile()) {
                     // we need to create a pull parser around the layout XML file, and then
                     // give that to our XmlBlockParser
-                    parser = new KXmlParser();
-                    parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
-                    parser.setInput(new FileInputStream(xml), "UTF-8"); //$NON-NLS-1$);
+                    parser = ParserFactory.create(xml);
 
                     return new BridgeXmlBlockParser(parser, mContext, mPlatformResourceFlag[0]);
                 }
@@ -317,10 +320,10 @@
 
     @Override
     public float getDimension(int id) throws NotFoundException {
-        ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
 
         if (value != null) {
-            String v = value.getValue();
+            String v = value.getSecond().getValue();
 
             if (v != null) {
                 if (v.equals(BridgeConstants.MATCH_PARENT) ||
@@ -330,7 +333,8 @@
                     return LayoutParams.WRAP_CONTENT;
                 }
 
-                if (ResourceHelper.stringToFloat(v, mTmpValue) &&
+                if (ResourceHelper.parseFloatAttribute(
+                        value.getFirst(), v, mTmpValue, true /*requireUnit*/) &&
                         mTmpValue.type == TypedValue.TYPE_DIMENSION) {
                     return mTmpValue.getDimension(mMetrics);
                 }
@@ -346,13 +350,14 @@
 
     @Override
     public int getDimensionPixelOffset(int id) throws NotFoundException {
-        ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
 
         if (value != null) {
-            String v = value.getValue();
+            String v = value.getSecond().getValue();
 
             if (v != null) {
-                if (ResourceHelper.stringToFloat(v, mTmpValue) &&
+                if (ResourceHelper.parseFloatAttribute(
+                        value.getFirst(), v, mTmpValue, true /*requireUnit*/) &&
                         mTmpValue.type == TypedValue.TYPE_DIMENSION) {
                     return TypedValue.complexToDimensionPixelOffset(mTmpValue.data, mMetrics);
                 }
@@ -368,13 +373,14 @@
 
     @Override
     public int getDimensionPixelSize(int id) throws NotFoundException {
-        ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
 
         if (value != null) {
-            String v = value.getValue();
+            String v = value.getSecond().getValue();
 
             if (v != null) {
-                if (ResourceHelper.stringToFloat(v, mTmpValue) &&
+                if (ResourceHelper.parseFloatAttribute(
+                        value.getFirst(), v, mTmpValue, true /*requireUnit*/) &&
                         mTmpValue.type == TypedValue.TYPE_DIMENSION) {
                     return TypedValue.complexToDimensionPixelSize(mTmpValue.data, mMetrics);
                 }
@@ -390,10 +396,10 @@
 
     @Override
     public int getInteger(int id) throws NotFoundException {
-        ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
 
-        if (value != null && value.getValue() != null) {
-            String v = value.getValue();
+        if (value != null && value.getSecond().getValue() != null) {
+            String v = value.getSecond().getValue();
             int radix = 10;
             if (v.startsWith("0x")) {
                 v = v.substring(2);
@@ -445,10 +451,10 @@
 
     @Override
     public String getString(int id) throws NotFoundException {
-        ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
 
-        if (value != null && value.getValue() != null) {
-            return value.getValue();
+        if (value != null && value.getSecond().getValue() != null) {
+            return value.getSecond().getValue();
         }
 
         // id was not found or not resolved. Throw a NotFoundException.
@@ -461,13 +467,14 @@
     @Override
     public void getValue(int id, TypedValue outValue, boolean resolveRefs)
             throws NotFoundException {
-        ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
 
         if (value != null) {
-            String v = value.getValue();
+            String v = value.getSecond().getValue();
 
             if (v != null) {
-                if (ResourceHelper.stringToFloat(v, outValue)) {
+                if (ResourceHelper.parseFloatAttribute(value.getFirst(), v, outValue,
+                        false /*requireUnit*/)) {
                     return;
                 }
 
@@ -490,19 +497,17 @@
 
     @Override
     public XmlResourceParser getXml(int id) throws NotFoundException {
-        ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
 
         if (value != null) {
-            String v = value.getValue();
+            String v = value.getSecond().getValue();
 
             if (v != null) {
                 // check this is a file
-                File f = new File(value.getValue());
+                File f = new File(v);
                 if (f.isFile()) {
                     try {
-                        KXmlParser parser = new KXmlParser();
-                        parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
-                        parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$);
+                        XmlPullParser parser = ParserFactory.create(f);
 
                         return new BridgeXmlBlockParser(parser, mContext, mPlatformResourceFlag[0]);
                     } catch (XmlPullParserException e) {
@@ -535,9 +540,7 @@
 
         File f = new File(file);
         try {
-            KXmlParser parser = new KXmlParser();
-            parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
-            parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$);
+            XmlPullParser parser = ParserFactory.create(f);
 
             return new BridgeXmlBlockParser(parser, mContext, mPlatformResourceFlag[0]);
         } catch (XmlPullParserException e) {
@@ -554,10 +557,10 @@
 
     @Override
     public InputStream openRawResource(int id) throws NotFoundException {
-        ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
+        Pair<String, ResourceValue> value = getResourceValue(id, mPlatformResourceFlag);
 
         if (value != null) {
-            String path = value.getValue();
+            String path = value.getSecond().getValue();
 
             if (path != null) {
                 // check this is a file
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
index b1fbf08..260cdc8 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeTypedArray.java
@@ -24,10 +24,10 @@
 import com.android.internal.util.XmlUtils;
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.BridgeConstants;
+import com.android.layoutlib.bridge.impl.ParserFactory;
 import com.android.layoutlib.bridge.impl.ResourceHelper;
 import com.android.resources.ResourceType;
 
-import org.kxml2.io.KXmlParser;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -41,7 +41,6 @@
 import android.view.ViewGroup.LayoutParams;
 
 import java.io.File;
-import java.io.FileInputStream;
 import java.util.Arrays;
 import java.util.Map;
 
@@ -211,7 +210,7 @@
         Map<String, Integer> map = null;
         if (mPlatformStyleable) {
             map = Bridge.getEnumValues(mNames[index]);
-        } else {
+        } else if (mStyleableName != null) {
             // get the styleable matching the resolved name
             RenderResources res = mContext.getRenderResources();
             ResourceValue styleable = res.getProjectResource(ResourceType.DECLARE_STYLEABLE,
@@ -331,9 +330,7 @@
         File f = new File(value);
         if (f.isFile()) {
             try {
-                KXmlParser parser = new KXmlParser();
-                parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
-                parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$);
+                XmlPullParser parser = ParserFactory.create(f);
 
                 BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
                         parser, mContext, resValue.isFramework());
@@ -377,26 +374,7 @@
      */
     @Override
     public int getInteger(int index, int defValue) {
-        if (mResourceData[index] == null) {
-            return defValue;
-        }
-
-        String s = mResourceData[index].getValue();
-
-        if (s != null) {
-            try {
-                return Integer.parseInt(s);
-            } catch (NumberFormatException e) {
-                Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
-                        String.format(
-                            "\"%s\" in attribute \"%2$s\" cannont be converted to an integer.",
-                            s, mNames[index]), null /*data*/);
-
-                // The default value is returned below.
-            }
-        }
-
-        return defValue;
+        return getInt(index, defValue);
     }
 
     /**
@@ -434,7 +412,7 @@
             return defValue;
         }
 
-        if (ResourceHelper.stringToFloat(s, mValue)) {
+        if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true /*requireUnit*/)) {
             return mValue.getDimension(mBridgeResources.mMetrics);
         }
 
@@ -561,7 +539,7 @@
             throw new RuntimeException();
         }
 
-        if (ResourceHelper.stringToFloat(s, mValue)) {
+        if (ResourceHelper.parseFloatAttribute(mNames[index], s, mValue, true /*requireUnit*/)) {
             float f = mValue.getDimension(mBridgeResources.mMetrics);
 
             final int res = (int)(f+0.5f);
@@ -599,14 +577,15 @@
             return defValue;
         }
 
-        if (ResourceHelper.stringToFloat(value, mValue)) {
+        if (ResourceHelper.parseFloatAttribute(mNames[index], value, mValue,
+                false /*requireUnit*/)) {
             return mValue.getFraction(base, pbase);
         }
 
         // looks like we were unable to resolve the fraction value
         Bridge.getLog().warning(LayoutLog.TAG_RESOURCES_FORMAT,
                 String.format(
-                    "\"%1$s\" in attribute \"%2$s\" cannont be converted to a fraction.",
+                    "\"%1$s\" in attribute \"%2$s\" cannot be converted to a fraction.",
                     value, mNames[index]), null /*data*/);
 
         return defValue;
@@ -803,7 +782,8 @@
 
         String s = mResourceData[index].getValue();
 
-        return ResourceHelper.stringToFloat(s, outValue);
+        return ResourceHelper.parseFloatAttribute(mNames[index], s, outValue,
+                false /*requireUnit*/);
     }
 
     /**
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
index 70dbaa4..1016b32 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
@@ -18,6 +18,7 @@
 
 
 import com.android.ide.common.rendering.api.ILayoutPullParser;
+import com.android.layoutlib.bridge.impl.ParserFactory;
 
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
@@ -54,6 +55,10 @@
      * @param platformFile Indicates whether the the file is a platform file or not.
      */
     public BridgeXmlBlockParser(XmlPullParser parser, BridgeContext context, boolean platformFile) {
+        if (ParserFactory.LOG_PARSER) {
+            System.out.println("CRTE " + parser.toString());
+        }
+
         mParser = parser;
         mContext = context;
         mPlatformFile = platformFile;
@@ -65,6 +70,10 @@
         }
     }
 
+    public XmlPullParser getParser() {
+        return mParser;
+    }
+
     public boolean isPlatformFile() {
         return mPlatformFile;
     }
@@ -247,18 +256,63 @@
     public int next() throws XmlPullParserException, IOException {
         if (!mStarted) {
             mStarted = true;
+
+            if (ParserFactory.LOG_PARSER) {
+                System.out.println("STRT " + mParser.toString());
+            }
+
             return START_DOCUMENT;
         }
+
         int ev = mParser.next();
 
+        if (ParserFactory.LOG_PARSER) {
+            System.out.println("NEXT " + mParser.toString() + " " +
+                    eventTypeToString(mEventType) + " -> " + eventTypeToString(ev));
+        }
+
         if (ev == END_TAG && mParser.getDepth() == 1) {
             // done with parser remove it from the context stack.
             ensurePopped();
+
+            if (ParserFactory.LOG_PARSER) {
+                System.out.println("");
+            }
         }
+
         mEventType = ev;
         return ev;
     }
 
+    public static String eventTypeToString(int eventType) {
+        switch (eventType) {
+            case START_DOCUMENT:
+                return "START_DOC";
+            case END_DOCUMENT:
+                return "END_DOC";
+            case START_TAG:
+                return "START_TAG";
+            case END_TAG:
+                return "END_TAG";
+            case TEXT:
+                return "TEXT";
+            case CDSECT:
+                return "CDSECT";
+            case ENTITY_REF:
+                return "ENTITY_REF";
+            case IGNORABLE_WHITESPACE:
+                return "IGNORABLE_WHITESPACE";
+            case PROCESSING_INSTRUCTION:
+                return "PROCESSING_INSTRUCTION";
+            case COMMENT:
+                return "COMMENT";
+            case DOCDECL:
+                return "DOCDECL";
+        }
+
+        return "????";
+    }
+
     public void require(int type, String namespace, String name)
             throws XmlPullParserException {
         if (type != getEventType()
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
index 060e6ee..df701d5 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/CustomBar.java
@@ -22,11 +22,11 @@
 import com.android.layoutlib.bridge.Bridge;
 import com.android.layoutlib.bridge.android.BridgeContext;
 import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
+import com.android.layoutlib.bridge.impl.ParserFactory;
 import com.android.layoutlib.bridge.impl.ResourceHelper;
 import com.android.resources.Density;
 import com.android.resources.ResourceType;
 
-import org.kxml2.io.KXmlParser;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -60,7 +60,7 @@
 
     protected abstract TextView getStyleableTextView();
 
-    protected CustomBar(Context context, Density density, String layoutPath)
+    protected CustomBar(Context context, Density density, String layoutPath, String name)
             throws XmlPullParserException {
         super(context);
         setOrientation(LinearLayout.HORIZONTAL);
@@ -69,11 +69,8 @@
         LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
                 Context.LAYOUT_INFLATER_SERVICE);
 
-        KXmlParser parser = new KXmlParser();
-        parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
-        parser.setInput(
-                getClass().getResourceAsStream(layoutPath),
-                "UTF8"); //$NON-NLS-1$
+        XmlPullParser parser = ParserFactory.create(getClass().getResourceAsStream(layoutPath),
+                name);
 
         BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(
                 parser, (BridgeContext) context, false /*platformFile*/);
@@ -230,7 +227,8 @@
 
                 if (textSize != null) {
                     TypedValue out = new TypedValue();
-                    if (ResourceHelper.stringToFloat(textSize.getValue(), out)) {
+                    if (ResourceHelper.parseFloatAttribute("textSize", textSize.getValue(), out,
+                            true /*requireUnit*/)) {
                         textView.setTextSize(
                                 out.getDimension(bridgeContext.getResources().mMetrics));
                     }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java
index 3af4e3a..f6edea4 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/FakeActionBar.java
@@ -29,7 +29,7 @@
 
     public FakeActionBar(Context context, Density density, String label, String icon)
             throws XmlPullParserException {
-        super(context, density, "/bars/action_bar.xml");
+        super(context, density, "/bars/action_bar.xml", "action_bar.xml");
 
         // Cannot access the inside items through id because no R.id values have been
         // created for them.
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java
index 9fab51a..5569e06 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/PhoneSystemBar.java
@@ -30,7 +30,7 @@
 public class PhoneSystemBar extends CustomBar {
 
     public PhoneSystemBar(Context context, Density density) throws XmlPullParserException {
-        super(context, density, "/bars/phone_system_bar.xml");
+        super(context, density, "/bars/phone_system_bar.xml", "phone_system_bar.xml");
 
         setGravity(mGravity | Gravity.RIGHT);
         setBackgroundColor(0xFF000000);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TabletSystemBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TabletSystemBar.java
index 5ca68fa..456ddb4 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TabletSystemBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TabletSystemBar.java
@@ -29,7 +29,7 @@
 public class TabletSystemBar extends CustomBar {
 
     public TabletSystemBar(Context context, Density density) throws XmlPullParserException {
-        super(context, density, "/bars/tablet_system_bar.xml");
+        super(context, density, "/bars/tablet_system_bar.xml", "tablet_system_bar.xml");
 
         setBackgroundColor(0xFF000000);
 
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
index d7401d9..5f5ebc4 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/bars/TitleBar.java
@@ -29,7 +29,7 @@
 
     public TitleBar(Context context, Density density, String label)
             throws XmlPullParserException {
-        super(context, density, "/bars/title_bar.xml");
+        super(context, density, "/bars/title_bar.xml", "title_bar.xml");
 
         // Cannot access the inside items through id because no R.id values have been
         // created for them.
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java
new file mode 100644
index 0000000..a235ec3
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ParserFactory.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2011 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.layoutlib.bridge.impl;
+
+
+import org.kxml2.io.KXmlParser;
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.InputStream;
+
+/**
+ * A factory for {@link XmlPullParser}.
+ *
+ */
+public class ParserFactory {
+
+    private final static String ENCODING = "UTF-8"; //$NON-NLS-1$
+
+    public final static boolean LOG_PARSER = false;
+
+    public static XmlPullParser create(File f)
+            throws XmlPullParserException, FileNotFoundException {
+        KXmlParser parser = instantiateParser(f.getName());
+        parser.setInput(new FileInputStream(f), ENCODING);
+        return parser;
+    }
+
+    public static XmlPullParser create(InputStream stream, String name)
+            throws XmlPullParserException {
+        KXmlParser parser = instantiateParser(name);
+        parser.setInput(stream, ENCODING);
+        return parser;
+    }
+
+    private static KXmlParser instantiateParser(String name) throws XmlPullParserException {
+        KXmlParser parser;
+        if (name != null) {
+            parser = new CustomParser(name);
+        } else {
+            parser = new KXmlParser();
+        }
+        parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
+        return parser;
+    }
+
+    private static class CustomParser extends KXmlParser {
+        private final String mName;
+
+        CustomParser(String name) {
+            super();
+            mName = name;
+        }
+
+        @Override
+        public String toString() {
+            return mName;
+        }
+    }
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index b800519..aa30e29 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -984,7 +984,8 @@
                         "status_bar_height");
 
                 if (value != null) {
-                    TypedValue typedValue = ResourceHelper.getValue(value.getValue());
+                    TypedValue typedValue = ResourceHelper.getValue("status_bar_height",
+                            value.getValue(), true /*requireUnit*/);
                     if (typedValue != null) {
                         // compute the pixel value based on the display metrics
                         mStatusBarSize = (int)typedValue.getDimension(metrics);
@@ -1016,7 +1017,8 @@
 
             if (value != null) {
                 // get the numerical value, if available
-                TypedValue typedValue = ResourceHelper.getValue(value.getValue());
+                TypedValue typedValue = ResourceHelper.getValue("actionBarSize", value.getValue(),
+                        true /*requireUnit*/);
                 if (typedValue != null) {
                     // compute the pixel value based on the display metrics
                     mActionBarSize = (int)typedValue.getDimension(metrics);
@@ -1040,7 +1042,8 @@
 
                 if (value != null) {
                     // get the numerical value, if available
-                    TypedValue typedValue = ResourceHelper.getValue(value.getValue());
+                    TypedValue typedValue = ResourceHelper.getValue("windowTitleSize",
+                            value.getValue(), true /*requireUnit*/);
                     if (typedValue != null) {
                         // compute the pixel value based on the display metrics
                         mTitleBarSize = (int)typedValue.getDimension(metrics);
@@ -1062,7 +1065,8 @@
                     "status_bar_height");
 
             if (value != null) {
-                TypedValue typedValue = ResourceHelper.getValue(value.getValue());
+                TypedValue typedValue = ResourceHelper.getValue("status_bar_height",
+                        value.getValue(), true /*requireUnit*/);
                 if (typedValue != null) {
                     // compute the pixel value based on the display metrics
                     mSystemBarSize = (int)typedValue.getDimension(metrics);
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
index e5efa4e..6dcb693 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/ResourceHelper.java
@@ -27,7 +27,6 @@
 import com.android.ninepatch.NinePatchChunk;
 import com.android.resources.Density;
 
-import org.kxml2.io.KXmlParser;
 import org.xmlpull.v1.XmlPullParser;
 import org.xmlpull.v1.XmlPullParserException;
 
@@ -121,9 +120,7 @@
                 try {
                     // let the framework inflate the ColorStateList from the XML file, by
                     // providing an XmlPullParser
-                    KXmlParser parser = new KXmlParser();
-                    parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
-                    parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$);
+                    XmlPullParser parser = ParserFactory.create(f);
 
                     BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
                             parser, context, resValue.isFramework());
@@ -203,9 +200,7 @@
             if (f.isFile()) {
                 try {
                     // let the framework inflate the Drawable from the XML file.
-                    KXmlParser parser = new KXmlParser();
-                    parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
-                    parser.setInput(new FileInputStream(f), "UTF-8"); //$NON-NLS-1$);
+                    XmlPullParser parser = ParserFactory.create(f);
 
                     BridgeXmlBlockParser blockParser = new BridgeXmlBlockParser(
                             parser, context, value.isFramework());
@@ -341,11 +336,11 @@
     };
 
     /**
-     * Returns the raw value from the given string.
+     * Returns the raw value from the given attribute float-type value string.
      * This object is only valid until the next call on to {@link ResourceHelper}.
      */
-    public static TypedValue getValue(String s) {
-        if (stringToFloat(s, mValue)) {
+    public static TypedValue getValue(String attribute, String value, boolean requireUnit) {
+        if (parseFloatAttribute(attribute, value, mValue, requireUnit)) {
             return mValue;
         }
 
@@ -353,22 +348,27 @@
     }
 
     /**
-     * Convert the string into a {@link TypedValue}.
-     * @param s
-     * @param outValue
+     * Parse a float attribute and return the parsed value into a given TypedValue.
+     * @param attribute the name of the attribute. Can be null if <var>requireUnit</var> is false.
+     * @param value the string value of the attribute
+     * @param outValue the TypedValue to receive the parsed value
+     * @param requireUnit whether the value is expected to contain a unit.
      * @return true if success.
      */
-    public static boolean stringToFloat(String s, TypedValue outValue) {
+    public static boolean parseFloatAttribute(String attribute, String value,
+            TypedValue outValue, boolean requireUnit) {
+        assert requireUnit == false || attribute != null;
+
         // remove the space before and after
-        s = s.trim();
-        int len = s.length();
+        value = value.trim();
+        int len = value.length();
 
         if (len <= 0) {
             return false;
         }
 
         // check that there's no non ascii characters.
-        char[] buf = s.toCharArray();
+        char[] buf = value.toCharArray();
         for (int i = 0 ; i < len ; i++) {
             if (buf[i] > 255) {
                 return false;
@@ -381,7 +381,7 @@
         }
 
         // now look for the string that is after the float...
-        Matcher m = sFloatPattern.matcher(s);
+        Matcher m = sFloatPattern.matcher(value);
         if (m.matches()) {
             String f_str = m.group(1);
             String end = m.group(2);
@@ -397,45 +397,7 @@
             if (end.length() > 0 && end.charAt(0) != ' ') {
                 // Might be a unit...
                 if (parseUnit(end, outValue, sFloatOut)) {
-
-                    f *= sFloatOut[0];
-                    boolean neg = f < 0;
-                    if (neg) {
-                        f = -f;
-                    }
-                    long bits = (long)(f*(1<<23)+.5f);
-                    int radix;
-                    int shift;
-                    if ((bits&0x7fffff) == 0) {
-                        // Always use 23p0 if there is no fraction, just to make
-                        // things easier to read.
-                        radix = TypedValue.COMPLEX_RADIX_23p0;
-                        shift = 23;
-                    } else if ((bits&0xffffffffff800000L) == 0) {
-                        // Magnitude is zero -- can fit in 0 bits of precision.
-                        radix = TypedValue.COMPLEX_RADIX_0p23;
-                        shift = 0;
-                    } else if ((bits&0xffffffff80000000L) == 0) {
-                        // Magnitude can fit in 8 bits of precision.
-                        radix = TypedValue.COMPLEX_RADIX_8p15;
-                        shift = 8;
-                    } else if ((bits&0xffffff8000000000L) == 0) {
-                        // Magnitude can fit in 16 bits of precision.
-                        radix = TypedValue.COMPLEX_RADIX_16p7;
-                        shift = 16;
-                    } else {
-                        // Magnitude needs entire range, so no fractional part.
-                        radix = TypedValue.COMPLEX_RADIX_23p0;
-                        shift = 23;
-                    }
-                    int mantissa = (int)(
-                        (bits>>shift) & TypedValue.COMPLEX_MANTISSA_MASK);
-                    if (neg) {
-                        mantissa = (-mantissa) & TypedValue.COMPLEX_MANTISSA_MASK;
-                    }
-                    outValue.data |=
-                        (radix<<TypedValue.COMPLEX_RADIX_SHIFT)
-                        | (mantissa<<TypedValue.COMPLEX_MANTISSA_SHIFT);
+                    computeTypedValue(outValue, f, sFloatOut[0]);
                     return true;
                 }
                 return false;
@@ -446,8 +408,20 @@
 
             if (end.length() == 0) {
                 if (outValue != null) {
-                    outValue.type = TypedValue.TYPE_FLOAT;
-                    outValue.data = Float.floatToIntBits(f);
+                    if (requireUnit == false) {
+                        outValue.type = TypedValue.TYPE_FLOAT;
+                        outValue.data = Float.floatToIntBits(f);
+                    } else {
+                        // no unit when required? Use dp and out an error.
+                        applyUnit(sUnitNames[1], outValue, sFloatOut);
+                        computeTypedValue(outValue, f, sFloatOut[0]);
+
+                        Bridge.getLog().error(LayoutLog.TAG_RESOURCES_RESOLVE,
+                                String.format(
+                                        "Dimension \"%1$s\" in attribute \"%2$s\" is missing unit!",
+                                        value, attribute),
+                                null);
+                    }
                     return true;
                 }
             }
@@ -456,20 +430,64 @@
         return false;
     }
 
+    private static void computeTypedValue(TypedValue outValue, float value, float scale) {
+        value *= scale;
+        boolean neg = value < 0;
+        if (neg) {
+            value = -value;
+        }
+        long bits = (long)(value*(1<<23)+.5f);
+        int radix;
+        int shift;
+        if ((bits&0x7fffff) == 0) {
+            // Always use 23p0 if there is no fraction, just to make
+            // things easier to read.
+            radix = TypedValue.COMPLEX_RADIX_23p0;
+            shift = 23;
+        } else if ((bits&0xffffffffff800000L) == 0) {
+            // Magnitude is zero -- can fit in 0 bits of precision.
+            radix = TypedValue.COMPLEX_RADIX_0p23;
+            shift = 0;
+        } else if ((bits&0xffffffff80000000L) == 0) {
+            // Magnitude can fit in 8 bits of precision.
+            radix = TypedValue.COMPLEX_RADIX_8p15;
+            shift = 8;
+        } else if ((bits&0xffffff8000000000L) == 0) {
+            // Magnitude can fit in 16 bits of precision.
+            radix = TypedValue.COMPLEX_RADIX_16p7;
+            shift = 16;
+        } else {
+            // Magnitude needs entire range, so no fractional part.
+            radix = TypedValue.COMPLEX_RADIX_23p0;
+            shift = 23;
+        }
+        int mantissa = (int)(
+            (bits>>shift) & TypedValue.COMPLEX_MANTISSA_MASK);
+        if (neg) {
+            mantissa = (-mantissa) & TypedValue.COMPLEX_MANTISSA_MASK;
+        }
+        outValue.data |=
+            (radix<<TypedValue.COMPLEX_RADIX_SHIFT)
+            | (mantissa<<TypedValue.COMPLEX_MANTISSA_SHIFT);
+    }
+
     private static boolean parseUnit(String str, TypedValue outValue, float[] outScale) {
         str = str.trim();
 
         for (UnitEntry unit : sUnitNames) {
             if (unit.name.equals(str)) {
-                outValue.type = unit.type;
-                outValue.data = unit.unit << TypedValue.COMPLEX_UNIT_SHIFT;
-                outScale[0] = unit.scale;
-
+                applyUnit(unit, outValue, outScale);
                 return true;
             }
         }
 
         return false;
     }
+
+    private static void applyUnit(UnitEntry unit, TypedValue outValue, float[] outScale) {
+        outValue.type = unit.type;
+        outValue.data = unit.unit << TypedValue.COMPLEX_UNIT_SHIFT;
+        outScale[0] = unit.scale;
+    }
 }
 
diff --git a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
index 70d5446..96436fe 100644
--- a/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
+++ b/tools/layoutlib/bridge/tests/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParserTest.java
@@ -16,14 +16,11 @@
 
 package com.android.layoutlib.bridge.android;
 
-import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
+import com.android.layoutlib.bridge.impl.ParserFactory;
 
-import org.kxml2.io.KXmlParser;
 import org.w3c.dom.Node;
 import org.xmlpull.v1.XmlPullParser;
 
-import java.io.InputStream;
-
 import junit.framework.TestCase;
 
 public class BridgeXmlBlockParserTest extends TestCase {
@@ -39,12 +36,12 @@
     }
 
     public void testXmlBlockParser() throws Exception {
-        XmlPullParser parser = new KXmlParser();
-        parser = new BridgeXmlBlockParser(parser, null, false /* platformResourceFlag */);
 
-        InputStream input = this.getClass().getClassLoader().getResourceAsStream(
-            "com/android/layoutlib/testdata/layout1.xml");
-        parser.setInput(input, "UTF-8"); //$NON-NLS-1$
+        XmlPullParser parser = ParserFactory.create(
+                getClass().getResourceAsStream("com/android/layoutlib/testdata/layout1.xml"),
+                        "layout1.xml");
+
+        parser = new BridgeXmlBlockParser(parser, null, false /* platformResourceFlag */);
 
         assertEquals(XmlPullParser.START_DOCUMENT, parser.next());
 
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 3df3736..2a033d1 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -1028,9 +1028,6 @@
         boolean wifiTethered = false;
         boolean wifiAvailable = false;
 
-        IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
-        INetworkManagementService service = INetworkManagementService.Stub.asInterface(b);
-
         if (mCm == null) {
             mCm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
         }
@@ -1043,14 +1040,14 @@
 
                     InterfaceConfiguration ifcg = null;
                     try {
-                        ifcg = service.getInterfaceConfig(intf);
+                        ifcg = nwService.getInterfaceConfig(intf);
                         if (ifcg != null) {
                             /* IP/netmask: 192.168.43.1/255.255.255.0 */
                             ifcg.addr = new LinkAddress(NetworkUtils.numericToInetAddress(
                                     "192.168.43.1"), 24);
                             ifcg.interfaceFlags = "[up]";
 
-                            service.setInterfaceConfig(intf, ifcg);
+                            nwService.setInterfaceConfig(intf, ifcg);
                         }
                     } catch (Exception e) {
                         Log.e(TAG, "Error configuring interface " + intf + ", :" + e);
@@ -1374,7 +1371,7 @@
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT
                 | Intent.FLAG_RECEIVER_REPLACE_PENDING);
         intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, mNetworkInfo);
-        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, mLinkProperties);
+        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, new LinkProperties (mLinkProperties));
         if (bssid != null)
             intent.putExtra(WifiManager.EXTRA_BSSID, bssid);
         mContext.sendStickyBroadcast(intent);
@@ -1390,7 +1387,7 @@
     private void sendLinkConfigurationChangedBroadcast() {
         Intent intent = new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION);
         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
-        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, mLinkProperties);
+        intent.putExtra(WifiManager.EXTRA_LINK_PROPERTIES, new LinkProperties(mLinkProperties));
         mContext.sendBroadcast(intent);
     }
 
@@ -1438,7 +1435,6 @@
             /* BSSID is valid only in ASSOCIATING state */
             mWifiInfo.setBSSID(stateChangeResult.BSSID);
         }
-        setNetworkDetailedState(WifiInfo.getDetailedStateOf(state));
 
         mSupplicantStateTracker.sendMessage(Message.obtain(message));
         mWpsStateMachine.sendMessage(Message.obtain(message));
@@ -1451,19 +1447,23 @@
      * using the interface, stopping DHCP & disabling interface
      */
     private void handleNetworkDisconnect() {
-        Log.d(TAG, "Reset connections and stopping DHCP");
+        Log.d(TAG, "Stopping DHCP and clearing IP");
 
         /*
-         * Reset connections & stop DHCP
+         * stop DHCP
          */
-        NetworkUtils.resetConnections(mInterfaceName);
-
         if (mDhcpStateMachine != null) {
             mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
             mDhcpStateMachine.quit();
             mDhcpStateMachine = null;
         }
 
+        try {
+            nwService.clearInterfaceAddresses(mInterfaceName);
+        } catch (Exception e) {
+            Log.e(TAG, "Failed to clear IP addresses on disconnect" + e);
+        }
+
         /* Reset data structures */
         mWifiInfo.setInetAddress(null);
         mWifiInfo.setBSSID(null);
@@ -1547,7 +1547,6 @@
             if (!linkProperties.equals(mLinkProperties)) {
                 Log.d(TAG, "Link configuration changed for netId: " + mLastNetworkId
                     + " old: " + mLinkProperties + "new: " + linkProperties);
-                NetworkUtils.resetConnections(mInterfaceName);
                 mLinkProperties = linkProperties;
                 sendLinkConfigurationChangedBroadcast();
             }
@@ -2660,13 +2659,11 @@
             } else {
                 DhcpInfoInternal dhcpInfoInternal = WifiConfigStore.getIpConfiguration(
                         mLastNetworkId);
-                IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
-                INetworkManagementService netd = INetworkManagementService.Stub.asInterface(b);
                 InterfaceConfiguration ifcg = new InterfaceConfiguration();
                 ifcg.addr = dhcpInfoInternal.makeLinkAddress();
                 ifcg.interfaceFlags = "[up]";
                 try {
-                    netd.setInterfaceConfig(mInterfaceName, ifcg);
+                    nwService.setInterfaceConfig(mInterfaceName, ifcg);
                     Log.v(TAG, "Static IP configuration succeeded");
                     sendMessage(CMD_STATIC_IP_SUCCESS, dhcpInfoInternal);
                 } catch (RemoteException re) {
@@ -2820,7 +2817,6 @@
                     if (mWifiInfo.getNetworkId() == result.getNetworkId()) {
                         if (result.hasIpChanged()) {
                             Log.d(TAG,"Reconfiguring IP on connection");
-                            NetworkUtils.resetConnections(mInterfaceName);
                             transitionTo(mConnectingState);
                         }
                         if (result.hasProxyChanged()) {
@@ -2979,7 +2975,12 @@
                     /* Ignore network disconnect */
                 case NETWORK_DISCONNECTION_EVENT:
                     break;
-               case CMD_START_SCAN:
+                case SUPPLICANT_STATE_CHANGE_EVENT:
+                    StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
+                    setNetworkDetailedState(WifiInfo.getDetailedStateOf(stateChangeResult.state));
+                    /* ConnectModeState does the rest of the handling */
+                    return NOT_HANDLED;
+                case CMD_START_SCAN:
                     /* Disable background scan temporarily during a regular scan */
                     if (mEnableBackgroundScan) {
                         WifiNative.enableBackgroundScanCommand(false);