Merge "Fixed an issue in SampleTable where the table index was incorrectly wrapped around to -1"
diff --git a/api/current.xml b/api/current.xml
index 3ccb4e9..059f4d4 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -32205,7 +32205,7 @@
  type="android.app.Notification"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <parameter name="icon" type="int">
@@ -32254,7 +32254,7 @@
  synchronized="false"
  static="false"
  final="false"
- deprecated="not deprecated"
+ deprecated="deprecated"
  visibility="public"
 >
 <parameter name="context" type="android.content.Context">
@@ -32524,6 +32524,16 @@
  visibility="public"
 >
 </field>
+<field name="largeIcon"
+ type="android.graphics.Bitmap"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="ledARGB"
  type="int"
  transient="false"
@@ -32574,27 +32584,6 @@
  visibility="public"
 >
 </field>
-<field name="tickerIcons"
- type="android.graphics.Bitmap[]"
- transient="false"
- volatile="false"
- value="null"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="tickerSubtitle"
- type="java.lang.CharSequence"
- transient="false"
- volatile="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
 <field name="tickerText"
  type="java.lang.CharSequence"
  transient="false"
@@ -32605,8 +32594,8 @@
  visibility="public"
 >
 </field>
-<field name="tickerTitle"
- type="java.lang.CharSequence"
+<field name="tickerView"
+ type="android.widget.RemoteViews"
  transient="false"
  volatile="false"
  static="false"
@@ -32637,6 +32626,334 @@
 >
 </field>
 </class>
+<class name="Notification.Builder"
+ extends="java.lang.Object"
+ abstract="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="Notification.Builder"
+ type="android.app.Notification.Builder"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+</constructor>
+<method name="getNotification"
+ return="android.app.Notification"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="setAutoCancel"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="autoCancel" type="boolean">
+</parameter>
+</method>
+<method name="setContent"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="views" type="android.widget.RemoteViews">
+</parameter>
+</method>
+<method name="setContentInfo"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="info" type="java.lang.CharSequence">
+</parameter>
+</method>
+<method name="setContentIntent"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intent" type="android.app.PendingIntent">
+</parameter>
+</method>
+<method name="setContentText"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="text" type="java.lang.CharSequence">
+</parameter>
+</method>
+<method name="setContentTitle"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="title" type="java.lang.CharSequence">
+</parameter>
+</method>
+<method name="setDefaults"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="defaults" type="int">
+</parameter>
+</method>
+<method name="setDeleteIntent"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intent" type="android.app.PendingIntent">
+</parameter>
+</method>
+<method name="setFullScreenIntent"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="intent" type="android.app.PendingIntent">
+</parameter>
+<parameter name="highPriority" type="boolean">
+</parameter>
+</method>
+<method name="setLargeIcon"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="icon" type="android.graphics.Bitmap">
+</parameter>
+</method>
+<method name="setLights"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="argb" type="int">
+</parameter>
+<parameter name="onMs" type="int">
+</parameter>
+<parameter name="offMs" type="int">
+</parameter>
+</method>
+<method name="setNumber"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="number" type="int">
+</parameter>
+</method>
+<method name="setOngoing"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="ongoing" type="boolean">
+</parameter>
+</method>
+<method name="setOnlyAlertOnce"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="onlyAlertOnce" type="boolean">
+</parameter>
+</method>
+<method name="setSmallIcon"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="icon" type="int">
+</parameter>
+</method>
+<method name="setSmallIcon"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="icon" type="int">
+</parameter>
+<parameter name="level" type="int">
+</parameter>
+</method>
+<method name="setSound"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="sound" type="android.net.Uri">
+</parameter>
+</method>
+<method name="setSound"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="sound" type="android.net.Uri">
+</parameter>
+<parameter name="streamType" type="int">
+</parameter>
+</method>
+<method name="setTicker"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="tickerText" type="java.lang.CharSequence">
+</parameter>
+</method>
+<method name="setTicker"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="tickerText" type="java.lang.CharSequence">
+</parameter>
+<parameter name="views" type="android.widget.RemoteViews">
+</parameter>
+</method>
+<method name="setVibrate"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="pattern" type="long[]">
+</parameter>
+</method>
+<method name="setWhen"
+ return="android.app.Notification.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="when" type="long">
+</parameter>
+</method>
+</class>
 <class name="NotificationManager"
  extends="java.lang.Object"
  abstract="false"
@@ -155686,6 +156003,17 @@
  visibility="public"
 >
 </field>
+<field name="GROUP_IS_READ_ONLY"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value="&quot;group_is_read_only&quot;"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="NOTES"
  type="java.lang.String"
  transient="false"
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index e602518..920e457 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -16,6 +16,7 @@
 
 package android.app;
 
+import java.text.NumberFormat;
 import java.util.Date;
 
 import android.app.PendingIntent;
@@ -29,8 +30,12 @@
 import android.text.TextUtils;
 import android.text.format.DateFormat;
 import android.text.format.DateUtils;
+import android.util.Slog;
+import android.view.View;
 import android.widget.RemoteViews;
 
+import com.android.internal.R;
+
 /**
  * A class that represents how a persistent notification is to be presented to
  * the user using the {@link android.app.NotificationManager}.
@@ -41,6 +46,8 @@
  */
 public class Notification implements Parcelable
 {
+    private static final String TAG = "Notification";
+
     /**
      * Use all default values (where applicable).
      */
@@ -84,6 +91,15 @@
     public int icon;
 
     /**
+     * If the icon in the status bar is to have more than one level, you can set this.  Otherwise,
+     * leave it at its default value of 0.
+     *
+     * @see android.widget.ImageView#setImageLevel
+     * @see android.graphics.drawable#setLevel
+     */
+    public int iconLevel;
+
+    /**
      * The number of events that this notification represents.  For example, in a new mail
      * notification, this could be the number of unread messages.  This number is superimposed over
      * the icon in the status bar.  If the number is 0 or negative, it is not shown in the status
@@ -132,38 +148,15 @@
      * text for when the text scrolls in and when it is displayed all at once
      * in conjunction with one or more icons.
      *
-     * @see #tickerTitle
-     * @see #tickerSubtitle
-     * @see #tickerIcons
+     * @see #tickerView
      */
     public CharSequence tickerText;
 
     /**
-     * The title line for the ticker over a the fat status bar on xlarge devices.
-     *
-     * @see #tickerText
-     * @see #tickerSubtitle
-     * @see #tickerIcons
+     * The view to show as the ticker in the status bar when the notification
+     * is posted.
      */
-    public CharSequence tickerTitle;
-
-    /**
-     * The subtitle line for the ticker over a the fat status bar on xlarge devices.
-     *
-     * @see #tickerText
-     * @see #tickerTitle
-     * @see #tickerIcons
-     */
-    public CharSequence tickerSubtitle;
-
-    /**
-     * The icons to show to the left of the other ticker fields.
-     *
-     * @see #tickerText
-     * @see #tickerTitle
-     * @see #tickerSubtitle
-     */
-    public Bitmap[] tickerIcons;
+    public RemoteViews tickerView;
 
     /**
      * The view that will represent this notification in the expanded status bar.
@@ -171,13 +164,9 @@
     public RemoteViews contentView;
 
     /**
-     * If the icon in the status bar is to have more than one level, you can set this.  Otherwise,
-     * leave it at its default value of 0.
-     *
-     * @see android.widget.ImageView#setImageLevel
-     * @see android.graphics.drawable#setLevel
+     * The bitmap that may escape the bounds of the panel and bar.
      */
-    public int iconLevel;
+    public Bitmap largeIcon;
 
     /**
      * The sound to play.
@@ -327,6 +316,7 @@
 
     /**
      * Constructs a Notification object with everything set to 0.
+     * You might want to consider using {@link Builder} instead.
      */
     public Notification()
     {
@@ -334,7 +324,6 @@
     }
 
     /**
-     * @deprecated use {@link #Notification(int,CharSequence,long)} and {@link #setLatestEventInfo}.
      * @hide
      */
     public Notification(Context context, int icon, CharSequence tickerText, long when,
@@ -356,7 +345,10 @@
      *                      activates.
      * @param when          The time to show in the time field.  In the System.currentTimeMillis
      *                      timebase.
+     *
+     * @deprecated Use {@link Builder} instead.
      */
+    @Deprecated
     public Notification(int icon, CharSequence tickerText, long when)
     {
         this.icon = icon;
@@ -384,23 +376,14 @@
             tickerText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
         }
         if (parcel.readInt() != 0) {
-            tickerTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
-        }
-        if (parcel.readInt() != 0) {
-            tickerSubtitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel);
-        }
-        final int tickerIconCount = parcel.readInt();
-        if (tickerIconCount >= 0) {
-            tickerIcons = new Bitmap[tickerIconCount];
-            for (int i=0; i<tickerIconCount; i++) {
-                if (parcel.readInt() != 0) {
-                    tickerIcons[i] = Bitmap.CREATOR.createFromParcel(parcel);
-                }
-            }
+            tickerView = RemoteViews.CREATOR.createFromParcel(parcel);
         }
         if (parcel.readInt() != 0) {
             contentView = RemoteViews.CREATOR.createFromParcel(parcel);
         }
+        if (parcel.readInt() != 0) {
+            largeIcon = Bitmap.CREATOR.createFromParcel(parcel);
+        }
         defaults = parcel.readInt();
         flags = parcel.readInt();
         if (parcel.readInt() != 0) {
@@ -434,22 +417,15 @@
         if (this.tickerText != null) {
             that.tickerText = this.tickerText.toString();
         }
-        if (this.tickerTitle != null) {
-            that.tickerTitle = this.tickerTitle.toString();
-        }
-        if (this.tickerSubtitle != null) {
-            that.tickerSubtitle = this.tickerSubtitle.toString();
-        }
-        if (this.tickerIcons != null) {
-            final int N = this.tickerIcons.length;
-            that.tickerIcons = new Bitmap[N];
-            for (int i=0; i<N; i++) {
-                that.tickerIcons[i] = Bitmap.createBitmap(this.tickerIcons[i]);
-            }
+        if (this.tickerView != null) {
+            that.tickerView = this.tickerView.clone();
         }
         if (this.contentView != null) {
             that.contentView = this.contentView.clone();
         }
+        if (this.largeIcon != null) {
+            that.largeIcon = Bitmap.createBitmap(this.largeIcon);
+        }
         that.iconLevel = that.iconLevel;
         that.sound = this.sound; // android.net.Uri is immutable
         that.audioStreamType = this.audioStreamType;
@@ -503,38 +479,24 @@
         } else {
             parcel.writeInt(0);
         }
-        if (tickerTitle != null) {
+        if (tickerView != null) {
             parcel.writeInt(1);
-            TextUtils.writeToParcel(tickerTitle, parcel, flags);
+            tickerView.writeToParcel(parcel, 0);
         } else {
             parcel.writeInt(0);
         }
-        if (tickerSubtitle != null) {
-            parcel.writeInt(1);
-            TextUtils.writeToParcel(tickerSubtitle, parcel, flags);
-        } else {
-            parcel.writeInt(0);
-        }
-        if (tickerIcons != null) {
-            final int N = tickerIcons.length;
-            parcel.writeInt(N);
-            for (int i=0; i<N; i++) {
-                if (tickerIcons[i] != null) {
-                    parcel.writeInt(1);
-                    tickerIcons[i].writeToParcel(parcel, flags);
-                } else {
-                    parcel.writeInt(0);
-                }
-            }
-        } else {
-            parcel.writeInt(-1);
-        }
         if (contentView != null) {
             parcel.writeInt(1);
             contentView.writeToParcel(parcel, 0);
         } else {
             parcel.writeInt(0);
         }
+        if (largeIcon != null) {
+            parcel.writeInt(1);
+            largeIcon.writeToParcel(parcel, 0);
+        } else {
+            parcel.writeInt(0);
+        }
 
         parcel.writeInt(defaults);
         parcel.writeInt(this.flags);
@@ -591,22 +553,25 @@
      * {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK} flag, which requires
      * that you take care of task management as described in 
      * <a href="{@docRoot}guide/topics/fundamentals.html#lcycles">Application Fundamentals: Activities and Tasks</a>.
+     * 
+     * @deprecated Use {@link Builder} instead.
      */
+    @Deprecated
     public void setLatestEventInfo(Context context,
             CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent) {
         RemoteViews contentView = new RemoteViews(context.getPackageName(),
-                com.android.internal.R.layout.status_bar_latest_event_content);
+                R.layout.status_bar_latest_event_content);
         if (this.icon != 0) {
-            contentView.setImageViewResource(com.android.internal.R.id.icon, this.icon);
+            contentView.setImageViewResource(R.id.icon, this.icon);
         }
         if (contentTitle != null) {
-            contentView.setTextViewText(com.android.internal.R.id.title, contentTitle);
+            contentView.setTextViewText(R.id.title, contentTitle);
         }
         if (contentText != null) {
-            contentView.setTextViewText(com.android.internal.R.id.text, contentText);
+            contentView.setTextViewText(R.id.text, contentText);
         }
         if (this.when != 0) {
-            contentView.setLong(com.android.internal.R.id.time, "setTime", when);
+            contentView.setLong(R.id.time, "setTime", when);
         }
 
         this.contentView = contentView;
@@ -651,4 +616,242 @@
         sb.append(")");
         return sb.toString();
     }
+
+    public static class Builder {
+        private Context mContext;
+
+        private long mWhen;
+        private int mSmallIcon;
+        private int mSmallIconLevel;
+        private int mNumber;
+        private CharSequence mContentTitle;
+        private CharSequence mContentText;
+        private CharSequence mContentInfo;
+        private PendingIntent mContentIntent;
+        private RemoteViews mContentView;
+        private PendingIntent mDeleteIntent;
+        private PendingIntent mFullScreenIntent;
+        private CharSequence mTickerText;
+        private RemoteViews mTickerView;
+        private Bitmap mLargeIcon;
+        private Uri mSound;
+        private int mAudioStreamType;
+        private long[] mVibrate;
+        private int mLedArgb;
+        private int mLedOnMs;
+        private int mLedOffMs;
+        private int mDefaults;
+        private int mFlags;
+
+        public Builder(Context context) {
+            mContext = context;
+            mWhen = System.currentTimeMillis();
+        }
+
+        public Builder setWhen(long when) {
+            mWhen = when;
+            return this;
+        }
+
+        public Builder setSmallIcon(int icon) {
+            mSmallIcon = icon;
+            return this;
+        }
+
+        public Builder setSmallIcon(int icon, int level) {
+            mSmallIcon = icon;
+            mSmallIconLevel = level;
+            return this;
+        }
+
+        public Builder setContentTitle(CharSequence title) {
+            mContentTitle = title;
+            return this;
+        }
+
+        public Builder setContentText(CharSequence text) {
+            mContentText = text;
+            return this;
+        }
+
+        public Builder setNumber(int number) {
+            mNumber = number;
+            return this;
+        }
+
+        public Builder setContentInfo(CharSequence info) {
+            mContentInfo = info;
+            return this;
+        }
+
+        public Builder setContent(RemoteViews views) {
+            mContentView = views;
+            return this;
+        }
+
+        public Builder setContentIntent(PendingIntent intent) {
+            mContentIntent = intent;
+            return this;
+        }
+
+        public Builder setDeleteIntent(PendingIntent intent) {
+            mDeleteIntent = intent;
+            return this;
+        }
+
+        public Builder setFullScreenIntent(PendingIntent intent, boolean highPriority) {
+            mFullScreenIntent = intent;
+            setFlag(FLAG_HIGH_PRIORITY, highPriority);
+            return this;
+        }
+
+        public Builder setTicker(CharSequence tickerText) {
+            mTickerText = tickerText;
+            return this;
+        }
+
+        public Builder setTicker(CharSequence tickerText, RemoteViews views) {
+            mTickerText = tickerText;
+            mTickerView = views;
+            return this;
+        }
+
+        public Builder setLargeIcon(Bitmap icon) {
+            mLargeIcon = icon;
+            return this;
+        }
+
+        public Builder setSound(Uri sound) {
+            mSound = sound;
+            mAudioStreamType = STREAM_DEFAULT;
+            return this;
+        }
+
+        public Builder setSound(Uri sound, int streamType) {
+            mSound = sound;
+            mAudioStreamType = streamType;
+            return this;
+        }
+
+        public Builder setVibrate(long[] pattern) {
+            mVibrate = pattern;
+            return this;
+        }
+
+        public Builder setLights(int argb, int onMs, int offMs) {
+            mLedArgb = argb;
+            mLedOnMs = onMs;
+            mLedOffMs = offMs;
+            mFlags |= FLAG_SHOW_LIGHTS;
+            return this;
+        }
+
+        public Builder setOngoing(boolean ongoing) {
+            setFlag(FLAG_ONGOING_EVENT, ongoing);
+            return this;
+        }
+
+        public Builder setOnlyAlertOnce(boolean onlyAlertOnce) {
+            setFlag(FLAG_ONLY_ALERT_ONCE, onlyAlertOnce);
+            return this;
+        }
+
+        public Builder setAutoCancel(boolean autoCancel) {
+            setFlag(FLAG_ONLY_ALERT_ONCE, autoCancel);
+            return this;
+        }
+
+        public Builder setDefaults(int defaults) {
+            mDefaults = defaults;
+            int moreFlags = 0;
+            if ((defaults & DEFAULT_LIGHTS) != 0) {
+                moreFlags |= FLAG_SHOW_LIGHTS;
+            }
+            return this;
+        }
+
+        private void setFlag(int mask, boolean value) {
+            if (value) {
+                mFlags |= mask;
+            } else {
+                mFlags &= ~mask;
+            }
+        }
+
+        private RemoteViews makeRemoteViews(int resId) {
+            RemoteViews contentView = new RemoteViews(mContext.getPackageName(), resId);
+            if (mSmallIcon != 0) {
+                contentView.setImageViewResource(R.id.icon, mSmallIcon);
+            }
+            if (mContentTitle != null) {
+                contentView.setTextViewText(R.id.title, mContentTitle);
+            }
+            if (mContentText != null) {
+                contentView.setTextViewText(R.id.text, mContentText);
+            }
+            if (mContentInfo != null) {
+                contentView.setTextViewText(R.id.info, mContentInfo);
+            } else if (mNumber > 0) {
+                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);
+            }
+            if (mWhen != 0) {
+                contentView.setLong(R.id.time, "setTime", mWhen);
+            }
+            return contentView;
+        }
+
+        private RemoteViews makeContentView() {
+            if (mContentView != null) {
+                return mContentView;
+            } else {
+                    return makeRemoteViews(mLargeIcon == null
+                            ? R.layout.status_bar_latest_event_content
+                        : R.layout.status_bar_latest_event_content_large_icon);
+            }
+        }
+
+        private RemoteViews makeTickerView() {
+            if (mTickerView != null) {
+                return mTickerView;
+            } else {
+                if (mContentView == null) {
+                    return makeRemoteViews(mLargeIcon == null
+                            ? R.layout.status_bar_latest_event_ticker
+                            : R.layout.status_bar_latest_event_ticker_large_icon);
+                } else {
+                    return null;
+                }
+            }
+        }
+
+        public Notification getNotification() {
+            Notification n = new Notification();
+            n.when = mWhen;
+            n.icon = mSmallIcon;
+            n.iconLevel = mSmallIconLevel;
+            n.number = mNumber;
+            n.contentView = makeContentView();
+            n.contentIntent = mContentIntent;
+            n.deleteIntent = mDeleteIntent;
+            n.fullScreenIntent = mFullScreenIntent;
+            n.tickerText = mTickerText;
+            n.tickerView = makeTickerView();
+            n.largeIcon = mLargeIcon;
+            n.sound = mSound;
+            n.audioStreamType = mAudioStreamType;
+            n.vibrate = mVibrate;
+            n.ledARGB = mLedArgb;
+            n.ledOnMS = mLedOnMs;
+            n.ledOffMS = mLedOffMs;
+            n.defaults = mDefaults;
+            n.flags = mFlags;
+            return n;
+        }
+    }
 }
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index c836e56..4facc39 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -32,6 +32,7 @@
 import java.io.StringWriter;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.concurrent.atomic.AtomicInteger;
 
 /**
  * <p>StrictMode is a developer tool which detects things you might be
@@ -208,6 +209,12 @@
      */
     private static volatile int sVmPolicyMask = 0;
 
