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

Commit 4a771667 authored by Joanne Chung's avatar Joanne Chung
Browse files

Improve PackageInstallerService.writeSessionsLocked lock hold

PackageInstallerService.writeSessionsLocked() holds mSession lock,
the method PackageInstallerSession.write() needs to access the mLock
in PackageInstallerSession that may be held by other process to
execute a long operation this may cause long API calls that may need
to wait for mSession lock.

To improve the problem, try to reduce lock holding time, copy session
to a local variable. The code doesn't need to acess mLock in mSession
lock to reduce the API call ANR.

Bug: 317945057
Test: manual
Change-Id: Ief0c97d627bebb9075f4bc6b94870d40dcb7bb4f
parent 535e7b75
Loading
Loading
Loading
Loading
+12 −9
Original line number Diff line number Diff line
@@ -291,9 +291,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
    @NonNull
    private final RequestThrottle mSettingsWriteRequest = new RequestThrottle(IoThread.getHandler(),
            () -> {
                synchronized (mSessions) {
                    return writeSessionsLocked();
                }
                return writeSessions();
            });

    public PackageInstallerService(Context context, PackageManagerService pm,
@@ -600,9 +598,16 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
                mHistoricalSessionsByInstaller.get(installerUid) + 1);
    }

    @GuardedBy("mSessions")
    private boolean writeSessionsLocked() {
        if (LOGD) Slog.v(TAG, "writeSessionsLocked()");
    private boolean writeSessions() {
        if (LOGD) Slog.v(TAG, "writeSessions()");
        final PackageInstallerSession[] sessions;
        synchronized (mSessions) {
            final int size = mSessions.size();
            sessions = new PackageInstallerSession[size];
            for (int i = 0; i < size; i++) {
                sessions[i] = mSessions.valueAt(i);
            }
        }

        FileOutputStream fos = null;
        try {
@@ -611,9 +616,7 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
            final TypedXmlSerializer out = Xml.resolveSerializer(fos);
            out.startDocument(null, true);
            out.startTag(null, TAG_SESSIONS);
            final int size = mSessions.size();
            for (int i = 0; i < size; i++) {
                final PackageInstallerSession session = mSessions.valueAt(i);
            for (var session : sessions) {
                session.write(out, mSessionsDir);
            }
            out.endTag(null, TAG_SESSIONS);