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

Commit a22a766e authored by Narayan Kamath's avatar Narayan Kamath
Browse files

Eagerly serialize historical sessions

mHistoricalSessions maintained a strong reference to a PackageInstallerSession,
which in turn kept references to Bitmaps and other heavy-weight objects around.

Since this field is primarily used for debugging, this change replaces it with
a String dump of the session in question. Each dump takes about 600bytes, which
is comparable to the sizes of the un-serialized raw objects.

Bug: 62485552
Test: Manual

Change-Id: I4949a64b538ab4a97384f4f8bc9a6ef155a4b128
parent a5b457b3
Loading
Loading
Loading
Loading
+22 −6
Original line number Diff line number Diff line
@@ -81,8 +81,10 @@ import android.util.ExceptionUtils;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import android.util.Xml;

import java.io.CharArrayWriter;
import libcore.io.IoUtils;

import com.android.internal.R;
@@ -195,7 +197,10 @@ public class PackageInstallerService extends IPackageInstaller.Stub {

    /** Historical sessions kept around for debugging purposes */
    @GuardedBy("mSessions")
    private final SparseArray<PackageInstallerSession> mHistoricalSessions = new SparseArray<>();
    private final List<String> mHistoricalSessions = new ArrayList<>();

    @GuardedBy("mSessions")
    private final SparseIntArray mHistoricalSessionsByInstaller = new SparseIntArray();

    /** Sessions allocated to legacy users */
    @GuardedBy("mSessions")
@@ -371,7 +376,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
                            // Since this is early during boot we don't send
                            // any observer events about the session, but we
                            // keep details around for dumpsys.
                            mHistoricalSessions.put(session.sessionId, session);
                            addHistoricalSessionLocked(session);
                        }
                        mAllocatedSessions.put(session.sessionId, true);
                    }
@@ -386,6 +391,18 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
        }
    }

    private void addHistoricalSessionLocked(PackageInstallerSession session) {
        CharArrayWriter writer = new CharArrayWriter();
        IndentingPrintWriter pw = new IndentingPrintWriter(writer, "    ");
        session.dump(pw);
        mHistoricalSessions.add(writer.toString());

        // Increment the number of sessions by this installerUid.
        mHistoricalSessionsByInstaller.put(
                session.installerUid,
                mHistoricalSessionsByInstaller.get(session.installerUid) + 1);
    }

    private PackageInstallerSession readSessionLocked(XmlPullParser in) throws IOException,
            XmlPullParserException {
        final int sessionId = readIntAttribute(in, ATTR_SESSION_ID);
@@ -676,7 +693,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
                throw new IllegalStateException(
                        "Too many active sessions for UID " + callingUid);
            }
            final int historicalCount = getSessionCount(mHistoricalSessions, callingUid);
            final int historicalCount = mHistoricalSessionsByInstaller.get(callingUid);
            if (historicalCount >= MAX_HISTORICAL_SESSIONS) {
                throw new IllegalStateException(
                        "Too many historical sessions for UID " + callingUid);
@@ -1228,8 +1245,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
            pw.increaseIndent();
            N = mHistoricalSessions.size();
            for (int i = 0; i < N; i++) {
                final PackageInstallerSession session = mHistoricalSessions.valueAt(i);
                session.dump(pw);
                pw.print(mHistoricalSessions.get(i));
                pw.println();
            }
            pw.println();
@@ -1264,7 +1280,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
                public void run() {
                    synchronized (mSessions) {
                        mSessions.remove(session.sessionId);
                        mHistoricalSessions.put(session.sessionId, session);
                        addHistoricalSessionLocked(session);

                        final File appIconFile = buildAppIconFile(session.sessionId);
                        if (appIconFile.exists()) {