+    /**
+     * The number of threads trying to do an async dropbox write.
+     * Just to limit ourselves out of paranoia.
+     */
+    private static final AtomicInteger sDropboxCallsInFlight = new AtomicInteger(0);
+
     private StrictMode() {}
 
     /**
@@ -984,7 +991,6 @@
             if (violationMaskSubset != 0) {
                 int violationBit = parseViolationFromMessage(info.crashInfo.exceptionMessage);
                 violationMaskSubset |= violationBit;
-                final int violationMaskSubsetFinal = violationMaskSubset;
                 final int savedPolicyMask = getThreadPolicyMask();
 
                 final boolean justDropBox = (info.policy & PENALTY_MASK) == PENALTY_DROPBOX;
@@ -995,20 +1001,7 @@
                     // call synchronously which Binder data suggests
                     // isn't always super fast, despite the implementation
                     // in the ActivityManager trying to be mostly async.
-                    new Thread("callActivityManagerForStrictModeDropbox") {
-                        public void run() {
-                            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
-                            try {
-                                ActivityManagerNative.getDefault().
-                                        handleApplicationStrictModeViolation(
-                                            RuntimeInit.getApplicationObject(),
-                                            violationMaskSubsetFinal,
-                                            info);
-                            } catch (RemoteException e) {
-                                Log.e(TAG, "RemoteException handling StrictMode violation", e);
-                            }
-                        }
-                    }.start();
+                    dropboxViolationAsync(violationMaskSubset, info);
                     return;
                 }
 
@@ -1040,6 +1033,44 @@
         }
     }
 
+    /**
+     * In the common case, as set by conditionallyEnableDebugLogging,
+     * we're just dropboxing any violations but not showing a dialog,
+     * not loggging, and not killing the process.  In these cases we
+     * don't need to do a synchronous call to the ActivityManager.
+     * This is used by both per-thread and vm-wide violations when
+     * applicable.
+     */
+    private static void dropboxViolationAsync(
+            final int violationMaskSubset, final ViolationInfo info) {
+        int outstanding = sDropboxCallsInFlight.incrementAndGet();
+        if (outstanding > 20) {
+            // What's going on?  Let's not make make the situation
+            // worse and just not log.
+            sDropboxCallsInFlight.decrementAndGet();
+            return;
+        }
+
+        if (LOG_V) Log.d(TAG, "Dropboxing async; in-flight=" + outstanding);
+
+        new Thread("callActivityManagerForStrictModeDropbox") {
+            public void run() {
+                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+                try {
+                    ActivityManagerNative.getDefault().
+                            handleApplicationStrictModeViolation(
+                                RuntimeInit.getApplicationObject(),
+                                violationMaskSubset,
+                                info);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "RemoteException handling StrictMode violation", e);
+                }
+                int outstanding = sDropboxCallsInFlight.decrementAndGet();
+                if (LOG_V) Log.d(TAG, "Dropbox complete; in-flight=" + outstanding);
+            }
+        }.start();
+    }
+
     private static class AndroidCloseGuardReporter implements CloseGuard.Reporter {
         public void report (String message, Throwable allocationSite) {
             onVmPolicyViolation(message, allocationSite);
@@ -1130,14 +1161,25 @@
             Log.e(TAG, message, originStack);
         }
 
-        if ((sVmPolicyMask & PENALTY_DROPBOX) != 0) {
-            final ViolationInfo info = new ViolationInfo(originStack, sVmPolicyMask);
+        boolean penaltyDropbox = (sVmPolicyMask & PENALTY_DROPBOX) != 0;
+        boolean penaltyDeath = (sVmPolicyMask & PENALTY_DEATH) != 0;
 
+        int violationMaskSubset = PENALTY_DROPBOX | DETECT_VM_CURSOR_LEAKS;
+        ViolationInfo info = new ViolationInfo(originStack, sVmPolicyMask);
+
+        if (penaltyDropbox && !penaltyDeath) {
+            // Common case for userdebug/eng builds.  If no death and
+            // just dropboxing, we can do the ActivityManager call
+            // asynchronously.
+            dropboxViolationAsync(violationMaskSubset, info);
+            return;
+        }
+
+        if (penaltyDropbox) {
             // The violationMask, passed to ActivityManager, is a
             // subset of the original StrictMode policy bitmask, with
             // only the bit violated and penalty bits to be executed
             // by the ActivityManagerService remaining set.
-            int violationMaskSubset = PENALTY_DROPBOX | DETECT_VM_CURSOR_LEAKS;
             final int savedPolicyMask = getThreadPolicyMask();
             try {
                 // First, remove any policy before we call into the Activity Manager,
@@ -1158,7 +1200,7 @@
             }
         }
 
-        if ((sVmPolicyMask & PENALTY_DEATH) != 0) {
+        if (penaltyDeath) {
             System.err.println("StrictMode VmPolicy violation with POLICY_DEATH; shutting down.");
             Process.killProcess(Process.myPid());
             System.exit(10);
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 2d2f205..d1ca0c9 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -5669,6 +5669,13 @@
          * Type: INTEGER (boolean)
          */
         public static final String FAVORITES = "favorites";
+
+        /**
+         * The "read-only" flag: "0" by default, "1" if the row cannot be modified or
+         * deleted except by a sync adapter.  See {@link ContactsContract#CALLER_IS_SYNCADAPTER}.
+         * <P>Type: INTEGER</P>
+         */
+        public static final String GROUP_IS_READ_ONLY = "group_is_read_only";
     }
 
     /**
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 61a30ab..9568e4f 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -780,50 +780,11 @@
             if (cacheMode == WebSettings.LOAD_NORMAL) {
                 cacheMode = WebSettings.LOAD_NO_CACHE;
             }
-            if (mSettings.getSavePassword() && hasPasswordField()) {
-                try {
-                    if (DebugFlags.BROWSER_FRAME) {
-                        Assert.assertNotNull(mCallbackProxy.getBackForwardList()
-                                .getCurrentItem());
-                    }
-                    WebAddress uri = new WebAddress(mCallbackProxy
-                            .getBackForwardList().getCurrentItem().getUrl());
-                    String schemePlusHost = uri.getScheme() + uri.getHost();
-                    String[] ret = getUsernamePassword();
-                    // Has the user entered a username/password pair and is
-                    // there some POST data
-                    if (ret != null && postData != null && 
-                            ret[0].length() > 0 && ret[1].length() > 0) {
-                        // Check to see if the username & password appear in
-                        // the post data (there could be another form on the
-                        // page and that was posted instead.
-                        String postString = new String(postData);
-                        if (postString.contains(URLEncoder.encode(ret[0])) &&
-                                postString.contains(URLEncoder.encode(ret[1]))) {
-                            String[] saved = mDatabase.getUsernamePassword(
-                                    schemePlusHost);
-                            if (saved != null) {
-                                // null username implies that user has chosen not to
-                                // save password
-                                if (saved[0] != null) {
-                                    // non-null username implies that user has
-                                    // chosen to save password, so update the 
-                                    // recorded password
-                                    mDatabase.setUsernamePassword(
-                                            schemePlusHost, ret[0], ret[1]);
-                                }
-                            } else {
-                                // CallbackProxy will handle creating the resume
-                                // message
-                                mCallbackProxy.onSavePassword(schemePlusHost, ret[0], 
-                                        ret[1], null);
-                            }
-                        }
-                    }
-                } catch (ParseException ex) {
-                    // if it is bad uri, don't save its password
-                }
-                
+            String[] ret = getUsernamePassword();
+            if (ret != null) {
+                String domUsername = ret[0];
+                String domPassword = ret[1];
+                maybeSavePassword(postData, domUsername, domPassword);
             }
         }
 
@@ -874,6 +835,68 @@
         return !synchronous ? loadListener : null;
     }
 
+    /**
+     * If this looks like a POST request (form submission) containing a username
+     * and password, give the user the option of saving them. Will either do
+     * nothing, or block until the UI interaction is complete.
+     *
+     * Called by startLoadingResource when using the Apache HTTP stack.
+     * Called directly by WebKit when using the Chrome HTTP stack.
+     *
+     * @param postData The data about to be sent as the body of a POST request.
+     * @param username The username entered by the user (sniffed from the DOM).
+     * @param password The password entered by the user (sniffed from the DOM).
+     */
+    private void maybeSavePassword(
+            byte[] postData, String username, String password) {
+        if (postData == null
+                || username == null || username.isEmpty()
+                || password == null || password.isEmpty()) {
+            return; // No password to save.
+        }
+
+        if (!mSettings.getSavePassword()) {
+            return; // User doesn't want to save passwords.
+        }
+
+        try {
+            if (DebugFlags.BROWSER_FRAME) {
+                Assert.assertNotNull(mCallbackProxy.getBackForwardList()
+                        .getCurrentItem());
+            }
+            WebAddress uri = new WebAddress(mCallbackProxy
+                    .getBackForwardList().getCurrentItem().getUrl());
+            String schemePlusHost = uri.getScheme() + uri.getHost();
+            // Check to see if the username & password appear in
+            // the post data (there could be another form on the
+            // page and that was posted instead.
+            String postString = new String(postData);
+            if (postString.contains(URLEncoder.encode(username)) &&
+                    postString.contains(URLEncoder.encode(password))) {
+                String[] saved = mDatabase.getUsernamePassword(
+                        schemePlusHost);
+                if (saved != null) {
+                    // null username implies that user has chosen not to
+                    // save password
+                    if (saved[0] != null) {
+                        // non-null username implies that user has
+                        // chosen to save password, so update the
+                        // recorded password
+                        mDatabase.setUsernamePassword(
+                                schemePlusHost, username, password);
+                    }
+                } else {
+                    // CallbackProxy will handle creating the resume
+                    // message
+                    mCallbackProxy.onSavePassword(schemePlusHost, username,
+                            password, null);
+                }
+            }
+        } catch (ParseException ex) {
+            // if it is bad uri, don't save its password
+        }
+    }
+
     // Called by jni from the chrome network stack.
     private WebResourceResponse shouldInterceptRequest(String url) {
         InputStream androidResource = inputStreamForAndroidResource(url);
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 1caa707..fafb6be 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -26,9 +26,12 @@
 import android.graphics.PixelFormat;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.text.BoringLayout.Metrics;
+import android.text.DynamicLayout;
 import android.text.Editable;
 import android.text.InputFilter;
 import android.text.Layout;
+import android.text.Layout.Alignment;
 import android.text.Selection;
 import android.text.Spannable;
 import android.text.TextPaint;
@@ -359,6 +362,68 @@
         }
     }
 
+    @Override
+    protected void makeNewLayout(int w, int hintWidth, Metrics boring,
+            Metrics hintBoring, int ellipsisWidth, boolean bringIntoView) {
+        // Necessary to get a Layout to work with, and to do the other work that
+        // makeNewLayout does.
+        super.makeNewLayout(w, hintWidth, boring, hintBoring, ellipsisWidth,
+                bringIntoView);
+
+        // For fields that do not draw, create a layout which is altered so that
+        // the text lines up.
+        if (DebugFlags.DRAW_WEBTEXTVIEW || willNotDraw()) {
+            float lineHeight = -1;
+            if (mWebView != null) {
+                float height = mWebView.nativeFocusCandidateLineHeight();
+                if (height != -1) {
+                    lineHeight = height * mWebView.getScale();
+                }
+            }
+            CharSequence text = getText();
+            // Copy from the existing Layout.
+            mLayout = new WebTextViewLayout(text, text, getPaint(), w,
+                    mLayout.getAlignment(), mLayout.getSpacingMultiplier(),
+                    mLayout.getSpacingAdd(), false, null, ellipsisWidth,
+                    lineHeight);
+        }
+    }
+
+    /**
+     * Custom layout which figures out its line spacing.  If -1 is passed in for
+     * the height, it will use the ascent and descent from the paint to
+     * determine the line spacing.  Otherwise it will use the spacing provided.
+     */
+    private static class WebTextViewLayout extends DynamicLayout {
+        private float mLineHeight;
+        private float mDifference;
+        public WebTextViewLayout(CharSequence base, CharSequence display,
+                TextPaint paint,
+                int width, Alignment align,
+                float spacingMult, float spacingAdd,
+                boolean includepad,
+                TextUtils.TruncateAt ellipsize, int ellipsizedWidth,
+                float lineHeight) {
+            super(base, display, paint, width, align, spacingMult, spacingAdd,
+                    includepad, ellipsize, ellipsizedWidth);
+            float paintLineHeight = paint.descent() - paint.ascent();
+            if (lineHeight == -1f) {
+                mLineHeight = paintLineHeight;
+                mDifference = 0f;
+            } else {
+                mLineHeight = lineHeight;
+                // Through trial and error, I found this calculation to improve
+                // the accuracy of line placement.
+                mDifference = (lineHeight - paintLineHeight) / 2;
+            }
+        }
+
+        @Override
+        public int getLineTop(int line) {
+            return Math.round(mLineHeight * line - mDifference);
+        }
+    }
+
     @Override public InputConnection onCreateInputConnection(
             EditorInfo outAttrs) {
         InputConnection connection = super.onCreateInputConnection(outAttrs);
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 5bf2ad4..602975f 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -906,6 +906,7 @@
 
         mCallbackProxy = new CallbackProxy(context, this);
         mViewManager = new ViewManager(this);
+        L10nUtils.loadStrings(context);
         mWebViewCore = new WebViewCore(context, this, mCallbackProxy, javascriptInterfaces);
         mDatabase = WebViewDatabase.getInstance(context);
         mScroller = new Scroller(context);
@@ -922,7 +923,6 @@
             startPrivateBrowsing();
         }
 
-        L10nUtils.loadStrings(context);
         mAutoFillData = new WebViewCore.AutoFillData();
     }
 
@@ -3549,6 +3549,15 @@
          * click action, look for a word under the  click. If one is found,
          * animate the text selection into view.
          * FIXME: no animation code yet */
+        return selectText();
+    }
+
+    /**
+     * Select the word at the last click point.
+     *
+     * @hide pending API council approval
+     */
+    public boolean selectText() {
         int x = viewToContentX((int) mLastTouchX + mScrollX);
         int y = viewToContentY((int) mLastTouchY + mScrollY);
         setUpSelect();
@@ -7461,6 +7470,7 @@
     /* package */ native int      nativeFocusCandidatePointer();
     private native String   nativeFocusCandidateText();
     /* package */ native float    nativeFocusCandidateTextSize();
+    /* package */ native int nativeFocusCandidateLineHeight();
     /**
      * Returns an integer corresponding to WebView.cpp::type.
      * See WebTextView.setType()
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index a3e9bc9..70cfee9 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -2542,7 +2542,6 @@
                         mTouchMode = TOUCH_MODE_SCROLL;
                         mMotionCorrection = 0;
                         motionPosition = findMotionRow(y);
-                        reportScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
                         mFlingRunnable.flywheelTouch();
                     }
                 }
@@ -2968,6 +2967,7 @@
                 } else {
                     endFling();
                     mTouchMode = TOUCH_MODE_SCROLL;
+                    reportScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
                 }
             }
         };
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 80a6a2f..78f3cd9 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -9015,7 +9015,13 @@
     private boolean                 mUserSetTextScaleX;
     private final Paint             mHighlightPaint;
     private int                     mHighlightColor = 0xCC475925;
-    private Layout                  mLayout;
+    /**
+     * This is temporarily visible to fix bug 3085564 in webView. Do not rely on
+     * this field being protected. Will be restored as private when lineHeight
+     * feature request 3215097 is implemented
+     * @hide
+     */
+    protected Layout                mLayout;
 
     private long                    mShowCursor;
     private Blink                   mBlink;
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_0.png b/core/res/res/drawable-mdpi/stat_sys_battery_0.png
index 4a5e99e..750e652 100644
--- a/core/res/res/drawable-mdpi/stat_sys_battery_0.png
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_0.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_10.png b/core/res/res/drawable-mdpi/stat_sys_battery_10.png
deleted file mode 100755
index b789f23..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_battery_10.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_100.png b/core/res/res/drawable-mdpi/stat_sys_battery_100.png
index d280aeb..70d7fa4 100644
--- a/core/res/res/drawable-mdpi/stat_sys_battery_100.png
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_100.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_15.png b/core/res/res/drawable-mdpi/stat_sys_battery_15.png
new file mode 100644
index 0000000..0eb58e1
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_15.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_20.png b/core/res/res/drawable-mdpi/stat_sys_battery_20.png
deleted file mode 100644
index 009a9fd..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_battery_20.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_28.png b/core/res/res/drawable-mdpi/stat_sys_battery_28.png
new file mode 100644
index 0000000..f634dde
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_28.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_40.png b/core/res/res/drawable-mdpi/stat_sys_battery_40.png
deleted file mode 100644
index 15b57f4..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_battery_40.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_43.png b/core/res/res/drawable-mdpi/stat_sys_battery_43.png
new file mode 100644
index 0000000..f0376bd
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_43.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_57.png b/core/res/res/drawable-mdpi/stat_sys_battery_57.png
new file mode 100644
index 0000000..840af66
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_57.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_60.png b/core/res/res/drawable-mdpi/stat_sys_battery_60.png
deleted file mode 100644
index 21078fd..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_battery_60.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_71.png b/core/res/res/drawable-mdpi/stat_sys_battery_71.png
new file mode 100644
index 0000000..04c3569
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_71.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_80.png b/core/res/res/drawable-mdpi/stat_sys_battery_80.png
deleted file mode 100644
index 9268f7b..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_battery_80.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_85.png b/core/res/res/drawable-mdpi/stat_sys_battery_85.png
new file mode 100644
index 0000000..c742da7
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_85.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim0.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim0.png
index ff3cabd..957dab3 100644
--- a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim0.png
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim0.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim1.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim1.png
deleted file mode 100644
index b563701..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim1.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim100.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim100.png
new file mode 100644
index 0000000..e6d7da0
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim100.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim15.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim15.png
new file mode 100644
index 0000000..957dab3
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim15.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim2.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim2.png
deleted file mode 100644
index 904989e..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim2.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim28.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim28.png
new file mode 100644
index 0000000..5aba0bb
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim28.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim3.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim3.png
deleted file mode 100644
index ba011c9..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim3.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim4.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim4.png
deleted file mode 100644
index 4f1c485..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim4.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim43.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim43.png
new file mode 100644
index 0000000..dc5fac6
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim43.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim5.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim5.png
deleted file mode 100644
index 4d3396d..0000000
--- a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim5.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim57.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim57.png
new file mode 100644
index 0000000..1233ed8
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim57.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim71.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim71.png
new file mode 100644
index 0000000..06d397b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim71.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim85.png b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim85.png
new file mode 100644
index 0000000..1056faf
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_charge_anim85.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_battery_unknown.png b/core/res/res/drawable-mdpi/stat_sys_battery_unknown.png
index ed72ebf..44eb313 100644
--- a/core/res/res/drawable-mdpi/stat_sys_battery_unknown.png
+++ b/core/res/res/drawable-mdpi/stat_sys_battery_unknown.png
Binary files differ
diff --git a/core/res/res/drawable/stat_sys_battery.xml b/core/res/res/drawable/stat_sys_battery.xml
index 968595d..1060375 100644
--- a/core/res/res/drawable/stat_sys_battery.xml
+++ b/core/res/res/drawable/stat_sys_battery.xml
@@ -20,11 +20,12 @@
 
 <level-list xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:maxLevel="4" android:drawable="@android:drawable/stat_sys_battery_0" />
-    <item android:maxLevel="14" android:drawable="@android:drawable/stat_sys_battery_10" />
-    <item android:maxLevel="29" android:drawable="@android:drawable/stat_sys_battery_20" />
-    <item android:maxLevel="49" android:drawable="@android:drawable/stat_sys_battery_40" />
-    <item android:maxLevel="69" android:drawable="@android:drawable/stat_sys_battery_60" />
-    <item android:maxLevel="89" android:drawable="@android:drawable/stat_sys_battery_80" />
+    <item android:maxLevel="15" android:drawable="@android:drawable/stat_sys_battery_15" />
+    <item android:maxLevel="35" android:drawable="@android:drawable/stat_sys_battery_28" />
+    <item android:maxLevel="49" android:drawable="@android:drawable/stat_sys_battery_43" />
+    <item android:maxLevel="60" android:drawable="@android:drawable/stat_sys_battery_57" />
+    <item android:maxLevel="75" android:drawable="@android:drawable/stat_sys_battery_71" />
+    <item android:maxLevel="90" android:drawable="@android:drawable/stat_sys_battery_85" />
     <item android:maxLevel="100" android:drawable="@android:drawable/stat_sys_battery_100" />
 </level-list>
 
diff --git a/core/res/res/drawable/stat_sys_battery_charge.xml b/core/res/res/drawable/stat_sys_battery_charge.xml
index 92d7c4f..a6c4575 100644
--- a/core/res/res/drawable/stat_sys_battery_charge.xml
+++ b/core/res/res/drawable/stat_sys_battery_charge.xml
@@ -1,7 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <!--
-/* //device/apps/common/res/drawable/stat_sys_battery.xml
-**
 ** Copyright 2007, The Android Open Source Project
 **
 ** Licensed under the Apache License, Version 2.0 (the "License"); 
@@ -19,56 +17,14 @@
 -->
 
 <level-list xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:maxLevel="14">
-        <animation-list
-                xmlns:android="http://schemas.android.com/apk/res/android"
-                android:oneshot="false">
-            <item android:drawable="@drawable/stat_sys_battery_charge_anim0" android:duration="2000" />
-            <item android:drawable="@drawable/stat_sys_battery_charge_anim1" android:duration="1000" />
-            <item android:drawable="@drawable/stat_sys_battery_charge_anim2" android:duration="1000" />
-            <item android:drawable="@drawable/stat_sys_battery_charge_anim3" android:duration="1000" />
-            <item android:drawable="@drawable/stat_sys_battery_charge_anim4" android:duration="1000" />
-            <item android:drawable="@drawable/stat_sys_battery_charge_anim5" android:duration="1000" />
-        </animation-list>
-    </item>
-    <item android:maxLevel="29">
-        <animation-list
-                xmlns:android="http://schemas.android.com/apk/res/android"
-                android:oneshot="false">
-            <item android:drawable="@drawable/stat_sys_battery_charge_anim1" android:duration="2000" />
-            <item android:drawable="@drawable/stat_sys_battery_charge_anim2" android:duration="1000" />
-            <item android:drawable="@drawable/stat_sys_battery_charge_anim3" android:duration="1000" />
-            <item android:drawable="@drawable/stat_sys_battery_charge_anim4" android:duration="1000" />
-            <item android:drawable="@drawable/stat_sys_battery_charge_anim5" android:duration="1000" />
-        </animation-list>
-    </item>
-    <item android:maxLevel="49">
-        <animation-list
-                xmlns:android="http://schemas.android.com/apk/res/android"
-                android:oneshot="false">
-            <item android:drawable="@drawable/stat_sys_battery_charge_anim2" android:duration="2000" />
-            <item android:drawable="@drawable/stat_sys_battery_charge_anim3" android:duration="1000" />
-            <item android:drawable="@drawable/stat_sys_battery_charge_anim4" android:duration="1000" />
-            <item android:drawable="@drawable/stat_sys_battery_charge_anim5" android:duration="1000" />
-        </animation-list>
-    </item>
-    <item android:maxLevel="69">
-        <animation-list
-                xmlns:android="http://schemas.android.com/apk/res/android"
-                android:oneshot="false">
-            <item android:drawable="@drawable/stat_sys_battery_charge_anim3" android:duration="2000" />
-            <item android:drawable="@drawable/stat_sys_battery_charge_anim4" android:duration="1000" />
-            <item android:drawable="@drawable/stat_sys_battery_charge_anim5" android:duration="1000" />
-        </animation-list>
-    </item>
-    <item android:maxLevel="89">
-        <animation-list
-                xmlns:android="http://schemas.android.com/apk/res/android"
-                android:oneshot="false">
-            <item android:drawable="@drawable/stat_sys_battery_charge_anim4" android:duration="2000" />
-            <item android:drawable="@drawable/stat_sys_battery_charge_anim5" android:duration="1000" />
-        </animation-list>
-    </item>
-    <item android:maxLevel="101" android:drawable="@drawable/stat_sys_battery_charge_anim5" />
+    <item android:maxLevel="4" android:drawable="@android:drawable/stat_sys_battery_charge_anim0" />
+    <item android:maxLevel="15" android:drawable="@android:drawable/stat_sys_battery_charge_anim15" />
+    <item android:maxLevel="35" android:drawable="@android:drawable/stat_sys_battery_charge_anim28" />
+    <item android:maxLevel="49" android:drawable="@android:drawable/stat_sys_battery_charge_anim43" />
+    <item android:maxLevel="60" android:drawable="@android:drawable/stat_sys_battery_charge_anim57" />
+    <item android:maxLevel="75" android:drawable="@android:drawable/stat_sys_battery_charge_anim71" />
+    <item android:maxLevel="90" android:drawable="@android:drawable/stat_sys_battery_charge_anim85" />
+    <item android:maxLevel="100" android:drawable="@android:drawable/stat_sys_battery_charge_anim100" />
 </level-list>
 
+
diff --git a/core/res/res/layout-xlarge/status_bar_latest_event_content.xml b/core/res/res/layout-xlarge/status_bar_latest_event_content.xml
index d599154..e4aa270 100644
--- a/core/res/res/layout-xlarge/status_bar_latest_event_content.xml
+++ b/core/res/res/layout-xlarge/status_bar_latest_event_content.xml
@@ -1,23 +1,20 @@
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-        android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        >
-
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    >
     <ImageView android:id="@+id/icon"
         android:layout_width="48dp"
         android:layout_height="64dp"
-        android:layout_alignParentLeft="true"
-        android:layout_alignParentTop="true"
+        android:layout_marginLeft="4dp"
         android:scaleType="center"
         />
-
     <LinearLayout
         android:layout_width="0dp"
         android:layout_height="wrap_content"
         android:layout_gravity="center_vertical"
         android:layout_weight="1"
         android:orientation="vertical"
-        android:paddingLeft="16dp"
+        android:paddingLeft="8dp"
         >
         <TextView android:id="@+id/title"
             android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title"
@@ -37,5 +34,13 @@
             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"
+        />
 </LinearLayout>
 
diff --git a/core/res/res/layout-xlarge/status_bar_latest_event_content_large_icon.xml b/core/res/res/layout-xlarge/status_bar_latest_event_content_large_icon.xml
new file mode 100644
index 0000000..1e1f9de
--- /dev/null
+++ b/core/res/res/layout-xlarge/status_bar_latest_event_content_large_icon.xml
@@ -0,0 +1,44 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    >
+    <LinearLayout
+        android:layout_width="0dp"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_vertical"
+        android:layout_weight="1"
+        android:orientation="vertical"
+        >
+        <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"
+            />
+        <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: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"
+        />
+    <ImageView android:id="@+id/icon"
+        android:layout_width="48dp"
+        android:layout_height="64dp"
+        android:scaleType="center"
+        />
+</LinearLayout>
+
diff --git a/core/res/res/layout-xlarge/status_bar_latest_event_ticker.xml b/core/res/res/layout-xlarge/status_bar_latest_event_ticker.xml
new file mode 100644
index 0000000..b09ed44
--- /dev/null
+++ b/core/res/res/layout-xlarge/status_bar_latest_event_ticker.xml
@@ -0,0 +1,44 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="@dimen/status_bar_height"
+    >
+    <ImageView android:id="@+id/icon"
+        android:layout_width="48dp"
+        android:layout_height="match_parent"
+        android:scaleType="center"
+        />
+    <LinearLayout
+        android:layout_width="0dp"
+        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"
+            />
+        <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: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"
+        />
+</LinearLayout>
+
diff --git a/core/res/res/layout-xlarge/status_bar_latest_event_ticker_large_icon.xml b/core/res/res/layout-xlarge/status_bar_latest_event_ticker_large_icon.xml
new file mode 100644
index 0000000..6c2e6f7
--- /dev/null
+++ b/core/res/res/layout-xlarge/status_bar_latest_event_ticker_large_icon.xml
@@ -0,0 +1,44 @@
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    >
+    <LinearLayout
+        android:layout_width="0dp"
+        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"
+            />
+        <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: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"
+        />
+    <ImageView android:id="@+id/icon"
+        android:layout_width="48dp"
+        android:layout_height="match_parent"
+        android:scaleType="center"
+        />
+</LinearLayout>
+
diff --git a/core/res/res/values-xlarge/dimens.xml b/core/res/res/values-xlarge/dimens.xml
index f52c627..fef3c13 100644
--- a/core/res/res/values-xlarge/dimens.xml
+++ b/core/res/res/values-xlarge/dimens.xml
@@ -21,6 +21,9 @@
     <dimen name="status_bar_height">48dip</dimen>
     <!-- Height of the status bar -->
     <dimen name="status_bar_icon_size">48dip</dimen>
+    <!-- Size of the giant number (unread count) in the notifications -->
+    <dimen name="status_bar_content_number_size">48sp</dimen>
+    
     <!-- Margin at the edge of the screen to ignore touch events for in the windowshade. -->
     <!-- Margin for permanent screen decorations at the bottom. -->
     <dimen name="screen_margin_bottom">48dip</dimen>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 403ec2f..7a429b0 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -213,12 +213,17 @@
         <item name="android:textStyle">bold</item>
     </style>
     <style name="TextAppearance.StatusBar.EventContent">
+        <item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
         <item name="android:textColor">?android:attr/textColorPrimaryInverse</item>
     </style>
     <style name="TextAppearance.StatusBar.EventContent.Title">
         <item name="android:textSize">18sp</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>
+    </style>
 
     <!-- Widget Styles -->
 
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
deleted file mode 100644
index 6baf5ea..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_default.png
new file mode 100644
index 0000000..615c8b6
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png
new file mode 100644
index 0000000..0122025
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.png
new file mode 100644
index 0000000..0786916
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_pressed.png
new file mode 100644
index 0000000..35f9240
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
deleted file mode 100644
index ed813dc..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_default.png
new file mode 100644
index 0000000..3eb22df
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_pressed.png
new file mode 100644
index 0000000..1ce9bd1
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_default.png
index bf33c946..259db7a 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_default.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png
new file mode 100644
index 0000000..993ea55
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
deleted file mode 100644
index d7775f2..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_default.png
new file mode 100644
index 0000000..fef2cf9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_pressed.png
new file mode 100644
index 0000000..05593bc
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
deleted file mode 100644
index 178af73..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_default.png
new file mode 100644
index 0000000..32c2c79
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_pressed.png
new file mode 100644
index 0000000..142c413
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/status_bar_home.xml b/packages/SystemUI/res/drawable/ic_sysbar_back.xml
similarity index 89%
copy from packages/SystemUI/res/drawable/status_bar_home.xml
copy to packages/SystemUI/res/drawable/ic_sysbar_back.xml
index 0011711..327ccd8 100644
--- a/packages/SystemUI/res/drawable/status_bar_home.xml
+++ b/packages/SystemUI/res/drawable/ic_sysbar_back.xml
@@ -15,7 +15,7 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true" android:drawable="@drawable/status_bar_home_pressed" />
-    <item android:drawable="@drawable/status_bar_home_default" />
+    <item android:state_pressed="true" android:drawable="@drawable/ic_sysbar_back_pressed" />
+    <item android:drawable="@drawable/ic_sysbar_back_default" />
 </selector>
 
diff --git a/packages/SystemUI/res/drawable/status_bar_home.xml b/packages/SystemUI/res/drawable/ic_sysbar_home.xml
similarity index 89%
copy from packages/SystemUI/res/drawable/status_bar_home.xml
copy to packages/SystemUI/res/drawable/ic_sysbar_home.xml
index 0011711..f4e585e 100644
--- a/packages/SystemUI/res/drawable/status_bar_home.xml
+++ b/packages/SystemUI/res/drawable/ic_sysbar_home.xml
@@ -15,7 +15,7 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true" android:drawable="@drawable/status_bar_home_pressed" />
-    <item android:drawable="@drawable/status_bar_home_default" />
+    <item android:state_pressed="true" android:drawable="@drawable/ic_sysbar_home_pressed" />
+    <item android:drawable="@drawable/ic_sysbar_home_default" />
 </selector>
 
diff --git a/packages/SystemUI/res/drawable/status_bar_home.xml b/packages/SystemUI/res/drawable/ic_sysbar_ime.xml
similarity index 89%
rename from packages/SystemUI/res/drawable/status_bar_home.xml
rename to packages/SystemUI/res/drawable/ic_sysbar_ime.xml
index 0011711..1accf00 100644
--- a/packages/SystemUI/res/drawable/status_bar_home.xml
+++ b/packages/SystemUI/res/drawable/ic_sysbar_ime.xml
@@ -15,7 +15,7 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true" android:drawable="@drawable/status_bar_home_pressed" />
-    <item android:drawable="@drawable/status_bar_home_default" />
+    <item android:state_pressed="true" android:drawable="@drawable/ic_sysbar_ime_pressed" />
+    <item android:drawable="@drawable/ic_sysbar_ime_default" />
 </selector>
 
diff --git a/packages/SystemUI/res/drawable/status_bar_home.xml b/packages/SystemUI/res/drawable/ic_sysbar_menu.xml
similarity index 89%
copy from packages/SystemUI/res/drawable/status_bar_home.xml
copy to packages/SystemUI/res/drawable/ic_sysbar_menu.xml
index 0011711..7a10607 100644
--- a/packages/SystemUI/res/drawable/status_bar_home.xml
+++ b/packages/SystemUI/res/drawable/ic_sysbar_menu.xml
@@ -15,7 +15,7 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true" android:drawable="@drawable/status_bar_home_pressed" />
-    <item android:drawable="@drawable/status_bar_home_default" />
+    <item android:state_pressed="true" android:drawable="@drawable/ic_sysbar_menu_pressed" />
+    <item android:drawable="@drawable/ic_sysbar_menu_default" />
 </selector>
 
diff --git a/packages/SystemUI/res/drawable/status_bar_home.xml b/packages/SystemUI/res/drawable/ic_sysbar_recent.xml
old mode 100644
new mode 100755
similarity index 88%
copy from packages/SystemUI/res/drawable/status_bar_home.xml
copy to packages/SystemUI/res/drawable/ic_sysbar_recent.xml
index 0011711..39a324b
--- a/packages/SystemUI/res/drawable/status_bar_home.xml
+++ b/packages/SystemUI/res/drawable/ic_sysbar_recent.xml
@@ -15,7 +15,7 @@
 -->
 
 <selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true" android:drawable="@drawable/status_bar_home_pressed" />
-    <item android:drawable="@drawable/status_bar_home_default" />
+    <item android:state_pressed="true" android:drawable="@drawable/ic_sysbar_recent_pressed" />
+    <item android:drawable="@drawable/ic_sysbar_recent_default" />
 </selector>
 
diff --git a/packages/SystemUI/res/drawable/status_bar_back.xml b/packages/SystemUI/res/drawable/status_bar_back.xml
deleted file mode 100644
index 92bf147..0000000
--- a/packages/SystemUI/res/drawable/status_bar_back.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true" android:drawable="@drawable/status_bar_back_pressed" />
-    <item android:drawable="@drawable/status_bar_back_default" />
-</selector>
-
diff --git a/packages/SystemUI/res/drawable/status_bar_menu.xml b/packages/SystemUI/res/drawable/status_bar_menu.xml
deleted file mode 100644
index aa7286e..0000000
--- a/packages/SystemUI/res/drawable/status_bar_menu.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true" android:drawable="@drawable/status_bar_menu_pressed" />
-    <item android:drawable="@drawable/status_bar_menu_default" />
-</selector>
-
diff --git a/packages/SystemUI/res/drawable/status_bar_recent.xml b/packages/SystemUI/res/drawable/status_bar_recent.xml
deleted file mode 100755
index d708455..0000000
--- a/packages/SystemUI/res/drawable/status_bar_recent.xml
+++ /dev/null
@@ -1,21 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
-
-     Licensed under the Apache License, Version 2.0 (the "License");
-     you may not use this file except in compliance with the License.
-     You may obtain a copy of the License at
-
-          http://www.apache.org/licenses/LICENSE-2.0
-
-     Unless required by applicable law or agreed to in writing, software
-     distributed under the License is distributed on an "AS IS" BASIS,
-     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-     See the License for the specific language governing permissions and
-     limitations under the License.
--->
-
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true" android:drawable="@drawable/status_bar_recent_pressed" />
-    <item android:drawable="@drawable/status_bar_recent_default" />
-</selector>
-
diff --git a/packages/SystemUI/res/drawable/ic_sysbar_icon_bg.xml b/packages/SystemUI/res/drawable/status_bar_ticker_background.xml
similarity index 73%
rename from packages/SystemUI/res/drawable/ic_sysbar_icon_bg.xml
rename to packages/SystemUI/res/drawable/status_bar_ticker_background.xml
index d8ba2a8..c230358 100644
--- a/packages/SystemUI/res/drawable/ic_sysbar_icon_bg.xml
+++ b/packages/SystemUI/res/drawable/status_bar_ticker_background.xml
@@ -4,9 +4,9 @@
      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.
@@ -14,8 +14,14 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true" android:drawable="@drawable/ic_sysbar_press_bg" />
-    <item android:drawable="@drawable/ic_sysbar_default_bg" />
-</selector>
+<layer-list
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:opacity="translucent"
+    >
+    <item
+        android:drawable="@drawable/ticker_background_color"
+        android:top="12dp"
+        />
+</layer-list>
+
 
diff --git a/packages/SystemUI/res/drawable/status_bar_home.xml b/packages/SystemUI/res/drawable/ticker_background.xml
similarity index 61%
copy from packages/SystemUI/res/drawable/status_bar_home.xml
copy to packages/SystemUI/res/drawable/ticker_background.xml
index 0011711..7320fa0 100644
--- a/packages/SystemUI/res/drawable/status_bar_home.xml
+++ b/packages/SystemUI/res/drawable/ticker_background.xml
@@ -1,12 +1,12 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2008 The Android Open Source Project
+<!-- Copyright (C) 2006 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
      you may not use this file except in compliance with the License.
      You may obtain a copy of the License at
-
+  
           http://www.apache.org/licenses/LICENSE-2.0
-
+  
      Unless required by applicable law or agreed to in writing, software
      distributed under the License is distributed on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -14,8 +14,14 @@
      limitations under the License.
 -->
 
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
-    <item android:state_pressed="true" android:drawable="@drawable/status_bar_home_pressed" />
-    <item android:drawable="@drawable/status_bar_home_default" />
-</selector>
+<layer-list
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:opacity="translucent"
+    >
+    <!-- the large icon extends 12dp beyond the edge of the status bar -->
+    <item
+        android:drawable="@drawable/notification_item_background_color"
+        android:top="12dp"
+        />
+</layer-list>
 
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar.xml b/packages/SystemUI/res/layout-xlarge/status_bar.xml
index d11e6da..4fa306e 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar.xml
@@ -39,7 +39,6 @@
                 android:id="@+id/notificationIcons"
                 android:layout_width="wrap_content"
                 android:layout_height="match_parent"
-                android:gravity="center_vertical"
                 android:orientation="horizontal"
                 >
                 <view
@@ -47,7 +46,9 @@
                     android:id="@+id/icons"
                     android:layout_width="wrap_content"
                     android:layout_height="@*android:dimen/status_bar_icon_size"
-                    android:layout_marginLeft="8dip"
+                    android:layout_gravity="top"
+                    android:layout_marginTop="5dp"
+                    android:layout_marginLeft="8dp"
                     />
             </com.android.systemui.statusbar.tablet.NotificationIconArea>
 
@@ -84,13 +85,15 @@
                         android:id="@+id/battery"
                         android:layout_height="wrap_content"
                         android:layout_width="wrap_content"
-                        android:layout_gravity="center_vertical"
+                        android:layout_gravity="top"
+                        android:layout_marginTop="18dp"
                         />
                     <ImageView
                         android:id="@+id/network"
                         android:layout_height="wrap_content"
                         android:layout_width="wrap_content"
-                        android:layout_gravity="center_vertical"
+                        android:layout_gravity="top"
+                        android:layout_marginTop="14dp"
                         android:src="@drawable/ic_sysbar_wifi_mini"
                         />
                 </LinearLayout>
@@ -112,7 +115,6 @@
                 android:paddingLeft="18dip"
                 android:paddingRight="18dip"
                 android:src="@drawable/ic_sysbar_back"
-                android:background="@drawable/ic_sysbar_icon_bg"
                 systemui:keyCode="4"
                 />
             <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
@@ -121,14 +123,13 @@
                 android:paddingLeft="18dip"
                 android:paddingRight="18dip"
                 android:src="@drawable/ic_sysbar_home"
-                android:background="@drawable/ic_sysbar_icon_bg"
                 systemui:keyCode="3"
                 />
             <ImageButton android:id="@+id/recent_apps"
                 android:layout_width="96dip"
                 android:layout_height="match_parent"
                 android:src="@drawable/ic_sysbar_recent"
-                android:background="@drawable/ic_sysbar_icon_bg"
+                android:background="@null"
                 android:paddingLeft="18dip"
                 android:clickable="true"
                 android:paddingRight="18dip"
@@ -139,7 +140,6 @@
                 android:paddingLeft="18dip"
                 android:paddingRight="18dip"
                 android:src="@drawable/ic_sysbar_menu"
-                android:background="@drawable/ic_sysbar_icon_bg"
                 systemui:keyCode="82"
                 android:visibility="invisible"
                 />
@@ -147,7 +147,6 @@
                 android:id="@+id/pocket"
                 android:layout_width="96dip"
                 android:layout_height="match_parent"
-                android:background="@drawable/ic_sysbar_icon_bg"
                 android:paddingLeft="18dip"
                 android:paddingRight="18dip"
                 android:animateLayoutChanges="true"
@@ -169,8 +168,7 @@
                 android:layout_width="wrap_content"
                 android:layout_height="match_parent"
                 android:layout_marginLeft="8dip"
-                android:src="@drawable/ic_sysbar_ime_default"
-                android:background="@drawable/ic_sysbar_icon_bg"
+                android:src="@drawable/ic_sysbar_ime"
                 android:visibility="invisible"
                 />
         </LinearLayout>
@@ -238,17 +236,5 @@
                 android:visibility="gone"
                 />
         </RelativeLayout>
-
-        <!-- ticker: transient incoming notification information -->
-        <FrameLayout
-            android:id="@+id/ticker"
-            android:layout_width="wrap_content"
-            android:layout_height="match_parent"
-            android:layout_alignParentRight="true"
-            android:layout_toRightOf="@+id/systemInfo"
-            android:paddingLeft="6dip"
-            android:gravity="center_vertical"
-            />
-            
     </RelativeLayout>
 </com.android.systemui.statusbar.tablet.TabletStatusBarView>
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_latest_event.xml b/packages/SystemUI/res/layout-xlarge/status_bar_latest_event.xml
index b6679a5..6b12d29 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_latest_event.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_latest_event.xml
@@ -13,13 +13,24 @@
         android:src="@drawable/status_bar_veto"
         android:scaleType="center"
         android:background="#ff000000"
+        android:paddingRight="8dp"
         />
 
+    <ImageView
+        android:id="@+id/large_icon"
+        android:layout_width="@dimen/notification_large_icon_width"
+        android:layout_height="@dimen/notification_large_icon_height"
+        android:layout_alignParentTop="true"
+        android:layout_alignParentLeft="true"
+        android:scaleType="center"
+        />
+        <!-- TODO: scaleType should be top-left but ImageView doesn't support that. -->
+
     <com.android.systemui.statusbar.LatestItemView android:id="@+id/content"
         android:layout_width="wrap_content"
         android:layout_height="64sp"
         android:layout_alignParentTop="true"
-        android:layout_alignParentLeft="true"
+        android:layout_toRightOf="@id/large_icon"
         android:layout_toLeftOf="@id/veto"
         android:layout_marginLeft="16dp"
         android:focusable="true"
diff --git a/packages/SystemUI/res/layout-xlarge/sysbar_panel_notifications.xml b/packages/SystemUI/res/layout-xlarge/sysbar_panel_notifications.xml
index b23cc7b..f9e2d5e 100644
--- a/packages/SystemUI/res/layout-xlarge/sysbar_panel_notifications.xml
+++ b/packages/SystemUI/res/layout-xlarge/sysbar_panel_notifications.xml
@@ -1,43 +1,40 @@
-<?xml version="1.0" encoding="utf-8"?>
 <!--
-/* apps/common/assets/default/default/skins/StatusBar.xml
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License"); 
-** you may not use this file except in compliance with the License. 
-** You may obtain a copy of the License at 
-**
-**     http://www.apache.org/licenses/LICENSE-2.0 
-**
-** Unless required by applicable law or agreed to in writing, software 
-** distributed under the License is distributed on an "AS IS" BASIS, 
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
-** See the License for the specific language governing permissions and 
-** limitations under the License.
-*/
+  Copyright (C) 2006 The Android Open Source Project
+ 
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+ 
+       http://www.apache.org/licenses/LICENSE-2.0
+ 
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
 -->
 
 <!--    android:background="@drawable/status_bar_closed_default_background" -->
 <com.android.systemui.statusbar.tablet.NotificationPanel
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_height="match_parent"
-    android:layout_width="540dp"
+    android:layout_width="match_parent"
     android:animateLayoutChanges="true"
     android:background="@drawable/bg_scrim_notification"
+    android:paddingTop="32dp"
     android:paddingBottom="32dp"
+    android:orientation="vertical"
+    android:gravity="right"
     >
 
     <com.android.systemui.statusbar.tablet.NotificationTitleArea
         android:id="@+id/title_area"
-        android:layout_height="wrap_content"
+        android:layout_height="160dp"
         android:layout_width="384dp"
-        android:layout_above="@+id/content_frame"
         android:layout_marginLeft="24dp"
-        android:paddingBottom="16dp"
+        android:paddingTop="20dp"
         android:orientation="vertical"
         android:animateLayoutChanges="true"
-        android:layout_alignParentRight="true"
         >
 
         <com.android.systemui.statusbar.tablet.HoloClock
@@ -143,8 +140,6 @@
         android:id="@+id/content_frame"
         android:layout_height="wrap_content"
         android:layout_width="408dp"
-        android:layout_alignParentBottom="true"
-        android:layout_alignParentRight="true"
         >
         <ScrollView
             android:id="@+id/notificationScroller"
diff --git a/packages/SystemUI/res/layout-xlarge/ticker.xml b/packages/SystemUI/res/layout-xlarge/ticker.xml
index c8d855f..cae6a77 100644
--- a/packages/SystemUI/res/layout-xlarge/ticker.xml
+++ b/packages/SystemUI/res/layout-xlarge/ticker.xml
@@ -18,36 +18,22 @@
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
+    android:layout_height="wrap_content"
     android:orientation="horizontal"
-    android:background="#ff000000"
+    android:background="@drawable/status_bar_ticker_background"
+    android:gravity="bottom"
     >
+    <!--
+    android:background="@drawable/ticker_background"
+    -->
 
-    <LinearLayout
-        xmlns:android="http://schemas.android.com/apk/res/android"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_weight="1"
-        android:layout_gravity="center_vertical"
-        android:orientation="vertical"
-        android:paddingLeft="12dp"
-        >
-
-        <TextView android:id="@+id/title"
-            xmlns:android="http://schemas.android.com/apk/res/android"
-            android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:textStyle="bold"
-            android:maxLines="1"
-            />
-        <TextView android:id="@+id/subtitle"
-            xmlns:android="http://schemas.android.com/apk/res/android"
-            android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:maxLines="1"
-            />
-    </LinearLayout>
+    <ImageView
+        android:id="@+id/large_icon"
+        android:layout_width="@dimen/notification_large_icon_height"
+        android:layout_height="@dimen/notification_large_icon_width"
+        android:scaleType="center"
+        android:visibility="gone"
+        />
+        <!-- TODO: scaleType should be top-left but ImageView doesn't support that. -->
 
 </LinearLayout>
diff --git a/packages/SystemUI/res/layout-xlarge/ticker_compat.xml b/packages/SystemUI/res/layout-xlarge/ticker_compat.xml
index 79c7543..5d9a680 100644
--- a/packages/SystemUI/res/layout-xlarge/ticker_compat.xml
+++ b/packages/SystemUI/res/layout-xlarge/ticker_compat.xml
@@ -18,11 +18,26 @@
 <LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="match_parent"
+    android:layout_height="@*android:dimen/status_bar_height"
     android:orientation="horizontal"
-    android:background="#ff000000"
+    android:background="@drawable/status_bar_ticker_background"
     >
 
+    <ImageView
+        android:id="@+id/large_icon"
+        android:layout_width="@dimen/notification_large_icon_width"
+        android:layout_height="@dimen/notification_large_icon_height"
+        android:scaleType="center"
+        android:visibility="gone"
+        />
+    
+    <ImageView android:id="@+id/left_icon"
+        android:layout_width="64dp"
+        android:layout_height="match_parent"
+        android:scaleType="center"
+        android:visibility="gone"
+        />
+
     <TextView android:id="@+id/text"
         android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker"
         android:layout_width="match_parent"
@@ -33,4 +48,11 @@
         android:maxLines="2"
         />
 
+    <ImageView android:id="@+id/right_icon"
+        android:layout_width="64dp"
+        android:layout_height="match_parent"
+        android:scaleType="center"
+        android:visibility="gone"
+        />
+
 </LinearLayout>
diff --git a/packages/SystemUI/res/values-xlarge/config.xml b/packages/SystemUI/res/values-xlarge/config.xml
index e6af4f5..e140914 100644
--- a/packages/SystemUI/res/values-xlarge/config.xml
+++ b/packages/SystemUI/res/values-xlarge/config.xml
@@ -26,5 +26,8 @@
      interface.  This name is in the ComponentName flattened format (package/class)  -->
     <string name="config_statusBarComponent">com.android.systemui.statusbar.tablet.TabletStatusBar</string>
 
+    <!-- Whether or not we show the number in the bar. -->
+    <bool name="config_statusBarShowNumber">false</bool>
+
 </resources>
 
diff --git a/packages/SystemUI/res/values-xlarge/dimens.xml b/packages/SystemUI/res/values-xlarge/dimens.xml
new file mode 100644
index 0000000..009b7a8
--- /dev/null
+++ b/packages/SystemUI/res/values-xlarge/dimens.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ * Copyright (c) 2006, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+*/
+-->
+<resources>
+    <!-- The width of the big icons in notifications. -->
+    <dimen name="notification_large_icon_width">60dp</dimen>
+    <!-- The width of the big icons in notifications. -->
+    <dimen name="notification_large_icon_height">60dp</dimen>
+    <!-- The width of the ticker, including the icon -->
+    <dimen name="notification_ticker_width">360dp</dimen>
+</resources>
+
+
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index fd2cf99..964e69b 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -19,4 +19,5 @@
 <resources>
     <drawable name="notification_number_text_color">#ffffffff</drawable>
     <drawable name="notification_item_background_color">#ff000000</drawable>
+    <drawable name="ticker_background_color">#ff1d1d1d</drawable>
 </resources>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 86beb14..05ed089 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -35,5 +35,8 @@
      interface.  This name is in the ComponentName flattened format (package/class)  -->
     <string name="config_statusBarComponent" translatable="false">com.android.systemui.statusbar.phone.PhoneStatusBar</string>
 
+    <!-- Whether or not we show the number in the bar. -->
+    <bool name="config_statusBarShowNumber">true</bool>
+
 </resources>
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 9a61be6..dbfbe11 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -93,7 +93,8 @@
             setImageLevel(icon.iconLevel);
         }
         if (!numberEquals) {
-            if (icon.number > 0) {
+            if (icon.number > 0 && mContext.getResources().getBoolean(
+                        R.bool.config_statusBarShowNumber)) {
                 if (mNumberBackground == null) {
                     mNumberBackground = getContext().getResources().getDrawable(
                             R.drawable.ic_notification_overlay);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
index 80cb5b2..5f49d8c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
@@ -19,16 +19,16 @@
 import android.content.Context;
 import android.util.AttributeSet;
 import android.util.Slog;
-import android.widget.ImageView;
-import android.widget.RelativeLayout;
-import android.widget.TextView;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.widget.FrameLayout;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
 
 import com.android.systemui.R;
 
-public class NotificationPanel extends RelativeLayout implements StatusBarPanel,
+public class NotificationPanel extends LinearLayout implements StatusBarPanel,
         View.OnClickListener {
     static final String TAG = "NotificationPanel";
 
@@ -71,6 +71,29 @@
         }
     }
 
+    /**
+     * We need to be aligned at the bottom.  LinearLayout can't do this, so instead,
+     * let LinearLayout do all the hard work, and then shift everything down to the bottom.
+     */
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        super.onLayout(changed, l, t, r, b);
+        // We know that none of our children are GONE, so don't worry about skipping GONE views.
+        final int N = getChildCount();
+        if (N == 0) {
+            return;
+        }
+        final int allocatedBottom = getChildAt(N-1).getBottom();
+        final int shift = b - allocatedBottom - getPaddingBottom();
+        if (shift <= 0) {
+            return;
+        }
+        for (int i=0; i<N; i++) {
+            final View c = getChildAt(i);
+            c.layout(c.getLeft(), c.getTop() + shift, c.getRight(), c.getBottom() + shift);
+        }
+    }
+
     public void onClick(View v) {
         if (v == mSettingsButton) {
             switchToSettingsMode();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 233ac45..ab509ef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -132,8 +132,6 @@
     NotificationIconArea.IconLayout mIconLayout;
 
     TabletTicker mTicker;
-    View mTickerView;
-    boolean mTicking;
 
     // for disabling the status bar
     int mDisabled = 0;
@@ -167,7 +165,7 @@
         mStatusBarView.setIgnoreChildren(0, mNotificationTrigger, mNotificationPanel);
 
         WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
-                ViewGroup.LayoutParams.WRAP_CONTENT,
+                ViewGroup.LayoutParams.MATCH_PARENT,
                 ViewGroup.LayoutParams.MATCH_PARENT,
                 WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
                 WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
@@ -278,7 +276,7 @@
         mNotificationPeekTapDuration = vc.getTapTimeout();
         mNotificationFlingVelocity = 300; // px/s
 
-        mTicker = new TabletTicker(context, (FrameLayout)sb.findViewById(R.id.ticker));
+        mTicker = new TabletTicker(context);
 
         // The icons
         mBatteryController = new BatteryController(mContext);
@@ -385,9 +383,7 @@
                     if (DEBUG) Slog.d(TAG, "opening notifications panel");
                     if (mNotificationPanel.getVisibility() == View.GONE) {
                         mNotificationPeekWindow.setVisibility(View.GONE);
-
                         mNotificationPanel.setVisibility(View.VISIBLE);
-
                         // synchronize with current shadow state
                         mShadowController.hideElement(mNotificationArea);
                     }
@@ -396,7 +392,6 @@
                     if (DEBUG) Slog.d(TAG, "closing notifications panel");
                     if (mNotificationPanel.getVisibility() == View.VISIBLE) {
                         mNotificationPanel.setVisibility(View.GONE);
-
                         // synchronize with current shadow state
                         mShadowController.showElement(mNotificationArea);
                     }
@@ -464,7 +459,7 @@
         boolean immersive = false;
         try {
             immersive = ActivityManagerNative.getDefault().isTopActivityImmersive();
-            Slog.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive"));
+            //Slog.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive"));
         } catch (RemoteException ex) {
         }
         if (false && immersive) {
@@ -603,9 +598,7 @@
     }
 
     private boolean hasTicker(Notification n) {
-        return !TextUtils.isEmpty(n.tickerText)
-                || !TextUtils.isEmpty(n.tickerTitle)
-                || !TextUtils.isEmpty(n.tickerSubtitle);
+        return n.tickerView != null || !TextUtils.isEmpty(n.tickerText);
     }
 
     private void tick(StatusBarNotification n) {
@@ -1005,13 +998,21 @@
                         } catch (RemoteException ex) {
                             // system process is dead if we're here.
                         }
-    //                    animateCollapse();
                     }
                 });
         } else {
             vetoButton.setVisibility(View.INVISIBLE);
         }
 
