diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index fa6995ad44e42..39f8e190aeab0 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -184,6 +184,11 @@ public class Notification implements Parcelable
*/
public long when;
+ /**
+ * The creation time of the notification
+ */
+ private long creationTime;
+
/**
* The resource id of a drawable to use as the icon in the status bar.
*
@@ -1479,6 +1484,7 @@ public class Notification implements Parcelable
public Notification()
{
this.when = System.currentTimeMillis();
+ this.creationTime = System.currentTimeMillis();
this.priority = PRIORITY_DEFAULT;
}
@@ -1516,6 +1522,7 @@ public class Notification implements Parcelable
this.icon = icon;
this.tickerText = tickerText;
this.when = when;
+ this.creationTime = System.currentTimeMillis();
}
/**
@@ -1526,6 +1533,7 @@ public class Notification implements Parcelable
int version = parcel.readInt();
when = parcel.readLong();
+ creationTime = parcel.readLong();
if (parcel.readInt() != 0) {
mSmallIcon = Icon.CREATOR.createFromParcel(parcel);
if (mSmallIcon.getType() == Icon.TYPE_RESOURCE) {
@@ -1614,6 +1622,7 @@ public class Notification implements Parcelable
*/
public void cloneInto(Notification that, boolean heavy) {
that.when = this.when;
+ that.creationTime = this.creationTime;
that.mSmallIcon = this.mSmallIcon;
that.number = this.number;
@@ -1794,6 +1803,7 @@ public class Notification implements Parcelable
parcel.writeInt(1);
parcel.writeLong(when);
+ parcel.writeLong(creationTime);
if (mSmallIcon == null && icon != 0) {
// you snuck an icon in here without using the builder; let's try to keep it
mSmallIcon = Icon.createWithResource("", icon);
@@ -3129,6 +3139,7 @@ public class Notification implements Parcelable
contentView.setViewVisibility(R.id.header_text, View.GONE);
contentView.setViewVisibility(R.id.header_text_divider, View.GONE);
contentView.setViewVisibility(R.id.time_divider, View.GONE);
+ contentView.setViewVisibility(R.id.time, View.GONE);
contentView.setImageViewIcon(R.id.profile_badge, null);
contentView.setViewVisibility(R.id.profile_badge, View.GONE);
}
@@ -3264,6 +3275,10 @@ public class Notification implements Parcelable
contentView.setViewVisibility(R.id.time, View.VISIBLE);
contentView.setLong(R.id.time, "setTime", mN.when);
}
+ } else {
+ // We still want a time to be set but gone, such that we can show and hide it
+ // on demand in case it's a child notification without anything in the header
+ contentView.setLong(R.id.time, "setTime", mN.when != 0 ? mN.when : mN.creationTime);
}
}
@@ -3331,7 +3346,7 @@ public class Notification implements Parcelable
* otherwise
*/
private boolean showsTimeOrChronometer() {
- return mN.when != 0 && mN.extras.getBoolean(EXTRA_SHOW_WHEN);
+ return mN.showsTimeOrChronometer();
}
private void resetStandardTemplateWithActions(RemoteViews big) {
@@ -3693,6 +3708,8 @@ public class Notification implements Parcelable
mN.extras = getAllExtras();
}
+ mN.creationTime = System.currentTimeMillis();
+
// lazy stuff from mContext; see comment in Builder(Context, Notification)
Notification.addFieldsFromContext(mContext, mN);
@@ -3825,6 +3842,15 @@ public class Notification implements Parcelable
}
}
+ /**
+ * @return true if the notification will show the time or the chronometer; false
+ * otherwise
+ * @hide
+ */
+ public boolean showsTimeOrChronometer() {
+ return when != 0 && extras.getBoolean(EXTRA_SHOW_WHEN);
+ }
+
/**
* An object that can apply a rich notification style to a {@link Notification.Builder}
* object.
diff --git a/core/java/android/widget/DateTimeView.java b/core/java/android/widget/DateTimeView.java
index 39eba7d3d7063..d2ee86622e082 100644
--- a/core/java/android/widget/DateTimeView.java
+++ b/core/java/android/widget/DateTimeView.java
@@ -131,8 +131,18 @@ public class DateTimeView extends TextView {
update();
}
+ @Override
+ @android.view.RemotableViewMethod
+ public void setVisibility(@Visibility int visibility) {
+ boolean gotVisible = visibility != GONE && getVisibility() == GONE;
+ super.setVisibility(visibility);
+ if (gotVisible) {
+ update();
+ }
+ }
+
void update() {
- if (mTime == null) {
+ if (mTime == null || getVisibility() == GONE) {
return;
}
if (mShowRelativeTime) {
diff --git a/core/res/res/layout/notification_template_header.xml b/core/res/res/layout/notification_template_header.xml
index 992e88e22ad9f..d16dcc6b906ce 100644
--- a/core/res/res/layout/notification_template_header.xml
+++ b/core/res/res/layout/notification_template_header.xml
@@ -69,15 +69,17 @@
android:text="@string/notification_header_divider_symbol"
android:singleLine="true"
android:visibility="gone"/>
-
+ android:showRelative="true"
+ android:singleLine="true"
+ android:visibility="gone" />
-
-
-
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java
index 06d79a7f91248..3363993dd2894 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationHeaderUtil.java
@@ -65,12 +65,7 @@ public class NotificationHeaderUtil {
ImageView expand = (ImageView) view.findViewById(
com.android.internal.R.id.expand_button);
applyToChild(icon, apply, header.getOriginalIconColor());
- int color = header.getOriginalNotificationColor();
- if (color == Notification.COLOR_DEFAULT) {
- color = view.getContext().getColor(
- com.android.internal.R.color.notification_icon_default_color);
- }
- applyToChild(expand, apply, color);
+ applyToChild(expand, apply, header.getOriginalNotificationColor());
}
private void applyToChild(View view, boolean shouldApply, int originalColor) {
@@ -116,7 +111,7 @@ public class NotificationHeaderUtil {
@Override
public boolean compare(View parent, View child, Object parentData,
Object childData) {
- return parent.getVisibility() == View.VISIBLE;
+ return parent.getVisibility() != View.GONE;
}
@Override
@@ -161,11 +156,11 @@ public class NotificationHeaderUtil {
mComparators.get(compI).apply(row);
}
// We need to sanitize the dividers since they might be off-balance now
- sanitizeDividers(row);
+ sanitizeHeaderViews(row);
}
}
- private void sanitizeDividers(ExpandableNotificationRow row) {
+ private void sanitizeHeaderViews(ExpandableNotificationRow row) {
if (row.isSummaryWithChildren()) {
sanitizeHeader(row.getNotificationHeader());
return;
@@ -188,9 +183,26 @@ public class NotificationHeaderUtil {
if (rowHeader == null) {
return;
}
+ final int childCount = rowHeader.getChildCount();
+ View time = rowHeader.findViewById(com.android.internal.R.id.time);
+ boolean hasVisibleText = false;
+ for (int i = 1; i < childCount - 1 ; i++) {
+ View child = rowHeader.getChildAt(i);
+ if (child instanceof TextView
+ && child.getVisibility() != View.GONE
+ && !mDividers.contains(Integer.valueOf(child.getId()))
+ && child != time) {
+ hasVisibleText = true;
+ break;
+ }
+ }
+ // in case no view is visible we make sure the time is visible
+ int timeVisibility = !hasVisibleText
+ || mRow.getStatusBarNotification().getNotification().showsTimeOrChronometer()
+ ? View.VISIBLE : View.GONE;
+ time.setVisibility(timeVisibility);
View left = null;
View right;
- final int childCount = rowHeader.getChildCount();
for (int i = 1; i < childCount - 1 ; i++) {
View child = rowHeader.getChildAt(i);
if (mDividers.contains(Integer.valueOf(child.getId()))) {
@@ -202,14 +214,14 @@ public class NotificationHeaderUtil {
// A divider was found, this needs to be hidden
i--;
break;
- } else if (right.getVisibility() == View.VISIBLE) {
+ } else if (right.getVisibility() != View.GONE && right instanceof TextView) {
visible = left != null;
left = right;
break;
}
}
child.setVisibility(visible ? View.VISIBLE : View.GONE);
- } else if (child.getVisibility() == View.VISIBLE) {
+ } else if (child.getVisibility() != View.GONE && child instanceof TextView) {
left = child;
}
}
@@ -219,7 +231,7 @@ public class NotificationHeaderUtil {
for (int compI = 0; compI < mComparators.size(); compI++) {
mComparators.get(compI).apply(row, true /* reset */);
}
- sanitizeDividers(row);
+ sanitizeHeaderViews(row);
}
private static class HeaderProcessor {