Implementing gradual image fade for the media template
Test: play music Merged-In: I525513ce1da1237c4edad32c0ed31e79d5eacd32 Change-Id: I525513ce1da1237c4edad32c0ed31e79d5eacd32 Fixes: 36561228
This commit is contained in:
@@ -4959,6 +4959,22 @@ public class Notification implements Parcelable
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return true if this is a media notification
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public boolean isMediaNotification() {
|
||||
Class<? extends Style> style = getNotificationStyle();
|
||||
if (MediaStyle.class.equals(style)) {
|
||||
return true;
|
||||
} else if (DecoratedMediaCustomViewStyle.class.equals(style)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean hasLargeIcon() {
|
||||
return mLargeIcon != null || largeIcon != null;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,6 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
/**
|
||||
@@ -34,8 +33,7 @@ import android.widget.RemoteViews;
|
||||
@RemoteViews.RemoteView
|
||||
public class MediaNotificationView extends FrameLayout {
|
||||
|
||||
private final int mMaxImageSize;
|
||||
private final int mImageMinTopMargin;
|
||||
private final int mSmallImageSize;
|
||||
private final int mNotificationContentMarginEnd;
|
||||
private final int mNotificationContentImageMarginEnd;
|
||||
private ImageView mRightIcon;
|
||||
@@ -57,72 +55,68 @@ public class MediaNotificationView extends FrameLayout {
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int mode = MeasureSpec.getMode(widthMeasureSpec);
|
||||
boolean hasIcon = mRightIcon.getVisibility() != GONE;
|
||||
if (!hasIcon) {
|
||||
resetHeaderIndention();
|
||||
}
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
int mode = MeasureSpec.getMode(widthMeasureSpec);
|
||||
boolean reMeasure = false;
|
||||
if (hasIcon && mode != MeasureSpec.UNSPECIFIED) {
|
||||
measureChild(mActions, widthMeasureSpec, heightMeasureSpec);
|
||||
int size = MeasureSpec.getSize(widthMeasureSpec);
|
||||
size = size - mActions.getMeasuredWidth();
|
||||
ViewGroup.MarginLayoutParams layoutParams =
|
||||
(MarginLayoutParams) mRightIcon.getLayoutParams();
|
||||
int imageEndMargin = layoutParams.getMarginEnd();
|
||||
size -= imageEndMargin;
|
||||
size = Math.min(size, mMaxImageSize);
|
||||
size = Math.max(size, mRightIcon.getMinimumWidth());
|
||||
layoutParams.width = size;
|
||||
layoutParams.height = size;
|
||||
mRightIcon.setLayoutParams(layoutParams);
|
||||
|
||||
// lets ensure that the main column doesn't run into the image
|
||||
ViewGroup.MarginLayoutParams mainParams
|
||||
= (MarginLayoutParams) mMainColumn.getLayoutParams();
|
||||
int marginEnd = size + imageEndMargin + mNotificationContentMarginEnd;
|
||||
if (marginEnd != mainParams.getMarginEnd()) {
|
||||
mainParams.setMarginEnd(marginEnd);
|
||||
mMainColumn.setLayoutParams(mainParams);
|
||||
int fullHeight = getMeasuredHeight();
|
||||
if (size < fullHeight) {
|
||||
size = mSmallImageSize;
|
||||
} else {
|
||||
size = fullHeight;
|
||||
}
|
||||
|
||||
}
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
ViewGroup.MarginLayoutParams iconParams =
|
||||
(MarginLayoutParams) mRightIcon.getLayoutParams();
|
||||
int topMargin = getMeasuredHeight() - mRightIcon.getMeasuredHeight()
|
||||
- iconParams.bottomMargin;
|
||||
// If the topMargin is high enough we can also remove the header constraint!
|
||||
boolean reMeasure = false;
|
||||
if (!hasIcon || topMargin >= mImageMinTopMargin) {
|
||||
reMeasure = resetHeaderIndention();
|
||||
} else {
|
||||
int paddingEnd = mNotificationContentImageMarginEnd;
|
||||
ViewGroup.MarginLayoutParams headerParams =
|
||||
(MarginLayoutParams) mHeader.getLayoutParams();
|
||||
int newMarginEnd = mRightIcon.getMeasuredWidth() + iconParams.getMarginEnd();
|
||||
if (headerParams.getMarginEnd() != newMarginEnd) {
|
||||
headerParams.setMarginEnd(newMarginEnd);
|
||||
mHeader.setLayoutParams(headerParams);
|
||||
if (layoutParams.width != size || layoutParams.height != size) {
|
||||
layoutParams.width = size;
|
||||
layoutParams.height = size;
|
||||
mRightIcon.setLayoutParams(layoutParams);
|
||||
reMeasure = true;
|
||||
}
|
||||
if (mHeader.getPaddingEnd() != paddingEnd) {
|
||||
|
||||
// lets ensure that the main column doesn't run into the image
|
||||
ViewGroup.MarginLayoutParams params
|
||||
= (MarginLayoutParams) mMainColumn.getLayoutParams();
|
||||
int marginEnd = size + imageEndMargin + mNotificationContentMarginEnd;
|
||||
if (marginEnd != params.getMarginEnd()) {
|
||||
params.setMarginEnd(marginEnd);
|
||||
mMainColumn.setLayoutParams(params);
|
||||
reMeasure = true;
|
||||
}
|
||||
int headerMarginEnd = size + imageEndMargin;
|
||||
params = (MarginLayoutParams) mHeader.getLayoutParams();
|
||||
if (params.getMarginEnd() != headerMarginEnd) {
|
||||
params.setMarginEnd(headerMarginEnd);
|
||||
mHeader.setLayoutParams(params);
|
||||
reMeasure = true;
|
||||
}
|
||||
if (mHeader.getPaddingEnd() != mNotificationContentImageMarginEnd) {
|
||||
mHeader.setPaddingRelative(mHeader.getPaddingStart(),
|
||||
mHeader.getPaddingTop(),
|
||||
paddingEnd,
|
||||
mNotificationContentImageMarginEnd,
|
||||
mHeader.getPaddingBottom());
|
||||
reMeasure = true;
|
||||
}
|
||||
}
|
||||
if (reMeasure) {
|
||||
measureChildWithMargins(mHeader, widthMeasureSpec, 0, heightMeasureSpec, 0);
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean resetHeaderIndention() {
|
||||
boolean remeasure = false;
|
||||
private void resetHeaderIndention() {
|
||||
if (mHeader.getPaddingEnd() != mNotificationContentMarginEnd) {
|
||||
mHeader.setPaddingRelative(mHeader.getPaddingStart(),
|
||||
mHeader.getPaddingTop(),
|
||||
mNotificationContentMarginEnd,
|
||||
mHeader.getPaddingBottom());
|
||||
remeasure = true;
|
||||
}
|
||||
ViewGroup.MarginLayoutParams headerParams =
|
||||
(MarginLayoutParams) mHeader.getLayoutParams();
|
||||
@@ -130,19 +124,14 @@ public class MediaNotificationView extends FrameLayout {
|
||||
if (headerParams.getMarginEnd() != 0) {
|
||||
headerParams.setMarginEnd(0);
|
||||
mHeader.setLayoutParams(headerParams);
|
||||
remeasure = true;
|
||||
}
|
||||
return remeasure;
|
||||
}
|
||||
|
||||
public MediaNotificationView(Context context, AttributeSet attrs, int defStyleAttr,
|
||||
int defStyleRes) {
|
||||
super(context, attrs, defStyleAttr, defStyleRes);
|
||||
mMaxImageSize = context.getResources().getDimensionPixelSize(
|
||||
com.android.internal.R.dimen.media_notification_expanded_image_max_size);
|
||||
mImageMinTopMargin = (int) (context.getResources().getDimensionPixelSize(
|
||||
com.android.internal.R.dimen.notification_content_margin_top)
|
||||
+ getResources().getDisplayMetrics().density * 2);
|
||||
mSmallImageSize = context.getResources().getDimensionPixelSize(
|
||||
com.android.internal.R.dimen.media_notification_expanded_image_small_size);
|
||||
mNotificationContentMarginEnd = context.getResources().getDimensionPixelSize(
|
||||
com.android.internal.R.dimen.notification_content_margin_end);
|
||||
mNotificationContentImageMarginEnd = context.getResources().getDimensionPixelSize(
|
||||
|
||||
@@ -23,6 +23,13 @@
|
||||
android:background="#00000000"
|
||||
android:tag="bigMediaNarrow"
|
||||
>
|
||||
<!-- The size will actually be determined at runtime -->
|
||||
<ImageView android:id="@+id/right_icon"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_gravity="top|end"
|
||||
android:scaleType="centerCrop"
|
||||
/>
|
||||
<include layout="@layout/notification_template_header"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="53dp"
|
||||
@@ -60,14 +67,4 @@
|
||||
<!-- media buttons will be added here -->
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView android:id="@+id/right_icon"
|
||||
android:layout_width="@dimen/media_notification_expanded_image_max_size"
|
||||
android:layout_height="@dimen/media_notification_expanded_image_max_size"
|
||||
android:minWidth="40dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="20dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:scaleType="centerCrop"
|
||||
/>
|
||||
</com.android.internal.widget.MediaNotificationView>
|
||||
|
||||
@@ -23,6 +23,13 @@
|
||||
android:background="#00000000"
|
||||
android:tag="media"
|
||||
>
|
||||
<ImageView android:id="@+id/right_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:adjustViewBounds="true"
|
||||
android:layout_gravity="top|end"
|
||||
android:scaleType="centerCrop"
|
||||
/>
|
||||
<include layout="@layout/notification_template_header"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="53dp" />
|
||||
@@ -61,5 +68,4 @@
|
||||
<!-- media buttons will be added here -->
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
<include layout="@layout/notification_template_right_icon" />
|
||||
</FrameLayout>
|
||||
|
||||
@@ -208,8 +208,8 @@
|
||||
<!-- The minimum height of the content if there are at least two lines or a picture-->
|
||||
<dimen name="notification_min_content_height">41dp</dimen>
|
||||
|
||||
<!-- The maximum size of the image in the expanded media notification -->
|
||||
<dimen name="media_notification_expanded_image_max_size">94dp</dimen>
|
||||
<!-- The small size of the image if the height drawing doesn't work anymore -->
|
||||
<dimen name="media_notification_expanded_image_small_size">72dp</dimen>
|
||||
|
||||
<!-- The maximum size of the image in the expanded media notification -->
|
||||
<dimen name="media_notification_expanded_image_margin_bottom">20dp</dimen>
|
||||
|
||||
@@ -2616,7 +2616,7 @@
|
||||
<java-symbol type="string" name="new_sms_notification_title" />
|
||||
<java-symbol type="string" name="new_sms_notification_content" />
|
||||
|
||||
<java-symbol type="dimen" name="media_notification_expanded_image_max_size" />
|
||||
<java-symbol type="dimen" name="media_notification_expanded_image_small_size" />
|
||||
<java-symbol type="dimen" name="media_notification_expanded_image_margin_bottom" />
|
||||
<java-symbol type="dimen" name="notification_content_image_margin_end" />
|
||||
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar.notification;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapShader;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.ColorMatrix;
|
||||
import android.graphics.ColorMatrixColorFilter;
|
||||
import android.graphics.LinearGradient;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.graphics.Shader;
|
||||
import android.graphics.Xfermode;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
/**
|
||||
* A utility class to colorize bitmaps with a color gradient and a special blending mode
|
||||
*/
|
||||
public class ImageGradientColorizer {
|
||||
public Bitmap colorize(Drawable drawable, int backgroundColor) {
|
||||
int width = drawable.getIntrinsicWidth();
|
||||
int height = drawable.getIntrinsicHeight();
|
||||
int size = Math.min(width, height);
|
||||
int widthInset = (width - size) / 2;
|
||||
int heightInset = (height - size) / 2;
|
||||
drawable = drawable.mutate();
|
||||
drawable.setBounds(- widthInset, - heightInset, width - widthInset, height - heightInset);
|
||||
Bitmap newBitmap = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(newBitmap);
|
||||
|
||||
// Values to calculate the luminance of a color
|
||||
float lr = 0.2126f;
|
||||
float lg = 0.7152f;
|
||||
float lb = 0.0722f;
|
||||
|
||||
// Extract the red, green, blue components of the color extraction color in
|
||||
// float and int form
|
||||
int tri = Color.red(backgroundColor);
|
||||
int tgi = Color.green(backgroundColor);
|
||||
int tbi = Color.blue(backgroundColor);
|
||||
|
||||
float tr = tri / 255f;
|
||||
float tg = tgi / 255f;
|
||||
float tb = tbi / 255f;
|
||||
|
||||
// Calculate the luminance of the color extraction color
|
||||
float cLum = (tr * lr + tg * lg + tb * lb) * 255;
|
||||
|
||||
ColorMatrix m = new ColorMatrix(new float[] {
|
||||
lr, lg, lb, 0, tri - cLum,
|
||||
lr, lg, lb, 0, tgi - cLum,
|
||||
lr, lg, lb, 0, tbi - cLum,
|
||||
0, 0, 0, 1, 0,
|
||||
});
|
||||
|
||||
drawable.setColorFilter(new ColorMatrixColorFilter(m));
|
||||
drawable.draw(canvas);
|
||||
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
LinearGradient linearGradient = new LinearGradient(0, 0, size, 0,
|
||||
new int[] {0, Color.argb(0.5f, 1, 1, 1), Color.BLACK},
|
||||
new float[] {0.0f, 0.4f, 1.0f}, Shader.TileMode.CLAMP);
|
||||
paint.setShader(linearGradient);
|
||||
Bitmap fadeIn = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
|
||||
Canvas fadeInCanvas = new Canvas(fadeIn);
|
||||
drawable.clearColorFilter();
|
||||
drawable.draw(fadeInCanvas);
|
||||
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
|
||||
fadeInCanvas.drawPaint(paint);
|
||||
canvas.drawBitmap(fadeIn, 0, 0, null);
|
||||
|
||||
linearGradient = new LinearGradient(0, 0, size, 0,
|
||||
new int[] {backgroundColor, Color.argb(0.5f, tr, tg, tb), 0},
|
||||
new float[] {0.0f, 0.6f, 1.0f}, Shader.TileMode.CLAMP);
|
||||
paint.setShader(linearGradient);
|
||||
paint.setXfermode(null);
|
||||
canvas.drawPaint(paint);
|
||||
return newBitmap;
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,8 @@ import android.graphics.drawable.Icon;
|
||||
import android.support.v4.graphics.ColorUtils;
|
||||
import android.support.v7.graphics.Palette;
|
||||
|
||||
import com.android.systemui.R;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -41,6 +43,8 @@ public class MediaNotificationProcessor {
|
||||
private static final float BLACK_MAX_LIGHTNESS = 0.08f;
|
||||
private static final float WHITE_MIN_LIGHTNESS = 0.92f;
|
||||
private static final int RESIZE_BITMAP_AREA = 150 * 150;
|
||||
private final ImageGradientColorizer mColorizer;
|
||||
private final Context mContext;
|
||||
private float[] mFilteredBackgroundHsl = null;
|
||||
private Palette.Filter mBlackWhiteFilter = (rgb, hsl) -> !isWhiteOrBlack(hsl);
|
||||
|
||||
@@ -48,10 +52,13 @@ public class MediaNotificationProcessor {
|
||||
* The context of the notification. This is the app context of the package posting the
|
||||
* notification.
|
||||
*/
|
||||
private final Context mContext;
|
||||
private final Context mPackageContext;
|
||||
private boolean mIsLowPriority;
|
||||
|
||||
public MediaNotificationProcessor(Context context) {
|
||||
public MediaNotificationProcessor(Context context, Context packageContext) {
|
||||
mContext = context;
|
||||
mPackageContext = packageContext;
|
||||
mColorizer = new ImageGradientColorizer();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,114 +71,124 @@ public class MediaNotificationProcessor {
|
||||
public void processNotification(Notification notification, Notification.Builder builder) {
|
||||
Icon largeIcon = notification.getLargeIcon();
|
||||
Bitmap bitmap = null;
|
||||
Drawable drawable = null;
|
||||
if (largeIcon != null) {
|
||||
Drawable drawable = largeIcon.loadDrawable(mContext);
|
||||
int width = drawable.getIntrinsicWidth();
|
||||
int height = drawable.getIntrinsicHeight();
|
||||
int area = width * height;
|
||||
if (area > RESIZE_BITMAP_AREA) {
|
||||
double factor = Math.sqrt((float) RESIZE_BITMAP_AREA / area);
|
||||
width = (int) (factor * width);
|
||||
height = (int) (factor * height);
|
||||
}
|
||||
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
drawable.setBounds(0, 0, width, height);
|
||||
drawable.draw(canvas);
|
||||
}
|
||||
if (bitmap != null) {
|
||||
// for the background we only take the left side of the image to ensure
|
||||
// a smooth transition
|
||||
Palette.Builder paletteBuilder = Palette.from(bitmap)
|
||||
.setRegion(0, 0, bitmap.getWidth() / 2, bitmap.getHeight())
|
||||
.clearFilters() // we want all colors, red / white / black ones too!
|
||||
.resizeBitmapArea(RESIZE_BITMAP_AREA);
|
||||
Palette palette = paletteBuilder.generate();
|
||||
int backgroundColor = findBackgroundColorAndFilter(palette);
|
||||
// we want the full region again
|
||||
paletteBuilder.setRegion(0, 0, bitmap.getWidth(), bitmap.getHeight());
|
||||
if (mFilteredBackgroundHsl != null) {
|
||||
paletteBuilder.addFilter((rgb, hsl) -> {
|
||||
// at least 10 degrees hue difference
|
||||
float diff = Math.abs(hsl[0] - mFilteredBackgroundHsl[0]);
|
||||
return diff > 10 && diff < 350;
|
||||
});
|
||||
}
|
||||
paletteBuilder.addFilter(mBlackWhiteFilter);
|
||||
palette = paletteBuilder.generate();
|
||||
int foregroundColor;
|
||||
if (ColorUtils.calculateLuminance(backgroundColor) > 0.5) {
|
||||
Palette.Swatch first = palette.getDarkVibrantSwatch();
|
||||
Palette.Swatch second = palette.getVibrantSwatch();
|
||||
if (first != null && second != null) {
|
||||
int firstPopulation = first.getPopulation();
|
||||
int secondPopulation = second.getPopulation();
|
||||
if (firstPopulation / secondPopulation
|
||||
< POPULATION_FRACTION_FOR_MORE_VIBRANT) {
|
||||
foregroundColor = second.getRgb();
|
||||
} else {
|
||||
foregroundColor = first.getRgb();
|
||||
}
|
||||
} else if (first != null) {
|
||||
foregroundColor = first.getRgb();
|
||||
} else if (second != null) {
|
||||
foregroundColor = second.getRgb();
|
||||
} else {
|
||||
first = palette.getMutedSwatch();
|
||||
second = palette.getDarkMutedSwatch();
|
||||
drawable = largeIcon.loadDrawable(mPackageContext);
|
||||
int backgroundColor = 0;
|
||||
if (notification.isColorizedMedia()) {
|
||||
int width = drawable.getIntrinsicWidth();
|
||||
int height = drawable.getIntrinsicHeight();
|
||||
int area = width * height;
|
||||
if (area > RESIZE_BITMAP_AREA) {
|
||||
double factor = Math.sqrt((float) RESIZE_BITMAP_AREA / area);
|
||||
width = (int) (factor * width);
|
||||
height = (int) (factor * height);
|
||||
}
|
||||
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
drawable.setBounds(0, 0, width, height);
|
||||
drawable.draw(canvas);
|
||||
|
||||
// for the background we only take the left side of the image to ensure
|
||||
// a smooth transition
|
||||
Palette.Builder paletteBuilder = Palette.from(bitmap)
|
||||
.setRegion(0, 0, bitmap.getWidth() / 2, bitmap.getHeight())
|
||||
.clearFilters() // we want all colors, red / white / black ones too!
|
||||
.resizeBitmapArea(RESIZE_BITMAP_AREA);
|
||||
Palette palette = paletteBuilder.generate();
|
||||
backgroundColor = findBackgroundColorAndFilter(palette);
|
||||
// we want the full region again
|
||||
paletteBuilder.setRegion(0, 0, bitmap.getWidth(), bitmap.getHeight());
|
||||
if (mFilteredBackgroundHsl != null) {
|
||||
paletteBuilder.addFilter((rgb, hsl) -> {
|
||||
// at least 10 degrees hue difference
|
||||
float diff = Math.abs(hsl[0] - mFilteredBackgroundHsl[0]);
|
||||
return diff > 10 && diff < 350;
|
||||
});
|
||||
}
|
||||
paletteBuilder.addFilter(mBlackWhiteFilter);
|
||||
palette = paletteBuilder.generate();
|
||||
int foregroundColor;
|
||||
if (ColorUtils.calculateLuminance(backgroundColor) > 0.5) {
|
||||
Palette.Swatch first = palette.getDarkVibrantSwatch();
|
||||
Palette.Swatch second = palette.getVibrantSwatch();
|
||||
if (first != null && second != null) {
|
||||
float firstSaturation = first.getHsl()[1];
|
||||
float secondSaturation = second.getHsl()[1];
|
||||
if (firstSaturation > secondSaturation) {
|
||||
foregroundColor = first.getRgb();
|
||||
} else {
|
||||
int firstPopulation = first.getPopulation();
|
||||
int secondPopulation = second.getPopulation();
|
||||
if (firstPopulation / secondPopulation
|
||||
< POPULATION_FRACTION_FOR_MORE_VIBRANT) {
|
||||
foregroundColor = second.getRgb();
|
||||
} else {
|
||||
foregroundColor = first.getRgb();
|
||||
}
|
||||
} else if (first != null) {
|
||||
foregroundColor = first.getRgb();
|
||||
} else if (second != null) {
|
||||
foregroundColor = second.getRgb();
|
||||
} else {
|
||||
foregroundColor = Color.BLACK;
|
||||
first = palette.getMutedSwatch();
|
||||
second = palette.getDarkMutedSwatch();
|
||||
if (first != null && second != null) {
|
||||
float firstSaturation = first.getHsl()[1];
|
||||
float secondSaturation = second.getHsl()[1];
|
||||
if (firstSaturation > secondSaturation) {
|
||||
foregroundColor = first.getRgb();
|
||||
} else {
|
||||
foregroundColor = second.getRgb();
|
||||
}
|
||||
} else if (first != null) {
|
||||
foregroundColor = first.getRgb();
|
||||
} else if (second != null) {
|
||||
foregroundColor = second.getRgb();
|
||||
} else {
|
||||
foregroundColor = Color.BLACK;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Palette.Swatch first = palette.getLightVibrantSwatch();
|
||||
Palette.Swatch second = palette.getVibrantSwatch();
|
||||
if (first != null && second != null) {
|
||||
int firstPopulation = first.getPopulation();
|
||||
int secondPopulation = second.getPopulation();
|
||||
if (firstPopulation / secondPopulation
|
||||
< POPULATION_FRACTION_FOR_MORE_VIBRANT) {
|
||||
foregroundColor = second.getRgb();
|
||||
} else {
|
||||
foregroundColor = first.getRgb();
|
||||
}
|
||||
} else if (first != null) {
|
||||
foregroundColor = first.getRgb();
|
||||
} else if (second != null) {
|
||||
foregroundColor = second.getRgb();
|
||||
} else {
|
||||
first = palette.getMutedSwatch();
|
||||
second = palette.getLightMutedSwatch();
|
||||
if (first != null && second != null) {
|
||||
float firstSaturation = first.getHsl()[1];
|
||||
float secondSaturation = second.getHsl()[1];
|
||||
if (firstSaturation > secondSaturation) {
|
||||
foregroundColor = first.getRgb();
|
||||
} else {
|
||||
foregroundColor = second.getRgb();
|
||||
}
|
||||
} else if (first != null) {
|
||||
foregroundColor = first.getRgb();
|
||||
} else if (second != null) {
|
||||
foregroundColor = second.getRgb();
|
||||
} else {
|
||||
foregroundColor = Color.WHITE;
|
||||
}
|
||||
}
|
||||
}
|
||||
builder.setColorPalette(backgroundColor, foregroundColor);
|
||||
} else {
|
||||
Palette.Swatch first = palette.getLightVibrantSwatch();
|
||||
Palette.Swatch second = palette.getVibrantSwatch();
|
||||
if (first != null && second != null) {
|
||||
int firstPopulation = first.getPopulation();
|
||||
int secondPopulation = second.getPopulation();
|
||||
if (firstPopulation / secondPopulation
|
||||
< POPULATION_FRACTION_FOR_MORE_VIBRANT) {
|
||||
foregroundColor = second.getRgb();
|
||||
} else {
|
||||
foregroundColor = first.getRgb();
|
||||
}
|
||||
} else if (first != null) {
|
||||
foregroundColor = first.getRgb();
|
||||
} else if (second != null) {
|
||||
foregroundColor = second.getRgb();
|
||||
} else {
|
||||
first = palette.getMutedSwatch();
|
||||
second = palette.getLightMutedSwatch();
|
||||
if (first != null && second != null) {
|
||||
float firstSaturation = first.getHsl()[1];
|
||||
float secondSaturation = second.getHsl()[1];
|
||||
if (firstSaturation > secondSaturation) {
|
||||
foregroundColor = first.getRgb();
|
||||
} else {
|
||||
foregroundColor = second.getRgb();
|
||||
}
|
||||
} else if (first != null) {
|
||||
foregroundColor = first.getRgb();
|
||||
} else if (second != null) {
|
||||
foregroundColor = second.getRgb();
|
||||
} else {
|
||||
foregroundColor = Color.WHITE;
|
||||
}
|
||||
}
|
||||
int id = mIsLowPriority
|
||||
? R.color.notification_material_background_low_priority_color
|
||||
: R.color.notification_material_background_color;
|
||||
backgroundColor = mContext.getColor(id);
|
||||
}
|
||||
builder.setColorPalette(backgroundColor, foregroundColor);
|
||||
Bitmap colorized = mColorizer.colorize(drawable, backgroundColor);
|
||||
builder.setLargeIcon(Icon.createWithBitmap(colorized));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,4 +252,8 @@ public class MediaNotificationProcessor {
|
||||
private boolean isWhite(float[] hslColor) {
|
||||
return hslColor[2] >= WHITE_MIN_LIGHTNESS;
|
||||
}
|
||||
|
||||
public void setIsLowPriority(boolean isLowPriority) {
|
||||
mIsLowPriority = isLowPriority;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,9 +310,10 @@ public class NotificationInflater {
|
||||
mSbn.getNotification());
|
||||
mPackageContext = mSbn.getPackageContext(mContext);
|
||||
Notification notification = mSbn.getNotification();
|
||||
if (notification.isColorizedMedia()) {
|
||||
MediaNotificationProcessor processor = new MediaNotificationProcessor(
|
||||
if (notification.isMediaNotification()) {
|
||||
MediaNotificationProcessor processor = new MediaNotificationProcessor(mContext,
|
||||
mPackageContext);
|
||||
processor.setIsLowPriority(mIsLowPriority);
|
||||
processor.processNotification(notification, recoveredBuilder);
|
||||
}
|
||||
return recoveredBuilder;
|
||||
|
||||
Reference in New Issue
Block a user