+        // the large icon
+        ImageView largeIcon = (ImageView)row.findViewById(R.id.large_icon);
+        if (sbn.notification.largeIcon != null) {
+            largeIcon.setImageBitmap(sbn.notification.largeIcon);
+        } else {
+            largeIcon.getLayoutParams().width = 0;
+            largeIcon.setVisibility(View.INVISIBLE);
+        }
+
         // bind the click event to the content area
         ViewGroup content = (ViewGroup)row.findViewById(R.id.content);
         // XXX: update to allow controls within notification views
@@ -1034,7 +1035,7 @@
             exception = e;
         }
         if (expanded == null) {
-            String ident = sbn.pkg + "/0x" + Integer.toHexString(sbn.id);
+            final String ident = sbn.pkg + "/0x" + Integer.toHexString(sbn.id);
             Slog.e(TAG, "couldn't inflate view for notification " + ident, exception);
             return false;
         } else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
index 3c3139f..7f743b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java
@@ -16,9 +16,14 @@
 
 package com.android.systemui.statusbar.tablet;
 
+import java.util.Arrays;
+
 import android.app.Notification;
 import android.content.Context;
+import android.content.res.Resources;
 import android.graphics.Bitmap;
+import android.graphics.PixelFormat;
+import android.graphics.drawable.Drawable;
 import android.os.Handler;
 import android.os.Message;
 import android.util.Slog;
