summaryrefslogtreecommitdiff
path: root/core/java/android
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android')
-rw-r--r--core/java/android/app/Notification.java305
-rw-r--r--core/java/android/widget/RemoteViews.java57
2 files changed, 182 insertions, 180 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 74634a9f2b39..94c6a5e150ee 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -25,6 +25,7 @@ import android.annotation.SystemApi;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.ColorStateList;
import android.graphics.Bitmap;
@@ -44,8 +45,8 @@ import android.os.Parcelable;
import android.os.SystemClock;
import android.os.UserHandle;
import android.text.TextUtils;
+import android.util.LayoutDirection;
import android.util.Log;
-import android.util.MathUtils;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
@@ -2999,25 +3000,35 @@ public class Notification implements Parcelable
}
private void resetStandardTemplate(RemoteViews contentView) {
- removeLargeIconBackground(contentView);
- contentView.setViewPadding(R.id.icon, 0, 0, 0, 0);
- contentView.setImageViewResource(R.id.icon, 0);
- contentView.setInt(R.id.icon, "setBackgroundResource", 0);
+ resetHeader(contentView);
+ resetContentMargins(contentView);
contentView.setViewVisibility(R.id.right_icon, View.GONE);
- contentView.setInt(R.id.right_icon, "setBackgroundResource", 0);
- contentView.setImageViewResource(R.id.right_icon, 0);
- contentView.setImageViewResource(R.id.icon, 0);
contentView.setTextViewText(R.id.title, null);
contentView.setTextViewText(R.id.text, null);
unshrinkLine3Text(contentView);
contentView.setTextViewText(R.id.text2, null);
contentView.setViewVisibility(R.id.text2, View.GONE);
contentView.setViewVisibility(R.id.info, View.GONE);
- contentView.setViewVisibility(R.id.time, View.GONE);
contentView.setViewVisibility(R.id.line3, View.GONE);
contentView.setViewVisibility(R.id.overflow_divider, View.GONE);
contentView.setViewVisibility(R.id.progress, View.GONE);
+ }
+
+ private void resetHeader(RemoteViews contentView) {
+ contentView.setImageViewResource(R.id.icon, 0);
+ contentView.setTextViewText(R.id.app_name_text, null);
contentView.setViewVisibility(R.id.chronometer, View.GONE);
+ contentView.setViewVisibility(R.id.expand_button, View.GONE);
+ contentView.setViewVisibility(R.id.sub_text_time_divider, View.GONE);
+ contentView.setViewVisibility(R.id.header_sub_text, View.GONE);
+ contentView.setViewVisibility(R.id.app_title_sub_text_divider, View.GONE);
+ contentView.setViewVisibility(R.id.number_of_children, View.GONE);
+ }
+
+ private void resetContentMargins(RemoteViews contentView) {
+ contentView.setViewLayoutMarginEnd(R.id.line1, 0);
+ contentView.setViewLayoutMarginEnd(R.id.line2, 0);
+ contentView.setViewLayoutMarginEnd(R.id.line3, 0);
}
private RemoteViews applyStandardTemplate(int resId) {
@@ -3033,21 +3044,13 @@ public class Notification implements Parcelable
resetStandardTemplate(contentView);
boolean showLine3 = false;
+ // TODO: look into line3 shrinking
boolean showLine2 = false;
boolean contentTextInLine2 = false;
final Bundle ex = mN.extras;
- if (mN.mLargeIcon != null) {
- contentView.setImageViewIcon(R.id.icon, mN.mLargeIcon);
- processLargeLegacyIcon(mN.mLargeIcon, contentView);
- contentView.setImageViewIcon(R.id.right_icon, mN.mSmallIcon);
- contentView.setViewVisibility(R.id.right_icon, View.VISIBLE);
- processSmallRightIcon(mN.mSmallIcon, contentView);
- } else { // small icon at left
- contentView.setImageViewIcon(R.id.icon, mN.mSmallIcon);
- contentView.setViewVisibility(R.id.icon, View.VISIBLE);
- processSmallIconAsLarge(mN.mSmallIcon, contentView);
- }
+ bindNotificationHeader(contentView);
+ bindLargeIcon(contentView);
if (ex.getCharSequence(EXTRA_TITLE) != null) {
contentView.setTextViewText(R.id.title,
processLegacyText(ex.getCharSequence(EXTRA_TITLE)));
@@ -3079,40 +3082,25 @@ public class Notification implements Parcelable
contentView.setViewVisibility(R.id.info, View.GONE);
}
- // Need to show three lines?
- if (ex.getCharSequence(EXTRA_SUB_TEXT) != null) {
- contentView.setTextViewText(R.id.text,
- processLegacyText(ex.getCharSequence(EXTRA_SUB_TEXT)));
- if (ex.getCharSequence(EXTRA_TEXT) != null) {
- contentView.setTextViewText(R.id.text2,
- processLegacyText(ex.getCharSequence(EXTRA_TEXT)));
- contentView.setViewVisibility(R.id.text2, View.VISIBLE);
- showLine2 = true;
- contentTextInLine2 = true;
- } else {
- contentView.setViewVisibility(R.id.text2, View.GONE);
- }
- } else {
- contentView.setViewVisibility(R.id.text2, View.GONE);
- final int max = ex.getInt(EXTRA_PROGRESS_MAX, 0);
- final int progress = ex.getInt(EXTRA_PROGRESS, 0);
- final boolean ind = ex.getBoolean(EXTRA_PROGRESS_INDETERMINATE);
- if (hasProgress && (max != 0 || ind)) {
- contentView.setViewVisibility(R.id.progress, View.VISIBLE);
- contentView.setProgressBar(
+ contentView.setViewVisibility(R.id.text2, View.GONE);
+ final int max = ex.getInt(EXTRA_PROGRESS_MAX, 0);
+ final int progress = ex.getInt(EXTRA_PROGRESS, 0);
+ final boolean ind = ex.getBoolean(EXTRA_PROGRESS_INDETERMINATE);
+ if (hasProgress && (max != 0 || ind)) {
+ contentView.setViewVisibility(R.id.progress, View.VISIBLE);
+ contentView.setProgressBar(
R.id.progress, max, progress, ind);
- contentView.setProgressBackgroundTintList(
- R.id.progress, ColorStateList.valueOf(mContext.getColor(
- R.color.notification_progress_background_color)));
+ contentView.setProgressBackgroundTintList(
+ R.id.progress, ColorStateList.valueOf(mContext.getColor(
+ R.color.notification_progress_background_color)));
if (mN.color != COLOR_DEFAULT) {
ColorStateList colorStateList = ColorStateList.valueOf(mN.color);
- contentView.setProgressTintList(R.id.progress, colorStateList);
- contentView.setProgressIndeterminateTintList(R.id.progress, colorStateList);
- }
- showLine2 = true;
- } else {
- contentView.setViewVisibility(R.id.progress, View.GONE);
+ contentView.setProgressTintList(R.id.progress, colorStateList);
+ contentView.setProgressIndeterminateTintList(R.id.progress, colorStateList);
}
+ showLine2 = true;
+ } else {
+ contentView.setViewVisibility(R.id.progress, View.GONE);
}
if (showLine2) {
@@ -3120,8 +3108,50 @@ public class Notification implements Parcelable
shrinkLine3Text(contentView);
}
+ // We want to add badge to first line of text.
+ boolean addedBadge = addProfileBadge(contentView,
+ contentTextInLine2 ? R.id.profile_badge_line2 : R.id.profile_badge_line3);
+ // If we added the badge to line 3 then we should show line 3.
+ if (addedBadge && !contentTextInLine2) {
+ showLine3 = true;
+ }
+
+ // Note getStandardView may hide line 3 again.
+ contentView.setViewVisibility(R.id.line3, showLine3 ? View.VISIBLE : View.GONE);
+ contentView.setViewVisibility(R.id.overflow_divider, showLine3 ? View.VISIBLE : View.GONE);
+ return contentView;
+ }
+
+ private void bindLargeIcon(RemoteViews contentView) {
+ if (mN.mLargeIcon != null) {
+ contentView.setViewVisibility(R.id.right_icon, View.VISIBLE);
+ contentView.setImageViewIcon(R.id.right_icon, mN.mLargeIcon);
+ processLargeLegacyIcon(mN.mLargeIcon, contentView);
+ int endMargin = mContext.getResources().getDimensionPixelSize(
+ R.dimen.notification_content_picture_margin);
+ contentView.setViewLayoutMarginEnd(R.id.line1, endMargin);
+ contentView.setViewLayoutMarginEnd(R.id.line2, endMargin);
+ contentView.setViewLayoutMarginEnd(R.id.line3, endMargin);
+ }
+ }
+
+ private void bindNotificationHeader(RemoteViews contentView) {
+ bindSmallIcon(contentView);
+ bindHeaderAppName(contentView);
+ bindHeaderSubText(contentView, mN.extras.getCharSequence(EXTRA_SUB_TEXT));
+ bindHeaderChronometerAndTime(contentView);
+ bindExpandButton(contentView);
+ }
+
+ private void bindExpandButton(RemoteViews contentView) {
+ contentView.setDrawableParameters(R.id.expand_button, false, -1, resolveColor(),
+ PorterDuff.Mode.SRC_ATOP, -1);
+ }
+
+ private void bindHeaderChronometerAndTime(RemoteViews contentView) {
if (showsTimeOrChronometer()) {
- if (ex.getBoolean(EXTRA_SHOW_CHRONOMETER)) {
+ contentView.setViewVisibility(R.id.sub_text_time_divider, View.VISIBLE);
+ if (mN.extras.getBoolean(EXTRA_SHOW_CHRONOMETER)) {
contentView.setViewVisibility(R.id.chronometer, View.VISIBLE);
contentView.setLong(R.id.chronometer, "setBase",
mN.when + (SystemClock.elapsedRealtime() - System.currentTimeMillis()));
@@ -3131,26 +3161,37 @@ public class Notification implements Parcelable
contentView.setLong(R.id.time, "setTime", mN.when);
}
}
+ }
- // Adjust padding depending on line count and font size.
- contentView.setViewPadding(R.id.line1, 0,
- calculateTopPadding(mContext, hasThreeLines(),
- mContext.getResources().getConfiguration().fontScale),
- 0, 0);
+ private void bindHeaderSubText(RemoteViews contentView, CharSequence subText) {
+ if (subText != null) {
+ // TODO: Remove the span entirely to only have the string with propper formating.
+ contentView.setTextViewText(R.id.header_sub_text, processLegacyText(subText));
+ contentView.setViewVisibility(R.id.header_sub_text, View.VISIBLE);
+ contentView.setViewVisibility(R.id.app_title_sub_text_divider, View.VISIBLE);
+ }
+ }
- // We want to add badge to first line of text.
- boolean addedBadge = addProfileBadge(contentView,
- contentTextInLine2 ? R.id.profile_badge_line2 : R.id.profile_badge_line3);
- // If we added the badge to line 3 then we should show line 3.
- if (addedBadge && !contentTextInLine2) {
- showLine3 = true;
+ private void bindHeaderAppName(RemoteViews contentView) {
+ PackageManager packageManager = mContext.getPackageManager();
+ ApplicationInfo info = null;
+ try {
+ info = packageManager.getApplicationInfo(mContext.getApplicationInfo().packageName,
+ 0);
+ } catch (final NameNotFoundException e) {
+ return;
+ }
+ CharSequence appName = info != null ? packageManager.getApplicationLabel(info)
+ : null;
+ if (TextUtils.isEmpty(appName)) {
+ return;
}
+ contentView.setTextViewText(R.id.app_name_text, appName);
+ }
- // Note getStandardView may hide line 3 again.
- contentView.setViewVisibility(R.id.line3, showLine3 ? View.VISIBLE : View.GONE);
- contentView.setViewVisibility(R.id.overflow_divider,
- showLine3 ? View.VISIBLE : View.GONE);
- return contentView;
+ private void bindSmallIcon(RemoteViews contentView) {
+ contentView.setImageViewIcon(R.id.icon, mN.mSmallIcon);
+ processSmallIconColor(mN.mSmallIcon, contentView);
}
/**
@@ -3185,25 +3226,6 @@ public class Notification implements Parcelable
return hasLine2 && hasLine3;
}
- /**
- * @hide
- */
- public static int calculateTopPadding(Context ctx, boolean hasThreeLines,
- float fontScale) {
- int padding = ctx.getResources().getDimensionPixelSize(hasThreeLines
- ? R.dimen.notification_top_pad_narrow
- : R.dimen.notification_top_pad);
- int largePadding = ctx.getResources().getDimensionPixelSize(hasThreeLines
- ? R.dimen.notification_top_pad_large_text_narrow
- : R.dimen.notification_top_pad_large_text);
- float largeFactor = (MathUtils.constrain(fontScale, 1.0f, LARGE_TEXT_SCALE) - 1f)
- / (LARGE_TEXT_SCALE - 1f);
-
- // Linearly interpolate the padding between large and normal with the font scale ranging
- // from 1f to LARGE_TEXT_SCALE
- return Math.round((1 - largeFactor) * padding + largeFactor * largePadding);
- }
-
private void resetStandardTemplateWithActions(RemoteViews big) {
big.setViewVisibility(R.id.actions, View.GONE);
big.setViewVisibility(R.id.action_divider, View.GONE);
@@ -3330,84 +3352,27 @@ public class Notification implements Parcelable
}
/**
- * Apply any necessary background to smallIcons being used in the largeIcon spot.
+ * Apply any necessariy colors to the small icon
*/
- private void processSmallIconAsLarge(Icon largeIcon, RemoteViews contentView) {
- if (!isLegacy()) {
- contentView.setDrawableParameters(R.id.icon, false, -1,
- 0xFFFFFFFF,
+ private void processSmallIconColor(Icon smallIcon, RemoteViews contentView) {
+ if (!isLegacy() || getColorUtil().isGrayscaleIcon(mContext, smallIcon)) {
+ contentView.setDrawableParameters(R.id.icon, false, -1, resolveColor(),
PorterDuff.Mode.SRC_ATOP, -1);
- applyLargeIconBackground(contentView);
- } else {
- if (getColorUtil().isGrayscaleIcon(mContext, largeIcon)) {
- applyLargeIconBackground(contentView);
- }
}
}
/**
- * Apply any necessary background to a largeIcon if it's a fake smallIcon (that is,
+ * Make the largeIcon dark if it's a fake smallIcon (that is,
* if it's grayscale).
*/
// TODO: also check bounds, transparency, that sort of thing.
private void processLargeLegacyIcon(Icon largeIcon, RemoteViews contentView) {
if (largeIcon != null && isLegacy()
&& getColorUtil().isGrayscaleIcon(mContext, largeIcon)) {
- applyLargeIconBackground(contentView);
- } else {
- removeLargeIconBackground(contentView);
- }
- }
-
- /**
- * Add a colored circle behind the largeIcon slot.
- */
- private void applyLargeIconBackground(RemoteViews contentView) {
- contentView.setInt(R.id.icon, "setBackgroundResource",
- R.drawable.notification_icon_legacy_bg);
-
- contentView.setDrawableParameters(
- R.id.icon,
- true,
- -1,
- resolveColor(),
- PorterDuff.Mode.SRC_ATOP,
- -1);
-
- int padding = mContext.getResources().getDimensionPixelSize(
- R.dimen.notification_large_icon_circle_padding);
- contentView.setViewPadding(R.id.icon, padding, padding, padding, padding);
- }
-
- private void removeLargeIconBackground(RemoteViews contentView) {
- contentView.setInt(R.id.icon, "setBackgroundResource", 0);
- }
-
- /**
- * Recolor small icons when used in the R.id.right_icon slot.
- */
- private void processSmallRightIcon(Icon smallIcon, RemoteViews contentView) {
- if (!isLegacy()) {
- contentView.setDrawableParameters(R.id.right_icon, false, -1,
- 0xFFFFFFFF,
+ // resolve color will fall back to the default when legacy
+ contentView.setDrawableParameters(R.id.icon, false, -1, resolveColor(),
PorterDuff.Mode.SRC_ATOP, -1);
}
- final boolean gray = isLegacy()
- && smallIcon.getType() == Icon.TYPE_RESOURCE
- && getColorUtil().isGrayscaleIcon(mContext, smallIcon.getResId());
- if (!isLegacy() || gray) {
- contentView.setInt(R.id.right_icon,
- "setBackgroundResource",
- R.drawable.notification_icon_legacy_bg);
-
- contentView.setDrawableParameters(
- R.id.right_icon,
- true,
- -1,
- resolveColor(),
- PorterDuff.Mode.SRC_ATOP,
- -1);
- }
}
private void sanitizeColor() {
@@ -3418,7 +3383,7 @@ public class Notification implements Parcelable
private int resolveColor() {
if (mN.color == COLOR_DEFAULT) {
- return mContext.getColor(R.color.notification_icon_bg_color);
+ return mContext.getColor(R.color.notification_icon_default_color);
}
return mN.color;
}
@@ -3622,19 +3587,19 @@ public class Notification implements Parcelable
contentView.setViewVisibility(R.id.line1, View.VISIBLE);
}
- // The last line defaults to the subtext, but can be replaced by mSummaryText
- final CharSequence overflowText =
- mSummaryTextSet ? mSummaryText
- : mBuilder.getAllExtras().getCharSequence(EXTRA_SUB_TEXT);
- if (overflowText != null) {
- contentView.setTextViewText(R.id.text, mBuilder.processLegacyText(overflowText));
+ final CharSequence overflowText = mSummaryTextSet ? mSummaryText : null;
+ final CharSequence subText = mBuilder.mN.extras.getCharSequence(EXTRA_SUB_TEXT);
+ boolean showSummaryOnBottom = overflowText != null && !overflowText.equals(subText);
+ if (showSummaryOnBottom) {
+ contentView
+ .setTextViewText(R.id.text, mBuilder.processLegacyText(overflowText));
contentView.setViewVisibility(R.id.overflow_divider, View.VISIBLE);
contentView.setViewVisibility(R.id.line3, View.VISIBLE);
} else {
// Clear text in case we use the line to show the profile badge.
- contentView.setTextViewText(R.id.text, "");
- contentView.setViewVisibility(R.id.overflow_divider, View.GONE);
- contentView.setViewVisibility(R.id.line3, View.GONE);
+ contentView.setTextViewText(com.android.internal.R.id.text, "");
+ contentView.setViewVisibility(com.android.internal.R.id.overflow_divider, View.GONE);
+ contentView.setViewVisibility(com.android.internal.R.id.line3, View.GONE);
}
return contentView;
@@ -3666,19 +3631,6 @@ public class Notification implements Parcelable
}
/**
- * Changes the padding of the first line such that the big and small content view have the
- * same top padding.
- *
- * @hide
- */
- protected void applyTopPadding(RemoteViews contentView) {
- int topPadding = Builder.calculateTopPadding(mBuilder.mContext,
- mBuilder.hasThreeLines(),
- mBuilder.mContext.getResources().getConfiguration().fontScale);
- contentView.setViewPadding(R.id.line1, 0, topPadding, 0, 0);
- }
-
- /**
* Apply any style-specific extras to this notification before shipping it out.
* @hide
*/
@@ -3853,8 +3805,6 @@ public class Notification implements Parcelable
contentView.setImageViewBitmap(R.id.big_picture, mPicture);
- applyTopPadding(contentView);
-
boolean twoTextLines = mBuilder.getAllExtras().getCharSequence(EXTRA_SUB_TEXT) != null
&& mBuilder.getAllExtras().getCharSequence(EXTRA_TEXT) != null;
mBuilder.addProfileBadge(contentView,
@@ -3985,8 +3935,6 @@ public class Notification implements Parcelable
contentView.setInt(R.id.big_text, "setMaxLines", calculateMaxLines());
contentView.setViewVisibility(R.id.text2, View.GONE);
- applyTopPadding(contentView);
-
mBuilder.shrinkLine3Text(contentView);
mBuilder.addProfileBadge(contentView, R.id.profile_badge_large_template);
@@ -4139,8 +4087,6 @@ public class Notification implements Parcelable
contentView.setViewVisibility(R.id.inbox_more,
mTexts.size() > rowIds.length ? View.VISIBLE : View.GONE);
- applyTopPadding(contentView);
-
mBuilder.shrinkLine3Text(contentView);
mBuilder.addProfileBadge(contentView, R.id.profile_badge_large_template);
@@ -4334,7 +4280,6 @@ public class Notification implements Parcelable
}
styleText(big);
hideRightIcon(big);
- applyTopPadding(big);
big.setViewVisibility(android.R.id.progress, View.GONE);
return big;
}
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index ce1c10863acd..0ed72e4df02b 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -1638,6 +1638,47 @@ public class RemoteViews implements Parcelable, Filter {
}
/**
+ * Helper action to set layout margin on a View.
+ */
+ private class ViewMarginEndAction extends Action {
+ public ViewMarginEndAction(int viewId, int end) {
+ this.viewId = viewId;
+ this.end = end;
+ }
+
+ public ViewMarginEndAction(Parcel parcel) {
+ viewId = parcel.readInt();
+ end = parcel.readInt();
+ }
+
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(TAG);
+ dest.writeInt(viewId);
+ dest.writeInt(end);
+ }
+
+ @Override
+ public void apply(View root, ViewGroup rootParent, OnClickHandler handler) {
+ final View target = root.findViewById(viewId);
+ if (target == null) {
+ return;
+ }
+ ViewGroup.LayoutParams layoutParams = target.getLayoutParams();
+ if (layoutParams instanceof ViewGroup.MarginLayoutParams) {
+ ((ViewGroup.MarginLayoutParams) layoutParams).setMarginEnd(end);
+ }
+ }
+
+ public String getActionName() {
+ return "ViewMarginEndAction";
+ }
+
+ int end;
+
+ public final static int TAG = 19;
+ }
+
+ /**
* Helper action to set a color filter on a compound drawable on a TextView. Supports relative
* (s/t/e/b) or cardinal (l/t/r/b) arrangement.
*/
@@ -1942,6 +1983,9 @@ public class RemoteViews implements Parcelable, Filter {
case SetRemoteInputsAction.TAG:
mActions.add(new SetRemoteInputsAction(parcel));
break;
+ case ViewMarginEndAction.TAG:
+ mActions.add(new ViewMarginEndAction(parcel));
+ break;
default:
throw new ActionException("Tag " + tag + " not found");
}
@@ -2549,6 +2593,19 @@ public class RemoteViews implements Parcelable, Filter {
}
/**
+ * @hide
+ * Equivalent to calling {@link android.view.ViewGroup.MarginLayoutParams#setMarginEnd(int)}.
+ * Only works if the {@link View#getLayoutParams()} supports margins.
+ * Hidden for now since we don't want to support this for all different layout margins yet.
+ *
+ * @param viewId The id of the view to change
+ * @param endMargin the left padding in pixels
+ */
+ public void setViewLayoutMarginEnd(int viewId, int endMargin) {
+ addAction(new ViewMarginEndAction(viewId, endMargin));
+ }
+
+ /**
* Call a method taking one boolean on a view in the layout for this RemoteViews.
*
* @param viewId The id of the view on which to call the method.