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

Commit 54a0c120 authored by Aran Ink's avatar Aran Ink Committed by Android (Google) Code Review
Browse files

Merge "Resize images in NotificationInlineImageResolver if too big."

parents a6781c83 f96bf427
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -1197,6 +1197,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
        if (mMenuRow != null && mMenuRow.getMenuView() != null) {
            mMenuRow.onConfigurationChanged();
        }
        if (mImageResolver != null) {
            mImageResolver.updateMaxImageSizes();
        }
    }

    public void onUiModeChanged() {
+55 −2
Original line number Diff line number Diff line
@@ -19,12 +19,17 @@ package com.android.systemui.statusbar.notification.row;
import android.app.ActivityManager;
import android.app.Notification;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;

import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.widget.ImageResolver;
import com.android.internal.widget.LocalImageResolver;
import com.android.internal.widget.MessagingMessage;
@@ -36,6 +41,10 @@ import java.util.Set;

/**
 * Custom resolver with built-in image cache for image messages.
 *
 * If the URL points to a bitmap that's larger than the maximum width or height, the bitmap
 * will be resized down to that maximum size before being cached. See {@link #getMaxImageWidth()},
 * {@link #getMaxImageHeight()}, and {@link #resolveImage(Uri)} for the downscaling implementation.
 */
public class NotificationInlineImageResolver implements ImageResolver {
    private static final String TAG = NotificationInlineImageResolver.class.getSimpleName();
@@ -44,6 +53,13 @@ public class NotificationInlineImageResolver implements ImageResolver {
    private final ImageCache mImageCache;
    private Set<Uri> mWantedUriSet;

    // max allowed bitmap width, in pixels
    @VisibleForTesting
    protected int mMaxImageWidth;
    // max allowed bitmap height, in pixels
    @VisibleForTesting
    protected int mMaxImageHeight;

    /**
     * Constructor.
     * @param context    Context.
@@ -56,6 +72,8 @@ public class NotificationInlineImageResolver implements ImageResolver {
        if (mImageCache != null) {
            mImageCache.setImageResolver(this);
        }

        updateMaxImageSizes();
    }

    /**
@@ -66,14 +84,49 @@ public class NotificationInlineImageResolver implements ImageResolver {
        return mImageCache != null && !ActivityManager.isLowRamDeviceStatic();
    }

    private boolean isLowRam() {
        return ActivityManager.isLowRamDeviceStatic();
    }

    /**
     * Update the maximum width and height allowed for bitmaps, ex. after a configuration change.
     */
    public void updateMaxImageSizes() {
        mMaxImageWidth = getMaxImageWidth();
        mMaxImageHeight = getMaxImageHeight();
    }

    @VisibleForTesting
    protected int getMaxImageWidth() {
        return mContext.getResources().getDimensionPixelSize(isLowRam()
                ? R.dimen.notification_custom_view_max_image_width_low_ram
                : R.dimen.notification_custom_view_max_image_width);
    }

    @VisibleForTesting
    protected int getMaxImageHeight() {
        return mContext.getResources().getDimensionPixelSize(isLowRam()
                ? R.dimen.notification_custom_view_max_image_height_low_ram
                : R.dimen.notification_custom_view_max_image_height);
    }

    @VisibleForTesting
    protected BitmapDrawable resolveImageInternal(Uri uri) throws IOException {
        return (BitmapDrawable) LocalImageResolver.resolveImage(uri, mContext);
    }

    /**
     * To resolve image from specified uri directly.
     * To resolve image from specified uri directly. If the resulting image is larger than the
     * maximum allowed size, scale it down.
     * @param uri Uri of the image.
     * @return Drawable of the image.
     * @throws IOException Throws if failed at resolving the image.
     */
    Drawable resolveImage(Uri uri) throws IOException {
        return LocalImageResolver.resolveImage(uri, mContext);
        BitmapDrawable image = resolveImageInternal(uri);
        Bitmap bitmap = image.getBitmap();
        image.setBitmap(Icon.scaleDownIfNecessary(bitmap, mMaxImageWidth, mMaxImageHeight));
        return image;
    }

    @Override
+100 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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.row;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertSame;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;

import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;

import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;

import com.android.systemui.SysuiTestCase;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.IOException;

@SmallTest
@RunWith(AndroidJUnit4.class)
public class NotificationInlineImageResolverTest extends SysuiTestCase {

    NotificationInlineImageResolver mResolver;
    Bitmap mBitmap;
    BitmapDrawable mBitmapDrawable;
    Uri mUri;

    @Before
    public void setup() {
        mResolver = spy(new NotificationInlineImageResolver(mContext, null));
        mBitmap = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888);
        mBitmapDrawable = new BitmapDrawable(mContext.getResources(), mBitmap);
        mUri = mock(Uri.class);
    }

    @Test
    public void refreshMaxImageSizes() {
        assertNotEquals("Starts different height", mResolver.mMaxImageHeight, 20);
        assertNotEquals("Starts different width", mResolver.mMaxImageWidth, 15);

        doReturn(20).when(mResolver).getMaxImageHeight();
        doReturn(15).when(mResolver).getMaxImageWidth();

        mResolver.updateMaxImageSizes();

        assertEquals("Height matches new config", mResolver.mMaxImageHeight, 20);
        assertEquals("Width matches new config", mResolver.mMaxImageWidth, 15);
    }

    @Test
    public void resolveImage_sizeTooBig() throws IOException {
        doReturn(mBitmapDrawable).when(mResolver).resolveImageInternal(mUri);
        mResolver.mMaxImageHeight = 5;
        mResolver.mMaxImageWidth = 5;

        // original bitmap size is 10x10
        BitmapDrawable resolved = (BitmapDrawable) mResolver.resolveImage(mUri);
        Bitmap resolvedBitmap = resolved.getBitmap();
        assertEquals("Bitmap width reduced", 5, resolvedBitmap.getWidth());
        assertEquals("Bitmap height reduced", 5, resolvedBitmap.getHeight());
        assertNotSame("Bitmap replaced", resolvedBitmap, mBitmap);
    }

    @Test
    public void resolveImage_sizeOK() throws IOException {
        doReturn(mBitmapDrawable).when(mResolver).resolveImageInternal(mUri);
        mResolver.mMaxImageWidth = 15;
        mResolver.mMaxImageHeight = 15;

        // original bitmap size is 10x10
        BitmapDrawable resolved = (BitmapDrawable) mResolver.resolveImage(mUri);
        Bitmap resolvedBitmap = resolved.getBitmap();
        assertEquals("Bitmap width unchanged", 10, resolvedBitmap.getWidth());
        assertEquals("Bitmap height unchanged", 10, resolvedBitmap.getHeight());
        assertSame("Bitmap not replaced", resolvedBitmap, mBitmap);
    }
}