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

Commit 2758d9c4 authored by Lee Shombert's avatar Lee Shombert Committed by Android (Google) Code Review
Browse files

Merge "Remove defer_display_events_when_frozen flag" into main

parents 330acbaa f09e243e
Loading
Loading
Loading
Loading
+0 −8
Original line number Diff line number Diff line
@@ -98,14 +98,6 @@ flag {
    is_fixed_read_only: true
}

flag {
    name: "defer_display_events_when_frozen"
    namespace: "system_performance"
    is_fixed_read_only: true
    description: "Defer submitting display events to frozen processes."
    bug: "326315985"
}

flag {
    name: "push_global_state_to_oomadjuster"
    namespace: "backstage_power"
+48 −208
Original line number Diff line number Diff line
@@ -29,7 +29,6 @@ import static android.Manifest.permission.MODIFY_HDR_CONVERSION_MODE;
import static android.Manifest.permission.RESTRICT_DISPLAY_MODES;
import static android.Manifest.permission.WRITE_SETTINGS;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_CACHED;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_GONE;
import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE;
import static android.hardware.display.DisplayManager.BRIGHTNESS_UNIT_PERCENTAGE;
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_ALWAYS_UNLOCKED;
@@ -347,7 +346,6 @@ public final class DisplayManagerService extends SystemService {
    private final SparseArray<CallbackRecord> mCallbacks = new SparseArray<>();

    // All callback records indexed by [uid][pid], for fast lookup by uid.
    // This is only used if {@link deferDisplayEventsWhenFrozen()} is true.
    @GuardedBy("mSyncRoot")
    private final SparseArray<SparseArray<CallbackRecord>> mCallbackRecordByPidByUid =
            new SparseArray<>();
@@ -503,13 +501,6 @@ public final class DisplayManagerService extends SystemService {
    // May be used outside of the lock but only on the handler thread.
    private final ArrayList<CallbackRecord> mTempCallbacks = new ArrayList<>();

    // Pending callback records indexed by calling process uid and pid.
    // Must be used outside of the lock mSyncRoot and should be self-locked.
    // This is only used when {@link deferDisplayEventsWhenFrozen()} is false.
    @GuardedBy("mPendingCallbackSelfLocked")
    private final SparseArray<SparseArray<PendingCallback>> mPendingCallbackSelfLocked =
            new SparseArray<>();

    // Temporary viewports, used when sending new viewport information to the
    // input system.  May be used outside of the lock but only on the handler thread.
    private final ArrayList<DisplayViewport> mTempViewports = new ArrayList<>();
@@ -1139,46 +1130,6 @@ public final class DisplayManagerService extends SystemService {
    private class UidImportanceListener implements ActivityManager.OnUidImportanceListener {
        @Override
        public void onUidImportance(int uid, int importance) {
            if (deferDisplayEventsWhenFrozen()) {
                onUidImportanceFlagged(uid, importance);
            } else {
                onUidImportanceUnflagged(uid, importance);
            }
        }

        private void onUidImportanceUnflagged(int uid, int importance) {
            synchronized (mPendingCallbackSelfLocked) {
                if (importance >= IMPORTANCE_GONE) {
                    // Clean up as the app is already gone
                    Slog.d(TAG, "Drop pending events for gone uid " + uid);
                    mPendingCallbackSelfLocked.delete(uid);
                    return;
                } else if (importance >= IMPORTANCE_CACHED) {
                    // Nothing to do as the app is still in cached mode
                    return;
                }

                // Do we care about this uid?
                SparseArray<PendingCallback> pendingCallbacks = mPendingCallbackSelfLocked.get(uid);
                if (pendingCallbacks == null) {
                    return;
                }

                // Send the pending events out when a certain uid becomes non-cached
                if (DEBUG) {
                    Slog.d(TAG, "Uid " + uid + " becomes " + importance);
                }
                for (int i = 0; i < pendingCallbacks.size(); i++) {
                    PendingCallback pendingCallback = pendingCallbacks.valueAt(i);
                    if (pendingCallback != null) {
                        pendingCallback.sendPendingDisplayEvent();
                    }
                }
                mPendingCallbackSelfLocked.delete(uid);
            }
        }

        private void onUidImportanceFlagged(int uid, int importance) {
            final boolean cached = (importance >= IMPORTANCE_CACHED);
            List<CallbackRecord> readyCallbackRecords = null;
            synchronized (mSyncRoot) {
@@ -1573,7 +1524,6 @@ public final class DisplayManagerService extends SystemService {
            }

            mCallbacks.put(callingPid, record);
            if (deferDisplayEventsWhenFrozen()) {
            SparseArray<CallbackRecord> uidPeers = mCallbackRecordByPidByUid.get(record.mUid);
            if (uidPeers == null) {
                uidPeers = new SparseArray<CallbackRecord>();
@@ -1582,12 +1532,10 @@ public final class DisplayManagerService extends SystemService {
            uidPeers.put(record.mPid, record);
        }
    }
    }

    private void onCallbackDied(CallbackRecord record) {
        synchronized (mSyncRoot) {
            mCallbacks.remove(record.mPid);
            if (deferDisplayEventsWhenFrozen()) {
            SparseArray<CallbackRecord> uidPeers = mCallbackRecordByPidByUid.get(record.mUid);
            if (uidPeers != null) {
                uidPeers.remove(record.mPid);
@@ -1595,7 +1543,6 @@ public final class DisplayManagerService extends SystemService {
                    mCallbackRecordByPidByUid.remove(record.mUid);
                }
            }
            }
            stopWifiDisplayScanLocked(record);
        }
    }
@@ -3743,46 +3690,9 @@ public final class DisplayManagerService extends SystemService {
        // After releasing the lock, send the notifications out.
        for (int i = 0; i < mTempCallbacks.size(); i++) {
            CallbackRecord callbackRecord = mTempCallbacks.get(i);
            if (deferDisplayEventsWhenFrozen()) {
                deliverEventFlagged(callbackRecord, displayId, event);
            } else {
                deliverEventUnflagged(callbackRecord, displayId, event);
            }
        }
        mTempCallbacks.clear();
    }

    private void deliverEventUnflagged(CallbackRecord callbackRecord, int displayId, int event) {
        final int uid = callbackRecord.mUid;
        final int pid = callbackRecord.mPid;
        if (isUidCached(uid)) {
            // For cached apps, save the pending event until it becomes non-cached
            synchronized (mPendingCallbackSelfLocked) {
                SparseArray<PendingCallback> pendingCallbacks = mPendingCallbackSelfLocked.get(
                    uid);
                if (extraLogging(callbackRecord.mPackageName)) {
                    Slog.i(TAG, "Uid is cached: " + uid
                            + ", pendingCallbacks: " + pendingCallbacks);
                }
                if (pendingCallbacks == null) {
                    pendingCallbacks = new SparseArray<>();
                    mPendingCallbackSelfLocked.put(uid, pendingCallbacks);
                }
                PendingCallback pendingCallback = pendingCallbacks.get(pid);
                if (pendingCallback == null) {
                    pendingCallbacks.put(pid,
                            new PendingCallback(callbackRecord, displayId, event));
                } else {
                    pendingCallback.addDisplayEvent(displayId, event);
                }
            }
        } else {
            callbackRecord.notifyDisplayEventAsync(displayId, event);
        }
    }

    private void deliverEventFlagged(CallbackRecord callbackRecord, int displayId, int event) {
        callbackRecord.notifyDisplayEventAsync(displayId, event);
        mTempCallbacks.clear();
    }

    private void deliverTopologyUpdate(DisplayTopology topology) {
@@ -4403,7 +4313,7 @@ public final class DisplayManagerService extends SystemService {
        private record Event(int displayId, @DisplayEvent int event) { };

        // The list of pending display events. This is null until there is a pending event to be
        // saved. This is only used if {@link deferDisplayEventsWhenFrozen()} is true.
        // saved.
        @GuardedBy("mCallback")
        @Nullable
        private ArrayList<Event> mPendingDisplayEvents;
@@ -4431,7 +4341,6 @@ public final class DisplayManagerService extends SystemService {
            mFrozen = false;
            mAlive = true;

            if (deferDisplayEventsWhenFrozen()) {
            try {
                callback.asBinder().addFrozenStateChangeCallback(this);
            } catch (UnsupportedOperationException e) {
@@ -4444,7 +4353,6 @@ public final class DisplayManagerService extends SystemService {
                // This is unexpected.  Just give up.
                throw new RuntimeException(e);
            }
            }

            String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
            mPackageName = packageNames == null ? null : packageNames[0];
@@ -4489,7 +4397,6 @@ public final class DisplayManagerService extends SystemService {
        /**
         * Set the frozen flag for this process.  Return true if the process is now ready to
         * receive events and there are pending events to be delivered.
         * This is only used if {@link deferDisplayEventsWhenFrozen()} is true.
         */
        private boolean setFrozen(boolean frozen) {
            synchronized (mCallback) {
@@ -4501,7 +4408,6 @@ public final class DisplayManagerService extends SystemService {
        /**
         * Set the cached flag for this process.  Return true if the process is now ready to
         * receive events and there are pending events to be delivered.
         * This is only used if {@link deferDisplayEventsWhenFrozen()} is true.
         */
        public boolean setCached(boolean cached) {
            synchronized (mCallback) {
@@ -4558,7 +4464,6 @@ public final class DisplayManagerService extends SystemService {
                return true;
            }

            if (deferDisplayEventsWhenFrozen()) {
            synchronized (mCallback) {
                // Add the new event to the pending list if the client frozen or cached (not
                // ready) or if there are existing pending events.  The latter condition
@@ -4573,7 +4478,6 @@ public final class DisplayManagerService extends SystemService {
                    return true;
                }
            }
            }

            if (!shouldReceiveRefreshRateWithChangeUpdate(event)) {
                // The client is not visible to the user and is not a system service, so do nothing.
@@ -4650,7 +4554,6 @@ public final class DisplayManagerService extends SystemService {

        // Add a single event to the pending list, possibly combining or collapsing events in the
        // list.
        // This is only used if {@link deferDisplayEventsWhenFrozen()} is true.
        @GuardedBy("mCallback")
        private void addDisplayEvent(int displayId, int event) {
            if (mPendingDisplayEvents == null) {
@@ -4692,7 +4595,6 @@ public final class DisplayManagerService extends SystemService {
                return true;
            }

            if (deferDisplayEventsWhenFrozen()) {
            synchronized (mCallback) {
                // Save the new update if the client frozen or cached (not ready).
                if (!isReadyLocked()) {
@@ -4701,7 +4603,6 @@ public final class DisplayManagerService extends SystemService {
                    return true;
                }
            }
            }

            return transmitTopologyUpdate(topology);
        }
@@ -4725,7 +4626,6 @@ public final class DisplayManagerService extends SystemService {

        // Send all pending events.  This can safely be called if the process is not ready, but it
        // would be unusual to do so.  The method returns true on success.
        // This is only used if {@link deferDisplayEventsWhenFrozen()} is true.
        public boolean dispatchPending() {
            Event[] pendingDisplayEvents = null;
            DisplayTopology pendingTopology;
@@ -4783,7 +4683,6 @@ public final class DisplayManagerService extends SystemService {

        // Return a string suitable for dumpsys.
        private String dump() {
            if (deferDisplayEventsWhenFrozen()) {
            final String fmt =
                    "mPid=%d mUid=%d mWifiDisplayScanRequested=%s"
                    + " cached=%s frozen=%s pendingDisplayEvents=%d pendingTopology=%b";
@@ -4793,57 +4692,6 @@ public final class DisplayManagerService extends SystemService {
                        (mPendingDisplayEvents == null) ? 0 : mPendingDisplayEvents.size(),
                        mPendingTopology != null);
            }
            } else {
                final String fmt =
                        "mPid=%d mUid=%d mWifiDisplayScanRequested=%s";
                return formatSimple(fmt,
                        mPid, mUid, mWifiDisplayScanRequested);
            }
        }
    }

    /**
     * This is only used if {@link deferDisplayEventsWhenFrozen()} is false.
     */
    private static final class PendingCallback {
        private final CallbackRecord mCallbackRecord;
        private final ArrayList<Pair<Integer, Integer>> mDisplayEvents;

        PendingCallback(CallbackRecord cr, int displayId, int event) {
            mCallbackRecord = cr;
            mDisplayEvents = new ArrayList<>();
            mDisplayEvents.add(new Pair<>(displayId, event));
        }

        public void addDisplayEvent(int displayId, int event) {
            // Ignore redundant events. Further optimization is possible by merging adjacent events.
            Pair<Integer, Integer> last = mDisplayEvents.get(mDisplayEvents.size() - 1);
            if (last.first == displayId && last.second == event) {
                if (DEBUG) {
                    Slog.d(TAG, "Ignore redundant display event " + displayId + "/" + event + " to "
                            + mCallbackRecord.mUid + "/" + mCallbackRecord.mPid);
                }
                return;
            }

            mDisplayEvents.add(new Pair<>(displayId, event));
        }

        public void sendPendingDisplayEvent() {
            for (int i = 0; i < mDisplayEvents.size(); i++) {
                Pair<Integer, Integer> displayEvent = mDisplayEvents.get(i);
                if (DEBUG) {
                    Slog.d(TAG, "Send pending display event #" + i + " " + displayEvent.first + "/"
                            + displayEvent.second + " to " + mCallbackRecord.mUid + "/"
                            + mCallbackRecord.mPid);
                }
                if (!mCallbackRecord.notifyDisplayEventAsync(displayEvent.first,
                        displayEvent.second)) {
                    Slog.d(TAG, "Drop pending events for dead process " + mCallbackRecord.mPid);
                    break;
                }
            }
            mDisplayEvents.clear();
        }
    }

@@ -6524,14 +6372,6 @@ public final class DisplayManagerService extends SystemService {
        }
    }

    /**
     * Return the value of the pause
     */
    private static boolean deferDisplayEventsWhenFrozen() {
        return android.os.Flags.binderFrozenStateChangeCallback()
                && com.android.server.am.Flags.deferDisplayEventsWhenFrozen();
    }

    interface DisplayInfoProvider {
        @Nullable
        DisplayInfo get(int displayId);
+5 −17
Original line number Diff line number Diff line
@@ -31,20 +31,14 @@ import android.hardware.display.VirtualDisplay;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.platform.test.annotations.RequiresFlagsEnabled;
import android.platform.test.flag.junit.CheckFlagsRule;
import android.platform.test.flag.junit.DeviceFlagsValueProvider;
import android.util.Log;
import android.util.SparseArray;

import androidx.annotation.GuardedBy;
import androidx.annotation.NonNull;

import com.android.server.am.Flags;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -62,10 +56,6 @@ import java.util.concurrent.TimeUnit;
public class DisplayEventDeliveryTest extends EventDeliveryTestBase {
    private static final String TAG = "DisplayEventDeliveryTest";

    @Rule
    public final CheckFlagsRule mCheckFlagsRule =
            DeviceFlagsValueProvider.createCheckFlagsRule();

    private static final String NAME = TAG;
    private static final int WIDTH = 720;
    private static final int HEIGHT = 480;
@@ -123,7 +113,7 @@ public class DisplayEventDeliveryTest extends EventDeliveryTestBase {
         * @param event The corresponding display event
         */
        public void addDisplayEvent(int event) {
            Log.d(TAG, "Received " + mDisplayId + " " + event);
            Log.i(TAG, "Received " + mDisplayId + " " + event);
            mExpectations.offer(event);
        }

@@ -150,7 +140,7 @@ public class DisplayEventDeliveryTest extends EventDeliveryTestBase {
                    event = mExpectations.poll(TEST_FAILURE_TIMEOUT_MSEC, TimeUnit.MILLISECONDS);
                    assertNotNull(event);
                    if (expect == event) {
                        Log.d(TAG, "Found    " + mDisplayId + " " + event);
                        Log.i(TAG, "Found    " + mDisplayId + " " + event);
                        return;
                    }
                } catch (InterruptedException e) {
@@ -182,11 +172,11 @@ public class DisplayEventDeliveryTest extends EventDeliveryTestBase {
                case MESSAGE_LAUNCHED:
                    mPid = msg.arg1;
                    mUid = msg.arg2;
                    Log.d(TAG, "Launched " + mPid + " " + mUid);
                    Log.i(TAG, "Launched " + mPid + " " + mUid);
                    mLatchActivityLaunch.countDown();
                    break;
                case MESSAGE_CALLBACK:
                    Log.d(TAG, "Callback " + msg.arg1 + " " + msg.arg2);
                    Log.i(TAG, "Callback " + msg.arg1 + " " + msg.arg2);
                    synchronized (mLock) {
                        // arg1: displayId
                        DisplayBundle bundle = mDisplayBundles.get(msg.arg1);
@@ -264,7 +254,7 @@ public class DisplayEventDeliveryTest extends EventDeliveryTestBase {
     * displays is set by the {@link #data()} parameter.
     */
    private void testDisplayEventsInternal(boolean cached, boolean frozen) {
        Log.d(TAG, "Start test testDisplayEvents " + mDisplayCount + " " + cached + " " + frozen);
        Log.i(TAG, "Start test testDisplayEvents " + mDisplayCount + " " + cached + " " + frozen);
        // Launch DisplayEventActivity and start listening to display events
        int pid = launchTestActivity();

@@ -361,7 +351,6 @@ public class DisplayEventDeliveryTest extends EventDeliveryTestBase {
     * Create virtual displays, change their configurations and release them.  The display app is
     * frozen and the test verifies that no events are delivered to the frozen app.
     */
    @RequiresFlagsEnabled(Flags.FLAG_DEFER_DISPLAY_EVENTS_WHEN_FROZEN)
    @Test
    public void testDisplayEventsFrozen() {
        assumeTrue(isAppFreezerEnabled());
@@ -372,7 +361,6 @@ public class DisplayEventDeliveryTest extends EventDeliveryTestBase {
     * Create virtual displays, change their configurations and release them.  The display app is
     * cached and frozen and the test verifies that no events are delivered to the app.
     */
    @RequiresFlagsEnabled(Flags.FLAG_DEFER_DISPLAY_EVENTS_WHEN_FROZEN)
    @Test
    public void testDisplayEventsCachedFrozen() {
        assumeTrue(isAppFreezerEnabled());
+2 −4
Original line number Diff line number Diff line
@@ -222,8 +222,7 @@ public class TopologyUpdateDeliveryTest extends EventDeliveryTestBase {
    /**
     * The app is frozen and the test verifies that no updates are delivered to the frozen app.
     */
    @RequiresFlagsEnabled({com.android.server.am.Flags.FLAG_DEFER_DISPLAY_EVENTS_WHEN_FROZEN,
            com.android.server.display.feature.flags.Flags.FLAG_DISPLAY_TOPOLOGY})
    @RequiresFlagsEnabled(com.android.server.display.feature.flags.Flags.FLAG_DISPLAY_TOPOLOGY)
    @Test
    public void testTopologyUpdateFrozen() {
        assumeTrue(isAppFreezerEnabled());
@@ -233,8 +232,7 @@ public class TopologyUpdateDeliveryTest extends EventDeliveryTestBase {
    /**
     * The app is cached and frozen and the test verifies that no updates are delivered to the app.
     */
    @RequiresFlagsEnabled({com.android.server.am.Flags.FLAG_DEFER_DISPLAY_EVENTS_WHEN_FROZEN,
            com.android.server.display.feature.flags.Flags.FLAG_DISPLAY_TOPOLOGY})
    @RequiresFlagsEnabled(com.android.server.display.feature.flags.Flags.FLAG_DISPLAY_TOPOLOGY)
    @Test
    public void testTopologyUpdateCachedFrozen() {
        assumeTrue(isAppFreezerEnabled());