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

Commit 7790b732 authored by Sean Stout's avatar Sean Stout
Browse files

Implement Phase 5 of Separate Power States

DisplayPowerRequestManager listens for the addition, removal, and change
of Displays and will appropriately create DisplayPowerRequests to manage
their power states.

At this stage the DisplayPowerRequests are simply created; only the
DisplayPowerRequest associated with the default display is interacted
with.

Test: manual
Bug: 138328918
Change-Id: I03f0c95aa23fc711d8d66150f315eed52bc57b2c
parent f45d13b0
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -64,6 +64,12 @@ public abstract class DisplayManagerInternal {
     */
    public abstract boolean isProximitySensorAvailable();

    /**
     * Returns the id of the {@link com.android.server.display.DisplayGroup} to which the provided
     * display belongs.
     */
    public abstract int getDisplayGroupId(int displayId);

    /**
     * Screenshot for internal system-only use such as rotation, etc.  This method includes
     * secure layers and the result should never be exposed to non-system applications.
+13 −1
Original line number Diff line number Diff line
@@ -22,10 +22,22 @@ import java.util.List;
/**
 * Represents a collection of {@link LogicalDisplay}s which act in unison for certain behaviors and
 * operations.
 * @hide
 */
public class DisplayGroup {

    final List<LogicalDisplay> mDisplays = new ArrayList<>();
    public static final int DEFAULT = 0;

    private final List<LogicalDisplay> mDisplays = new ArrayList<>();
    private final int mGroupId;

    DisplayGroup(int groupId) {
        mGroupId = groupId;
    }

    int getGroupId() {
        return mGroupId;
    }

    void addDisplay(LogicalDisplay display) {
        if (!mDisplays.contains(display)) {
+7 −0
Original line number Diff line number Diff line
@@ -2535,6 +2535,13 @@ public final class DisplayManagerService extends SystemService {
            }
        }

        @Override
        public int getDisplayGroupId(int displayId) {
            synchronized (mSyncRoot) {
                return mLogicalDisplayMapper.getDisplayGroupIdLocked(displayId);
            }
        }

        @Override
        public SurfaceControl.ScreenshotHardwareBuffer systemScreenshot(int displayId) {
            return systemScreenshotInternal(displayId);
+18 −2
Original line number Diff line number Diff line
@@ -94,6 +94,7 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
    private final SparseArray<LogicalDisplay> mLogicalDisplays =
            new SparseArray<LogicalDisplay>();
    private int mNextNonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1;
    private int mNextNonDefaultGroupId = DisplayGroup.DEFAULT + 1;

    /** A mapping from logical display id to display group. */
    private final SparseArray<DisplayGroup> mDisplayGroups = new SparseArray<>();
@@ -178,6 +179,15 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
        }
    }

    public int getDisplayGroupIdLocked(int displayId) {
        final DisplayGroup displayGroup = mDisplayGroups.get(displayId);
        if (displayGroup != null) {
            return displayGroup.getGroupId();
        }

        return -1;
    }

    public void dumpLocked(PrintWriter pw) {
        pw.println("LogicalDisplayMapper:");
        IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
@@ -309,7 +319,8 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {

        final DisplayGroup displayGroup;
        if (isDefault || (deviceInfo.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP) != 0) {
            displayGroup = new DisplayGroup();
            final int groupId = assignDisplayGroupIdLocked(isDefault);
            displayGroup = new DisplayGroup(groupId);
        } else {
            displayGroup = mDisplayGroups.get(Display.DEFAULT_DISPLAY);
        }
@@ -345,7 +356,8 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
                if ((flags & Display.FLAG_OWN_DISPLAY_GROUP) != 0) {
                    // The display should have its own DisplayGroup.
                    if (defaultDisplayGroup.removeDisplay(display)) {
                        final DisplayGroup displayGroup = new DisplayGroup();
                        final int groupId = assignDisplayGroupIdLocked(false);
                        final DisplayGroup displayGroup = new DisplayGroup(groupId);
                        displayGroup.addDisplay(display);
                        mDisplayGroups.append(display.getDisplayIdLocked(), displayGroup);
                    }
@@ -381,6 +393,10 @@ class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
        return isDefault ? Display.DEFAULT_DISPLAY : mNextNonDefaultDisplayId++;
    }

    private int assignDisplayGroupIdLocked(boolean isDefault) {
        return isDefault ? DisplayGroup.DEFAULT : mNextNonDefaultGroupId++;
    }

    private int assignLayerStackLocked(int displayId) {
        // Currently layer stacks and display ids are the same.
        // This need not be the case.
+122 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.power;

import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManagerInternal;
import android.hardware.display.DisplayManagerInternal.DisplayPowerRequest;
import android.os.Handler;
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.view.Display;

import com.android.internal.annotations.GuardedBy;
import com.android.server.display.DisplayGroup;

/**
 * Responsible for creating {@link DisplayPowerRequest}s and associating them with
 * {@link com.android.server.display.DisplayGroup}s.
 *
 * Each {@link com.android.server.display.DisplayGroup} has a single {@link DisplayPowerRequest}
 * which is used to request power state changes to every display in the group.
 */
class DisplayPowerRequestMapper {

    private final Object mLock = new Object();

    /** A mapping from LogicalDisplay Id to DisplayGroup Id. */
    @GuardedBy("mLock")
    private final SparseIntArray mDisplayGroupIds = new SparseIntArray();

    /** A mapping from DisplayGroup Id to DisplayPowerRequest. */
    @GuardedBy("mLock")
    private final SparseArray<DisplayPowerRequest> mDisplayPowerRequests = new SparseArray<>();

    private final DisplayManagerInternal mDisplayManagerInternal;

    private final DisplayManager.DisplayListener mDisplayListener =
            new DisplayManager.DisplayListener() {

                @Override
                public void onDisplayAdded(int displayId) {
                    synchronized (mLock) {
                        if (mDisplayGroupIds.indexOfKey(displayId) >= 0) {
                            return;
                        }
                        final int displayGroupId = mDisplayManagerInternal.getDisplayGroupId(
                                displayId);
                        if (!mDisplayPowerRequests.contains(displayGroupId)) {
                            // A new DisplayGroup was created; create a new DisplayPowerRequest.
                            mDisplayPowerRequests.append(displayGroupId, new DisplayPowerRequest());
                        }
                        mDisplayGroupIds.append(displayId, displayGroupId);
                    }
                }

                @Override
                public void onDisplayRemoved(int displayId) {
                    synchronized (mLock) {
                        final int index = mDisplayGroupIds.indexOfKey(displayId);
                        if (index < 0) {
                            return;
                        }
                        final int displayGroupId = mDisplayGroupIds.valueAt(index);
                        mDisplayGroupIds.removeAt(index);

                        if (mDisplayGroupIds.indexOfValue(displayGroupId) < 0) {
                            // The DisplayGroup no longer exists; delete the DisplayPowerRequest.
                            mDisplayPowerRequests.delete(displayGroupId);
                        }
                    }
                }

                @Override
                public void onDisplayChanged(int displayId) {
                    synchronized (mLock) {
                        final int newDisplayGroupId = mDisplayManagerInternal.getDisplayGroupId(
                                displayId);
                        final int oldDisplayGroupId = mDisplayGroupIds.get(displayId);

                        if (!mDisplayPowerRequests.contains(newDisplayGroupId)) {
                            // A new DisplayGroup was created; create a new DisplayPowerRequest.
                            mDisplayPowerRequests.append(newDisplayGroupId,
                                    new DisplayPowerRequest());
                        }
                        mDisplayGroupIds.put(displayId, newDisplayGroupId);

                        if (mDisplayGroupIds.indexOfValue(oldDisplayGroupId) < 0) {
                            // The DisplayGroup no longer exists; delete the DisplayPowerRequest.
                            mDisplayPowerRequests.delete(oldDisplayGroupId);
                        }
                    }
                }
            };

    DisplayPowerRequestMapper(DisplayManager displayManager,
            DisplayManagerInternal displayManagerInternal, Handler handler) {
        mDisplayManagerInternal = displayManagerInternal;
        displayManager.registerDisplayListener(mDisplayListener, handler);
        mDisplayPowerRequests.append(DisplayGroup.DEFAULT, new DisplayPowerRequest());
        mDisplayGroupIds.append(Display.DEFAULT_DISPLAY, DisplayGroup.DEFAULT);
    }

    DisplayPowerRequest get(int displayId) {
        synchronized (mLock) {
            return mDisplayPowerRequests.get(mDisplayGroupIds.get(displayId));
        }
    }
}
Loading