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

Commit 5ab4fb75 authored by Marco Ballesio's avatar Marco Ballesio
Browse files

CachedAppOptimizer: ensure binder is never frozen with app unfrozen

Unfreezing a binder interface after the app, as well as freezing it
before the app, opens a time window during wich the process is active
and yet synchrnous binder transactions would fail.

Unfreeze binder before the app, and similarly freeze it after freezing,
to ensure consistent states.

Bug: b/171239744
Test: verified correct working of the sequence by manually sending
synchronous messages during the critical intervals.

Change-Id: I5fad4cdf497a567aceb15b1fc3025b049c54983e
parent ef7605be
Loading
Loading
Loading
Loading
+21 −20
Original line number Diff line number Diff line
@@ -776,17 +776,6 @@ public final class CachedAppOptimizer {

        long freezeTime = app.freezeUnfreezeTime;

        try {
            Process.setProcessFrozen(app.pid, app.uid, false);

            app.freezeUnfreezeTime = SystemClock.uptimeMillis();
            app.frozen = false;
        } catch (Exception e) {
            Slog.e(TAG_AM, "Unable to unfreeze " + app.pid + " " + app.processName
                    + ". Any related user experience might be hanged.");
        }

        if (!app.frozen) {
        try {
            freezeBinder(app.pid, false);
        } catch (RuntimeException e) {
@@ -798,6 +787,17 @@ public final class CachedAppOptimizer {
            return;
        }

        try {
            Process.setProcessFrozen(app.pid, app.uid, false);

            app.freezeUnfreezeTime = SystemClock.uptimeMillis();
            app.frozen = false;
        } catch (Exception e) {
            Slog.e(TAG_AM, "Unable to unfreeze " + app.pid + " " + app.processName
                    + ". This might cause inconsistency or UI hangs.");
        }

        if (!app.frozen) {
            if (DEBUG_FREEZER) {
                Slog.d(TAG_AM, "sync unfroze " + app.pid + " " + app.processName);
            }
@@ -1110,14 +1110,6 @@ public final class CachedAppOptimizer {
                    return;
                }

                try {
                    freezeBinder(pid, true);
                } catch (RuntimeException e) {
                    // TODO: it might be preferable to kill the target pid in this case
                    Slog.e(TAG_AM, "Unable to freeze binder for " + pid + " " + name);
                    return;
                }

                if (pid == 0 || proc.frozen) {
                    // Already frozen or not a real process, either one being
                    // launched or one being killed
@@ -1146,6 +1138,15 @@ public final class CachedAppOptimizer {

                EventLog.writeEvent(EventLogTags.AM_FREEZE, pid, name);

                try {
                    freezeBinder(pid, true);
                } catch (RuntimeException e) {
                    Slog.e(TAG_AM, "Unable to freeze binder for " + pid + " " + name);
                    proc.kill("Unable to freeze binder interface",
                            ApplicationExitInfo.REASON_OTHER,
                            ApplicationExitInfo.SUBREASON_INVALID_STATE, true);
                }

                // See above for why we're not taking mPhenotypeFlagLock here
                if (mRandom.nextFloat() < mFreezerStatsdSampleRate) {
                    FrameworkStatsLog.write(FrameworkStatsLog.APP_FREEZE_CHANGED,