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

Commit db845967 authored by Dominik Laskowski's avatar Dominik Laskowski
Browse files

Add android.view.DisplayAddress

This CL augments DisplayInfo#address from String to an instance of
either DisplayAddress.Physical or DisplayAddress.Network. This can
be used to obtain the stable port and model for physical displays.

It also wires up DisplayViewport#physicalPort for use by InputFlinger.

Bug: 116025192
Test: dumpsys display
Change-Id: I2928b8b325b992b949b99a7d9175512f7930a54f
parent 3316a0a0
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -75,7 +75,7 @@ public final class Display {
    private final int mLayerStack;
    private final int mFlags;
    private final int mType;
    private final String mAddress;
    private final DisplayAddress mAddress;
    private final int mOwnerUid;
    private final String mOwnerPackageName;
    private final Resources mResources;
@@ -556,7 +556,7 @@ public final class Display {
     * @hide
     */
    @UnsupportedAppUsage
    public String getAddress() {
    public DisplayAddress getAddress() {
        return mAddress;
    }

+174 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2019 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 android.view;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;

/** Display identifier that is stable across reboots.
 *
 * @hide
 */
public abstract class DisplayAddress implements Parcelable {
    /**
     * Creates an address for a physical display given its stable ID.
     *
     * A physical display ID is stable if the display can be identified using EDID information.
     *
     * @param physicalDisplayId A physical display ID.
     * @return The {@link Physical} address, or {@code null} if the ID is not stable.
     * @see SurfaceControl#getPhysicalDisplayIds
     */
    @Nullable
    public static Physical fromPhysicalDisplayId(long physicalDisplayId) {
        final Physical address = new Physical(physicalDisplayId);
        return address.getModel() == 0 ? null : address;
    }

    /**
     * Creates an address for a network display given its MAC address.
     *
     * @param macAddress A MAC address in colon notation.
     * @return The {@link Network} address.
     */
    @NonNull
    public static Network fromMacAddress(String macAddress) {
        return new Network(macAddress);
    }

    /**
     * Address for a physically connected display.
     *
     * A {@link Physical} address is represented by a 64-bit identifier combining the port and model
     * of a display. The port, located in the least significant byte, uniquely identifies a physical
     * connector on the device for display output like eDP or HDMI. The model, located in the upper
     * bits, uniquely identifies a display model across manufacturers by encoding EDID information.
     */
    public static final class Physical extends DisplayAddress {
        private static final int PHYSICAL_DISPLAY_ID_MODEL_SHIFT = 8;
        private static final int PORT_MASK = 0xFF;

        private final long mPhysicalDisplayId;

        /**
         * Physical port to which the display is connected.
         */
        public byte getPort() {
            return (byte) mPhysicalDisplayId;
        }

        /**
         * Model identifier unique across manufacturers.
         */
        public long getModel() {
            return mPhysicalDisplayId >>> PHYSICAL_DISPLAY_ID_MODEL_SHIFT;
        }

        @Override
        public boolean equals(Object other) {
            return other instanceof Physical
                    && mPhysicalDisplayId == ((Physical) other).mPhysicalDisplayId;
        }

        @Override
        public String toString() {
            return new StringBuilder("{")
                    .append("port=").append(getPort() & PORT_MASK)
                    .append(", model=0x").append(Long.toHexString(getModel()))
                    .append("}")
                    .toString();
        }

        @Override
        public int hashCode() {
            return Long.hashCode(mPhysicalDisplayId);
        }

        @Override
        public void writeToParcel(Parcel out, int flags) {
            out.writeLong(mPhysicalDisplayId);
        }

        private Physical(long physicalDisplayId) {
            mPhysicalDisplayId = physicalDisplayId;
        }

        public static final Parcelable.Creator<Physical> CREATOR =
                new Parcelable.Creator<Physical>() {
                    @Override
                    public Physical createFromParcel(Parcel in) {
                        return new Physical(in.readLong());
                    }

                    @Override
                    public Physical[] newArray(int size) {
                        return new Physical[size];
                    }
                };
    }

    /**
     * Address for a network-connected display.
     */
    public static final class Network extends DisplayAddress {
        private final String mMacAddress;

        @Override
        public boolean equals(Object other) {
            return other instanceof Network && mMacAddress.equals(((Network) other).mMacAddress);
        }

        @Override
        public String toString() {
            return mMacAddress;
        }

        @Override
        public int hashCode() {
            return mMacAddress.hashCode();
        }

        @Override
        public void writeToParcel(Parcel out, int flags) {
            out.writeString(mMacAddress);
        }

        private Network(String macAddress) {
            mMacAddress = macAddress;
        }

        public static final Parcelable.Creator<Network> CREATOR =
                new Parcelable.Creator<Network>() {
                    @Override
                    public Network createFromParcel(Parcel in) {
                        return new Network(in.readString());
                    }

                    @Override
                    public Network[] newArray(int size) {
                        return new Network[size];
                    }
                };
    }

    @Override
    public int describeContents() {
        return 0;
    }
}
+3 −3
Original line number Diff line number Diff line
@@ -60,7 +60,7 @@ public final class DisplayInfo implements Parcelable {
     * Display address, or null if none.
     * Interpretation varies by display type.
     */
    public String address;
    public DisplayAddress address;

    /**
     * The human-readable name of the display.
@@ -383,7 +383,7 @@ public final class DisplayInfo implements Parcelable {
        layerStack = source.readInt();
        flags = source.readInt();
        type = source.readInt();
        address = source.readString();
        address = source.readParcelable(null);
        name = source.readString();
        appWidth = source.readInt();
        appHeight = source.readInt();
@@ -430,7 +430,7 @@ public final class DisplayInfo implements Parcelable {
        dest.writeInt(layerStack);
        dest.writeInt(this.flags);
        dest.writeInt(type);
        dest.writeString(address);
        dest.writeParcelable(address, flags);
        dest.writeString(name);
        dest.writeInt(appWidth);
        dest.writeInt(appHeight);
+7 −2
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.display;
import android.graphics.Rect;
import android.hardware.display.DisplayViewport;
import android.os.IBinder;
import android.view.DisplayAddress;
import android.view.Surface;
import android.view.SurfaceControl;

@@ -225,9 +226,13 @@ abstract class DisplayDevice {
        viewport.deviceHeight = isRotated ? info.width : info.height;

        viewport.uniqueId = info.uniqueId;
        // TODO(b/112898898) Use an actual port here.

        if (info.address instanceof DisplayAddress.Physical) {
            viewport.physicalPort = ((DisplayAddress.Physical) info.address).getPort();
        } else {
            viewport.physicalPort = null;
        }
    }

    /**
     * Dumps the local state of the display device.
+2 −1
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.display;
import android.hardware.display.DisplayViewport;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.DisplayAddress;
import android.view.DisplayCutout;
import android.view.Surface;

@@ -274,7 +275,7 @@ final class DisplayDeviceInfo {
     * Display address, or null if none.
     * Interpretation varies by display type.
     */
    public String address;
    public DisplayAddress address;

    /**
     * Display state.
Loading