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

Commit 9926272f authored by Michael Jurka's avatar Michael Jurka
Browse files

Reduce memory usage of default thumbnail

Bug: 10639174

Change-Id: I2b7f3844e77427d2327a7d89c63e4f3b0d890bc0
parent 1656a346
Loading
Loading
Loading
Loading
+40 −0
Original line number Original line Diff line number Diff line
/*
 * Copyright (C) 2013 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.recent;

import android.graphics.drawable.ColorDrawable;

public class ColorDrawableWithDimensions extends ColorDrawable {
    private int mWidth;
    private int mHeight;

    public ColorDrawableWithDimensions(int color, int width, int height) {
        super(color);
        mWidth = width;
        mHeight = height;
    }

    @Override
    public int getIntrinsicWidth() {
        return mWidth;
    }

    @Override
    public int getIntrinsicHeight() {
        return mHeight;
    }
}
+8 −10
Original line number Original line Diff line number Diff line
@@ -25,7 +25,7 @@ import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Handler;
@@ -62,8 +62,8 @@ public class RecentTasksLoader implements View.OnTouchListener {
    private Handler mHandler;
    private Handler mHandler;


    private int mIconDpi;
    private int mIconDpi;
    private Bitmap mDefaultThumbnailBackground;
    private ColorDrawableWithDimensions mDefaultThumbnailBackground;
    private Bitmap mDefaultIconBackground;
    private ColorDrawableWithDimensions mDefaultIconBackground;
    private int mNumTasksInFirstScreenful = Integer.MAX_VALUE;
    private int mNumTasksInFirstScreenful = Integer.MAX_VALUE;


    private boolean mFirstScreenful;
    private boolean mFirstScreenful;
@@ -100,7 +100,7 @@ public class RecentTasksLoader implements View.OnTouchListener {
        // Render default icon (just a blank image)
        // Render default icon (just a blank image)
        int defaultIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.app_icon_size);
        int defaultIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.app_icon_size);
        int iconSize = (int) (defaultIconSize * mIconDpi / res.getDisplayMetrics().densityDpi);
        int iconSize = (int) (defaultIconSize * mIconDpi / res.getDisplayMetrics().densityDpi);
        mDefaultIconBackground = Bitmap.createBitmap(iconSize, iconSize, Bitmap.Config.ARGB_8888);
        mDefaultIconBackground = new ColorDrawableWithDimensions(0x00000000, iconSize, iconSize);


        // Render the default thumbnail background
        // Render the default thumbnail background
        int thumbnailWidth =
        int thumbnailWidth =
@@ -110,9 +110,7 @@ public class RecentTasksLoader implements View.OnTouchListener {
        int color = res.getColor(R.drawable.status_bar_recents_app_thumbnail_background);
        int color = res.getColor(R.drawable.status_bar_recents_app_thumbnail_background);


        mDefaultThumbnailBackground =
        mDefaultThumbnailBackground =
                Bitmap.createBitmap(thumbnailWidth, thumbnailHeight, Bitmap.Config.ARGB_8888);
                new ColorDrawableWithDimensions(color, thumbnailWidth, thumbnailHeight);
        Canvas c = new Canvas(mDefaultThumbnailBackground);
        c.drawColor(color);
    }
    }


    public void setRecentsPanel(RecentsPanelView newRecentsPanel, RecentsPanelView caller) {
    public void setRecentsPanel(RecentsPanelView newRecentsPanel, RecentsPanelView caller) {
@@ -125,11 +123,11 @@ public class RecentTasksLoader implements View.OnTouchListener {
        }
        }
    }
    }


    public Bitmap getDefaultThumbnail() {
    public Drawable getDefaultThumbnail() {
        return mDefaultThumbnailBackground;
        return mDefaultThumbnailBackground;
    }
    }


    public Bitmap getDefaultIcon() {
    public Drawable getDefaultIcon() {
        return mDefaultIconBackground;
        return mDefaultIconBackground;
    }
    }


@@ -199,7 +197,7 @@ public class RecentTasksLoader implements View.OnTouchListener {
                + td + ": " + thumbnail);
                + td + ": " + thumbnail);
        synchronized (td) {
        synchronized (td) {
            if (thumbnail != null) {
            if (thumbnail != null) {
                td.setThumbnail(thumbnail);
                td.setThumbnail(new BitmapDrawable(mContext.getResources(), thumbnail));
            } else {
            } else {
                td.setThumbnail(mDefaultThumbnailBackground);
                td.setThumbnail(mDefaultThumbnailBackground);
            }
            }
+11 −1
Original line number Original line Diff line number Diff line
@@ -22,7 +22,10 @@ import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
import android.os.UserHandle;
import android.util.DisplayMetrics;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.Log;
@@ -68,7 +71,14 @@ public class Recents extends SystemUI implements RecentsComponent {
                }
                }


            } else {
            } else {
                Bitmap first = firstTask.getThumbnail();
                Bitmap first = null;
                if (firstTask.getThumbnail() instanceof BitmapDrawable) {
                    first = ((BitmapDrawable) firstTask.getThumbnail()).getBitmap();
                } else {
                    first = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
                    Drawable d = RecentTasksLoader.getInstance(mContext).getDefaultThumbnail();
                    d.draw(new Canvas(first));
                }
                final Resources res = mContext.getResources();
                final Resources res = mContext.getResources();


                float thumbWidth = res
                float thumbWidth = res
+22 −18
Original line number Original line Diff line number Diff line
@@ -113,7 +113,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
    /* package */ final static class ViewHolder {
    /* package */ final static class ViewHolder {
        View thumbnailView;
        View thumbnailView;
        ImageView thumbnailViewImage;
        ImageView thumbnailViewImage;
        Bitmap thumbnailViewImageBitmap;
        Drawable thumbnailViewDrawable;
        ImageView iconView;
        ImageView iconView;
        TextView labelView;
        TextView labelView;
        TextView descriptionView;
        TextView descriptionView;
@@ -151,7 +151,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
            // the thumbnail later (if they both have the same dimensions)
            // the thumbnail later (if they both have the same dimensions)
            updateThumbnail(holder, mRecentTasksLoader.getDefaultThumbnail(), false, false);
            updateThumbnail(holder, mRecentTasksLoader.getDefaultThumbnail(), false, false);
            holder.iconView = (ImageView) convertView.findViewById(R.id.app_icon);
            holder.iconView = (ImageView) convertView.findViewById(R.id.app_icon);
            holder.iconView.setImageBitmap(mRecentTasksLoader.getDefaultIcon());
            holder.iconView.setImageDrawable(mRecentTasksLoader.getDefaultIcon());
            holder.labelView = (TextView) convertView.findViewById(R.id.app_label);
            holder.labelView = (TextView) convertView.findViewById(R.id.app_label);
            holder.calloutLine = convertView.findViewById(R.id.recents_callout_line);
            holder.calloutLine = convertView.findViewById(R.id.recents_callout_line);
            holder.descriptionView = (TextView) convertView.findViewById(R.id.app_description);
            holder.descriptionView = (TextView) convertView.findViewById(R.id.app_description);
@@ -227,7 +227,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
        public void recycleView(View v) {
        public void recycleView(View v) {
            ViewHolder holder = (ViewHolder) v.getTag();
            ViewHolder holder = (ViewHolder) v.getTag();
            updateThumbnail(holder, mRecentTasksLoader.getDefaultThumbnail(), false, false);
            updateThumbnail(holder, mRecentTasksLoader.getDefaultThumbnail(), false, false);
            holder.iconView.setImageBitmap(mRecentTasksLoader.getDefaultIcon());
            holder.iconView.setImageDrawable(mRecentTasksLoader.getDefaultIcon());
            holder.iconView.setVisibility(INVISIBLE);
            holder.iconView.setVisibility(INVISIBLE);
            holder.iconView.animate().cancel();
            holder.iconView.animate().cancel();
            holder.labelView.setText(null);
            holder.labelView.setText(null);
@@ -488,23 +488,23 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
        }
        }
    }
    }


    private void updateThumbnail(ViewHolder h, Bitmap thumbnail, boolean show, boolean anim) {
    private void updateThumbnail(ViewHolder h, Drawable thumbnail, boolean show, boolean anim) {
        if (thumbnail != null) {
        if (thumbnail != null) {
            // Should remove the default image in the frame
            // Should remove the default image in the frame
            // that this now covers, to improve scrolling speed.
            // that this now covers, to improve scrolling speed.
            // That can't be done until the anim is complete though.
            // That can't be done until the anim is complete though.
            h.thumbnailViewImage.setImageBitmap(thumbnail);
            h.thumbnailViewImage.setImageDrawable(thumbnail);


            // scale the image to fill the full width of the ImageView. do this only if
            // scale the image to fill the full width of the ImageView. do this only if
            // we haven't set a bitmap before, or if the bitmap size has changed
            // we haven't set a bitmap before, or if the bitmap size has changed
            if (h.thumbnailViewImageBitmap == null ||
            if (h.thumbnailViewDrawable == null ||
                h.thumbnailViewImageBitmap.getWidth() != thumbnail.getWidth() ||
                h.thumbnailViewDrawable.getIntrinsicWidth() != thumbnail.getIntrinsicWidth() ||
                h.thumbnailViewImageBitmap.getHeight() != thumbnail.getHeight()) {
                h.thumbnailViewDrawable.getIntrinsicHeight() != thumbnail.getIntrinsicHeight()) {
                if (mFitThumbnailToXY) {
                if (mFitThumbnailToXY) {
                    h.thumbnailViewImage.setScaleType(ScaleType.FIT_XY);
                    h.thumbnailViewImage.setScaleType(ScaleType.FIT_XY);
                } else {
                } else {
                    Matrix scaleMatrix = new Matrix();
                    Matrix scaleMatrix = new Matrix();
                    float scale = mThumbnailWidth / (float) thumbnail.getWidth();
                    float scale = mThumbnailWidth / (float) thumbnail.getIntrinsicWidth();
                    scaleMatrix.setScale(scale, scale);
                    scaleMatrix.setScale(scale, scale);
                    h.thumbnailViewImage.setScaleType(ScaleType.MATRIX);
                    h.thumbnailViewImage.setScaleType(ScaleType.MATRIX);
                    h.thumbnailViewImage.setImageMatrix(scaleMatrix);
                    h.thumbnailViewImage.setImageMatrix(scaleMatrix);
@@ -517,7 +517,7 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
                }
                }
                h.thumbnailView.setVisibility(View.VISIBLE);
                h.thumbnailView.setVisibility(View.VISIBLE);
            }
            }
            h.thumbnailViewImageBitmap = thumbnail;
            h.thumbnailViewDrawable = thumbnail;
        }
        }
    }
    }


