Merge "Reducing bitmap sizes in notifications" into oc-dr1-dev
am: 8ffa981686
Change-Id: I20fbb857570c0e7bb02659b9026b0800d5939bc2
This commit is contained in:
@@ -33,6 +33,7 @@ import android.content.pm.PackageManager;
|
|||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
import android.content.pm.ShortcutInfo;
|
import android.content.pm.ShortcutInfo;
|
||||||
import android.content.res.ColorStateList;
|
import android.content.res.ColorStateList;
|
||||||
|
import android.content.res.Resources;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
@@ -1089,6 +1090,11 @@ public class Notification implements Parcelable
|
|||||||
*/
|
*/
|
||||||
public static final String EXTRA_CONTAINS_CUSTOM_VIEW = "android.contains.customView";
|
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.
|
* {@link #extras} key: the audio contents of this notification.
|
||||||
*
|
*
|
||||||
@@ -4943,9 +4949,13 @@ public class Notification implements Parcelable
|
|||||||
buildUnstyled();
|
buildUnstyled();
|
||||||
|
|
||||||
if (mStyle != null) {
|
if (mStyle != null) {
|
||||||
|
mStyle.reduceImageSizes(mContext);
|
||||||
|
mStyle.purgeResources();
|
||||||
mStyle.buildStyled(mN);
|
mStyle.buildStyled(mN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mN.reduceImageSizes(mContext);
|
||||||
|
|
||||||
if (mContext.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.N
|
if (mContext.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.N
|
||||||
&& (useExistingRemoteView())) {
|
&& (useExistingRemoteView())) {
|
||||||
if (mN.contentView == null) {
|
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
|
* @return whether this notification is a foreground service notification
|
||||||
*/
|
*/
|
||||||
@@ -5435,6 +5491,14 @@ public class Notification implements Parcelable
|
|||||||
public boolean displayCustomViewInline() {
|
public boolean displayCustomViewInline() {
|
||||||
return false;
|
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
|
* @hide
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -312,6 +312,7 @@ public class NotificationManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
|
if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
|
||||||
|
notification.reduceImageSizes(mContext);
|
||||||
final Notification copy = Builder.maybeCloneStrippedForDelivery(notification);
|
final Notification copy = Builder.maybeCloneStrippedForDelivery(notification);
|
||||||
try {
|
try {
|
||||||
service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
|
service.enqueueNotificationWithTag(pkg, mContext.getOpPackageName(), tag, id,
|
||||||
|
|||||||
@@ -198,6 +198,22 @@ public class RemoteViews implements Parcelable, Filter {
|
|||||||
mActions.add(new SetRemoteInputsAction(viewId, remoteInputs));
|
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!
|
* Handle with care!
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -21,8 +21,8 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="top|end">
|
android:layout_gravity="top|end">
|
||||||
<ImageView android:id="@+id/right_icon"
|
<ImageView android:id="@+id/right_icon"
|
||||||
android:layout_width="40dp"
|
android:layout_width="@dimen/notification_right_icon_size"
|
||||||
android:layout_height="40dp"
|
android:layout_height="@dimen/notification_right_icon_size"
|
||||||
android:layout_gravity="top|end"
|
android:layout_gravity="top|end"
|
||||||
android:layout_marginTop="36dp"
|
android:layout_marginTop="36dp"
|
||||||
android:layout_marginEnd="@dimen/notification_content_margin_end"
|
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_velocity">120dp</dimen>
|
||||||
<dimen name="item_touch_helper_swipe_escape_max_velocity">800dp</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 -->
|
<!-- 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>
|
<dimen name="autofill_dataset_picker_max_size">90%</dimen>
|
||||||
|
|
||||||
|
|||||||
@@ -2944,6 +2944,14 @@
|
|||||||
<java-symbol type="style" name="AutofillDatasetPicker" />
|
<java-symbol type="style" name="AutofillDatasetPicker" />
|
||||||
<java-symbol type="dimen" name="autofill_dataset_picker_max_size"/>
|
<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 -->
|
<!-- Accessibility fingerprint gestures -->
|
||||||
<java-symbol type="string" name="capability_title_canCaptureFingerprintGestures" />
|
<java-symbol type="string" name="capability_title_canCaptureFingerprintGestures" />
|
||||||
<java-symbol type="string" name="capability_desc_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
|
* Implement this interface to receive a callback when
|
||||||
* {@link #loadDrawableAsync(Context, OnDrawableLoadedListener, Handler) loadDrawableAsync}
|
* {@link #loadDrawableAsync(Context, OnDrawableLoadedListener, Handler) loadDrawableAsync}
|
||||||
|
|||||||
Reference in New Issue
Block a user