diff options
Diffstat (limited to 'core/java/android')
| -rw-r--r-- | core/java/android/app/Notification.java | 305 | ||||
| -rw-r--r-- | core/java/android/widget/RemoteViews.java | 57 |
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. |
