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

Commit 648f69b9 authored by Craig Mautner's avatar Craig Mautner
Browse files

Remove activity icon bitmaps from system process.

When a TaskDescription is sent up to the system process, the Bitmap
contained in the mIcon member is immediately flushed to disk and the
name of the file replaces it in the TaskDescription. Thereby saving
mucho RAM for better uses.

Fixes bug 17527308.

Change-Id: Ifac63ea5d12ed091d1eb03e178b8b847a827f940
parent c1e1550b
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -5066,7 +5066,7 @@ public class Activity extends ContextThemeWrapper
    public void setTaskDescription(ActivityManager.TaskDescription taskDescription) {
        ActivityManager.TaskDescription td;
        // Scale the icon down to something reasonable if it is provided
        if (taskDescription.getIcon() != null) {
        if (taskDescription.getIconFilename() == null && taskDescription.getIcon() != null) {
            final int size = ActivityManager.getLauncherLargeIconSizeInner(this);
            final Bitmap icon = Bitmap.createScaledBitmap(taskDescription.getIcon(), size, size, true);
            td = new ActivityManager.TaskDescription(taskDescription.getLabel(), icon,
+80 −3
Original line number Diff line number Diff line
@@ -56,9 +56,11 @@ import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Size;
import android.util.Slog;
import org.xmlpull.v1.XmlSerializer;

import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
@@ -508,8 +510,18 @@ public class ActivityManager {
     * Information you can set and retrieve about the current activity within the recent task list.
     */
    public static class TaskDescription implements Parcelable {
        /** @hide */
        public static final String ATTR_TASKDESCRIPTION_PREFIX = "task_description_";
        private static final String ATTR_TASKDESCRIPTIONLABEL =
                ATTR_TASKDESCRIPTION_PREFIX + "label";
        private static final String ATTR_TASKDESCRIPTIONCOLOR =
                ATTR_TASKDESCRIPTION_PREFIX + "color";
        private static final String ATTR_TASKDESCRIPTIONICONFILENAME =
                ATTR_TASKDESCRIPTION_PREFIX + "icon_filename";

        private String mLabel;
        private Bitmap mIcon;
        private String mIconFilename;
        private int mColorPrimary;

        /**
@@ -529,6 +541,12 @@ public class ActivityManager {
            mColorPrimary = colorPrimary;
        }

        /** @hide */
        public TaskDescription(String label, int colorPrimary, String iconFilename) {
            this(label, null, colorPrimary);
            mIconFilename = iconFilename;
        }

        /**
         * Creates the TaskDescription to the specified values.
         *
@@ -559,7 +577,10 @@ public class ActivityManager {
         * Creates a copy of another TaskDescription.
         */
        public TaskDescription(TaskDescription td) {
            this(td.getLabel(), td.getIcon(), td.getPrimaryColor());
            mLabel = td.mLabel;
            mIcon = td.mIcon;
            setPrimaryColor(td.mColorPrimary);
            mIconFilename = td.mIconFilename;
        }

        private TaskDescription(Parcel source) {
@@ -579,7 +600,7 @@ public class ActivityManager {
         * @hide
         */
        public void setPrimaryColor(int primaryColor) {
            mColorPrimary = primaryColor;
            mColorPrimary = 0xFF000000 | primaryColor;
        }

        /**
@@ -590,6 +611,16 @@ public class ActivityManager {
            mIcon = icon;
        }

        /**
         * Moves the icon bitmap reference from an actual Bitmap to a file containing the
         * bitmap.
         * @hide
         */
        public void setIconFilename(String iconFilename) {
            mIconFilename = iconFilename;
            mIcon = null;
        }

        /**
         * @return The label and description of the current state of this task.
         */
@@ -601,8 +632,23 @@ public class ActivityManager {
         * @return The icon that represents the current state of this task.
         */
        public Bitmap getIcon() {
            if (mIcon != null) {
                return mIcon;
            }
            if (mIconFilename != null) {
                try {
                    return ActivityManagerNative.getDefault().
                            getTaskDescriptionIcon(mIconFilename);
                } catch (RemoteException e) {
                }
            }
            return null;
        }

        /** @hide */
        public String getIconFilename() {
            return mIconFilename;
        }

        /**
         * @return The color override on the theme's primary color.
@@ -611,6 +657,30 @@ public class ActivityManager {
            return mColorPrimary;
        }

        /** @hide */
        public void saveToXml(XmlSerializer out) throws IOException {
            if (mLabel != null) {
                out.attribute(null, ATTR_TASKDESCRIPTIONLABEL, mLabel);
            }
            if (mColorPrimary != 0) {
                out.attribute(null, ATTR_TASKDESCRIPTIONCOLOR, Integer.toHexString(mColorPrimary));
            }
            if (mIconFilename != null) {
                out.attribute(null, ATTR_TASKDESCRIPTIONICONFILENAME, mIconFilename);
            }
        }

        /** @hide */
        public void restoreFromXml(String attrName, String attrValue) {
            if (ATTR_TASKDESCRIPTIONLABEL.equals(attrName)) {
                setLabel(attrValue);
            } else if (ATTR_TASKDESCRIPTIONCOLOR.equals(attrName)) {
                setPrimaryColor((int) Long.parseLong(attrValue, 16));
            } else if (ATTR_TASKDESCRIPTIONICONFILENAME.equals(attrName)) {
                setIconFilename(attrValue);
            }
        }

        @Override
        public int describeContents() {
            return 0;
@@ -631,12 +701,19 @@ public class ActivityManager {
                mIcon.writeToParcel(dest, 0);
            }
            dest.writeInt(mColorPrimary);
            if (mIconFilename == null) {
                dest.writeInt(0);
            } else {
                dest.writeInt(1);
                dest.writeString(mIconFilename);
            }
        }

        public void readFromParcel(Parcel source) {
            mLabel = source.readInt() > 0 ? source.readString() : null;
            mIcon = source.readInt() > 0 ? Bitmap.CREATOR.createFromParcel(source) : null;
            mColorPrimary = source.readInt();
            mIconFilename = source.readInt() > 0 ? source.readString() : null;
        }

        public static final Creator<TaskDescription> CREATOR
+28 −0
Original line number Diff line number Diff line
@@ -2253,6 +2253,20 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
            return true;
        }

        case GET_TASK_DESCRIPTION_ICON_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            String filename = data.readString();
            Bitmap icon = getTaskDescriptionIcon(filename);
            reply.writeNoException();
            if (icon == null) {
                reply.writeInt(0);
            } else {
                reply.writeInt(1);
                icon.writeToParcel(reply, 0);
            }
            return true;
        }

        case REQUEST_VISIBLE_BEHIND_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IBinder token = data.readStrongBinder();
@@ -5240,6 +5254,20 @@ class ActivityManagerProxy implements IActivityManager
        reply.recycle();
    }

    @Override
    public Bitmap getTaskDescriptionIcon(String filename) throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeString(filename);
        mRemote.transact(GET_TASK_DESCRIPTION_ICON_TRANSACTION, data, reply, 0);
        reply.readException();
        final Bitmap icon = reply.readInt() == 0 ? null : Bitmap.CREATOR.createFromParcel(reply);
        data.recycle();
        reply.recycle();
        return icon;
    }

    @Override
    public boolean requestVisibleBehind(IBinder token, boolean visible) throws RemoteException {
        Parcel data = Parcel.obtain();
+2 −0
Original line number Diff line number Diff line
@@ -451,6 +451,7 @@ public interface IActivityManager extends IInterface {

    public void setTaskDescription(IBinder token, ActivityManager.TaskDescription values)
            throws RemoteException;
    public Bitmap getTaskDescriptionIcon(String filename) throws RemoteException;

    public boolean requestVisibleBehind(IBinder token, boolean visible) throws RemoteException;
    public boolean isBackgroundVisibleBehind(IBinder token) throws RemoteException;
@@ -775,4 +776,5 @@ public interface IActivityManager extends IInterface {
    int RELEASE_ACTIVITY_INSTANCE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+235;
    int RELEASE_SOME_ACTIVITIES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+236;
    int BOOT_ANIMATION_COMPLETE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+237;
    int GET_TASK_DESCRIPTION_ICON_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+238;
}
+6 −1
Original line number Diff line number Diff line
@@ -8375,12 +8375,17 @@ public final class ActivityManagerService extends ActivityManagerNative
        synchronized (this) {
            ActivityRecord r = ActivityRecord.isInStackLocked(token);
            if (r != null) {
                r.taskDescription = td;
                r.setTaskDescription(td);
                r.task.updateTaskDescription();
            }
        }
    }
    @Override
    public Bitmap getTaskDescriptionIcon(String filename) {
        return mTaskPersister.getTaskDescriptionIcon(filename);
    }
    private void cleanUpRemovedTaskLocked(TaskRecord tr, int flags) {
        mRecentTasks.remove(tr);
        tr.removedFromRecents(mTaskPersister);
Loading