diff options
12 files changed, 280 insertions, 65 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index 7eab7c8..3af6917 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -34,6 +34,8 @@ import android.util.Slog; import android.view.View; import android.widget.RemoteViews; +import com.android.internal.R; + /** * A class that represents how a persistent notification is to be presented to * the user using the {@link android.app.NotificationManager}. @@ -379,6 +381,9 @@ public class Notification implements Parcelable if (parcel.readInt() != 0) { contentView = RemoteViews.CREATOR.createFromParcel(parcel); } + if (parcel.readInt() != 0) { + largeIcon = Bitmap.CREATOR.createFromParcel(parcel); + } defaults = parcel.readInt(); flags = parcel.readInt(); if (parcel.readInt() != 0) { @@ -418,6 +423,9 @@ public class Notification implements Parcelable if (this.contentView != null) { that.contentView = this.contentView.clone(); } + if (this.largeIcon != null) { + that.largeIcon = Bitmap.createBitmap(this.largeIcon); + } that.iconLevel = that.iconLevel; that.sound = this.sound; // android.net.Uri is immutable that.audioStreamType = this.audioStreamType; @@ -483,6 +491,12 @@ public class Notification implements Parcelable } else { parcel.writeInt(0); } + if (largeIcon != null) { + parcel.writeInt(1); + largeIcon.writeToParcel(parcel, 0); + } else { + parcel.writeInt(0); + } parcel.writeInt(defaults); parcel.writeInt(this.flags); @@ -546,18 +560,18 @@ public class Notification implements Parcelable public void setLatestEventInfo(Context context, CharSequence contentTitle, CharSequence contentText, PendingIntent contentIntent) { RemoteViews contentView = new RemoteViews(context.getPackageName(), - com.android.internal.R.layout.status_bar_latest_event_content); + R.layout.status_bar_latest_event_content); if (this.icon != 0) { - contentView.setImageViewResource(com.android.internal.R.id.icon, this.icon); + contentView.setImageViewResource(R.id.icon, this.icon); } if (contentTitle != null) { - contentView.setTextViewText(com.android.internal.R.id.title, contentTitle); + contentView.setTextViewText(R.id.title, contentTitle); } if (contentText != null) { - contentView.setTextViewText(com.android.internal.R.id.text, contentText); + contentView.setTextViewText(R.id.text, contentText); } if (this.when != 0) { - contentView.setLong(com.android.internal.R.id.time, "setTime", when); + contentView.setLong(R.id.time, "setTime", when); } this.contentView = contentView; @@ -754,36 +768,41 @@ public class Notification implements Parcelable } } + private RemoteViews makeRemoteViews(int resId) { + RemoteViews contentView = new RemoteViews(mContext.getPackageName(), resId); + if (mSmallIcon != 0) { + contentView.setImageViewResource(R.id.icon, mSmallIcon); + } + if (mContentTitle != null) { + contentView.setTextViewText(R.id.title, mContentTitle); + } + if (mContentText != null) { + contentView.setTextViewText(R.id.text, mContentText); + } + if (mContentInfo != null) { + contentView.setTextViewText(R.id.info, mContentInfo); + } else if (mNumber > 0) { + NumberFormat f = NumberFormat.getIntegerInstance(); + contentView.setTextViewText(R.id.info, f.format(mNumber)); + contentView.setFloat(R.id.info, "setTextSize", + mContext.getResources().getDimensionPixelSize( + R.dimen.status_bar_content_number_size)); + } else { + contentView.setViewVisibility(R.id.info, View.GONE); + } + if (mWhen != 0) { + contentView.setLong(R.id.time, "setTime", mWhen); + } + return contentView; + } + private RemoteViews makeContentView() { if (mContentView != null) { return mContentView; } else { - RemoteViews contentView = new RemoteViews(mContext.getPackageName(), - com.android.internal.R.layout.status_bar_latest_event_content); - if (mSmallIcon != 0) { - contentView.setImageViewResource(com.android.internal.R.id.icon, mSmallIcon); - } - if (mContentTitle != null) { - contentView.setTextViewText(com.android.internal.R.id.title, mContentTitle); - } - if (mContentText != null) { - contentView.setTextViewText(com.android.internal.R.id.text, mContentText); - } - if (mContentInfo != null) { - contentView.setTextViewText(com.android.internal.R.id.info, mContentInfo); - } else if (mNumber > 0) { - NumberFormat f = NumberFormat.getIntegerInstance(); - contentView.setTextViewText(com.android.internal.R.id.info, f.format(mNumber)); - contentView.setFloat(com.android.internal.R.id.info, "setTextSize", - mContext.getResources().getDimensionPixelSize( - com.android.internal.R.dimen.status_bar_content_number_size)); - } else { - contentView.setViewVisibility(com.android.internal.R.id.info, View.GONE); - } - if (mWhen != 0) { - contentView.setLong(com.android.internal.R.id.time, "setTime", mWhen); - } - return contentView; + return makeRemoteViews(mLargeIcon == null + ? R.layout.status_bar_latest_event_content + : R.layout.status_bar_latest_event_content_large_icon); } } @@ -791,7 +810,13 @@ public class Notification implements Parcelable if (mTickerView != null) { return mTickerView; } else { - return makeContentView(); + if (mContentView == null) { + return makeRemoteViews(mLargeIcon == null + ? R.layout.status_bar_latest_event_ticker + : R.layout.status_bar_latest_event_ticker_large_icon); + } else { + return null; + } } } diff --git a/core/res/res/layout-xlarge/status_bar_latest_event_content.xml b/core/res/res/layout-xlarge/status_bar_latest_event_content.xml index d71bcd8..3afd08a 100644 --- a/core/res/res/layout-xlarge/status_bar_latest_event_content.xml +++ b/core/res/res/layout-xlarge/status_bar_latest_event_content.xml @@ -2,20 +2,19 @@ android:layout_width="match_parent" android:layout_height="match_parent" > - <ImageView android:id="@+id/icon" android:layout_width="48dp" android:layout_height="64dp" + android:layout_marginLeft="4dp" android:scaleType="center" /> - <LinearLayout android:layout_width="0dp" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_weight="1" android:orientation="vertical" - android:paddingLeft="16dp" + android:paddingLeft="8dp" > <TextView android:id="@+id/title" android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title" @@ -40,6 +39,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" + android:paddingLeft="8dp" /> </LinearLayout> diff --git a/core/res/res/layout-xlarge/status_bar_latest_event_content_large_icon.xml b/core/res/res/layout-xlarge/status_bar_latest_event_content_large_icon.xml new file mode 100644 index 0000000..9dcc7c7 --- /dev/null +++ b/core/res/res/layout-xlarge/status_bar_latest_event_content_large_icon.xml @@ -0,0 +1,43 @@ +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + > + <LinearLayout + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:layout_weight="1" + android:orientation="vertical" + > + <TextView android:id="@+id/title" + android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:singleLine="true" + android:ellipsize="marquee" + android:fadingEdge="horizontal" + /> + <TextView android:id="@+id/text" + android:textAppearance="@style/TextAppearance.StatusBar.EventContent" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_weight="1" + android:singleLine="true" + android:ellipsize="marquee" + android:fadingEdge="horizontal" + /> + </LinearLayout> + <TextView android:id="@+id/info" + android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:paddingLeft="8dp" + /> + <ImageView android:id="@+id/icon" + android:layout_width="48dp" + android:layout_height="64dp" + android:scaleType="center" + /> +</LinearLayout> + diff --git a/core/res/res/layout-xlarge/status_bar_latest_event_ticker.xml b/core/res/res/layout-xlarge/status_bar_latest_event_ticker.xml new file mode 100644 index 0000000..4861d84 --- /dev/null +++ b/core/res/res/layout-xlarge/status_bar_latest_event_ticker.xml @@ -0,0 +1,43 @@ +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="@dimen/status_bar_height" + > + <ImageView android:id="@+id/icon" + android:layout_width="48dp" + android:layout_height="64dp" + android:scaleType="center" + /> + <LinearLayout + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:layout_weight="1" + android:orientation="vertical" + android:paddingLeft="16dp" + > + <TextView android:id="@+id/title" + android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:singleLine="true" + android:ellipsize="marquee" + android:fadingEdge="horizontal" + /> + <TextView android:id="@+id/text" + android:textAppearance="@style/TextAppearance.StatusBar.EventContent" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_weight="1" + android:singleLine="true" + android:ellipsize="marquee" + android:fadingEdge="horizontal" + /> + </LinearLayout> + <TextView android:id="@+id/info" + android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + /> +</LinearLayout> + diff --git a/core/res/res/layout-xlarge/status_bar_latest_event_ticker_large_icon.xml b/core/res/res/layout-xlarge/status_bar_latest_event_ticker_large_icon.xml new file mode 100644 index 0000000..4f4afd2 --- /dev/null +++ b/core/res/res/layout-xlarge/status_bar_latest_event_ticker_large_icon.xml @@ -0,0 +1,43 @@ +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + > + <LinearLayout + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + android:layout_weight="1" + android:orientation="vertical" + android:paddingLeft="16dp" + > + <TextView android:id="@+id/title" + android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Title" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:singleLine="true" + android:ellipsize="marquee" + android:fadingEdge="horizontal" + /> + <TextView android:id="@+id/text" + android:textAppearance="@style/TextAppearance.StatusBar.EventContent" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_weight="1" + android:singleLine="true" + android:ellipsize="marquee" + android:fadingEdge="horizontal" + /> + </LinearLayout> + <TextView android:id="@+id/info" + android:textAppearance="@style/TextAppearance.StatusBar.EventContent.Info" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center_vertical" + /> + <ImageView android:id="@+id/icon" + android:layout_width="48dp" + android:layout_height="64dp" + android:scaleType="center" + /> +</LinearLayout> + diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_latest_event.xml b/packages/SystemUI/res/layout-xlarge/status_bar_latest_event.xml index b6679a5..3633227 100644 --- a/packages/SystemUI/res/layout-xlarge/status_bar_latest_event.xml +++ b/packages/SystemUI/res/layout-xlarge/status_bar_latest_event.xml @@ -13,13 +13,24 @@ android:src="@drawable/status_bar_veto" android:scaleType="center" android:background="#ff000000" + android:paddingRight="8dp" /> + <ImageView + android:id="@+id/large_icon" + android:layout_width="60dp" + android:layout_height="60dp" + android:layout_alignParentTop="true" + android:layout_alignParentLeft="true" + android:scaleType="center" + /> + <!-- TODO: scaleType should be top-left but ImageView doesn't support that. --> + <com.android.systemui.statusbar.LatestItemView android:id="@+id/content" android:layout_width="wrap_content" android:layout_height="64sp" android:layout_alignParentTop="true" - android:layout_alignParentLeft="true" + android:layout_toRightOf="@id/large_icon" android:layout_toLeftOf="@id/veto" android:layout_marginLeft="16dp" android:focusable="true" diff --git a/packages/SystemUI/res/layout-xlarge/ticker.xml b/packages/SystemUI/res/layout-xlarge/ticker.xml index d3a52c5..10acb13 100644 --- a/packages/SystemUI/res/layout-xlarge/ticker.xml +++ b/packages/SystemUI/res/layout-xlarge/ticker.xml @@ -27,5 +27,13 @@ android:background="@drawable/ticker_background" --> + <ImageView + android:id="@+id/large_icon" + android:layout_width="60dp" + android:layout_height="60dp" + android:scaleType="center" + android:visibility="gone" + /> + <!-- TODO: scaleType should be top-left but ImageView doesn't support that. --> </LinearLayout> diff --git a/packages/SystemUI/res/layout-xlarge/ticker_compat.xml b/packages/SystemUI/res/layout-xlarge/ticker_compat.xml index 5703896..90d4133 100644 --- a/packages/SystemUI/res/layout-xlarge/ticker_compat.xml +++ b/packages/SystemUI/res/layout-xlarge/ticker_compat.xml @@ -23,10 +23,19 @@ android:background="#ff1d1d1d" > - <ImageView android:id="@+id/icon" + <ImageView + android:id="@+id/large_icon" + android:layout_width="60dp" + android:layout_height="60dp" + android:scaleType="center" + android:visibility="gone" + /> + + <ImageView android:id="@+id/left_icon" android:layout_width="64dp" android:layout_height="match_parent" android:scaleType="center" + android:visibility="gone" /> <TextView android:id="@+id/text" @@ -39,4 +48,11 @@ android:maxLines="2" /> + <ImageView android:id="@+id/right_icon" + android:layout_width="64dp" + android:layout_height="match_parent" + android:scaleType="center" + android:visibility="gone" + /> + </LinearLayout> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java index b917324..7cc546a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java @@ -1009,6 +1009,15 @@ public class TabletStatusBar extends StatusBar { vetoButton.setVisibility(View.INVISIBLE); } + // the large icon + ImageView largeIcon = (ImageView)row.findViewById(R.id.large_icon); + if (sbn.notification.largeIcon != null) { + largeIcon.setImageBitmap(sbn.notification.largeIcon); + } else { + largeIcon.getLayoutParams().width = 0; + largeIcon.setVisibility(View.INVISIBLE); + } + // bind the click event to the content area ViewGroup content = (ViewGroup)row.findViewById(R.id.content); // XXX: update to allow controls within notification views diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java index 73dbdc38..cf4db41 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java @@ -148,6 +148,12 @@ public class TabletTicker extends Handler { ViewGroup group; int layoutId; + int iconId; + if (n.largeIcon != null) { + iconId = R.id.right_icon; + } else { + iconId = R.id.left_icon; + } if (n.tickerView != null) { group = (ViewGroup)inflater.inflate(R.layout.ticker, null, false); View expanded = null; @@ -172,14 +178,19 @@ public class TabletTicker extends Handler { group = (ViewGroup)inflater.inflate(R.layout.ticker_compat, mParent, false); final Drawable icon = StatusBarIconView.getIcon(mContext, new StatusBarIcon(notification.pkg, n.icon, n.iconLevel, 0)); - ImageView iv = (ImageView)group.findViewById(R.id.icon); + ImageView iv = (ImageView)group.findViewById(iconId); iv.setImageDrawable(icon); + iv.setVisibility(View.VISIBLE); TextView tv = (TextView)group.findViewById(R.id.text); tv.setText(n.tickerText); } else { throw new RuntimeException("tickerView==null && tickerText==null"); } - // TODO: Add Large icon + ImageView largeIcon = (ImageView)group.findViewById(R.id.large_icon); + if (n.largeIcon != null) { + largeIcon.setImageBitmap(n.largeIcon); + largeIcon.setVisibility(View.VISIBLE); + } return group; } } diff --git a/tests/StatusBar/res/drawable-mdpi/pineapple.png b/tests/StatusBar/res/drawable-mdpi/pineapple.png Binary files differnew file mode 100644 index 0000000..7377b96 --- /dev/null +++ b/tests/StatusBar/res/drawable-mdpi/pineapple.png diff --git a/tests/StatusBar/src/com/android/statusbartest/NotificationBuilderTest.java b/tests/StatusBar/src/com/android/statusbartest/NotificationBuilderTest.java index fddb4d5..3c26212 100644 --- a/tests/StatusBar/src/com/android/statusbartest/NotificationBuilderTest.java +++ b/tests/StatusBar/src/com/android/statusbartest/NotificationBuilderTest.java @@ -62,57 +62,63 @@ public class NotificationBuilderTest extends TestActivity new Test("Basic Content (1)") { public void run() { int id = 1; + final Notification.Builder b = makeBasicBuilder(this, id); - Notification.Builder b = new Notification.Builder(NotificationBuilderTest.this); + mNM.notify(id, b.getNotification()); + } + }, + + new Test("Content w/ Info (1)") { + public void run() { + int id = 1; + final Notification.Builder b = makeBasicBuilder(this, id); - b.setWhen(System.currentTimeMillis()); - b.setSmallIcon(R.drawable.ic_statusbar_chat); - b.setContentTitle("Title"); - b.setContentText("text\nline2"); - b.setContentIntent(makeContentIntent(id)); - b.setDeleteIntent(makeDeleteIntent(id)); + b.setContentInfo("Snoozed"); mNM.notify(id, b.getNotification()); } }, - new Test("Basic Content w/ Info (1)") { + new Test("w/ Number (1)") { public void run() { int id = 1; + final Notification.Builder b = makeBasicBuilder(this, id); - Notification.Builder b = new Notification.Builder(NotificationBuilderTest.this); - - b.setWhen(System.currentTimeMillis()); - b.setSmallIcon(R.drawable.ic_statusbar_chat); - b.setContentTitle("Title"); - b.setContentText("text\nline2"); - b.setContentIntent(makeContentIntent(id)); - b.setDeleteIntent(makeDeleteIntent(id)); - b.setContentInfo("Snoozed"); + b.setNumber(12345); mNM.notify(id, b.getNotification()); } }, - new Test("Basic Content w/ Number (1)") { + new Test("w/ Number and Large Icon (1)") { public void run() { int id = 1; + final Notification.Builder b = makeBasicBuilder(this, id); - Notification.Builder b = new Notification.Builder(NotificationBuilderTest.this); + b.setNumber(42); - b.setWhen(System.currentTimeMillis()); - b.setSmallIcon(R.drawable.ic_statusbar_chat); - b.setContentTitle("Title"); - b.setContentText("text\nline2"); - b.setContentIntent(makeContentIntent(id)); - b.setDeleteIntent(makeDeleteIntent(id)); - b.setNumber(12345); + final BitmapDrawable bd = (BitmapDrawable)getResources().getDrawable( + R.drawable.pineapple); + b.setLargeIcon(Bitmap.createBitmap(bd.getBitmap())); mNM.notify(id, b.getNotification()); } }, }; + private Notification.Builder makeBasicBuilder(Test t, int id) { + final Notification.Builder b = new Notification.Builder(this); + + b.setWhen(System.currentTimeMillis()); + b.setSmallIcon(R.drawable.ic_statusbar_chat); + b.setContentTitle("Notification builder Test"); + b.setContentText(t.name + "\nhappy notifying"); + b.setContentIntent(makeContentIntent(id)); + b.setDeleteIntent(makeDeleteIntent(id)); + + return b; + } + private PendingIntent makeContentIntent(int id) { Intent intent = new Intent(this, ConfirmationActivity.class); intent.setData(Uri.fromParts("content", "//status_bar_test/content/" + id, null)); |