Merge "Reducing bitmap sizes in notifications" into oc-dr1-dev
This commit is contained in:
@@ -33,6 +33,7 @@ import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
@@ -1089,6 +1090,11 @@ public class Notification implements Parcelable
|
||||
*/
|
||||
public static final String EXTRA_CONTAINS_CUSTOM_VIEW = "android.contains.customView";
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public static final String EXTRA_REDUCED_IMAGES = "android.reduced.images";
|
||||
|
||||
/**
|
||||
* {@link #extras} key: the audio contents of this notification.
|
||||
*
|
||||
@@ -4943,9 +4949,13 @@ public class Notification implements Parcelable
|
||||
buildUnstyled();
|
||||
|
||||
if (mStyle != null) {
|
||||
mStyle.reduceImageSizes(mContext);
|
||||
mStyle.purgeResources();
|
||||
mStyle.buildStyled(mN);
|
||||
}
|
||||
|
||||
mN.reduceImageSizes(mContext);
|
||||
|
||||
if (mContext.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.N
|
||||
&& (useExistingRemoteView())) {
|
||||
if (mN.contentView == null) {
|
||||
@@ -5134,6 +5144,52 @@ public class Notification implements Parcelable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduces the image sizes to conform to a maximum allowed size. This also processes all custom
|
||||
* remote views.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
void reduceImageSizes(Context context) {
|
||||
if (extras.getBoolean(EXTRA_REDUCED_IMAGES)) {
|
||||
return;
|
||||
}
|
||||
if (mLargeIcon != null || largeIcon != null) {
|
||||
Resources resources = context.getResources();
|
||||
Class<? extends Style> style = getNotificationStyle();
|
||||
int maxWidth = resources.getDimensionPixelSize(R.dimen.notification_right_icon_size);
|
||||
int maxHeight = maxWidth;
|
||||
if (MediaStyle.class.equals(style)
|
||||
|| DecoratedMediaCustomViewStyle.class.equals(style)) {
|
||||
maxHeight = resources.getDimensionPixelSize(
|
||||
R.dimen.notification_media_image_max_height);
|
||||
maxWidth = resources.getDimensionPixelSize(
|
||||
R.dimen.notification_media_image_max_width);
|
||||
}
|
||||
if (mLargeIcon != null) {
|
||||
mLargeIcon.scaleDownIfNecessary(maxWidth, maxHeight);
|
||||
}
|
||||
if (largeIcon != null) {
|
||||
largeIcon = Icon.scaleDownIfNecessary(largeIcon, maxWidth, maxHeight);
|
||||
}
|
||||
}
|
||||
reduceImageSizesForRemoteView(contentView, context);
|
||||
reduceImageSizesForRemoteView(headsUpContentView, context);
|
||||
reduceImageSizesForRemoteView(bigContentView, context);
|
||||
extras.putBoolean(EXTRA_REDUCED_IMAGES, true);
|
||||
}
|
||||
|
||||
private void reduceImageSizesForRemoteView(RemoteViews remoteView, Context context) {
|
||||
if (remoteView != null) {
|
||||
Resources resources = context.getResources();
|
||||
int maxWidth = resources.getDimensionPixelSize(
|
||||
R.dimen.notification_custom_view_max_image_width);
|
||||
int maxHeight = resources.getDimensionPixelSize(
|
||||
R.dimen.notification_custom_view_max_image_height);
|
||||
remoteView.reduceImageSizes(maxWidth, maxHeight);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return whether this notification is a foreground service notification
|
||||
*/
|
||||
@@ -5435,6 +5491,14 @@ public class Notification implements Parcelable
|
||||
public boolean displayCustomViewInline() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduces the image sizes contained in this style.
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void reduceImageSizes(Context context) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -5530,6 +5594,27 @@ public class Notification implements Parcelable
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
@Override
|
||||
public void reduceImageSizes(Context context) {
|
||||
super.reduceImageSizes(context);
|
||||
Resources resources = context.getResources();
|
||||
if (mPicture != null) {
|
||||
int maxPictureWidth = resources.getDimensionPixelSize(
|
||||
R.dimen.notification_big_picture_max_height);
|
||||
int maxPictureHeight = resources.getDimensionPixelSize(
|
||||
R.dimen.notification_big_picture_max_width);
|
||||
mPicture = Icon.scaleDownIfNecessary(mPicture, maxPictureWidth, maxPictureHeight);
|
||||
}
|
||||
if (mBigLargeIcon != null) {
|
||||
int rightIconSize = resources.getDimensionPixelSize(
|
||||
R.dimen.notification_right_icon_size);
|
||||
mBigLargeIcon.scaleDownIfNecessary(rightIconSize, rightIconSize);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
|
||||
@@ -312,6 +312,7 @@ public class NotificationManager {
|
||||
}
|
||||
}
|
||||
if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
|
||||
notification.reduceImageSizes(mContext);
|
||||
final Notification copy = Builder.maybeCloneStrippedForDelivery(notification);
|
||||
try {
|
||||
service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
|
||||
|
||||
@@ -198,6 +198,22 @@ public class RemoteViews implements Parcelable, Filter {
|
||||
mActions.add(new SetRemoteInputsAction(viewId, remoteInputs));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reduces all images and ensures that they are all below the given sizes.
|
||||
*
|
||||
* @param maxWidth the maximum width allowed
|
||||
* @param maxHeight the maximum height allowed
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void reduceImageSizes(int maxWidth, int maxHeight) {
|
||||
ArrayList<Bitmap> cache = mBitmapCache.mBitmaps;
|
||||
for (int i = 0; i < cache.size(); i++) {
|
||||
Bitmap bitmap = cache.get(i);
|
||||
cache.set(i, Icon.scaleDownIfNecessary(bitmap, maxWidth, maxHeight));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle with care!
|
||||
*/
|
||||
|
||||
@@ -21,8 +21,8 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top|end">
|
||||
<ImageView android:id="@+id/right_icon"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_width="@dimen/notification_right_icon_size"
|
||||
android:layout_height="@dimen/notification_right_icon_size"
|
||||
android:layout_gravity="top|end"
|
||||
android:layout_marginTop="36dp"
|
||||
android:layout_marginEnd="@dimen/notification_content_margin_end"
|
||||
|
||||
@@ -580,6 +580,21 @@
|
||||
<dimen name="item_touch_helper_swipe_escape_velocity">120dp</dimen>
|
||||
<dimen name="item_touch_helper_swipe_escape_max_velocity">800dp</dimen>
|
||||
|
||||
<!-- The maximum height of any image in a remote view. This is applied to all images in custom remoteviews. This value is determined by the maximum notification height -->
|
||||
<dimen name="notification_custom_view_max_image_height">284dp</dimen>
|
||||
<!-- The maximum height of any image in a remote view. This is applied to all images in custom remoteviews. This value is determined a maximum notification width -->
|
||||
<dimen name="notification_custom_view_max_image_width">450dp</dimen>
|
||||
<!-- The maximum height of a big picture in a notification. The images will be reduced to that height in case they are bigger. This value is determined by the maximum notification height -->
|
||||
<dimen name="notification_big_picture_max_height">284dp</dimen>
|
||||
<!-- The maximum width of a big picture in a notification. The images will be reduced to that width in case they are bigger. This value is determined by the standard panel size -->
|
||||
<dimen name="notification_big_picture_max_width">416dp</dimen>
|
||||
<!-- The maximum height of a image in a media notification. The images will be reduced to that height in case they are bigger. This value is determined by the expanded media template-->
|
||||
<dimen name="notification_media_image_max_height">140dp</dimen>
|
||||
<!-- The maximum width of a image in a media notification. The images will be reduced to that width in case they are bigger.-->
|
||||
<dimen name="notification_media_image_max_width">280dp</dimen>
|
||||
<!-- The size of the right icon -->
|
||||
<dimen name="notification_right_icon_size">40dp</dimen>
|
||||
|
||||
<!-- Max width/height of the autofill data set picker as a fraction of the screen width/height -->
|
||||
<dimen name="autofill_dataset_picker_max_size">90%</dimen>
|
||||
|
||||
|
||||
@@ -2946,6 +2946,14 @@
|
||||
<java-symbol type="style" name="AutofillDatasetPicker" />
|
||||
<java-symbol type="dimen" name="autofill_dataset_picker_max_size"/>
|
||||
|
||||
<java-symbol type="dimen" name="notification_big_picture_max_height"/>
|
||||
<java-symbol type="dimen" name="notification_big_picture_max_width"/>
|
||||
<java-symbol type="dimen" name="notification_media_image_max_width"/>
|
||||
<java-symbol type="dimen" name="notification_media_image_max_height"/>
|
||||
<java-symbol type="dimen" name="notification_right_icon_size"/>
|
||||
<java-symbol type="dimen" name="notification_custom_view_max_image_height"/>
|
||||
<java-symbol type="dimen" name="notification_custom_view_max_image_width"/>
|
||||
|
||||
<!-- Accessibility fingerprint gestures -->
|
||||
<java-symbol type="string" name="capability_title_canCaptureFingerprintGestures" />
|
||||
<java-symbol type="string" name="capability_desc_canCaptureFingerprintGestures" />
|
||||
|
||||
@@ -804,6 +804,43 @@ public final class Icon implements Parcelable {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Scale down a bitmap to a given max width and max height. The scaling will be done in a uniform way
|
||||
* @param bitmap the bitmap to scale down
|
||||
* @param maxWidth the maximum width allowed
|
||||
* @param maxHeight the maximum height allowed
|
||||
*
|
||||
* @return the scaled bitmap if necessary or the original bitmap if no scaling was needed
|
||||
* @hide
|
||||
*/
|
||||
public static Bitmap scaleDownIfNecessary(Bitmap bitmap, int maxWidth, int maxHeight) {
|
||||
int bitmapWidth = bitmap.getWidth();
|
||||
int bitmapHeight = bitmap.getHeight();
|
||||
if (bitmapWidth > maxWidth || bitmapHeight > maxHeight) {
|
||||
float scale = Math.min((float) maxWidth / bitmapWidth,
|
||||
(float) maxHeight / bitmapHeight);
|
||||
bitmap = Bitmap.createScaledBitmap(bitmap, (int) (scale * bitmapWidth),
|
||||
(int) (scale * bitmapHeight), true /* filter */);
|
||||
}
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Scale down this icon to a given max width and max height.
|
||||
* The scaling will be done in a uniform way and currently only bitmaps are supported.
|
||||
* @param maxWidth the maximum width allowed
|
||||
* @param maxHeight the maximum height allowed
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
public void scaleDownIfNecessary(int maxWidth, int maxHeight) {
|
||||
if (mType != TYPE_BITMAP && mType != TYPE_ADAPTIVE_BITMAP) {
|
||||
return;
|
||||
}
|
||||
Bitmap bitmap = getBitmap();
|
||||
setBitmap(scaleDownIfNecessary(bitmap, maxWidth, maxHeight));
|
||||
}
|
||||
|
||||
/**
|
||||
* Implement this interface to receive a callback when
|
||||
* {@link #loadDrawableAsync(Context, OnDrawableLoadedListener, Handler) loadDrawableAsync}
|
||||
|
||||
Reference in New Issue
Block a user