summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Sandler <dsandler@android.com>2012-03-29 06:09:02 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2012-03-29 06:09:02 -0700
commit970de33c8d4e234f65aaf2088531ac4b526be43a (patch)
tree18593ac8f99b7a44b781273461df16e86e345451
parentf3fda6962a4bf0d9defebb648065e502b0c10737 (diff)
parentf3b7343246bf20a8024853abe9c8eeef767d26da (diff)
downloadframeworks_base-970de33c8d4e234f65aaf2088531ac4b526be43a.zip
frameworks_base-970de33c8d4e234f65aaf2088531ac4b526be43a.tar.gz
frameworks_base-970de33c8d4e234f65aaf2088531ac4b526be43a.tar.bz2
Merge "The beginning of expanded notifications."
-rw-r--r--api/current.txt1
-rw-r--r--core/java/android/app/Notification.java181
-rw-r--r--core/res/res/layout/notification_template_big_picture.xml17
-rw-r--r--core/res/res/layout/status_bar_latest_event_content.xml2
-rw-r--r--core/res/res/layout/status_bar_latest_event_content_large_icon.xml11
-rw-r--r--core/res/res/values/public.xml3
-rw-r--r--packages/SystemUI/res/layout/status_bar_notification_row.xml26
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java35
8 files changed, 205 insertions, 71 deletions
diff --git a/api/current.txt b/api/current.txt
index d6a17e6..8273d23 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3724,6 +3724,7 @@ package android.app {
method public android.app.Notification.Builder setSmallIcon(int, int);
method public android.app.Notification.Builder setSound(android.net.Uri);
method public android.app.Notification.Builder setSound(android.net.Uri, int);
+ method public android.app.Notification.Builder setSubText(java.lang.CharSequence);
method public android.app.Notification.Builder setTicker(java.lang.CharSequence);
method public android.app.Notification.Builder setTicker(java.lang.CharSequence, android.widget.RemoteViews);
method public android.app.Notification.Builder setUsesIntruderAlert(boolean);
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index bbb6a4e..1356801 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -187,7 +187,6 @@ public class Notification implements Parcelable
*/
public RemoteViews contentView;
-
/**
* The view that will represent this notification in the pop-up "intruder alert" dialog.
* @hide
@@ -195,6 +194,14 @@ public class Notification implements Parcelable
public RemoteViews intruderView;
/**
+ * A larger version of {@link #contentView}, giving the Notification an
+ * opportunity to show more detail. The system UI may choose to show this
+ * instead of the normal content view at its discretion.
+ * @hide
+ */
+ public RemoteViews bigContentView;
+
+ /**
* The bitmap that may escape the bounds of the panel and bar.
*/
public Bitmap largeIcon;
@@ -584,6 +591,9 @@ public class Notification implements Parcelable
if (parcel.readInt() != 0) {
intruderView = RemoteViews.CREATOR.createFromParcel(parcel);
}
+ if (parcel.readInt() != 0) {
+ bigContentView = RemoteViews.CREATOR.createFromParcel(parcel);
+ }
}
@Override
@@ -650,6 +660,9 @@ public class Notification implements Parcelable
if (this.intruderView != null) {
that.intruderView = this.intruderView.clone();
}
+ if (this.bigContentView != null) {
+ that.bigContentView = this.bigContentView.clone();
+ }
return that;
}
@@ -747,6 +760,13 @@ public class Notification implements Parcelable
} else {
parcel.writeInt(0);
}
+
+ if (bigContentView != null) {
+ parcel.writeInt(1);
+ bigContentView.writeToParcel(parcel, 0);
+ } else {
+ parcel.writeInt(0);
+ }
}
/**
@@ -896,6 +916,7 @@ public class Notification implements Parcelable
private CharSequence mContentTitle;
private CharSequence mContentText;
private CharSequence mContentInfo;
+ private CharSequence mSubText;
private PendingIntent mContentIntent;
private RemoteViews mContentView;
private PendingIntent mDeleteIntent;
@@ -1013,6 +1034,15 @@ public class Notification implements Parcelable
}
/**
+ * Set the third line of text in the platform notification template.
+ * Don't use if you're also using {@link #setProgress(int, int, boolean)}; they occupy the same location in the standard template.
+ */
+ public Builder setSubText(CharSequence text) {
+ mSubText = text;
+ return this;
+ }
+
+ /**
* Set the large number at the right-hand side of the notification. This is
* equivalent to setContentInfo, although it might show the number in a different
* font size for readability.
@@ -1025,7 +1055,6 @@ public class Notification implements Parcelable
/**
* A small piece of additional information pertaining to this notification.
*
-
* The platform template will draw this on the last line of the notification, at the far
* right (to the right of a smallIcon if it has been placed there).
*/
@@ -1037,7 +1066,6 @@ public class Notification implements Parcelable
/**
* Set the progress this notification represents.
*
-
* The platform template will represent this using a {@link ProgressBar}.
*/
public Builder setProgress(int max, int progress, boolean indeterminate) {
@@ -1050,7 +1078,6 @@ public class Notification implements Parcelable
/**
* Supply a custom RemoteViews to use instead of the platform template.
*
-
* @see Notification#contentView
*/
public Builder setContent(RemoteViews views) {
@@ -1061,17 +1088,12 @@ public class Notification implements Parcelable
/**
* Supply a {@link PendingIntent} to be sent when the notification is clicked.
*
-
* As of {@link android.os.Build.VERSION_CODES#HONEYCOMB}, if this field is unset and you
* have specified a custom RemoteViews with {@link #setContent(RemoteViews)}, you can use
* {@link RemoteViews#setOnClickPendingIntent RemoteViews.setOnClickPendingIntent(int,PendingIntent)}
-
* to assign PendingIntents to individual views in that custom layout (i.e., to create
-
- * clickable buttons inside the
- * notification view).
+ * clickable buttons inside the notification view).
*
-
* @see Notification#contentIntent Notification.contentIntent
*/
public Builder setContentIntent(PendingIntent intent) {
@@ -1082,7 +1104,6 @@ public class Notification implements Parcelable
/**
* Supply a {@link PendingIntent} to send when the notification is cleared explicitly by the user.
*
-
* @see Notification#deleteIntent
*/
public Builder setDeleteIntent(PendingIntent intent) {
@@ -1115,7 +1136,6 @@ public class Notification implements Parcelable
* Set the "ticker" text which is displayed in the status bar when the notification first
* arrives.
*
-
* @see Notification#tickerText
*/
public Builder setTicker(CharSequence tickerText) {
@@ -1355,20 +1375,28 @@ public class Notification implements Parcelable
}
}
- private RemoteViews makeRemoteViews(int resId) {
+ private RemoteViews applyStandardTemplate(int resId) {
RemoteViews contentView = new RemoteViews(mContext.getPackageName(), resId);
boolean hasLine3 = false;
+ boolean hasLine2 = false;
+ int smallIconImageViewId = R.id.icon;
+ if (mLargeIcon != null) {
+ contentView.setImageViewBitmap(R.id.icon, mLargeIcon);
+ smallIconImageViewId = R.id.right_icon;
+ }
if (mSmallIcon != 0) {
- contentView.setImageViewResource(R.id.icon, mSmallIcon);
- contentView.setViewVisibility(R.id.icon, View.VISIBLE);
+ contentView.setImageViewResource(smallIconImageViewId, mSmallIcon);
+ contentView.setViewVisibility(smallIconImageViewId, View.VISIBLE);
} else {
- contentView.setViewVisibility(R.id.icon, View.GONE);
+ contentView.setViewVisibility(smallIconImageViewId, View.GONE);
}
if (mContentTitle != null) {
contentView.setTextViewText(R.id.title, mContentTitle);
}
if (mContentText != null) {
- contentView.setTextViewText(R.id.text, mContentText);
+ contentView.setTextViewText(
+ (mSubText != null) ? R.id.text2 : R.id.text,
+ mContentText);
hasLine3 = true;
}
if (mContentInfo != null) {
@@ -1390,12 +1418,19 @@ public class Notification implements Parcelable
} else {
contentView.setViewVisibility(R.id.info, View.GONE);
}
- if (mProgressMax != 0 || mProgressIndeterminate) {
- contentView.setProgressBar(
- R.id.progress, mProgressMax, mProgress, mProgressIndeterminate);
- contentView.setViewVisibility(R.id.progress, View.VISIBLE);
+
+ if (mSubText != null) {
+ contentView.setTextViewText(R.id.text, mSubText);
+ contentView.setViewVisibility(R.id.text2, View.VISIBLE);
} else {
- contentView.setViewVisibility(R.id.progress, View.GONE);
+ contentView.setViewVisibility(R.id.text2, View.GONE);
+ if (mProgressMax != 0 || mProgressIndeterminate) {
+ contentView.setProgressBar(
+ R.id.progress, mProgressMax, mProgress, mProgressIndeterminate);
+ contentView.setViewVisibility(R.id.progress, View.VISIBLE);
+ } else {
+ contentView.setViewVisibility(R.id.progress, View.GONE);
+ }
}
if (mWhen != 0) {
contentView.setLong(R.id.time, "setTime", mWhen);
@@ -1408,9 +1443,7 @@ public class Notification implements Parcelable
if (mContentView != null) {
return mContentView;
} else {
- return makeRemoteViews(mLargeIcon == null
- ? R.layout.status_bar_latest_event_content
- : R.layout.status_bar_latest_event_content_large_icon);
+ return applyStandardTemplate(R.layout.status_bar_latest_event_content); // no more special large_icon flavor
}
}
@@ -1419,7 +1452,7 @@ public class Notification implements Parcelable
return mTickerView;
} else {
if (mContentView == null) {
- return makeRemoteViews(mLargeIcon == null
+ return applyStandardTemplate(mLargeIcon == null
? R.layout.status_bar_latest_event_ticker
: R.layout.status_bar_latest_event_ticker_large_icon);
} else {
@@ -1516,4 +1549,100 @@ public class Notification implements Parcelable
return n;
}
}
+
+ /**
+ * @hide because this API is still very rough
+ *
+ * This is a "rebuilder": It consumes a Builder object and modifies its output.
+ *
+ * This represents the "big picture" style notification, with a large Bitmap atop the usual notification.
+ *
+ * Usage:
+ * <pre class="prettyprint">
+ * Notification noti = new Notification.BigPictureStyle(
+ * new Notification.Builder()
+ * .setContentTitle(&quot;New mail from &quot; + sender.toString())
+ * .setContentText(subject)
+ * .setSmallIcon(R.drawable.new_mail)
+ * .setLargeIcon(aBitmap))
+ * .bigPicture(aBigBitmap)
+ * .build();
+ * </pre>
+ */
+ public static class BigPictureStyle {
+ private Builder mBuilder;
+ private Bitmap mPicture;
+
+ public BigPictureStyle(Builder builder) {
+ mBuilder = builder;
+ }
+
+ public BigPictureStyle bigPicture(Bitmap b) {
+ mPicture = b;
+ return this;
+ }
+
+ private RemoteViews makeBigContentView() {
+ RemoteViews contentView = mBuilder.applyStandardTemplate(R.layout.notification_template_big_picture);
+
+ contentView.setImageViewBitmap(R.id.big_picture, mPicture);
+
+ return contentView;
+ }
+
+ public Notification build() {
+ Notification wip = mBuilder.getNotification();
+ wip.bigContentView = makeBigContentView();
+ return wip;
+ }
+ }
+
+ /**
+ * @hide because this API is still very rough
+ *
+ * This is a "rebuilder": It consumes a Builder object and modifies its output.
+ *
+ * This represents the "big text" style notification, with more area for the main content text to be read in its entirety.
+ *
+ * Usage:
+ * <pre class="prettyprint">
+ * Notification noti = new Notification.BigPictureStyle(
+ * new Notification.Builder()
+ * .setContentTitle(&quot;New mail from &quot; + sender.toString())
+ * .setContentText(subject)
+ * .setSmallIcon(R.drawable.new_mail)
+ * .setLargeIcon(aBitmap))
+ * .bigText(aVeryLongString)
+ * .build();
+ * </pre>
+ */
+ public static class BigTextStyle {
+ private Builder mBuilder;
+ private CharSequence mBigText;
+
+ public BigTextStyle(Builder builder) {
+ mBuilder = builder;
+ }
+
+ public BigTextStyle bigText(CharSequence cs) {
+ mBigText = cs;
+ return this;
+ }
+
+ private RemoteViews makeBigContentView() {
+ RemoteViews contentView = mBuilder.applyStandardTemplate(R.layout.status_bar_latest_event_content);
+
+ contentView.setTextViewText(R.id.big_text, mBigText);
+ contentView.setViewVisibility(R.id.big_text, View.VISIBLE);
+ contentView.setTextViewText(R.id.text, ""); // XXX: what do do with this spot?
+
+ return contentView;
+ }
+
+ public Notification build() {
+ Notification wip = mBuilder.getNotification();
+ wip.bigContentView = makeBigContentView();
+ return wip;
+ }
+ }
}
diff --git a/core/res/res/layout/notification_template_big_picture.xml b/core/res/res/layout/notification_template_big_picture.xml
new file mode 100644
index 0000000..6eb934e
--- /dev/null
+++ b/core/res/res/layout/notification_template_big_picture.xml
@@ -0,0 +1,17 @@
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/status_bar_latest_event_content"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ >
+ <ImageView
+ android:id="@+id/big_picture"
+ android:layout_width="match_parent"
+ android:layout_height="192dp"
+ android:scaleType="centerCrop"
+ />
+ <include layout="@layout/status_bar_latest_event_content"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/notification_large_icon_height"
+ android:layout_marginTop="192dp"
+ />
+</FrameLayout> \ No newline at end of file
diff --git a/core/res/res/layout/status_bar_latest_event_content.xml b/core/res/res/layout/status_bar_latest_event_content.xml
index ec1bc81..57c149f 100644
--- a/core/res/res/layout/status_bar_latest_event_content.xml
+++ b/core/res/res/layout/status_bar_latest_event_content.xml
@@ -1,7 +1,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/status_bar_latest_event_content"
android:layout_width="match_parent"
- android:layout_height="match_parent"
+ android:layout_height="wrap_content"
>
<ImageView android:id="@+id/icon"
android:layout_width="@dimen/notification_large_icon_width"
diff --git a/core/res/res/layout/status_bar_latest_event_content_large_icon.xml b/core/res/res/layout/status_bar_latest_event_content_large_icon.xml
index a2253b7..5f38e6a 100644
--- a/core/res/res/layout/status_bar_latest_event_content_large_icon.xml
+++ b/core/res/res/layout/status_bar_latest_event_content_large_icon.xml
@@ -6,6 +6,8 @@
android:orientation="vertical"
android:paddingLeft="12dp"
android:paddingRight="12dp"
+ android:paddingTop="4dp"
+ android:paddingBottom="4dp"
>
<LinearLayout
android:id="@+id/line1"
@@ -44,6 +46,13 @@
android:ellipsize="marquee"
android:visibility="gone"
/>
+ <TextView android:id="@+id/big_text"
+ android:textAppearance="@style/TextAppearance.StatusBar.EventContent"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:singleLine="false"
+ android:visibility="gone"
+ />
<LinearLayout
android:id="@+id/line3"
android:layout_width="match_parent"
@@ -70,7 +79,7 @@
android:gravity="center"
android:paddingLeft="8dp"
/>
- <ImageView android:id="@+id/icon"
+ <ImageView android:id="@+id/right_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index e1bc33b..9c5f4d6 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -198,6 +198,8 @@
<java-symbol type="id" name="action0" />
<java-symbol type="id" name="action1" />
<java-symbol type="id" name="action2" />
+ <java-symbol type="id" name="big_picture" />
+ <java-symbol type="id" name="big_text" />
<java-symbol type="attr" name="actionModeShareDrawable" />
<java-symbol type="attr" name="alertDialogCenterButtons" />
@@ -1070,6 +1072,7 @@
<java-symbol type="layout" name="zoom_controls" />
<java-symbol type="layout" name="zoom_magnify" />
<java-symbol type="layout" name="notification_intruder_content" />
+ <java-symbol type="layout" name="notification_template_big_picture" />
<java-symbol type="anim" name="slide_in_child_bottom" />
<java-symbol type="anim" name="slide_in_right" />
diff --git a/packages/SystemUI/res/layout/status_bar_notification_row.xml b/packages/SystemUI/res/layout/status_bar_notification_row.xml
index abbc89a..c307c6e 100644
--- a/packages/SystemUI/res/layout/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout/status_bar_notification_row.xml
@@ -1,4 +1,4 @@
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/notification_height"
>
@@ -7,31 +7,17 @@
android:id="@+id/veto"
android:layout_width="48dp"
android:layout_height="match_parent"
- android:layout_centerVertical="true"
- android:layout_alignParentRight="true"
+ android:gravity="right"
android:layout_marginRight="-80dp"
android:background="@null"
android:paddingRight="8dp"
android:paddingLeft="8dp"
/>
- <ImageView
- android:id="@+id/large_icon"
- android:layout_width="@android:dimen/notification_large_icon_width"
- android:layout_height="@android:dimen/notification_large_icon_height"
- android:layout_alignParentTop="true"
- android:layout_alignParentLeft="true"
- android:scaleType="center"
- android:clickable="true"
- android:background="@*android:drawable/notify_panel_notification_icon_bg_tile"
- />
-
<com.android.systemui.statusbar.LatestItemView android:id="@+id/content"
android:layout_width="match_parent"
- android:layout_height="64dp"
- android:layout_alignParentTop="true"
- android:layout_toRightOf="@id/large_icon"
- android:layout_alignParentRight="true"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/notification_divider_height"
android:focusable="true"
android:clickable="true"
android:background="@drawable/notification_row_bg"
@@ -40,8 +26,8 @@
<View
android:layout_width="match_parent"
android:layout_height="@dimen/notification_divider_height"
- android:layout_alignParentBottom="true"
+ android:gravity="bottom"
android:background="@drawable/status_bar_notification_row_background_color"
/>
-</RelativeLayout>
+</FrameLayout>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 85e0a8a..023b21f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -675,10 +675,8 @@ public class PhoneStatusBar extends BaseStatusBar {
if (contentIntent != null) {
final View.OnClickListener listener = new NotificationClicker(contentIntent,
notification.pkg, notification.tag, notification.id);
- oldEntry.largeIcon.setOnClickListener(listener);
oldEntry.content.setOnClickListener(listener);
} else {
- oldEntry.largeIcon.setOnClickListener(null);
oldEntry.content.setOnClickListener(null);
}
// Update the icon.
@@ -690,13 +688,6 @@ public class PhoneStatusBar extends BaseStatusBar {
handleNotificationError(key, notification, "Couldn't update icon: " + ic);
return;
}
- // Update the large icon
- if (notification.notification.largeIcon != null) {
- oldEntry.largeIcon.setImageBitmap(notification.notification.largeIcon);
- } else {
- oldEntry.largeIcon.getLayoutParams().width = 0;
- oldEntry.largeIcon.setVisibility(View.INVISIBLE);
- }
}
catch (RuntimeException e) {
// It failed to add cleanly. Log, and remove the view from the panel.
@@ -878,7 +869,10 @@ public class PhoneStatusBar extends BaseStatusBar {
private boolean inflateViews(NotificationData.Entry entry, ViewGroup parent) {
StatusBarNotification sbn = entry.notification;
- RemoteViews remoteViews = sbn.notification.contentView;
+ // XXX: temporary: while testing big notifications, auto-expand all of them
+ final boolean big = (sbn.notification.bigContentView != null);
+ RemoteViews remoteViews = big ? sbn.notification.bigContentView
+ : sbn.notification.contentView;
if (remoteViews == null) {
return false;
}
@@ -887,20 +881,18 @@ public class PhoneStatusBar extends BaseStatusBar {
LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
View row = inflater.inflate(R.layout.status_bar_notification_row, parent, false);
+ ViewGroup.LayoutParams lp = row.getLayoutParams();
+ if (big) {
+ lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ } else {
+ lp.height = mContext.getResources().getDimensionPixelSize(R.dimen.notification_height);
+ }
+ row.setLayoutParams(lp);
View vetoButton = updateNotificationVetoButton(row, sbn);
vetoButton.setContentDescription(mContext.getString(
R.string.accessibility_remove_notification));
- // the large icon
- ImageView largeIcon = (ImageView)row.findViewById(R.id.large_icon);
- if (sbn.notification.largeIcon != null) {
- largeIcon.setImageBitmap(sbn.notification.largeIcon);
- largeIcon.setContentDescription(sbn.notification.tickerText);
- } else {
- largeIcon.getLayoutParams().width = 0;
- largeIcon.setVisibility(View.INVISIBLE);
- }
- largeIcon.setContentDescription(sbn.notification.tickerText);
+ // NB: the large icon is now handled entirely by the template
// bind the click event to the content area
ViewGroup content = (ViewGroup)row.findViewById(R.id.content);
@@ -911,10 +903,8 @@ public class PhoneStatusBar extends BaseStatusBar {
if (contentIntent != null) {
final View.OnClickListener listener = new NotificationClicker(contentIntent,
sbn.pkg, sbn.tag, sbn.id);
- largeIcon.setOnClickListener(listener);
content.setOnClickListener(listener);
} else {
- largeIcon.setOnClickListener(null);
content.setOnClickListener(null);
}
@@ -940,7 +930,6 @@ public class PhoneStatusBar extends BaseStatusBar {
entry.row = row;
entry.content = content;
entry.expanded = expanded;
- entry.largeIcon = largeIcon;
return true;
}