@@ -26,16 +31,18 @@
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
+import android.view.WindowManager;
+import android.view.WindowManagerImpl;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
 import android.widget.LinearLayout;
 import android.widget.TextView;
 
+import com.android.internal.statusbar.StatusBarIcon;
 import com.android.internal.statusbar.StatusBarNotification;
 
 import com.android.systemui.R;
-
-import java.util.Arrays;
+import com.android.systemui.statusbar.StatusBarIconView;
 
 public class TabletTicker extends Handler {
     private static final String TAG = "StatusBar.TabletTicker";
@@ -45,17 +52,16 @@
     private static final int ADVANCE_DELAY = 5000; // 5 seconds
 
     private Context mContext;
-    private FrameLayout mParent;
 
+    private ViewGroup mWindow;
     private StatusBarNotification mCurrentNotification;
     private View mCurrentView;
 
     private StatusBarNotification[] mQueue;
     private int mQueuePos;
 
-    public TabletTicker(Context context, FrameLayout parent) {
+    public TabletTicker(Context context) {
         mContext = context;
-        mParent = parent;
 
         // TODO: Make this a configuration value.
         // 3 is enough to let us see most cases, but not get so far behind that it's annoying.
@@ -102,18 +108,33 @@
     private void advance() {
         // Out with the old...
         if (mCurrentView != null) {
-            mParent.removeView(mCurrentView);
+            mWindow.removeView(mCurrentView);
             mCurrentView = null;
             mCurrentNotification = null;
         }
 
         // In with the new...
-        final StatusBarNotification next = dequeue();
-        if (next != null) {
+        StatusBarNotification next = dequeue();
+        while (next != null) {
             mCurrentNotification = next;
             mCurrentView = makeTickerView(next);
-            mParent.addView(mCurrentView);
-            sendEmptyMessageDelayed(MSG_ADVANCE, ADVANCE_DELAY);
+            if (mCurrentView != null) {
+                if (mWindow == null) {
+                    mWindow = makeWindow();
+                    WindowManagerImpl.getDefault().addView(mWindow, mWindow.getLayoutParams());
+                }
+                mWindow.addView(mCurrentView);
+                sendEmptyMessageDelayed(MSG_ADVANCE, ADVANCE_DELAY);
+                break;
+            }
+            next = dequeue();
+        }
+
+        // if there's nothing left, close the window
+        // TODO: Do this when the animation is done instead
+        if (mCurrentView == null) {
+            WindowManagerImpl.getDefault().removeView(mWindow);
+            mWindow = null;
         }
     }
 
@@ -133,46 +154,76 @@
         return notification;
     }
 
+    private ViewGroup makeWindow() {
+        final Resources res = mContext.getResources();
+        final FrameLayout view = new FrameLayout(mContext);
+        final int width = res.getDimensionPixelSize(R.dimen.notification_ticker_width);
+        final int height = res.getDimensionPixelSize(R.dimen.notification_large_icon_height);
+        WindowManager.LayoutParams lp = new WindowManager.LayoutParams(width, height,
+                WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
+                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
+                    | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                    | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
+                PixelFormat.TRANSLUCENT);
+        lp.gravity = Gravity.BOTTOM | Gravity.RIGHT;
+        lp.setTitle("NotificationTicker");
+        view.setLayoutParams(lp);
+        return view;
+    }
+
     private View makeTickerView(StatusBarNotification notification) {
         final Notification n = notification.notification;
 
         LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(
                 Context.LAYOUT_INFLATER_SERVICE);
 
-        int layoutId;
         ViewGroup group;
-        if (n.tickerTitle != null || n.tickerSubtitle != null) {
-            group = (ViewGroup)inflater.inflate(R.layout.ticker, mParent, false);
-            if (n.tickerTitle != null) {
-                final TextView title = (TextView)group.findViewById(R.id.title);
-                title.setText(n.tickerTitle);
-            }
-            if (n.tickerSubtitle != null) {
-                final TextView subtitle = (TextView)group.findViewById(R.id.subtitle);
-                subtitle.setText(n.tickerSubtitle);
-            }
+        int layoutId;
+        int iconId;
+        if (n.largeIcon != null) {
+            iconId = R.id.right_icon;
         } else {
-            group = (ViewGroup)inflater.inflate(R.layout.ticker_compat, mParent, false);
+            iconId = R.id.left_icon;
+        }
+        if (n.tickerView != null) {
+            group = (ViewGroup)inflater.inflate(R.layout.ticker, null, false);
+            View expanded = null;
+            Exception exception = null;
+            try {
+                expanded = n.tickerView.apply(mContext, group);
+            }
+            catch (RuntimeException e) {
+                exception = e;
+            }
+            if (expanded == null) {
+                final String ident = notification.pkg
+                        + "/0x" + Integer.toHexString(notification.id);
+                Slog.e(TAG, "couldn't inflate view for notification " + ident, exception);
+                return null;
+            }
+            final int statusBarHeight = mContext.getResources().getDimensionPixelSize(
+                    com.android.internal.R.dimen.status_bar_height);
+            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
+                    ViewGroup.LayoutParams.WRAP_CONTENT, statusBarHeight, 1.0f);
+            lp.gravity = Gravity.BOTTOM;
+            group.addView(expanded, lp);
+        } else if (n.tickerText != null) {
+            group = (ViewGroup)inflater.inflate(R.layout.ticker_compat, mWindow, false);
+            final Drawable icon = StatusBarIconView.getIcon(mContext,
+                    new StatusBarIcon(notification.pkg, n.icon, n.iconLevel, 0));
+            ImageView iv = (ImageView)group.findViewById(iconId);
+            iv.setImageDrawable(icon);
+            iv.setVisibility(View.VISIBLE);
             TextView tv = (TextView)group.findViewById(R.id.text);
             tv.setText(n.tickerText);
+        } else {
+            throw new RuntimeException("tickerView==null && tickerText==null");
         }
-
-        // No more than 2 icons.
-        if (n.tickerIcons != null) {
-            int N = n.tickerIcons.length;
-            if (N > 2) {
-                N = 2;
-            }
-            for (int i=N-1; i>= 0; i--) {
-                Bitmap b = n.tickerIcons[i];
-                if (b != null) {
-                    ImageView iv = (ImageView)inflater.inflate(R.layout.ticker_icon, group, false);
-                    iv.setImageBitmap(b);
-                    group.addView(iv, 0);
-                }
-            }
+        ImageView largeIcon = (ImageView)group.findViewById(R.id.large_icon);
+        if (n.largeIcon != null) {
+            largeIcon.setImageBitmap(n.largeIcon);
+            largeIcon.setVisibility(View.VISIBLE);
         }
-
         return group;
     }
 }
diff --git a/services/java/com/android/server/BatteryService.java b/services/java/com/android/server/BatteryService.java
index 40883bd..47599c8 100644
--- a/services/java/com/android/server/BatteryService.java
+++ b/services/java/com/android/server/BatteryService.java
@@ -473,10 +473,15 @@
     private final int getIcon(int level) {
         if (mBatteryStatus == BatteryManager.BATTERY_STATUS_CHARGING) {
             return com.android.internal.R.drawable.stat_sys_battery_charge;
-        } else if (mBatteryStatus == BatteryManager.BATTERY_STATUS_DISCHARGING ||
-                mBatteryStatus == BatteryManager.BATTERY_STATUS_NOT_CHARGING ||
-                mBatteryStatus == BatteryManager.BATTERY_STATUS_FULL) {
+        } else if (mBatteryStatus == BatteryManager.BATTERY_STATUS_DISCHARGING) {
             return com.android.internal.R.drawable.stat_sys_battery;
+        } else if (mBatteryStatus == BatteryManager.BATTERY_STATUS_NOT_CHARGING
+                || mBatteryStatus == BatteryManager.BATTERY_STATUS_FULL) {
+            if (isPowered() && mBatteryLevel >= 100) {
+                return com.android.internal.R.drawable.stat_sys_battery_charge;
+            } else {
+                return com.android.internal.R.drawable.stat_sys_battery;
+            }
         } else {
             return com.android.internal.R.drawable.stat_sys_battery_unknown;
         }
diff --git a/services/java/com/android/server/NotificationManagerService.java b/services/java/com/android/server/NotificationManagerService.java
index 1081a20..6de7e6a 100755
--- a/services/java/com/android/server/NotificationManagerService.java
+++ b/services/java/com/android/server/NotificationManagerService.java
@@ -272,11 +272,13 @@
 
         public void onNotificationClick(String pkg, String tag, int id) {
             cancelNotification(pkg, tag, id, Notification.FLAG_AUTO_CANCEL,
-                    Notification.FLAG_FOREGROUND_SERVICE);
+                    Notification.FLAG_FOREGROUND_SERVICE, true);
         }
 
         public void onNotificationClear(String pkg, String tag, int id) {
-            cancelNotification(pkg, tag, id, 0, 0); // maybe add some flags?
+            cancelNotification(pkg, tag, id, 0,
+                Notification.FLAG_ONGOING_EVENT | Notification.FLAG_FOREGROUND_SERVICE,
+                true);
         }
 
         public void onPanelRevealed() {
@@ -312,7 +314,7 @@
                 int uid, int initialPid, String message) {
             Slog.d(TAG, "onNotification error pkg=" + pkg + " tag=" + tag + " id=" + id
                     + "; will crashApplication(uid=" + uid + ", pid=" + initialPid + ")");
-            cancelNotification(pkg, tag, id, 0, 0);
+            cancelNotification(pkg, tag, id, 0, 0, false);
             long ident = Binder.clearCallingIdentity();
             try {
                 ActivityManagerNative.getDefault().crashApplication(uid, initialPid, pkg,
@@ -855,7 +857,20 @@
         manager.sendAccessibilityEvent(event);
     }
 
-    private void cancelNotificationLocked(NotificationRecord r) {
+    private void cancelNotificationLocked(NotificationRecord r, boolean sendDelete) {
+        // tell the app
+        if (sendDelete) {
+            if (r.notification.deleteIntent != null) {
+                try {
+                    r.notification.deleteIntent.send();
+                } catch (PendingIntent.CanceledException ex) {
+                    // do nothing - there's no relevant way to recover, and
+                    //     no reason to let this propagate
+                    Slog.w(TAG, "canceled PendingIntent for " + r.pkg, ex);
+                }
+            }
+        }
+
         // status bar
         if (r.notification.icon != 0) {
             long identity = Binder.clearCallingIdentity();
@@ -904,7 +919,7 @@
      * and none of the {@code mustNotHaveFlags}.
      */
     private void cancelNotification(String pkg, String tag, int id, int mustHaveFlags,
-            int mustNotHaveFlags) {
+            int mustNotHaveFlags, boolean sendDelete) {
         EventLog.writeEvent(EventLogTags.NOTIFICATION_CANCEL, pkg, id, mustHaveFlags);
 
         synchronized (mNotificationList) {
@@ -921,7 +936,7 @@
 
                 mNotificationList.remove(index);
 
-                cancelNotificationLocked(r);
+                cancelNotificationLocked(r, sendDelete);
                 updateLightsLocked();
             }
         }
@@ -954,7 +969,7 @@
                     return true;
                 }
                 mNotificationList.remove(i);
-                cancelNotificationLocked(r);
+                cancelNotificationLocked(r, false);
             }
             if (canceledSomething) {
                 updateLightsLocked();
@@ -973,7 +988,7 @@
         // Don't allow client applications to cancel foreground service notis.
         cancelNotification(pkg, tag, id, 0,
                 Binder.getCallingUid() == Process.SYSTEM_UID
-                ? 0 : Notification.FLAG_FOREGROUND_SERVICE);
+                ? 0 : Notification.FLAG_FOREGROUND_SERVICE, false);
     }
 
     public void cancelAllNotifications(String pkg) {
@@ -1009,17 +1024,8 @@
 
                 if ((r.notification.flags & (Notification.FLAG_ONGOING_EVENT
                                 | Notification.FLAG_NO_CLEAR)) == 0) {
-                    if (r.notification.deleteIntent != null) {
-                        try {
-                            r.notification.deleteIntent.send();
-                        } catch (PendingIntent.CanceledException ex) {
-                            // do nothing - there's no relevant way to recover, and
-                            //     no reason to let this propagate
-                            Slog.w(TAG, "canceled PendingIntent for " + r.pkg, ex);
-                        }
-                    }
                     mNotificationList.remove(i);
-                    cancelNotificationLocked(r);
+                    cancelNotificationLocked(r, true);
                 }
             }
 
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index ec05437..0c20064 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -9354,7 +9354,7 @@
                         // If the window has moved due to its containing
                         // content frame changing, then we'd like to animate
                         // it.  The checks here are ordered by what is least
-                        //Êlikely to be true first.
+                        // likely to be true first.
                         if (w.mContentChanged && !wasAnimating && !w.mLastHidden && !mDisplayFrozen
                                 && (w.mFrame.top != w.mLastFrame.top
                                         || w.mFrame.left != w.mLastFrame.left)
diff --git a/tests/StatusBar/AndroidManifest.xml b/tests/StatusBar/AndroidManifest.xml
index c1ca618..b1734bb 100644
--- a/tests/StatusBar/AndroidManifest.xml
+++ b/tests/StatusBar/AndroidManifest.xml
@@ -21,6 +21,13 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
+        <activity android:name="NotificationBuilderTest" android:label="_Notify Builder">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
         <activity android:name="ToastTest" android:label="_Toasts">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
@@ -35,6 +42,8 @@
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
         </activity>
+        <activity android:name="ConfirmationActivity" android:theme="@android:style/Theme.Dialog">
+        </activity>
         <activity android:name="TestAlertActivity" android:theme="@android:style/Theme.Dialog">
         </activity>
     </application>
diff --git a/tests/StatusBar/res/drawable-mdpi/pineapple.png b/tests/StatusBar/res/drawable-mdpi/pineapple.png
new file mode 100644
index 0000000..7377b96
--- /dev/null
+++ b/tests/StatusBar/res/drawable-mdpi/pineapple.png
Binary files differ
diff --git a/tests/StatusBar/res/layout/confirmation_activity.xml b/tests/StatusBar/res/layout/confirmation_activity.xml
new file mode 100644
index 0000000..50d1a49
--- /dev/null
+++ b/tests/StatusBar/res/layout/confirmation_activity.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="wrap_content"
+    android:layout_height="wrap_content"
+    android:layout_gravity="center"
+    android:gravity="center_horizontal"
+    android:orientation="vertical"
+    >
+
+    <TextView android:id="@+id/text"
+        style="?android:attr/textAppearanceLarge"
+        android:padding="5dip"
+        android:singleLine="true"
+        android:ellipsize="end"
+        android:gravity="center"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content" />
+
+    <Button
+        android:id="@+id/ok"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_weight="3"
+        android:onClick="dismiss"
+        android:text="Ok" />
+
+</LinearLayout>
diff --git a/tests/StatusBar/src/com/android/statusbartest/ConfirmationActivity.java b/tests/StatusBar/src/com/android/statusbartest/ConfirmationActivity.java
new file mode 100644
index 0000000..5ce8f3f
--- /dev/null
+++ b/tests/StatusBar/src/com/android/statusbartest/ConfirmationActivity.java
@@ -0,0 +1,32 @@
+package com.android.statusbartest;
+
+import android.app.Activity;
+import android.view.View;
+import android.widget.TextView;
+
+public class ConfirmationActivity extends Activity {
+    public static final String EXTRA_TITLE = "title";
+    public static final String EXTRA_TEXT = "text";
+
+    @Override
+    public void onResume() {
+        super.onResume();
+        setContentView(R.layout.confirmation_activity);
+        setTitle(getTextExtra(EXTRA_TITLE, "Title"));
+        ((TextView)findViewById(R.id.text)).setText(getTextExtra(EXTRA_TEXT, "text"));
+        findViewById(R.id.ok).setOnClickListener(new View.OnClickListener() {
+                public void onClick(View v) {
+                    finish();
+                }
+            });
+    }
+
+    private String getTextExtra(String extra, String def) {
+        final String text = getIntent().getStringExtra(extra);
+        if (text == null) {
+            return def;
+        } else {
+            return text;
+        }
+    }
+}
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationBuilderTest.java b/tests/StatusBar/src/com/android/statusbartest/NotificationBuilderTest.java
new file mode 100644
index 0000000..3c26212
--- /dev/null
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationBuilderTest.java
@@ -0,0 +1,138 @@
+/*
+ * 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.statusbartest;
+
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.drawable.BitmapDrawable;
+import android.net.Uri;
+import android.os.Environment;
+import android.os.Vibrator;
+import android.os.Handler;
+import android.util.Log;
+import android.net.Uri;
+import android.os.SystemClock;
+import android.widget.RemoteViews;
+import android.os.PowerManager;
+
+public class NotificationBuilderTest extends TestActivity
+{
+    private final static String TAG = "NotificationTestList";
+
+    NotificationManager mNM;
+
+    @Override
+    protected String tag() {
+        return TAG;
+    }
+
+    @Override
+    protected Test[] tests() {
+        mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
+        
+        return mTests;
+    }
+
+    private Test[] mTests = new Test[] {
+        new Test("Cancel (1)") {
+            public void run() {
+                mNM.cancel(1);
+            }
+        },
+
+        new Test("Basic Content (1)") {
+            public void run() {
+                int id = 1;
+                final Notification.Builder b = makeBasicBuilder(this, id);
+
+                mNM.notify(id, b.getNotification());
+            }
+        },
+
+        new Test("Content w/ Info (1)") {
+            public void run() {
+                int id = 1;
+                final Notification.Builder b = makeBasicBuilder(this, id);
+
+                b.setContentInfo("Snoozed");
+
+                mNM.notify(id, b.getNotification());
+            }
+        },
+
+        new Test("w/ Number (1)") {
+            public void run() {
+                int id = 1;
+                final Notification.Builder b = makeBasicBuilder(this, id);
+
+                b.setNumber(12345);
+
+                mNM.notify(id, b.getNotification());
+            }
+        },
+
+        new Test("w/ Number and Large Icon (1)") {
+            public void run() {
+                int id = 1;
+                final Notification.Builder b = makeBasicBuilder(this, id);
+
+                b.setNumber(42);
+
+                final BitmapDrawable bd = (BitmapDrawable)getResources().getDrawable(
+                        R.drawable.pineapple);
+                b.setLargeIcon(Bitmap.createBitmap(bd.getBitmap()));
+
+                mNM.notify(id, b.getNotification());
+            }
+        },
+    };
+
+    private Notification.Builder makeBasicBuilder(Test t, int id) {
+        final Notification.Builder b = new Notification.Builder(this);
+
+        b.setWhen(System.currentTimeMillis());
+        b.setSmallIcon(R.drawable.ic_statusbar_chat);
+        b.setContentTitle("Notification builder Test");
+        b.setContentText(t.name + "\nhappy notifying");
+        b.setContentIntent(makeContentIntent(id));
+        b.setDeleteIntent(makeDeleteIntent(id));
+
+        return b;
+    }
+
+    private PendingIntent makeContentIntent(int id) {
+        Intent intent = new Intent(this, ConfirmationActivity.class);
+        intent.setData(Uri.fromParts("content", "//status_bar_test/content/" + id, null));
+        intent.putExtra(ConfirmationActivity.EXTRA_TITLE, "Content intent");
+        intent.putExtra(ConfirmationActivity.EXTRA_TEXT, "id: " + id);
+        return PendingIntent.getActivity(this, 0, intent, 0);
+    }
+
+    private PendingIntent makeDeleteIntent(int id) {
+        Intent intent = new Intent(this, ConfirmationActivity.class);
+        intent.setData(Uri.fromParts("content", "//status_bar_test/delete/" + id, null));
+        intent.putExtra(ConfirmationActivity.EXTRA_TITLE, "Delete intent");
+        intent.putExtra(ConfirmationActivity.EXTRA_TEXT, "id: " + id);
+        return PendingIntent.getActivity(this, 0, intent, 0);
+    }
+}
+
diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
index 2df97dc..0f0637f 100644
--- a/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
+++ b/tests/StatusBar/src/com/android/statusbartest/NotificationTestList.java
@@ -135,95 +135,6 @@
             }
         },
 
-        new Test("Ticker 1 line & icon") {
-            public void run() {
-                Notification n = new Notification(R.drawable.icon1, "tick tick tick",
-                        mActivityCreateTime);
-                n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
-                            "This is a notification!!!", makeIntent());
-                n.tickerIcons = new Bitmap[1];
-                n.tickerIcons[0] = loadBitmap(R.drawable.icon3);
-                mNM.notify(1, n);
-            }
-        },
-
-        new Test("Ticker 2 lines") {
-            public void run() {
-                Notification n = new Notification(R.drawable.icon1, "tick tick tick\ntock tock",
-                        mActivityCreateTime);
-                n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
-                            "This is a notification!!!", makeIntent());
-                mNM.notify(1, n);
-            }
-        },
-
-        new Test("Ticker title") {
-            public void run() {
-                Notification n = new Notification(R.drawable.icon1, null,
-                        mActivityCreateTime);
-                n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
-                            "This is a notification!!!", makeIntent());
-                n.tickerTitle = "This is a title";
-                mNM.notify(1, n);
-            }
-        },
-
-        new Test("Ticker subtitle") {
-            public void run() {
-                Notification n = new Notification(R.drawable.icon1, null,
-                        mActivityCreateTime);
-                n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
-                            "This is a notification!!!", makeIntent());
-                n.tickerSubtitle = "and a subtitle";
-                mNM.notify(1, n);
-            }
-        },
-
-        new Test("Ticker title & subtitle") {
-            public void run() {
-                Notification n = new Notification(R.drawable.icon1, null,
-                        mActivityCreateTime);
-                n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
-                            "This is a notification!!!", makeIntent());
-                n.tickerTitle = "This is a title it is really really longggggg long long long long";
-                n.tickerSubtitle = "and a subtitle it is really really longggggg long long long long long long long long long long long long long long long long";
-                mNM.notify(1, n);
-            }
-        },
-
-        new Test("Ticker text, title & subtitle") {
-            public void run() {
-                Notification n = new Notification(R.drawable.icon1, "not visible",
-                        mActivityCreateTime);
-                n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
-                            "This is a notification!!!", makeIntent());
-                n.tickerTitle = "This is a title";
-                n.tickerSubtitle = "and a subtitle";
-                mNM.notify(1, n);
-            }
-        },
-
-        new Test("Ticker title, subtitle & 2 icons") {
-            public void run() {
-                Notification n = new Notification(R.drawable.icon1, null,
-                        mActivityCreateTime);
-                n.setLatestEventInfo(NotificationTestList.this, "Persistent #1",
-                            "This is a notification!!!", makeIntent());
-                n.tickerTitle = "This is a title";
-                n.tickerSubtitle = "and a subtitle";
-
-                n.tickerIcons = new Bitmap[2];
-                n.tickerIcons[0] = loadBitmap(R.drawable.icon3);
-                n.tickerIcons[1] = loadBitmap(R.drawable.app_gmail);
-
-                mNM.notify(1, n);
-                /*
-                n.tickerIcons[0].recycle();
-                n.tickerIcons[1].recycle();
-                */
-            }
-        },
-
         new Test("No view") {
             public void run() {
                 Notification n = new Notification(R.drawable.icon1, "No view",