Merge "Import translations. DO NOT MERGE" into mnc-dev
diff --git a/api/current.txt b/api/current.txt
index 5fac213..95d8f1e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -4781,6 +4781,8 @@
     method public android.app.Notification clone();
     method public int describeContents();
     method public java.lang.String getGroup();
+    method public android.graphics.drawable.Icon getLargeIcon();
+    method public android.graphics.drawable.Icon getSmallIcon();
     method public java.lang.String getSortKey();
     method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent);
     method public void writeToParcel(android.os.Parcel, int);
@@ -4925,6 +4927,7 @@
     ctor public Notification.BigPictureStyle();
     ctor public Notification.BigPictureStyle(android.app.Notification.Builder);
     method public android.app.Notification.BigPictureStyle bigLargeIcon(android.graphics.Bitmap);
+    method public android.app.Notification.BigPictureStyle bigLargeIcon(android.graphics.drawable.Icon);
     method public android.app.Notification.BigPictureStyle bigPicture(android.graphics.Bitmap);
     method public android.app.Notification.BigPictureStyle setBigContentTitle(java.lang.CharSequence);
     method public android.app.Notification.BigPictureStyle setSummaryText(java.lang.CharSequence);
@@ -4963,6 +4966,7 @@
     method public android.app.Notification.Builder setGroup(java.lang.String);
     method public android.app.Notification.Builder setGroupSummary(boolean);
     method public android.app.Notification.Builder setLargeIcon(android.graphics.Bitmap);
+    method public android.app.Notification.Builder setLargeIcon(android.graphics.drawable.Icon);
     method public android.app.Notification.Builder setLights(int, int, int);
     method public android.app.Notification.Builder setLocalOnly(boolean);
     method public android.app.Notification.Builder setNumber(int);
@@ -4974,6 +4978,7 @@
     method public android.app.Notification.Builder setShowWhen(boolean);
     method public android.app.Notification.Builder setSmallIcon(int);
     method public android.app.Notification.Builder setSmallIcon(int, int);
+    method public android.app.Notification.Builder setSmallIcon(android.graphics.drawable.Icon);
     method public android.app.Notification.Builder setSortKey(java.lang.String);
     method public android.app.Notification.Builder setSound(android.net.Uri);
     method public deprecated android.app.Notification.Builder setSound(android.net.Uri, int);
@@ -40267,6 +40272,7 @@
     method public void setImageAlpha(int);
     method public void setImageBitmap(android.graphics.Bitmap);
     method public void setImageDrawable(android.graphics.drawable.Drawable);
+    method public void setImageIcon(android.graphics.drawable.Icon);
     method public void setImageLevel(int);
     method public void setImageMatrix(android.graphics.Matrix);
     method public void setImageResource(int);
@@ -40847,7 +40853,9 @@
     method public void setDouble(int, java.lang.String, double);
     method public void setEmptyView(int, int);
     method public void setFloat(int, java.lang.String, float);
+    method public void setIcon(int, java.lang.String, android.graphics.drawable.Icon);
     method public void setImageViewBitmap(int, android.graphics.Bitmap);
+    method public void setImageViewIcon(int, android.graphics.drawable.Icon);
     method public void setImageViewResource(int, int);
     method public void setImageViewUri(int, android.net.Uri);
     method public void setInt(int, java.lang.String, int);
diff --git a/api/system-current.txt b/api/system-current.txt
index d727b22..5d11b25 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -4875,6 +4875,8 @@
     method public android.app.Notification clone();
     method public int describeContents();
     method public java.lang.String getGroup();
+    method public android.graphics.drawable.Icon getLargeIcon();
+    method public android.graphics.drawable.Icon getSmallIcon();
     method public java.lang.String getSortKey();
     method public deprecated void setLatestEventInfo(android.content.Context, java.lang.CharSequence, java.lang.CharSequence, android.app.PendingIntent);
     method public void writeToParcel(android.os.Parcel, int);
@@ -5019,6 +5021,7 @@
     ctor public Notification.BigPictureStyle();
     ctor public Notification.BigPictureStyle(android.app.Notification.Builder);
     method public android.app.Notification.BigPictureStyle bigLargeIcon(android.graphics.Bitmap);
+    method public android.app.Notification.BigPictureStyle bigLargeIcon(android.graphics.drawable.Icon);
     method public android.app.Notification.BigPictureStyle bigPicture(android.graphics.Bitmap);
     method public android.app.Notification.BigPictureStyle setBigContentTitle(java.lang.CharSequence);
     method public android.app.Notification.BigPictureStyle setSummaryText(java.lang.CharSequence);
@@ -5057,6 +5060,7 @@
     method public android.app.Notification.Builder setGroup(java.lang.String);
     method public android.app.Notification.Builder setGroupSummary(boolean);
     method public android.app.Notification.Builder setLargeIcon(android.graphics.Bitmap);
+    method public android.app.Notification.Builder setLargeIcon(android.graphics.drawable.Icon);
     method public android.app.Notification.Builder setLights(int, int, int);
     method public android.app.Notification.Builder setLocalOnly(boolean);
     method public android.app.Notification.Builder setNumber(int);
@@ -5068,6 +5072,7 @@
     method public android.app.Notification.Builder setShowWhen(boolean);
     method public android.app.Notification.Builder setSmallIcon(int);
     method public android.app.Notification.Builder setSmallIcon(int, int);
+    method public android.app.Notification.Builder setSmallIcon(android.graphics.drawable.Icon);
     method public android.app.Notification.Builder setSortKey(java.lang.String);
     method public android.app.Notification.Builder setSound(android.net.Uri);
     method public deprecated android.app.Notification.Builder setSound(android.net.Uri, int);
@@ -42842,6 +42847,7 @@
     method public void setImageAlpha(int);
     method public void setImageBitmap(android.graphics.Bitmap);
     method public void setImageDrawable(android.graphics.drawable.Drawable);
+    method public void setImageIcon(android.graphics.drawable.Icon);
     method public void setImageLevel(int);
     method public void setImageMatrix(android.graphics.Matrix);
     method public void setImageResource(int);
@@ -43422,7 +43428,9 @@
     method public void setDouble(int, java.lang.String, double);
     method public void setEmptyView(int, int);
     method public void setFloat(int, java.lang.String, float);
