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);
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);
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);
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);
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);
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);
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);
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);
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;
*/
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
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);
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();
*/
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.
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
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);
parcel.writeInt(1);
parcel.writeLong(when);
- parcel.writeInt(icon);
+ mSmallIcon.writeToParcel(parcel, 0);
parcel.writeInt(number);
if (contentIntent != null) {
parcel.writeInt(1);
} 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);
}
}
/**
+ * 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() {
private Context mContext;
private long mWhen;
- private int mSmallIcon;
+ private Icon mSmallIcon, mLargeIcon;
private int mSmallIconLevel;
private int mNumber;
private CharSequence mContentTitle;
private PendingIntent mFullScreenIntent;
private CharSequence mTickerText;
private RemoteViews mTickerView;
- private Bitmap mLargeIcon;
private Uri mSound;
private int mAudioStreamType;
private AudioAttributes mAudioAttributes;
* @see Notification#icon
*/
public Builder setSmallIcon(@DrawableRes int icon) {
- mSmallIcon = icon;
- return this;
+ return setSmallIcon(Icon.createWithResource(mContext.getResources(), icon));
}
/**
* @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;
}
}
/**
- * 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).
+ * 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 b) {
+ return setLargeIcon(b != null ? Icon.createWithBitmap(b) : null);
+ }
+
+ /**
+ * Add a large icon to the notification content view.
*
- * @see Notification#largeIcon
+ * 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(Bitmap icon) {
+ public Builder setLargeIcon(Icon icon) {
mLargeIcon = icon;
return this;
}
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);
}
/**
* 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);
+ }
}
}
* 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);
/**
* 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);
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;
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;
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);
// Notification fields.
mWhen = n.when;
- mSmallIcon = n.icon;
+ mSmallIcon = n.mSmallIcon;
mSmallIconLevel = n.iconLevel;
mNumber = n.number;
mFullScreenIntent = n.fullScreenIntent;
mTickerText = n.tickerText;
mTickerView = n.tickerView;
- mLargeIcon = n.largeIcon;
+ mLargeIcon = n.mLargeIcon;
mSound = n.sound;
mAudioStreamType = n.audioStreamType;
mAudioAttributes = n.audioAttributes;
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);
*/
public static class BigPictureStyle extends Style {
private Bitmap mPicture;
- private Bitmap mBigLargeIcon;
+ private Icon mBigLargeIcon;
private boolean mBigLargeIconSet = false;
public BigPictureStyle() {
* 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;
}
// 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;
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;
}
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();
}
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);
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;
}
}
+ 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".
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;
// 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);
}
}
}
- 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);
}
}
}
- 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);
}
}
}
- 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";
// 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
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);
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);
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);
}
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);
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;
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
}
/**
- * 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() {
package com.android.systemui.statusbar.phone;
+import android.graphics.drawable.Icon;
import android.os.Bundle;
import android.os.UserHandle;
import android.view.Gravity;
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;
v.set(icon);
addView(v, 0, new LinearLayout.LayoutParams(mIconSize, mIconSize));
}
-}
\ No newline at end of file
+}
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);
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);
}
}
// status bar
- if (r.getNotification().icon != 0) {
+ if (r.getNotification().getSmallIcon() != null) {
r.isCanceled = true;
mListeners.notifyRemovedLocked(r.sbn);
}