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

Commit 081d655e authored by Kenneth Ford's avatar Kenneth Ford
Browse files

Adds getRearDisplayMetrics method

Allows the metrics for the rear display to be accessed
synchronously to provide in the jetpack client library

Bug: 273813115
Test: ExtensionRearDisplayTest#testGetRearDisplayMetrics
Change-Id: Ic07f080a39db8f9332c9b4ba79c5529884e4f851
parent 56fc7e54
Loading
Loading
Loading
Loading
+49 −39
Original line number Diff line number Diff line
@@ -31,12 +31,14 @@ import android.view.DisplayAddress;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.window.extensions.WindowExtensions;
import androidx.window.extensions.core.util.function.Consumer;

import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.ArrayUtils;

import java.util.Objects;
import java.util.concurrent.Executor;

/**
@@ -51,6 +53,7 @@ import java.util.concurrent.Executor;
public class WindowAreaComponentImpl implements WindowAreaComponent,
        DeviceStateManager.DeviceStateCallback {

    private static final int INVALID_DISPLAY_ADDRESS = -1;
    private final Object mLock = new Object();

    @NonNull
@@ -69,8 +72,7 @@ public class WindowAreaComponentImpl implements WindowAreaComponent,
    private final int mConcurrentDisplayState;
    @NonNull
    private final int[] mFoldedDeviceStates;
    @NonNull
    private long mRearDisplayAddress = 0;
    private long mRearDisplayAddress = INVALID_DISPLAY_ADDRESS;
    @WindowAreaSessionState
    private int mRearDisplaySessionStatus = WindowAreaComponent.SESSION_STATE_INACTIVE;

@@ -109,10 +111,7 @@ public class WindowAreaComponentImpl implements WindowAreaComponent,
                R.integer.config_deviceStateConcurrentRearDisplay);

        mDeviceStateManager.registerCallback(mExecutor, this);
        if (mConcurrentDisplayState != INVALID_DEVICE_STATE) {
            mRearDisplayAddress = Long.parseLong(context.getResources().getString(
                    R.string.config_rearDisplayPhysicalAddress));
        }
        mRearDisplayAddress = getRearDisplayAddress(context);
    }

    /**
@@ -219,6 +218,44 @@ public class WindowAreaComponentImpl implements WindowAreaComponent,
        }
    }

    /**
     * Returns the{@link DisplayMetrics} associated with the rear facing display. If the rear facing
     * display was not found in the display list, but we have already computed the
     * {@link DisplayMetrics} for that display, we return the cached value. If no display has been
     * found, then we return an empty {@link DisplayMetrics} value.
     *
     * TODO(b/267563768): Update with guidance from Display team for missing displays.
     *
     * @since {@link WindowExtensions#VENDOR_API_LEVEL_3}
     */
    @Override
    public DisplayMetrics getRearDisplayMetrics() {
        DisplayMetrics metrics = null;

        // DISPLAY_CATEGORY_REAR displays are only available when you are in the concurrent
        // display state, so we have to look through all displays to match the address
        Display[] displays = mDisplayManager.getDisplays(
                DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED);
        for (int i = 0; i < displays.length; i++) {
            DisplayAddress.Physical address =
                    (DisplayAddress.Physical) displays[i].getAddress();
            if (mRearDisplayAddress == address.getPhysicalDisplayId()) {
                metrics = new DisplayMetrics();
                displays[i].getRealMetrics(metrics);
                break;
            }
        }

        synchronized (mLock) {
            // Update the rear display metrics with our latest value if one was received
            if (metrics != null) {
                mRearDisplayMetrics = metrics;
            }

            return Objects.requireNonNullElseGet(mRearDisplayMetrics, DisplayMetrics::new);
        }
    }

    /**
     * Adds a listener interested in receiving updates on the RearDisplayPresentationStatus
     * of the device. Because this is being called from the OEM provided
@@ -260,8 +297,8 @@ public class WindowAreaComponentImpl implements WindowAreaComponent,
                return;
            }
            @WindowAreaStatus int currentStatus = getCurrentRearDisplayPresentationModeStatus();
            DisplayMetrics metrics =
                    currentStatus == STATUS_UNSUPPORTED ? null : getRearDisplayMetrics();
            DisplayMetrics metrics = currentStatus == STATUS_UNSUPPORTED ? new DisplayMetrics()
                    : getRearDisplayMetrics();
            consumer.accept(
                    new RearDisplayPresentationStatus(currentStatus, metrics));
        }
@@ -478,37 +515,10 @@ public class WindowAreaComponentImpl implements WindowAreaComponent,
        }
    }

    /**
     * Returns the{@link DisplayMetrics} associated with the rear facing display. If the rear facing
     * display was not found in the display list, but we have already computed the
     * {@link DisplayMetrics} for that display, we return the cached value.
     *
     * TODO(b/267563768): Update with guidance from Display team for missing displays.
     *
     * @throws IllegalArgumentException if the display is not found and there is no cached
     * {@link DisplayMetrics} for this display.
     */
    @GuardedBy("mLock")
    private DisplayMetrics getRearDisplayMetrics() {
        Display[] displays = mDisplayManager.getDisplays(
                DisplayManager.DISPLAY_CATEGORY_ALL_INCLUDING_DISABLED);
        for (int i = 0; i < displays.length; i++) {
            DisplayAddress.Physical address =
                    (DisplayAddress.Physical) displays[i].getAddress();
            if (mRearDisplayAddress == address.getPhysicalDisplayId()) {
                if (mRearDisplayMetrics == null) {
                    mRearDisplayMetrics = new DisplayMetrics();
                }
                displays[i].getRealMetrics(mRearDisplayMetrics);
                return mRearDisplayMetrics;
            }
        }
        if (mRearDisplayMetrics != null) {
            return mRearDisplayMetrics;
        } else {
            throw new IllegalArgumentException(
                    "No display found with the provided display address");
        }
    private long getRearDisplayAddress(Context context) {
        String address = context.getResources().getString(
                R.string.config_rearDisplayPhysicalAddress);
        return address.isEmpty() ? INVALID_DISPLAY_ADDRESS : Long.parseLong(address);
    }

    @GuardedBy("mLock")