@@ -668,15 +668,19 @@ public class RecentsPanelView extends FrameLayout implements OnItemClickListener
        final Context context = view.getContext();
        final Context context = view.getContext();
        final ActivityManager am = (ActivityManager)
        final ActivityManager am = (ActivityManager)
                context.getSystemService(Context.ACTIVITY_SERVICE);
                context.getSystemService(Context.ACTIVITY_SERVICE);
        Bitmap bm = holder.thumbnailViewImageBitmap;

        boolean usingDrawingCache;
        Bitmap bm = null;
        boolean usingDrawingCache = true;
        if (holder.thumbnailViewDrawable instanceof BitmapDrawable) {
            bm = ((BitmapDrawable) holder.thumbnailViewDrawable).getBitmap();
            if (bm.getWidth() == holder.thumbnailViewImage.getWidth() &&
            if (bm.getWidth() == holder.thumbnailViewImage.getWidth() &&
                    bm.getHeight() == holder.thumbnailViewImage.getHeight()) {
                    bm.getHeight() == holder.thumbnailViewImage.getHeight()) {
                usingDrawingCache = false;
                usingDrawingCache = false;
        } else {
            }
        }
        if (usingDrawingCache) {
            holder.thumbnailViewImage.setDrawingCacheEnabled(true);
            holder.thumbnailViewImage.setDrawingCacheEnabled(true);
            bm = holder.thumbnailViewImage.getDrawingCache();
            bm = holder.thumbnailViewImage.getDrawingCache();
            usingDrawingCache = true;
        }
        }
        Bundle opts = (bm == null) ?
        Bundle opts = (bm == null) ?
                null :
                null :
+3 −3
Original line number Original line Diff line number Diff line
@@ -29,7 +29,7 @@ public final class TaskDescription {
    final String packageName; // used to override animations (see onClick())
    final String packageName; // used to override animations (see onClick())
    final CharSequence description;
    final CharSequence description;


    private Bitmap mThumbnail; // generated by Activity.onCreateThumbnail()
    private Drawable mThumbnail; // generated by Activity.onCreateThumbnail()
    private Drawable mIcon; // application package icon
    private Drawable mIcon; // application package icon
    private CharSequence mLabel; // application package label
    private CharSequence mLabel; // application package label
    private boolean mLoaded;
    private boolean mLoaded;
@@ -85,11 +85,11 @@ public final class TaskDescription {
        mIcon = icon;
        mIcon = icon;
    }
    }


    public void setThumbnail(Bitmap thumbnail) {
    public void setThumbnail(Drawable thumbnail) {
        mThumbnail = thumbnail;
        mThumbnail = thumbnail;
    }
    }


    public Bitmap getThumbnail() {
    public Drawable getThumbnail() {
        return mThumbnail;
        return mThumbnail;
    }
    }
}
}