+    method public void setIcon(int, java.lang.String, android.graphics.drawable.Icon);
     method public void setImageViewBitmap(int, android.graphics.Bitmap);
+    method public void setImageViewIcon(int, android.graphics.drawable.Icon);
     method public void setImageViewResource(int, int);
     method public void setImageViewUri(int, android.net.Uri);
     method public void setInt(int, java.lang.String, int);
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 49b2549..3ffeea7 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -30,6 +30,7 @@
 import android.graphics.Canvas;
 import android.graphics.PorterDuff;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
 import android.media.AudioAttributes;
 import android.media.AudioManager;
 import android.media.session.MediaSession;
@@ -885,6 +886,9 @@
      */
     public static final int HEADS_UP_REQUESTED = 2;
 
+    private Icon mSmallIcon;
+    private Icon mLargeIcon;
+
     /**
      * Structure to encapsulate a named action that can be shown as part of this notification.
      * It must include an icon, a label, and a {@link PendingIntent} to be fired when the action is
@@ -1362,7 +1366,7 @@
         int version = parcel.readInt();
 
         when = parcel.readLong();
-        icon = parcel.readInt();
+        mSmallIcon = Icon.CREATOR.createFromParcel(parcel);
         number = parcel.readInt();
         if (parcel.readInt() != 0) {
             contentIntent = PendingIntent.CREATOR.createFromParcel(parcel);
@@ -1380,7 +1384,7 @@
             contentView = RemoteViews.CREATOR.createFromParcel(parcel);
         }
         if (parcel.readInt() != 0) {
-            largeIcon = Bitmap.CREATOR.createFromParcel(parcel);
+            mLargeIcon = Icon.CREATOR.createFromParcel(parcel);
         }
         defaults = parcel.readInt();
         flags = parcel.readInt();
@@ -1445,7 +1449,7 @@
      */
     public void cloneInto(Notification that, boolean heavy) {
         that.when = this.when;
-        that.icon = this.icon;
+        that.mSmallIcon = this.mSmallIcon;
         that.number = this.number;
 
         // PendingIntents are global, so there's no reason (or way) to clone them.
@@ -1462,8 +1466,8 @@
         if (heavy && this.contentView != null) {
             that.contentView = this.contentView.clone();
         }
-        if (heavy && this.largeIcon != null) {
-            that.largeIcon = Bitmap.createBitmap(this.largeIcon);
+        if (heavy && this.mLargeIcon != null) {
+            that.mLargeIcon = this.mLargeIcon;
         }
         that.iconLevel = this.iconLevel;
         that.sound = this.sound; // android.net.Uri is immutable
@@ -1544,7 +1548,7 @@
         contentView = null;
         bigContentView = null;
         headsUpContentView = null;
-        largeIcon = null;
+        mLargeIcon = null;
         if (extras != null) {
             extras.remove(Notification.EXTRA_LARGE_ICON);
             extras.remove(Notification.EXTRA_LARGE_ICON_BIG);
@@ -1586,7 +1590,7 @@
         parcel.writeInt(1);
 
         parcel.writeLong(when);
-        parcel.writeInt(icon);
+        mSmallIcon.writeToParcel(parcel, 0);
         parcel.writeInt(number);
         if (contentIntent != null) {
             parcel.writeInt(1);
@@ -1618,9 +1622,9 @@
         } else {
             parcel.writeInt(0);
         }
-        if (largeIcon != null) {
+        if (mLargeIcon != null) {
             parcel.writeInt(1);
-            largeIcon.writeToParcel(parcel, 0);
+            mLargeIcon.writeToParcel(parcel, 0);
         } else {
             parcel.writeInt(0);
         }
@@ -1865,6 +1869,27 @@
     }
 
     /**
+     * The small icon representing this notification in the status bar and content view.
+     *
+     * @return the small icon representing this notification.
+     *
+     * @see Builder#getSmallIcon()
+     * @see Builder#setSmallIcon(Icon)
+     */
+    public Icon getSmallIcon() {
+        return mSmallIcon;
+    }
+
+    /**
+     * The large icon shown in this notification's content view.
+     * @see Builder#getLargeIcon()
+     * @see Builder#setLargeIcon(Icon)
+     */
+    public Icon getLargeIcon() {
+        return mLargeIcon;
+    }
+
+    /**
      * @hide
      */
     public boolean isValid() {
@@ -1966,7 +1991,7 @@
         private Context mContext;
 
         private long mWhen;
-        private int mSmallIcon;
+        private Icon mSmallIcon, mLargeIcon;
         private int mSmallIconLevel;
         private int mNumber;
         private CharSequence mContentTitle;
@@ -1979,7 +2004,6 @@
         private PendingIntent mFullScreenIntent;
         private CharSequence mTickerText;
         private RemoteViews mTickerView;
-        private Bitmap mLargeIcon;
         private Uri mSound;
         private int mAudioStreamType;
         private AudioAttributes mAudioAttributes;
@@ -2160,8 +2184,7 @@
          * @see Notification#icon
          */
         public Builder setSmallIcon(@DrawableRes int icon) {
-            mSmallIcon = icon;
-            return this;
+            return setSmallIcon(Icon.createWithResource(mContext.getResources(), icon));
         }
 
         /**
@@ -2176,8 +2199,20 @@
          * @see Notification#iconLevel
          */
         public Builder setSmallIcon(@DrawableRes int icon, int level) {
-            mSmallIcon = icon;
             mSmallIconLevel = level;
+            return setSmallIcon(icon);
+        }
+
+        /**
+         * Set the small icon, which will be used to represent the notification in the
+         * status bar and content view (unless overriden there by a
+         * {@link #setLargeIcon(Bitmap) large icon}).
+         *
+         * @param icon An Icon object to use.
+         * @see Notification#icon
+         */
+        public Builder setSmallIcon(Icon icon) {
+            mSmallIcon = icon;
             return this;
         }
 
@@ -2324,14 +2359,24 @@
         }
 
         /**
-         * Add a large icon to the notification (and the ticker on some devices).
+         * Add a large icon to the notification content view.
          *
          * In the platform template, this image will be shown on the left of the notification view
-         * in place of the {@link #setSmallIcon(int) small icon} (which will move to the right side).
-         *
-         * @see Notification#largeIcon
+         * in place of the {@link #setSmallIcon(Icon) small icon} (which will be placed in a small
+         * badge atop the large icon).
          */
-        public Builder setLargeIcon(Bitmap icon) {
+        public Builder setLargeIcon(Bitmap b) {
+            return setLargeIcon(b != null ? Icon.createWithBitmap(b) : null);
+        }
+
+        /**
+         * Add a large icon to the notification content view.
+         *
+         * In the platform template, this image will be shown on the left of the notification view
+         * in place of the {@link #setSmallIcon(Icon) small icon} (which will be placed in a small
+         * badge atop the large icon).
+         */
+        public Builder setLargeIcon(Icon icon) {
             mLargeIcon = icon;
             return this;
         }
@@ -2840,13 +2885,13 @@
             boolean contentTextInLine2 = false;
 
             if (mLargeIcon != null) {
-                contentView.setImageViewBitmap(R.id.icon, mLargeIcon);
+                contentView.setImageViewIcon(R.id.icon, mLargeIcon);
                 processLargeLegacyIcon(mLargeIcon, contentView);
-                contentView.setImageViewResource(R.id.right_icon, mSmallIcon);
+                contentView.setImageViewIcon(R.id.right_icon, mSmallIcon);
                 contentView.setViewVisibility(R.id.right_icon, View.VISIBLE);
                 processSmallRightIcon(mSmallIcon, contentView);
             } else { // small icon at left
-                contentView.setImageViewResource(R.id.icon, mSmallIcon);
+                contentView.setImageViewIcon(R.id.icon, mSmallIcon);
                 contentView.setViewVisibility(R.id.icon, View.VISIBLE);
                 processSmallIconAsLarge(mSmallIcon, contentView);
             }
@@ -3086,14 +3131,16 @@
         /**
          * Apply any necessary background to smallIcons being used in the largeIcon spot.
          */
-        private void processSmallIconAsLarge(int largeIconId, RemoteViews contentView) {
+        private void processSmallIconAsLarge(Icon largeIcon, RemoteViews contentView) {
             if (!isLegacy()) {
                 contentView.setDrawableParameters(R.id.icon, false, -1,
                         0xFFFFFFFF,
                         PorterDuff.Mode.SRC_ATOP, -1);
-            }
-            if (!isLegacy() || mColorUtil.isGrayscaleIcon(mContext, largeIconId)) {
                 applyLargeIconBackground(contentView);
+            } else {
+                if (mColorUtil.isGrayscaleIcon(mContext, largeIcon)) {
+                    applyLargeIconBackground(contentView);
+                }
             }
         }
 
@@ -3102,8 +3149,9 @@
          * if it's grayscale).
          */
         // TODO: also check bounds, transparency, that sort of thing.
-        private void processLargeLegacyIcon(Bitmap largeIcon, RemoteViews contentView) {
-            if (isLegacy() && mColorUtil.isGrayscaleIcon(largeIcon)) {
+        private void processLargeLegacyIcon(Icon largeIcon, RemoteViews contentView) {
+            if (largeIcon != null && isLegacy()
+                    && mColorUtil.isGrayscaleIcon(mContext, largeIcon)) {
                 applyLargeIconBackground(contentView);
             } else {
                 removeLargeIconBackground(contentView);
@@ -3137,14 +3185,15 @@
         /**
          * Recolor small icons when used in the R.id.right_icon slot.
          */
-        private void processSmallRightIcon(int smallIconDrawableId,
-                RemoteViews contentView) {
+        private void processSmallRightIcon(Icon smallIcon, RemoteViews contentView) {
             if (!isLegacy()) {
                 contentView.setDrawableParameters(R.id.right_icon, false, -1,
                         0xFFFFFFFF,
                         PorterDuff.Mode.SRC_ATOP, -1);
             }
-            if (!isLegacy() || mColorUtil.isGrayscaleIcon(mContext, smallIconDrawableId)) {
+            final boolean gray = (smallIcon.getType() == Icon.TYPE_RESOURCE
+                    && mColorUtil.isGrayscaleIcon(mContext, smallIcon.getResId()));
+            if (!isLegacy() || gray) {
                 contentView.setInt(R.id.right_icon,
                         "setBackgroundResource",
                         R.drawable.notification_icon_legacy_bg);
@@ -3180,7 +3229,10 @@
         public Notification buildUnstyled() {
             Notification n = new Notification();
             n.when = mWhen;
-            n.icon = mSmallIcon;
+            n.mSmallIcon = mSmallIcon;
+            if (mSmallIcon.getType() == Icon.TYPE_RESOURCE) {
+                n.icon = mSmallIcon.getResId();
+            }
             n.iconLevel = mSmallIconLevel;
             n.number = mNumber;
 
@@ -3192,7 +3244,10 @@
             n.fullScreenIntent = mFullScreenIntent;
             n.tickerText = mTickerText;
             n.tickerView = makeTickerView();
-            n.largeIcon = mLargeIcon;
+            n.mLargeIcon = mLargeIcon;
+            if (mLargeIcon != null && mLargeIcon.getType() == Icon.TYPE_BITMAP) {
+                n.largeIcon = mLargeIcon.getBitmap();
+            }
             n.sound = mSound;
             n.audioStreamType = mAudioStreamType;
             n.audioAttributes = mAudioAttributes;
@@ -3242,7 +3297,7 @@
             extras.putCharSequence(EXTRA_TEXT, mContentText);
             extras.putCharSequence(EXTRA_SUB_TEXT, mSubText);
             extras.putCharSequence(EXTRA_INFO_TEXT, mContentInfo);
-            extras.putInt(EXTRA_SMALL_ICON, mSmallIcon);
+            extras.putParcelable(EXTRA_SMALL_ICON, mSmallIcon);
             extras.putInt(EXTRA_PROGRESS, mProgress);
             extras.putInt(EXTRA_PROGRESS_MAX, mProgressMax);
             extras.putBoolean(EXTRA_PROGRESS_INDETERMINATE, mProgressIndeterminate);
@@ -3430,7 +3485,7 @@
 
             // Notification fields.
             mWhen = n.when;
-            mSmallIcon = n.icon;
+            mSmallIcon = n.mSmallIcon;
             mSmallIconLevel = n.iconLevel;
             mNumber = n.number;
 
@@ -3441,7 +3496,7 @@
             mFullScreenIntent = n.fullScreenIntent;
             mTickerText = n.tickerText;
             mTickerView = n.tickerView;
-            mLargeIcon = n.largeIcon;
+            mLargeIcon = n.mLargeIcon;
             mSound = n.sound;
             mAudioStreamType = n.audioStreamType;
             mAudioAttributes = n.audioAttributes;
@@ -3472,7 +3527,7 @@
             mContentText = extras.getCharSequence(EXTRA_TEXT);
             mSubText = extras.getCharSequence(EXTRA_SUB_TEXT);
             mContentInfo = extras.getCharSequence(EXTRA_INFO_TEXT);
-            mSmallIcon = extras.getInt(EXTRA_SMALL_ICON);
+            mSmallIcon = extras.getParcelable(EXTRA_SMALL_ICON);
             mProgress = extras.getInt(EXTRA_PROGRESS);
             mProgressMax = extras.getInt(EXTRA_PROGRESS_MAX);
             mProgressIndeterminate = extras.getBoolean(EXTRA_PROGRESS_INDETERMINATE);
@@ -3764,7 +3819,7 @@
      */
     public static class BigPictureStyle extends Style {
         private Bitmap mPicture;
-        private Bitmap mBigLargeIcon;
+        private Icon mBigLargeIcon;
         private boolean mBigLargeIconSet = false;
 
         public BigPictureStyle() {
@@ -3803,8 +3858,15 @@
          * Override the large icon when the big notification is shown.
          */
         public BigPictureStyle bigLargeIcon(Bitmap b) {
+            return bigLargeIcon(b != null ? Icon.createWithBitmap(b) : null);
+        }
+
+        /**
+         * Override the large icon when the big notification is shown.
+         */
+        public BigPictureStyle bigLargeIcon(Icon icon) {
             mBigLargeIconSet = true;
-            mBigLargeIcon = b;
+            mBigLargeIcon = icon;
             return this;
         }
 
@@ -3815,7 +3877,7 @@
             //   1. mBigLargeIconSet -> mBigLargeIcon (null or non-null) applies, overrides
             //          mLargeIcon
             //   2. !mBigLargeIconSet -> mLargeIcon applies
-            Bitmap oldLargeIcon = null;
+            Icon oldLargeIcon = null;
             if (mBigLargeIconSet) {
                 oldLargeIcon = mBuilder.mLargeIcon;
                 mBuilder.mLargeIcon = mBigLargeIcon;
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 814882a..30f373a 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -3855,8 +3855,8 @@
     private class SelectionStartHandleView extends HandleView {
         // Indicates whether the cursor is making adjustments within a word.
         private boolean mInWord = false;
-        // Offset to track difference between touch and word boundary.
-        protected int mTouchWordOffset;
+        // Difference between touch position and word boundary position.
+        private float mTouchWordDelta;
 
         public SelectionStartHandleView(Drawable drawableLtr, Drawable drawableRtl) {
             super(drawableLtr, drawableRtl);
@@ -3908,18 +3908,36 @@
                         offset = mPreviousOffset;
                     }
                 }
-                mTouchWordOffset = Math.max(trueOffset - offset, 0);
-                positionCursor = true;
-            } else if (offset - mTouchWordOffset > mPreviousOffset || currLine > mPrevLine) {
-                // User is shrinking the selection.
-                if (currLine > mPrevLine) {
-                    // We're on a different line, so we'll snap to word boundaries.
-                    offset = start;
-                    mTouchWordOffset = Math.max(trueOffset - offset, 0);
+                final Layout layout = mTextView.getLayout();
+                if (layout != null && offset < trueOffset) {
+                    final float adjustedX = layout.getPrimaryHorizontal(offset);
+                    mTouchWordDelta =
+                            mTextView.convertToLocalHorizontalCoordinate(x) - adjustedX;
                 } else {
-                    offset -= mTouchWordOffset;
+                    mTouchWordDelta = 0.0f;
                 }
                 positionCursor = true;
+            } else {
+                final int adjustedOffset =
+                        mTextView.getOffsetAtCoordinate(currLine, x - mTouchWordDelta);
+                if (adjustedOffset > mPreviousOffset || currLine > mPrevLine) {
+                    // User is shrinking the selection.
+                    if (currLine > mPrevLine) {
+                        // We're on a different line, so we'll snap to word boundaries.
+                        offset = start;
+                        final Layout layout = mTextView.getLayout();
+                        if (layout != null && offset < trueOffset) {
+                            final float adjustedX = layout.getPrimaryHorizontal(offset);
+                            mTouchWordDelta =
+                                    mTextView.convertToLocalHorizontalCoordinate(x) - adjustedX;
+                        } else {
+                            mTouchWordDelta = 0.0f;
+                        }
+                    } else {
+                        offset = adjustedOffset;
+                    }
+                    positionCursor = true;
+                }
             }
 
             // Handles can not cross and selection is at least one character.
@@ -3934,7 +3952,7 @@
                     } else {
                         offset = alteredOffset;
                     }
-                    mTouchWordOffset = 0;
+                    mTouchWordDelta = 0.0f;
                 }
                 mInWord = !getWordIteratorWithText().isBoundary(offset);
                 positionAtCursorOffset(offset, false);
@@ -3946,7 +3964,7 @@
             boolean superResult = super.onTouchEvent(event);
             if (event.getActionMasked() == MotionEvent.ACTION_UP) {
                 // Reset the touch word offset when the user has lifted their finger.
-                mTouchWordOffset = 0;
+                mTouchWordDelta = 0.0f;
             }
             return superResult;
         }
@@ -3955,8 +3973,8 @@
     private class SelectionEndHandleView extends HandleView {
         // Indicates whether the cursor is making adjustments within a word.
         private boolean mInWord = false;
-        // Offset to track difference between touch and word boundary.
-        protected int mTouchWordOffset;
+        // Difference between touch position and word boundary position.
+        private float mTouchWordDelta;
 
         public SelectionEndHandleView(Drawable drawableLtr, Drawable drawableRtl) {
             super(drawableLtr, drawableRtl);
@@ -4008,18 +4026,36 @@
                         offset = mPreviousOffset;
                     }
                 }
-                mTouchWordOffset = Math.max(offset - trueOffset, 0);
-                positionCursor = true;
-            } else if (offset + mTouchWordOffset < mPreviousOffset || currLine < mPrevLine) {
-                // User is shrinking the selection.
-                if (currLine < mPrevLine) {
-                    // We're on a different line, so we'll snap to word boundaries.
-                    offset = end;
-                    mTouchWordOffset = Math.max(offset - trueOffset, 0);
+                final Layout layout = mTextView.getLayout();
+                if (layout != null && offset > trueOffset) {
+                    final float adjustedX = layout.getPrimaryHorizontal(offset);
+                    mTouchWordDelta =
+                            adjustedX - mTextView.convertToLocalHorizontalCoordinate(x);
                 } else {
-                    offset += mTouchWordOffset;
+                    mTouchWordDelta = 0.0f;
                 }
                 positionCursor = true;
+            } else {
+                final int adjustedOffset =
+                        mTextView.getOffsetAtCoordinate(currLine, x + mTouchWordDelta);
+                if (adjustedOffset < mPreviousOffset || currLine < mPrevLine) {
+                    // User is shrinking the selection.
+                    if (currLine < mPrevLine) {
+                        // We're on a different line, so we'll snap to word boundaries.
+                        offset = end;
+                        final Layout layout = mTextView.getLayout();
+                        if (layout != null && offset > trueOffset) {
+                            final float adjustedX = layout.getPrimaryHorizontal(offset);
+                            mTouchWordDelta =
+                                    adjustedX - mTextView.convertToLocalHorizontalCoordinate(x);
+                        } else {
+                            mTouchWordDelta = 0.0f;
+                        }
+                    } else {
+                        offset = adjustedOffset;
+                    }
+                    positionCursor = true;
+                }
             }
 
             if (positionCursor) {
@@ -4034,7 +4070,7 @@
                     } else {
                         offset = Math.min(alteredOffset, length);
                     }
-                    mTouchWordOffset = 0;
+                    mTouchWordDelta = 0.0f;
                 }
                 mInWord = !getWordIteratorWithText().isBoundary(offset);
                 positionAtCursorOffset(offset, false);
@@ -4046,7 +4082,7 @@
             boolean superResult = super.onTouchEvent(event);
             if (event.getActionMasked() == MotionEvent.ACTION_UP) {
                 // Reset the touch word offset when the user has lifted their finger.
-                mTouchWordOffset = 0;
+                mTouchWordDelta = 0.0f;
             }
             return superResult;
         }
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index 05059bc..94cda88 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -36,8 +36,10 @@
 import android.graphics.Xfermode;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
 import android.net.Uri;
 import android.os.Build;
+import android.os.Handler;
 import android.text.TextUtils;
 import android.util.AttributeSet;
 import android.util.Log;
@@ -462,6 +464,21 @@
     }
 
     /**
+     * Sets the content of this ImageView to the specified Icon.
+     *
+     * <p class="note">Depending on the Icon type, this may do Bitmap reading and decoding
+     * on the UI thread, which can cause UI jank.  If that's a concern, consider using
+     * {@link Icon#loadDrawableAsync(Context, Handler, Icon.OnDrawableLoadedListener)}
+     * and then {@link #setImageDrawable(android.graphics.drawable.Drawable)} instead.</p>
+     *
+     * @param icon an Icon holding the desired image
+     */
+    @android.view.RemotableViewMethod
+    public void setImageIcon(Icon icon) {
+        setImageDrawable(icon.loadDrawable(mContext));
+    }
+
+    /**
      * Applies a tint to the image drawable. Does not modify the current tint
      * mode, which is {@link PorterDuff.Mode#SRC_IN} by default.
      * <p>
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index a10be11..dc75fd0 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -35,6 +35,7 @@
 import android.graphics.PorterDuff;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
@@ -1072,6 +1073,7 @@
         static final int BUNDLE = 13;
         static final int INTENT = 14;
         static final int COLOR_STATE_LIST = 15;
+        static final int ICON = 16;
 
         String methodName;
         int type;
@@ -1150,6 +1152,10 @@
                         this.value = ColorStateList.CREATOR.createFromParcel(in);
                     }
                     break;
+                case ICON:
+                    if (in.readInt() != 0) {
+                        this.value = Icon.CREATOR.createFromParcel(in);
+                    }
                 default:
                     break;
             }
@@ -1225,6 +1231,13 @@
                     if (this.value != null) {
                         ((ColorStateList)this.value).writeToParcel(out, flags);
                     }
+                    break;
+                case ICON:
+                    out.writeInt(this.value != null ? 1 : 0);
+                    if (this.value != null) {
+                        ((Icon)this.value).writeToParcel(out, flags);
+                    }
+                    break;
                 default:
                     break;
             }
@@ -1262,6 +1275,8 @@
                     return Intent.class;
                 case COLOR_STATE_LIST:
                     return ColorStateList.class;
+                case ICON:
+                    return Icon.class;
                 default:
                     return null;
             }
@@ -2082,6 +2097,16 @@
     }
 
     /**
+     * Equivalent to calling ImageView.setImageIcon
+     *
+     * @param viewId The id of the view whose bitmap should change
+     * @param icon The new Icon for the ImageView
+     */
+    public void setImageViewIcon(int viewId, Icon icon) {
+        setIcon(viewId, "setImageIcon", icon);
+    }
+
+    /**
      * Equivalent to calling AdapterView.setEmptyView
      *
      * @param viewId The id of the view on which to set the empty view
@@ -2519,6 +2544,17 @@
     }
 
     /**
+     * Call a method taking one Icon on a view in the layout for this RemoteViews.
+     *
+     * @param viewId The id of the view on which to call the method.
+     * @param methodName The name of the method to call.
+     * @param value The {@link android.graphics.drawable.Icon} to pass the method.
+     */
+    public void setIcon(int viewId, String methodName, Icon value) {
+        addAction(new ReflectionAction(viewId, methodName, ReflectionAction.ICON, value));
+    }
+
+    /**
      * Equivalent to calling View.setContentDescription(CharSequence).
      *
      * @param viewId The id of the view whose content description should change.
diff --git a/core/java/com/android/internal/statusbar/StatusBarIcon.java b/core/java/com/android/internal/statusbar/StatusBarIcon.java
index e0792cb..4693d4b 100644
--- a/core/java/com/android/internal/statusbar/StatusBarIcon.java
+++ b/core/java/com/android/internal/statusbar/StatusBarIcon.java
@@ -16,40 +16,46 @@
 
 package com.android.internal.statusbar;
 
+import android.graphics.drawable.Icon;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.UserHandle;
 
 public class StatusBarIcon implements Parcelable {
-    public String iconPackage;
     public UserHandle user;
-    public int iconId;
+    public Icon icon;
     public int iconLevel;
     public boolean visible = true;
     public int number;
     public CharSequence contentDescription;
 
-    public StatusBarIcon(String iconPackage, UserHandle user, int iconId, int iconLevel, int number,
+    public StatusBarIcon(UserHandle user, Icon icon, int iconLevel, int number,
             CharSequence contentDescription) {
-        this.iconPackage = iconPackage;
         this.user = user;
-        this.iconId = iconId;
+        this.icon = icon;
         this.iconLevel = iconLevel;
         this.number = number;
         this.contentDescription = contentDescription;
     }
 
+    public StatusBarIcon(String iconPackage, UserHandle user,
+            int iconId, int iconLevel, int number,
+            CharSequence contentDescription) {
+        this(user, Icon.createWithResource(iconPackage, iconId),
+                iconLevel, number, contentDescription);
+    }
+
     @Override
     public String toString() {
-        return "StatusBarIcon(pkg=" + this.iconPackage + "user=" + user.getIdentifier()
-                + " id=0x" + Integer.toHexString(this.iconId)
+        return "StatusBarIcon(icon=" + this.icon
+                + " user=" + user.getIdentifier()
                 + " level=" + this.iconLevel + " visible=" + visible
                 + " num=" + this.number + " )";
     }
 
     @Override
     public StatusBarIcon clone() {
-        StatusBarIcon that = new StatusBarIcon(this.iconPackage, this.user, this.iconId,
+        StatusBarIcon that = new StatusBarIcon(this.user, this.icon,
                 this.iconLevel, this.number, this.contentDescription);
         that.visible = this.visible;
         return that;
@@ -63,9 +69,8 @@
     }
 
     public void readFromParcel(Parcel in) {
-        this.iconPackage = in.readString();
+        this.icon = (Icon) in.readParcelable(null);
         this.user = (UserHandle) in.readParcelable(null);
-        this.iconId = in.readInt();
         this.iconLevel = in.readInt();
         this.visible = in.readInt() != 0;
         this.number = in.readInt();
@@ -73,9 +78,8 @@
     }
 
     public void writeToParcel(Parcel out, int flags) {
-        out.writeString(this.iconPackage);
+        out.writeParcelable(this.icon, 0);
         out.writeParcelable(this.user, 0);
-        out.writeInt(this.iconId);
         out.writeInt(this.iconLevel);
         out.writeInt(this.visible ? 1 : 0);
         out.writeInt(this.number);
diff --git a/core/java/com/android/internal/util/NotificationColorUtil.java b/core/java/com/android/internal/util/NotificationColorUtil.java
index 3249ea3..60769734 100644
--- a/core/java/com/android/internal/util/NotificationColorUtil.java
+++ b/core/java/com/android/internal/util/NotificationColorUtil.java
@@ -24,6 +24,7 @@
 import android.graphics.drawable.AnimationDrawable;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
 import android.graphics.drawable.VectorDrawable;
 import android.text.SpannableStringBuilder;
 import android.text.Spanned;
@@ -129,6 +130,20 @@
         }
     }
 
+    public boolean isGrayscaleIcon(Context context, Icon icon) {
+        if (icon == null) {
+            return false;
+        }
+        switch (icon.getType()) {
+            case Icon.TYPE_BITMAP:
+                return isGrayscaleIcon(icon.getBitmap());
+            case Icon.TYPE_RESOURCE:
+                return isGrayscaleIcon(context, icon.getResId());
+            default:
+                return false;
+        }
+    }
+
     /**
      * Checks whether a drawable with a resoure id is a small grayscale icon.
      * Grayscale here means "very close to a perfect gray"; icon means "no larger than 64dp".
diff --git a/graphics/java/android/graphics/drawable/Icon.java b/graphics/java/android/graphics/drawable/Icon.java
index 668a14a..37fb703 100644
--- a/graphics/java/android/graphics/drawable/Icon.java
+++ b/graphics/java/android/graphics/drawable/Icon.java
@@ -53,10 +53,14 @@
 public final class Icon implements Parcelable {
     private static final String TAG = "Icon";
 
-    private static final int TYPE_BITMAP   = 1;
-    private static final int TYPE_RESOURCE = 2;
-    private static final int TYPE_DATA     = 3;
-    private static final int TYPE_URI      = 4;
+    /** @hide */
+    public static final int TYPE_BITMAP   = 1;
+    /** @hide */
+    public static final int TYPE_RESOURCE = 2;
+    /** @hide */
+    public static final int TYPE_DATA     = 3;
+    /** @hide */
+    public static final int TYPE_URI      = 4;
 
     private static final int VERSION_STREAM_SERIALIZER = 1;
 
@@ -81,15 +85,34 @@
     // TYPE_DATA: data offset
     private int             mInt2;
 
-    // Internal accessors for different mType variants
-    private Bitmap getBitmap() {
+    /**
+     * @return The type of image data held in this Icon. One of
+     * {@link #TYPE_BITMAP},
+     * {@link #TYPE_RESOURCE},
+     * {@link #TYPE_DATA}, or
+     * {@link #TYPE_URI}.
+     * @hide
+     */
+    public int getType() {
+        return mType;
+    }
+
+    /**
+     * @return The {@link android.graphics.Bitmap} held by this {@link #TYPE_BITMAP} Icon.
+     * @hide
+     */
+    public Bitmap getBitmap() {
         if (mType != TYPE_BITMAP) {
             throw new IllegalStateException("called getBitmap() on " + this);
         }
         return (Bitmap) mObj1;
     }
 
-    private int getDataLength() {
+    /**
+     * @return The length of the compressed bitmap byte array held by this {@link #TYPE_DATA} Icon.
+     * @hide
+     */
+    public int getDataLength() {
         if (mType != TYPE_DATA) {
             throw new IllegalStateException("called getDataLength() on " + this);
         }
@@ -98,7 +121,12 @@
         }
     }
 
-    private int getDataOffset() {
+    /**
+     * @return The offset into the byte array held by this {@link #TYPE_DATA} Icon at which
+     * valid compressed bitmap data is found.
+     * @hide
+     */
+    public int getDataOffset() {
         if (mType != TYPE_DATA) {
             throw new IllegalStateException("called getDataOffset() on " + this);
         }
@@ -107,7 +135,12 @@
         }
     }
 
-    private byte[] getDataBytes() {
+    /**
+     * @return The byte array held by this {@link #TYPE_DATA} Icon ctonaining compressed
+     * bitmap data.
+     * @hide
+     */
+    public byte[] getDataBytes() {
         if (mType != TYPE_DATA) {
             throw new IllegalStateException("called getDataBytes() on " + this);
         }
@@ -116,39 +149,58 @@
         }
     }
 
-    private Resources getResources() {
+    /**
+     * @return The {@link android.content.res.Resources} for this {@link #TYPE_RESOURCE} Icon.
+     * @hide
+     */
+    public Resources getResources() {
         if (mType != TYPE_RESOURCE) {
             throw new IllegalStateException("called getResources() on " + this);
         }
         return (Resources) mObj1;
     }
 
-    private String getResPackage() {
+    /**
+     * @return The package containing resources for this {@link #TYPE_RESOURCE} Icon.
+     * @hide
+     */
+    public String getResPackage() {
         if (mType != TYPE_RESOURCE) {
             throw new IllegalStateException("called getResPackage() on " + this);
         }
         return mString1;
     }
 
-    private int getResId() {
+    /**
+     * @return The resource ID for this {@link #TYPE_RESOURCE} Icon.
+     * @hide
+     */
+    public int getResId() {
         if (mType != TYPE_RESOURCE) {
             throw new IllegalStateException("called getResId() on " + this);
         }
         return mInt1;
     }
 
-    private String getUriString() {
+    /**
+     * @return The URI (as a String) for this {@link #TYPE_URI} Icon.
+     * @hide
+     */
+    public String getUriString() {
         if (mType != TYPE_URI) {
             throw new IllegalStateException("called getUriString() on " + this);
         }
         return mString1;
     }
 
-    private Uri getUri() {
+    /**
+     * @return The {@link android.net.Uri} for this {@link #TYPE_URI} Icon.
+     * @hide
+     */
+    public Uri getUri() {
         return Uri.parse(getUriString());
     }
 
-    // Convert a int32 into a four-char string
     private static final String typeToString(int x) {
         switch (x) {
             case TYPE_BITMAP: return "BITMAP";
diff --git a/packages/SettingsProvider/res/values-gu-rIN/defaults.xml b/packages/SettingsProvider/res/values-gu-rIN/defaults.xml
new file mode 100644
index 0000000..22443a5
--- /dev/null
+++ b/packages/SettingsProvider/res/values-gu-rIN/defaults.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="def_device_name" msgid="6309317409634339402">"%1$s %2$s"</string>
+    <string name="def_device_name_simple" msgid="9037785625140748221">"%1$s"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-gu-rIN/strings.xml b/packages/SettingsProvider/res/values-gu-rIN/strings.xml
new file mode 100644
index 0000000..7241974
--- /dev/null
+++ b/packages/SettingsProvider/res/values-gu-rIN/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"સેટિંગ્સ સંગ્રહ"</string>
+</resources>
diff --git a/packages/SettingsProvider/res/values-sq-rAL/strings.xml b/packages/SettingsProvider/res/values-sq-rAL/strings.xml
new file mode 100644
index 0000000..a8e66d5
--- /dev/null
+++ b/packages/SettingsProvider/res/values-sq-rAL/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+/**
+ * Copyright (c) 2007, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); 
+ * you may not use this file except in compliance with the License. 
+ * You may obtain a copy of the License at 
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0 
+ *
+ * Unless required by applicable law or agreed to in writing, software 
+ * distributed under the License is distributed on an "AS IS" BASIS, 
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
+ * See the License for the specific language governing permissions and 
+ * limitations under the License.
+ */
+ -->
+
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+    <string name="app_label" msgid="4567566098528588863">"Hapësira ruajtëse e \"Cilësimeve\""</string>
+</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index 715f4e4..be33085 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -194,7 +194,7 @@
         // we compose the final post-save notification below.
         mNotificationBuilder.setLargeIcon(croppedIcon);
         // But we still don't set it for the expanded view, allowing the smallIcon to show here.
-        mNotificationStyle.bigLargeIcon(null);
+        mNotificationStyle.bigLargeIcon((Bitmap) null);
     }
 
     @Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 2913c7d..1e488f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -1390,9 +1390,9 @@
             final ImageView profileBadge = (ImageView) publicViewLocal.findViewById(
                     R.id.profile_badge_line3);
 
-            final StatusBarIcon ic = new StatusBarIcon(entry.notification.getPackageName(),
+            final StatusBarIcon ic = new StatusBarIcon(
                     entry.notification.getUser(),
-                    entry.notification.getNotification().icon,
+                    entry.notification.getNotification().getSmallIcon(),
                     entry.notification.getNotification().iconLevel,
                     entry.notification.getNotification().number,
                     entry.notification.getNotification().tickerText);
@@ -1770,9 +1770,9 @@
                 sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId()), n);
         iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
 
-        final StatusBarIcon ic = new StatusBarIcon(sbn.getPackageName(),
+        final StatusBarIcon ic = new StatusBarIcon(
                 sbn.getUser(),
-                    n.icon,
+                    n.getSmallIcon(),
                     n.iconLevel,
                     n.number,
                     n.tickerText);
@@ -1916,9 +1916,9 @@
             try {
                 if (entry.icon != null) {
                     // Update the icon
-                    final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(),
+                    final StatusBarIcon ic = new StatusBarIcon(
                             notification.getUser(),
-                            n.icon,
+                            n.getSmallIcon(),
                             n.iconLevel,
                             n.number,
                             n.tickerText);
@@ -1938,9 +1938,9 @@
         }
         if (!updateSuccessful) {
             if (DEBUG) Log.d(TAG, "not reusing notification for key: " + key);
-            final StatusBarIcon ic = new StatusBarIcon(notification.getPackageName(),
+            final StatusBarIcon ic = new StatusBarIcon(
                     notification.getUser(),
-                    n.icon,
+                    n.getSmallIcon(),
                     n.iconLevel,
                     n.number,
                     n.tickerText);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index e6847d8..3294e15 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -24,6 +24,7 @@
 import android.graphics.Paint;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
 import android.os.UserHandle;
 import android.text.TextUtils;
 import android.util.AttributeSet;
@@ -100,13 +101,23 @@
         return a.equals(b);
     }
 
+    public boolean equalIcons(Icon a, Icon b) {
+        if (a == b) return true;
+        if (a.getType() != b.getType()) return false;
+        switch (a.getType()) {
+            case Icon.TYPE_RESOURCE:
+                return a.getResPackage().equals(b.getResPackage()) && a.getResId() == b.getResId();
+            case Icon.TYPE_URI:
+                return a.getUriString().equals(b.getUriString());
+            default:
+                return false;
+        }
+    }
     /**
      * Returns whether the set succeeded.
      */
     public boolean set(StatusBarIcon icon) {
-        final boolean iconEquals = mIcon != null
-                && streq(mIcon.iconPackage, icon.iconPackage)
-                && mIcon.iconId == icon.iconId;
+        final boolean iconEquals = mIcon != null && equalIcons(mIcon.icon, icon.icon);
         final boolean levelEquals = iconEquals
                 && mIcon.iconLevel == icon.iconLevel;
         final boolean visibilityEquals = mIcon != null
@@ -167,45 +178,18 @@
     }
 
     /**
-     * Returns the right icon to use for this item, respecting the iconId and
-     * iconPackage (if set)
+     * Returns the right icon to use for this item
      *
-     * @param context Context to use to get resources if iconPackage is not set
+     * @param context Context to use to get resources
      * @return Drawable for this item, or null if the package or item could not
      *         be found
      */
     public static Drawable getIcon(Context context, StatusBarIcon icon) {
-        Resources r = null;
-
-        if (icon.iconPackage != null) {
-            try {
-                int userId = icon.user.getIdentifier();
-                if (userId == UserHandle.USER_ALL) {
-                    userId = UserHandle.USER_OWNER;
-                }
-                r = context.getPackageManager()
-                        .getResourcesForApplicationAsUser(icon.iconPackage, userId);
-            } catch (PackageManager.NameNotFoundException ex) {
-                Log.e(TAG, "Icon package not found: " + icon.iconPackage);
-                return null;
-            }
-        } else {
-            r = context.getResources();
+        int userId = icon.user.getIdentifier();
+        if (userId == UserHandle.USER_ALL) {
+            userId = UserHandle.USER_OWNER;
         }
-
-        if (icon.iconId == 0) {
-            return null;
-        }
-
-        try {
-            return r.getDrawable(icon.iconId);
-        } catch (RuntimeException e) {
-            Log.w(TAG, "Icon not found in "
-                  + (icon.iconPackage != null ? icon.iconId : "<system>")
-                  + ": " + Integer.toHexString(icon.iconId));
-        }
-
-        return null;
+        return icon.icon.loadDrawableAsUser(context, userId);
     }
 
     public StatusBarIcon getStatusBarIcon() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
index 44168bc..26d1c86 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DemoStatusIcons.java
@@ -16,6 +16,7 @@
 
 package com.android.systemui.statusbar.phone;
 
+import android.graphics.drawable.Icon;
 import android.os.Bundle;
 import android.os.UserHandle;
 import android.view.Gravity;
@@ -132,8 +133,7 @@
                     break;
                 } else {
                     StatusBarIcon icon = v.getStatusBarIcon();
-                    icon.iconPackage = iconPkg;
-                    icon.iconId = iconId;
+                    icon.icon = Icon.createWithResource(icon.icon.getResPackage(), iconId);
                     v.set(icon);
                     v.updateDrawable();
                     return;
@@ -152,4 +152,4 @@
         v.set(icon);
         addView(v, 0, new LinearLayout.LayoutParams(mIconSize, mIconSize));
     }
-}
\ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 290fb657..de74a04 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2017,7 +2017,7 @@
             throw new IllegalArgumentException("null not allowed: pkg=" + pkg
                     + " id=" + id + " notification=" + notification);
         }
-        if (notification.icon != 0) {
+        if (notification.getSmallIcon() != null) {
             if (!notification.isValid()) {
                 throw new IllegalArgumentException("Invalid notification (): pkg=" + pkg
                         + " id=" + id + " notification=" + notification);
@@ -2138,11 +2138,11 @@
                     applyZenModeLocked(r);
                     mRankingHelper.sort(mNotificationList);
 
-                    if (notification.icon != 0) {
+                    if (notification.getSmallIcon() != null) {
                         StatusBarNotification oldSbn = (old != null) ? old.sbn : null;
                         mListeners.notifyPostedLocked(n, oldSbn);
                     } else {
-                        Slog.e(TAG, "Not posting notification with icon==0: " + notification);
+                        Slog.e(TAG, "Not posting notification without small icon: " + notification);
                         if (old != null && !old.isCanceled) {
                             mListeners.notifyRemovedLocked(n);
                         }
@@ -2715,7 +2715,7 @@
         }
 
         // status bar
-        if (r.getNotification().icon != 0) {
+        if (r.getNotification().getSmallIcon() != null) {
             r.isCanceled = true;
             mListeners.notifyRemovedLocked(r.sbn);
         }
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 5e996725..a2b1858 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -757,7 +757,7 @@
      * of state change events.
      * <p>
      * <b>Note:</b> If an application's target SDK version is
-     * {@link android.os.Build.VERSION_CODES#MNC} or newer, network
+     * {@link android.os.Build.VERSION_CODES#LOLLIPOP} or newer, network
      * communication may not use Wi-Fi even if Wi-Fi is connected; traffic may
      * instead be sent through another network, such as cellular data,
      * Bluetooth tethering, or Ethernet. For example, traffic will never use a
@@ -776,7 +776,7 @@
      * @return {@code true} if the operation succeeded
      */
     public boolean enableNetwork(int netId, boolean disableOthers) {
-        final boolean pin = disableOthers && mTargetSdkVersion < Build.VERSION_CODES.MNC;
+        final boolean pin = disableOthers && mTargetSdkVersion < Build.VERSION_CODES.LOLLIPOP;
         if (pin) {
             registerPinningNetworkCallback();
         }
@@ -1057,7 +1057,7 @@
             }
             synchronized(this) {
                 record = mService.reportActivityInfo();
-                if (record.isValid()) {
+                if (record != null && record.isValid()) {
                     return record;
                 } else {
                     return null;