Icon support comes to Notification.
And you may ask yourself: what is that beautiful icon? And you may ask yourself: where does that API go to? And you may ask yourself: is it a resource? is it a Bitmap? And you may say to yourself: my god, what have I done Bug: 18568715 Change-Id: I4377b311c538bd1cf36b3fba22326bae81af40c9
This commit is contained in:
@@ -4781,6 +4781,8 @@ package android.app {
|
||||
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 @@ package android.app {
|
||||
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 @@ package android.app {
|
||||
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 @@ package android.app {
|
||||
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);
|
||||
|
||||
@@ -4875,6 +4875,8 @@ package android.app {
|
||||
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 @@ package android.app {
|
||||
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 @@ package android.app {
|
||||
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 @@ package android.app {
|
||||
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);
|
||||
|
||||
@@ -30,6 +30,7 @@ import android.graphics.Bitmap;
|
||||
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 class Notification implements Parcelable
|
||||
*/
|
||||
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 @@ public class Notification implements Parcelable
|
||||
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 @@ public class Notification implements Parcelable
|
||||
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 class Notification implements Parcelable
|
||||
*/
|
||||
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 @@ public class Notification implements Parcelable
|
||||
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 @@ public class Notification implements Parcelable
|
||||
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 @@ public class Notification implements Parcelable
|
||||
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 @@ public class Notification implements Parcelable
|
||||
} 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);
|
||||
}
|
||||
@@ -1864,6 +1868,27 @@ public class Notification implements Parcelable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
@@ -1966,7 +1991,7 @@ public class Notification implements Parcelable
|
||||
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 @@ public class Notification implements Parcelable
|
||||
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 @@ public class Notification implements Parcelable
|
||||
* @see Notification#icon
|
||||
*/
|
||||
public Builder setSmallIcon(@DrawableRes int icon) {
|
||||
mSmallIcon = icon;
|
||||
return this;
|
||||
return setSmallIcon(Icon.createWithResource(mContext.getResources(), icon));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2176,8 +2199,20 @@ public class Notification implements Parcelable
|
||||
* @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 @@ public class Notification implements Parcelable
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 @@ public class Notification implements Parcelable
|
||||
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 @@ public class Notification implements Parcelable
|
||||
/**
|
||||
* 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 @@ public class Notification implements Parcelable
|
||||
* 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 @@ public class Notification implements Parcelable
|
||||
/**
|
||||
* 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 class Notification implements Parcelable
|
||||
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 @@ public class Notification implements Parcelable
|
||||
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 @@ public class Notification implements Parcelable
|
||||
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 @@ public class Notification implements Parcelable
|
||||
|
||||
// Notification fields.
|
||||
mWhen = n.when;
|
||||
mSmallIcon = n.icon;
|
||||
mSmallIcon = n.mSmallIcon;
|
||||
mSmallIconLevel = n.iconLevel;
|
||||
mNumber = n.number;
|
||||
|
||||
@@ -3441,7 +3496,7 @@ public class Notification implements Parcelable
|
||||
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 @@ public class Notification implements Parcelable
|
||||
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 class Notification implements Parcelable
|
||||
*/
|
||||
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 @@ public class Notification implements Parcelable
|
||||
* 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 @@ public class Notification implements Parcelable
|
||||
// 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;
|
||||
|
||||
@@ -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 class StatusBarIcon implements Parcelable {
|
||||
}
|
||||
|
||||
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 class StatusBarIcon implements Parcelable {
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.graphics.Color;
|
||||
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 class NotificationColorUtil {
|
||||
}
|
||||
}
|
||||
|
||||
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".
|
||||
|
||||
@@ -53,10 +53,14 @@ import java.io.OutputStream;
|
||||
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 @@ public final class Icon implements Parcelable {
|
||||
// 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 @@ public final class Icon implements Parcelable {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ public final class Icon implements Parcelable {
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ public final class Icon implements Parcelable {
|
||||
}
|
||||
}
|
||||
|
||||
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";
|
||||
|
||||
@@ -194,7 +194,7 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi
|
||||
// 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
|
||||
|
||||
@@ -1390,9 +1390,9 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
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 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
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 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
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 @@ public abstract class BaseStatusBar extends SystemUI implements
|
||||
}
|
||||
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);
|
||||
|
||||
@@ -24,6 +24,7 @@ import android.graphics.Canvas;
|
||||
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 @@ public class StatusBarIconView extends AnimatedImageView {
|
||||
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 @@ public class StatusBarIconView extends AnimatedImageView {
|
||||
}
|
||||
|
||||
/**
|
||||
* 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() {
|
||||
|
||||
@@ -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 @@ public class DemoStatusIcons extends LinearLayout implements DemoMode {
|
||||
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 @@ public class DemoStatusIcons extends LinearLayout implements DemoMode {
|
||||
v.set(icon);
|
||||
addView(v, 0, new LinearLayout.LayoutParams(mIconSize, mIconSize));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2017,7 +2017,7 @@ public class NotificationManagerService extends SystemService {
|
||||
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 @@ public class NotificationManagerService extends SystemService {
|
||||
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 @@ public class NotificationManagerService extends SystemService {
|
||||
}
|
||||
|
||||
// status bar
|
||||
if (r.getNotification().icon != 0) {
|
||||
if (r.getNotification().getSmallIcon() != null) {
|
||||
r.isCanceled = true;
|
||||
mListeners.notifyRemovedLocked(r.sbn);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user