Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d0426628 authored by Selim Cinek's avatar Selim Cinek
Browse files

Reducing bitmap sizes in notifications

Bitmap sizes could be arbitrary large when they were sent
over to the system. We're now reducing them to reasonable
sizes.s

Also fixed that notification bitmaps were not put into
ashmem anymore since it got lost in a refactor.

Test: code inspection
Bug: 62319200
Change-Id: I87db7656e749666b9eab1f67fd497f155c407e18
parent ac86bc87
Loading
Loading
Loading
Loading
+84 −0
Original line number Diff line number Diff line
@@ -1091,6 +1091,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.
     *
@@ -4956,8 +4961,12 @@ 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) {
@@ -5158,6 +5167,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
     */
@@ -5459,6 +5514,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) {
        }
    }

    /**
@@ -5554,6 +5617,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
         */
+1 −0
Original line number Diff line number Diff line
@@ -307,6 +307,7 @@ public class NotificationManager {
            }
        }
        if (localLOGV) Log.v(TAG, pkg + ": notify(" + id + ", " + notification + ")");
        notification.reduceImageSizes(mContext);
        ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
        boolean isLowRam = am.isLowRamDevice();
        final Notification copy = Builder.maybeCloneStrippedForDelivery(notification, isLowRam);
+16 −0
Original line number Diff line number Diff line
@@ -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!
     */
+2 −2
Original line number Diff line number Diff line
@@ -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"
+15 −0
Original line number Diff line number Diff line
@@ -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>

Loading