DisplayManagerService启动及主屏添加-Android13
命令查看屏幕信息:
$ dumpsys SurfaceFlinger --display-id # Example output. Display 21691504607621632 (HWC display 0): port=0 pnpId=SHP displayName="LQ123P1JX32" Display 9834494747159041 (HWC display 2): port=1 pnpId=HWP displayName="HP Z24i" Display 1886279400700944 (HWC display 1): port=2 pnpId=AUS displayName="ASUS MB16AP"
mInfo.width = mActiveSfDisplayMode.width
:屏幕宽mInfo.height = mActiveSfDisplayMode.height
:屏幕高mInfo.densityDpi = getLogicalDensity()
:屏幕DensitymInfo.xDpi = mActiveSfDisplayMode.xDpi
:显示器在X方向上的DPI物理密度mInfo.yDpi = mActiveSfDisplayMode.yDpi
:显示器在Y方向上的DPI物理密度。mInfo.installOrientation = mStaticDisplayInfo.installOrientation
:显示面板的安装方向相对于其自然方向。mInfo.type = Display.TYPE_INTERNAL 或 Display.TYPE_EXTERNAL
:内置屏幕<string name="display_manager_built_in_display_name">Built-in Screen</string>
、HDMI 屏幕<string name="display_manager_hdmi_display_name">HDMI Screen</string>
public int rotation = Surface.ROTATION_0
:显示旋转方向
添加 “内置屏幕”
1080 x 2400
density 420, 420.0 x 420.0 dpi
rotation 0
type INTERNAL
installOrientation 0
09-14 16:10:38.304 607 650 I DisplayDeviceRepository: Display device added: DisplayDeviceInfo{"内置屏幕": uniqueId="local:4619827259835644672", 1080 x 2400, modeId 1, renderFrameRate 60.000004, defaultModeId 1, supportedModes [{id=1, width=1080, height=2400, fps=60.000004, alternativeRefreshRates=[], supportedHdrTypes=[]}], colorMode 0, supportedColorModes [0], hdrCapabilities HdrCapabilities{mSupportedHdrTypes=[], mMaxLuminance=500.0, mMaxAverageLuminance=500.0, mMinLuminance=0.0}, allmSupported false, gameContentTypeSupported false, density 420, 420.0 x 420.0 dpi, appVsyncOff 1000000, presDeadline 16666666, touch INTERNAL, rotation 0, type INTERNAL, address {port=0, model=0x401cec6a7a2b7b}, deviceProductInfo DeviceProductInfo{name=EMU_display_0, manufacturerPnpId=GGL, productId=1, modelYear=null, manufactureDate=ManufactureDate{week=27, year=2006}, connectionToSinkType=0}, state UNKNOWN, committedState UNKNOWN, frameRateOverride , brightnessMinimum 0.0, brightnessMaximum 1.0, brightnessDefault 0.39763778, hdrSdrRatio NaN, FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY, FLAG_ROTATES_WITH_CONTENT, FLAG_SECURE, FLAG_SUPPORTS_PROTECTED_BUFFERS, FLAG_TRUSTED, installOrientation 0, displayShape DisplayShape{ spec=-1893857183 displayWidth=1080 displayHeight=2400 physicalPixelDisplaySizeRatio=1.0 rotation=0 offsetX=0 offsetY=0 scale=1.0}} 09-14 16:10:38.307 607 650 I LogicalDisplayMapper: Applying layout: [{dispId: 0(ON), displayGroupName: , addr: {port=0, model=0x401cec6a7a2b7b}, mThermalBrightnessThrottlingMapId: null, mRefreshRateZoneId: null, mLeadDisplayId: -1, mThermalRefreshRateThrottlingMapId: null}], Previous layout: null 09-14 16:10:38.317 607 650 I LogicalDisplayMapper: Setting new display group 0 for display 0, from previous group: null 09-14 16:10:38.320 607 650 I LogicalDisplayMapper: Adding new display: 0: DisplayInfo{"内置屏幕", displayId 0, displayGroupId 0, FLAG_SECURE, FLAG_SUPPORTS_PROTECTED_BUFFERS, FLAG_TRUSTED, real 1080 x 2400, largest app 1080 x 2400, smallest app 1080 x 2400, appVsyncOff 1000000, presDeadline 16666666, mode 160.000004, defaultMode 1, modes [{id=1, width=1080, height=2400, fps=60.000004, alternativeRefreshRates=[], supportedHdrTypes=[]}], hdrCapabilities HdrCapabilities{mSupportedHdrTypes=[], mMaxLuminance=500.0, mMaxAverageLuminance=500.0, mMinLuminance=0.0}, userDisabledHdrTypes [], minimalPostProcessingSupported false, rotation 0, state UNKNOWN, committedState UNKNOWN, type INTERNAL, uniqueId "local:4619827259835644672", app 1080 x 2400, density 420 (420.0 x 420.0) dpi, layerStack 0, colorMode 0, supportedColorModes [0], address {port=0, model=0x401cec6a7a2b7b}, deviceProductInfo DeviceProductInfo{name=EMU_display_0, manufacturerPnpId=GGL, productId=1, modelYear=null, manufactureDate=ManufactureDate{week=27, year=2006}, connectionToSinkType=0}, removeMode 0, refreshRateOverride 0.0, brightnessMinimum 0.0, brightnessMaximum 1.0, brightnessDefault 0.39763778, installOrientation ROTATION_0, layoutLimitedRefreshRate null, hdrSdrRatio not_available, thermalRefreshRateThrottling {}, thermalBrightnessThrottlingDataId default} 09-14 16:10:49.174 607 650 I DisplayDeviceRepository: Display device changed state: "内置屏幕", ON 09-14 16:10:49.185 607 650 I DisplayDeviceRepository: Display device changed state: "内置屏幕", ON 09-14 16:10:50.814 607 650 I DisplayDeviceRepository: Display device added: DisplayDeviceInfo{"叠加视图 #1": uniqueId="overlay:1", 1920 x 1080, modeId 2, renderFrameRate 60.000004, defaultModeId 2, supportedModes [{id=2, width=1920, height=1080, fps=60.000004, alternativeRefreshRates=[], supportedHdrTypes=[]}], colorMode 0, supportedColorModes [0], hdrCapabilities null, allmSupported false, gameContentTypeSupported false, density 320, 320.0 x 320.0 dpi, appVsyncOff 0, presDeadline 33333332, touch VIRTUAL, rotation 0, type OVERLAY, deviceProductInfo null, state ON, committedState UNKNOWN, frameRateOverride , brightnessMinimum 0.0, brightnessMaximum 0.0, brightnessDefault 0.0, hdrSdrRatio NaN, FLAG_SECURE, FLAG_PRESENTATION, FLAG_TRUSTED, installOrientation 0, displayShape DisplayShape{ spec=729782573 displayWidth=1920 displayHeight=1080 physicalPixelDisplaySizeRatio=1.0 rotation=0 offsetX=0 offsetY=0 scale=1.0}} 09-14 16:10:50.820 607 650 I LogicalDisplayMapper: Applying layout: [{dispId: 0(ON), displayGroupName: , addr: {port=0, model=0x401cec6a7a2b7b}, mThermalBrightnessThrottlingMapId: null, mRefreshRateZoneId: null, mLeadDisplayId: -1, mThermalRefreshRateThrottlingMapId: null}], Previous layout: [{dispId: 0(ON), displayGroupName: , addr: {port=0, model=0x401cec6a7a2b7b}, mThermalBrightnessThrottlingMapId: null, mRefreshRateZoneId: null, mLeadDisplayId: -1, mThermalRefreshRateThrottlingMapId: null}] 09-14 16:10:50.821 607 650 I LogicalDisplayMapper: Setting new display group 0 for display 2, from previous group: null 09-14 16:10:50.825 607 650 I LogicalDisplayMapper: Adding new display: 2: DisplayInfo{"叠加视图 #1", displayId 2, displayGroupId 0, FLAG_SECURE, FLAG_PRESENTATION, FLAG_TRUSTED, real 1920 x 1080, largest app 1920 x 1080, smallest app 1920 x 1080, appVsyncOff 0, presDeadline 33333332, mode 260.000004, defaultMode 2, modes [{id=2, width=1920, height=1080, fps=60.000004, alternativeRefreshRates=[], supportedHdrTypes=[]}], hdrCapabilities null, userDisabledHdrTypes [], minimalPostProcessingSupported false, rotation 0, state ON, committedState UNKNOWN, type OVERLAY, uniqueId "overlay:1", app 1920 x 1080, density 320 (320.0 x 320.0) dpi, layerStack 2, colorMode 0, supportedColorModes [0], deviceProductInfo null, removeMode 0, refreshRateOverride 0.0, brightnessMinimum 0.0, brightnessMaximum 0.0, brightnessDefault 0.0, installOrientation ROTATION_0, layoutLimitedRefreshRate null, hdrSdrRatio not_available, thermalRefreshRateThrottling {}, thermalBrightnessThrottlingDataId default} 09-14 16:10:58.994 607 650 I DisplayDeviceRepository: Display device changed: DisplayDeviceInfo{"内置屏幕": uniqueId="local:4619827259835644672", 1080 x 2400, modeId 1, renderFrameRate 60.000004, defaultModeId 1, supportedModes [{id=1, width=1080, height=2400, fps=60.000004, alternativeRefreshRates=[], supportedHdrTypes=[]}], colorMode 0, supportedColorModes [0], hdrCapabilities HdrCapabilities{mSupportedHdrTypes=[], mMaxLuminance=500.0, mMaxAverageLuminance=500.0, mMinLuminance=0.0}, allmSupported false, gameContentTypeSupported false, density 420, 420.0 x 420.0 dpi, appVsyncOff 1000000, presDeadline 16666666, cutout DisplayCutout{insets=Rect(0, 132 - 0, 0) waterfall=Insets{left=0, top=0, right=0, bottom=0} boundingRect={Bounds=[Rect(0, 0 - 0, 0), Rect(479, 0 - 601, 132), Rect(0, 0 - 0, 0), Rect(0, 0 - 0, 0)]} cutoutPathParserInfo={CutoutPathParserInfo{displayWidth=1080 displayHeight=2400 physicalDisplayWidth=1080 physicalDisplayHeight=2400 density={2.625} cutoutSpec={m 576,65.75 a 36.25,36.25 0 0 0 -72.5,0 36.25,36.25 0 0 0 72.5,0 z @left} rotation={0} scale={1.0} physicalPixelDisplaySizeRatio={1.0}}}}, touch INTERNAL, rotation 0, type INTERNAL, address {port=0, model=0x401cec6a7a2b7b}, deviceProductInfo DeviceProductInfo{name=EMU_display_0, manufacturerPnpId=GGL, productId=1, modelYear=null, manufactureDate=ManufactureDate{week=27, year=2006}, connectionToSinkType=0}, state ON, committedState ON, frameRateOverride , brightnessMinimum 0.0, brightnessMaximum 1.0, brightnessDefault 0.39763778, hdrSdrRatio NaN, roundedCorners RoundedCorners{[RoundedCorner{position=TopLeft, radius=104, center=Point(104, 104)}, RoundedCorner{position=TopRight, radius=104, center=Point(976, 104)}, RoundedCorner{position=BottomRight, radius=102, center=Point(978, 2298)}, RoundedCorner{position=BottomLeft, radius=102, center=Point(102, 2298)}]}, FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY, FLAG_ROTATES_WITH_CONTENT, FLAG_SECURE, FLAG_SUPPORTS_PROTECTED_BUFFERS, FLAG_TRUSTED, installOrientation 0, displayShape DisplayS ... 09-14 16:10:59.203 607 650 I DisplayDeviceRepository: Display device changed: DisplayDeviceInfo{"叠加视图 #1": uniqueId="overlay:1", 1920 x 1080, modeId 2, renderFrameRate 60.000004, defaultModeId 2, supportedModes [{id=2, width=1920, height=1080, fps=60.000004, alternativeRefreshRates=[], supportedHdrTypes=[]}], colorMode 0, supportedColorModes [0], hdrCapabilities null, allmSupported false, gameContentTypeSupported false, density 320, 320.0 x 320.0 dpi, appVsyncOff 0, presDeadline 33333332, touch VIRTUAL, rotation 0, type OVERLAY, deviceProductInfo null, state ON, committedState UNKNOWN, frameRateOverride , brightnessMinimum 0.0, brightnessMaximum 0.0, brightnessDefault 0.0, hdrSdrRatio NaN, FLAG_SECURE, FLAG_PRESENTATION, FLAG_TRUSTED, installOrientation 0, displayShape DisplayShape{ spec=729782573 displayWidth=1920 displayHeight=1080 physicalPixelDisplaySizeRatio=1.0 rotation=0 offsetX=0 offsetY=0 scale=1.0}} 09-14 16:10:59.210 607 650 I DisplayDeviceRepository: Display device changed: DisplayDeviceInfo{"叠加视图 #1": uniqueId="overlay:1", 1920 x 1080, modeId 2, renderFrameRate 60.000004, defaultModeId 2, supportedModes [{id=2, width=1920, height=1080, fps=60.000004, alternativeRefreshRates=[], supportedHdrTypes=[]}], colorMode 0, supportedColorModes [0], hdrCapabilities null, allmSupported false, gameContentTypeSupported false, density 320, 320.0 x 320.0 dpi, appVsyncOff 0, presDeadline 33333332, touch VIRTUAL, rotation 0, type OVERLAY, deviceProductInfo null, state ON, committedState UNKNOWN, frameRateOverride , brightnessMinimum 0.0, brightnessMaximum 0.0, brightnessDefault 0.0, hdrSdrRatio NaN, FLAG_SECURE, FLAG_PRESENTATION, FLAG_TRUSTED, installOrientation 0, displayShape DisplayShape{ spec=729782573 displayWidth=1920 displayHeight=1080 physicalPixelDisplaySizeRatio=1.0 rotation=0 offsetX=0 offsetY=0 scale=1.0}} 09-14 16:10:44.078 607 650 I DisplayDeviceRepository: Display device changed: DisplayDeviceInfo{"叠加视图 #1": uniqueId="overlay:1", 1920 x 1080, modeId 2, renderFrameRate 60.000004, defaultModeId 2, supportedModes [{id=2, width=1920, height=1080, fps=60.000004, alternativeRefreshRates=[], supportedHdrTypes=[]}], colorMode 0, supportedColorModes [0], hdrCapabilities null, allmSupported false, gameContentTypeSupported false, density 320, 320.0 x 320.0 dpi, appVsyncOff 0, presDeadline 33333332, touch VIRTUAL, rotation 0, type OVERLAY, deviceProductInfo null, state ON, committedState UNKNOWN, frameRateOverride , brightnessMinimum 0.0, brightnessMaximum 0.0, brightnessDefault 0.0, hdrSdrRatio NaN, FLAG_SECURE, FLAG_PRESENTATION, FLAG_TRUSTED, installOrientation 0, displayShape DisplayShape{ spec=729782573 displayWidth=1920 displayHeight=1080 physicalPixelDisplaySizeRatio=1.0 rotation=0 offsetX=0 offsetY=0 scale=1.0}} 09-14 16:10:44.343 607 650 I LogicalDisplayMapper: Requesting Transition to state: 0, from state=-1, interactive=true, mBootCompleted=true 09-14 16:10:44.343 607 650 I LogicalDisplayMapper: Applying layout: [{dispId: 0(ON), displayGroupName: , addr: {port=0, model=0x401cec6a7a2b7b}, mThermalBrightnessThrottlingMapId: null, mRefreshRateZoneId: null, mLeadDisplayId: -1, mThermalRefreshRateThrottlingMapId: null}], Previous layout: [{dispId: 0(ON), displayGroupName: , addr: {port=0, model=0x401cec6a7a2b7b}, mThermalBrightnessThrottlingMapId: null, mRefreshRateZoneId: null, mLeadDisplayId: -1, mThermalRefreshRateThrottlingMapId: null}] 09-14 16:10:48.835 607 650 I DisplayDeviceRepository: Display device changed: DisplayDeviceInfo{"内置屏幕": uniqueId="local:4619827259835644672", 1080 x 2400, modeId 1, renderFrameRate 60.000004, defaultModeId 1, supportedModes [{id=1, width=1080, height=2400, fps=60.000004, alternativeRefreshRates=[], supportedHdrTypes=[]}], colorMode 0, supportedColorModes [0], hdrCapabilities HdrCapabilities{mSupportedHdrTypes=[], mMaxLuminance=500.0, mMaxAverageLuminance=500.0, mMinLuminance=0.0}, allmSupported false, gameContentTypeSupported false, density 420, 420.0 x 420.0 dpi, appVsyncOff 1000000, presDeadline 16666666, cutout DisplayCutout{insets=Rect(0, 132 - 0, 0) waterfall=Insets{left=0, top=0, right=0, bottom=0} boundingRect={Bounds=[Rect(0, 0 - 0, 0), Rect(479, 0 - 601, 132), Rect(0, 0 - 0, 0), Rect(0, 0 - 0, 0)]} cutoutPathParserInfo={CutoutPathParserInfo{displayWidth=1080 displayHeight=2400 physicalDisplayWidth=1080 physicalDisplayHeight=2400 density={2.625} cutoutSpec={m 576,65.75 a 36.25,36.25 0 0 0 -72.5,0 36.25,36.25 0 0 0 72.5,0 z @left} rotation={0} scale={1.0} physicalPixelDisplaySizeRatio={1.0}}}}, touch INTERNAL, rotation 0, type INTERNAL, address {port=0, model=0x401cec6a7a2b7b}, deviceProductInfo DeviceProductInfo{name=EMU_display_0, manufacturerPnpId=GGL, productId=1, modelYear=null, manufactureDate=ManufactureDate{week=27, year=2006}, connectionToSinkType=0}, state ON, committedState ON, frameRateOverride , brightnessMinimum 0.0, brightnessMaximum 1.0, brightnessDefault 0.39763778, hdrSdrRatio NaN, roundedCorners RoundedCorners{[RoundedCorner{position=TopLeft, radius=104, center=Point(104, 104)}, RoundedCorner{position=TopRight, radius=104, center=Point(976, 104)}, RoundedCorner{position=BottomRight, radius=102, center=Point(978, 2298)}, RoundedCorner{position=BottomLeft, radius=102, center=Point(102, 2298)}]}, FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY, FLAG_ROTATES_WITH_CONTENT, FLAG_SECURE, FLAG_SUPPORTS_PROTECTED_BUFFERS, FLAG_TRUSTED, installOrientation 0, displayShape DisplayS ... 09-14 16:11:13.939 607 650 I DisplayDeviceRepository: Display device changed: DisplayDeviceInfo{"叠加视图 #1": uniqueId="overlay:1", 1920 x 1080, modeId 2, renderFrameRate 60.000004, defaultModeId 2, supportedModes [{id=2, width=1920, height=1080, fps=60.000004, alternativeRefreshRates=[], supportedHdrTypes=[]}], colorMode 0, supportedColorModes [0], hdrCapabilities null, allmSupported false, gameContentTypeSupported false, density 320, 320.0 x 320.0 dpi, appVsyncOff 0, presDeadline 33333332, touch VIRTUAL, rotation 0, type OVERLAY, deviceProductInfo null, state ON, committedState UNKNOWN, frameRateOverride , brightnessMinimum 0.0, brightnessMaximum 0.0, brightnessDefault 0.0, hdrSdrRatio NaN, FLAG_SECURE, FLAG_PRESENTATION, FLAG_TRUSTED, installOrientation 0, displayShape DisplayShape{ spec=729782573 displayWidth=1920 displayHeight=1080 physicalPixelDisplaySizeRatio=1.0 rotation=0 offsetX=0 offsetY=0 scale=1.0}} 09-14 16:11:24.379 607 650 I DisplayDeviceRepository: Display device changed state: "内置屏幕", OFF 09-14 16:11:24.390 607 650 I DisplayDeviceRepository: Display device changed state: "内置屏幕", OFF 09-14 16:11:24.425 607 650 I DisplayDeviceRepository: Display device changed state: "叠加视图 #1", OFF 09-14 16:11:24.478 607 650 I DisplayDeviceRepository: Display device changed: DisplayDeviceInfo{"叠加视图 #1": uniqueId="overlay:1", 1920 x 1080, modeId 2, renderFrameRate 60.000004, defaultModeId 2, supportedModes [{id=2, width=1920, height=1080, fps=60.000004, alternativeRefreshRates=[], supportedHdrTypes=[]}], colorMode 0, supportedColorModes [0], hdrCapabilities null, allmSupported false, gameContentTypeSupported false, density 320, 320.0 x 320.0 dpi, appVsyncOff 0, presDeadline 33333332, touch VIRTUAL, rotation 0, type OVERLAY, deviceProductInfo null, state OFF, committedState UNKNOWN, frameRateOverride , brightnessMinimum 0.0, brightnessMaximum 0.0, brightnessDefault 0.0, hdrSdrRatio NaN, FLAG_SECURE, FLAG_PRESENTATION, FLAG_TRUSTED, installOrientation 0, displayShape DisplayShape{ spec=729782573 displayWidth=1920 displayHeight=1080 physicalPixelDisplaySizeRatio=1.0 rotation=0 offsetX=0 offsetY=0 scale=1.0}} 09-14 16:11:27.676 607 650 I DisplayDeviceRepository: Display device changed state: "内置屏幕", ON 09-14 16:11:27.688 607 650 I DisplayDeviceRepository: Display device changed state: "内置屏幕", ON 09-14 16:11:27.777 607 650 I DisplayDeviceRepository: Display device changed state: "叠加视图 #1", ON 09-14 16:11:27.829 607 650 I DisplayDeviceRepository: Display device changed: DisplayDeviceInfo{"叠加视图 #1": uniqueId="overlay:1", 1920 x 1080, modeId 2, renderFrameRate 60.000004, defaultModeId 2, supportedModes [{id=2, width=1920, height=1080, fps=60.000004, alternativeRefreshRates=[], supportedHdrTypes=[]}], colorMode 0, supportedColorModes [0], hdrCapabilities null, allmSupported false, gameContentTypeSupported false, density 320, 320.0 x 320.0 dpi, appVsyncOff 0, presDeadline 33333332, touch VIRTUAL, rotation 0, type OVERLAY, deviceProductInfo null, state ON, committedState UNKNOWN, frameRateOverride , brightnessMinimum 0.0, brightnessMaximum 0.0, brightnessDefault 0.0, hdrSdrRatio NaN, FLAG_SECURE, FLAG_PRESENTATION, FLAG_TRUSTED, installOrientation 0, displayShape DisplayShape{ spec=729782573 displayWidth=1920 displayHeight=1080 physicalPixelDisplaySizeRatio=1.0 rotation=0 offsetX=0 offsetY=0 scale=1.0}} 09-14 16:14:42.174 607 650 I DisplayDeviceRepository: Display device removed: DisplayDeviceInfo{"叠加视图 #1": uniqueId="overlay:1", 1920 x 1080, modeId 2, renderFrameRate 60.000004, defaultModeId 2, supportedModes [{id=2, width=1920, height=1080, fps=60.000004, alternativeRefreshRates=[], supportedHdrTypes=[]}], colorMode 0, supportedColorModes [0], hdrCapabilities null, allmSupported false, gameContentTypeSupported false, density 320, 320.0 x 320.0 dpi, appVsyncOff 0, presDeadline 33333332, touch VIRTUAL, rotation 0, type OVERLAY, deviceProductInfo null, state ON, committedState UNKNOWN, frameRateOverride , brightnessMinimum 0.0, brightnessMaximum 0.0, brightnessDefault 0.0, hdrSdrRatio NaN, FLAG_SECURE, FLAG_PRESENTATION, FLAG_TRUSTED, installOrientation 0, displayShape DisplayShape{ spec=729782573 displayWidth=1920 displayHeight=1080 physicalPixelDisplaySizeRatio=1.0 rotation=0 offsetX=0 offsetY=0 scale=1.0}} 09-14 16:14:42.191 607 650 I LogicalDisplayMapper: Removing display: 2
frameworks/base/services/core/java/com/android/server/display/DisplayDeviceRepository.java
frameworks/base/services/core/java/com/android/server/display/LocalDisplayAdapter.java
public DisplayDeviceInfo getDisplayDeviceInfoLocked() {
if (mInfo == null) {
mInfo = new DisplayDeviceInfo();
mInfo.width = mActiveSfDisplayMode.width;
mInfo.height = mActiveSfDisplayMode.height;
mInfo.modeId = mActiveModeId;
mInfo.renderFrameRate = mActiveRenderFrameRate;
mInfo.defaultModeId = getPreferredModeId();
mInfo.supportedModes = getDisplayModes(mSupportedModes);
mInfo.colorMode = mActiveColorMode;
mInfo.allmSupported = mAllmSupported;
mInfo.gameContentTypeSupported = mGameContentTypeSupported;
mInfo.supportedColorModes =
new int[mSupportedColorModes.size()];
for (int i = 0; i < mSupportedColorModes.size(); i++) {
mInfo.supportedColorModes[i] = mSupportedColorModes.get(i);
}
mInfo.hdrCapabilities = mHdrCapabilities;
mInfo.appVsyncOffsetNanos = mActiveSfDisplayMode.appVsyncOffsetNanos;
mInfo.presentationDeadlineNanos = mActiveSfDisplayMode.presentationDeadlineNanos;
mInfo.state = mState;
mInfo.committedState = mCommittedState;
mInfo.uniqueId = getUniqueId();
final DisplayAddress.Physical physicalAddress =
DisplayAddress.fromPhysicalDisplayId(mPhysicalDisplayId);
mInfo.address = physicalAddress;
mInfo.densityDpi = getLogicalDensity();
mInfo.xDpi = mActiveSfDisplayMode.xDpi;
mInfo.yDpi = mActiveSfDisplayMode.yDpi;
mInfo.deviceProductInfo = mStaticDisplayInfo.deviceProductInfo;
// Assume that all built-in displays that have secure output (eg. HDCP) also
// support compositing from gralloc protected buffers.
if (mStaticDisplayInfo.secure) {
mInfo.flags = DisplayDeviceInfo.FLAG_SECURE
| DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS;
}
final Resources res = getOverlayContext().getResources();
mInfo.flags |= DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY;
if (mIsFirstDisplay) {
if (res.getBoolean(R.bool.config_mainBuiltInDisplayIsRound)
|| (Build.IS_EMULATOR
&& SystemProperties.getBoolean(PROPERTY_EMULATOR_CIRCULAR, false))) {
mInfo.flags |= DisplayDeviceInfo.FLAG_ROUND;
}
} else {
if (!res.getBoolean(R.bool.config_localDisplaysMirrorContent)) {
mInfo.flags |= DisplayDeviceInfo.FLAG_OWN_CONTENT_ONLY;
}
if (isDisplayPrivate(physicalAddress)) {
mInfo.flags |= DisplayDeviceInfo.FLAG_PRIVATE;
}
}
if (DisplayCutout.getMaskBuiltInDisplayCutout(res, mInfo.uniqueId)) {
mInfo.flags |= DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT;
}
final Display.Mode maxDisplayMode =
DisplayUtils.getMaximumResolutionDisplayMode(mInfo.supportedModes);
final int maxWidth =
maxDisplayMode == null ? mInfo.width : maxDisplayMode.getPhysicalWidth();
final int maxHeight =
maxDisplayMode == null ? mInfo.height : maxDisplayMode.getPhysicalHeight();
mInfo.displayCutout = DisplayCutout.fromResourcesRectApproximation(res,
mInfo.uniqueId, maxWidth, maxHeight, mInfo.width, mInfo.height);
mInfo.roundedCorners = RoundedCorners.fromResources(
res, mInfo.uniqueId, maxWidth, maxHeight, mInfo.width, mInfo.height);
mInfo.installOrientation = mStaticDisplayInfo.installOrientation;
mInfo.displayShape = DisplayShape.fromResources(
res, mInfo.uniqueId, maxWidth, maxHeight, mInfo.width, mInfo.height);
mInfo.name = getDisplayDeviceConfig().getName();
if (mStaticDisplayInfo.isInternal) {
mInfo.type = Display.TYPE_INTERNAL;
mInfo.touch = DisplayDeviceInfo.TOUCH_INTERNAL;
mInfo.flags |= DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT;
if (mInfo.name == null) {
mInfo.name = res.getString(R.string.display_manager_built_in_display_name);
}
} else {
mInfo.type = Display.TYPE_EXTERNAL;
mInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL;
mInfo.flags |= DisplayDeviceInfo.FLAG_PRESENTATION;
if (mInfo.name == null) {
mInfo.name = getContext().getResources().getString(
R.string.display_manager_hdmi_display_name);
}
}
mInfo.frameRateOverrides = mFrameRateOverrides;
// The display is trusted since it is created by system.
mInfo.flags |= DisplayDeviceInfo.FLAG_TRUSTED;
mInfo.brightnessMinimum = PowerManager.BRIGHTNESS_MIN;
mInfo.brightnessMaximum = PowerManager.BRIGHTNESS_MAX;
mInfo.brightnessDefault = getDisplayDeviceConfig().getBrightnessDefault();
mInfo.hdrSdrRatio = mCurrentHdrSdrRatio;
}
return mInfo;
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("DisplayDeviceInfo{\"");
sb.append(name).append("\": uniqueId=\"").append(uniqueId).append("\", ");
sb.append(width).append(" x ").append(height);
sb.append(", modeId ").append(modeId);
sb.append(", renderFrameRate ").append(renderFrameRate);
sb.append(", defaultModeId ").append(defaultModeId);
sb.append(", supportedModes ").append(Arrays.toString(supportedModes));
sb.append(", colorMode ").append(colorMode);
sb.append(", supportedColorModes ").append(Arrays.toString(supportedColorModes));
sb.append(", hdrCapabilities ").append(hdrCapabilities);
sb.append(", allmSupported ").append(allmSupported);
sb.append(", gameContentTypeSupported ").append(gameContentTypeSupported);
sb.append(", density ").append(densityDpi);
sb.append(", ").append(xDpi).append(" x ").append(yDpi).append(" dpi");
sb.append(", appVsyncOff ").append(appVsyncOffsetNanos);
sb.append(", presDeadline ").append(presentationDeadlineNanos);
if (displayCutout != null) {
sb.append(", cutout ").append(displayCutout);
}
sb.append(", touch ").append(touchToString(touch));
sb.append(", rotation ").append(rotation);
sb.append(", type ").append(Display.typeToString(type));
if (address != null) {
sb.append(", address ").append(address);
}
sb.append(", deviceProductInfo ").append(deviceProductInfo);
sb.append(", state ").append(Display.stateToString(state));
sb.append(", committedState ").append(Display.stateToString(committedState));
if (ownerUid != 0 || ownerPackageName != null) {
sb.append(", owner ").append(ownerPackageName);
sb.append(" (uid ").append(ownerUid).append(")");
}
sb.append(", frameRateOverride ");
for (DisplayEventReceiver.FrameRateOverride frameRateOverride : frameRateOverrides) {
sb.append(frameRateOverride).append(" ");
}
sb.append(", brightnessMinimum ").append(brightnessMinimum);
sb.append(", brightnessMaximum ").append(brightnessMaximum);
sb.append(", brightnessDefault ").append(brightnessDefault);
sb.append(", hdrSdrRatio ").append(hdrSdrRatio);
if (roundedCorners != null) {
sb.append(", roundedCorners ").append(roundedCorners);
}
sb.append(flagsToString(flags));
sb.append(", installOrientation ").append(installOrientation);
if (displayShape != null) {
sb.append(", displayShape ").append(displayShape);
}
sb.append("}");
return sb.toString();
}
private static String touchToString(int touch) {
switch (touch) {
case TOUCH_NONE:
return "NONE";
case TOUCH_INTERNAL:
return "INTERNAL";
case TOUCH_EXTERNAL:
return "EXTERNAL";
case TOUCH_VIRTUAL:
return "VIRTUAL";
default:
return Integer.toString(touch);
}
}
1、fw侧获取物理屏幕信息就是
LocalDisplayAdapter.java
中LocalDisplayDevice.getDisplayDeviceInfoLocked()
2、根据物理屏幕信息在LogicalDisplayMapper.java
中创建对应LogicalDisplay
,紧接着通知到RootWindowContainer.java
在onDisplayAdded
方法中创建对应DisplayContent
3、DisplayContent
这里就是逻辑屏幕显示信息刷新,主要关注逻辑界面方向DisplayRotation
、更新设置setDisplayInfoOverrideFromWindowManager
4、更新逻辑屏幕信息mOverrideDisplayInfo
(LogicalDisplay
中setDisplayInfoOverrideFromWindowManagerLocked
);主屏onVsyc
信号同步刷新configureDisplayLocked
设置device.setProjectionLocked(t, orientation, mTempLayerStackRect, mTempDisplayRect)
,最终更新到sf 中
frameworks/base/services/core/java/com/android/server/wm/RootWindowContainer.java
frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
frameworks/base/services/core/java/com/android/server/display/LogicalDisplay.java
RootWindowContainer.java#onDisplayAdded
1、
mDisplayInfo.rotation
:最终获取mDisplayRotation.getRotation()
2、mDisplayInfo.logicalWidth、mDisplayInfo.logicalHeight
:根据逻辑屏幕方向宽高交换
3、mWmService.mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(mDisplayId, mDisplayInfo)
:最终设置到LogicalDisplay
中setDisplayInfoOverrideFromWindowManagerLocked
的mOverrideDisplayInfo
DisplayContent.java#updateDisplayAndOrientation
DisplayManagerService.java#setDisplayInfoOverrideFromWindowManager
LogicalDisplay.java#setDisplayInfoOverrideFromWindowManagerLocked
/**
* Update {@link #mDisplayInfo} and other internal variables when display is rotated or config
* changed.
* Do not call if {@link WindowManagerService#mDisplayReady} == false.
*/
private DisplayInfo updateDisplayAndOrientation(Configuration outConfig) {
// Use the effective "visual" dimensions based on current rotation
final int rotation = getRotation();
final boolean rotated = (rotation == ROTATION_90 || rotation == ROTATION_270);
final int dw = rotated ? mBaseDisplayHeight : mBaseDisplayWidth;
final int dh = rotated ? mBaseDisplayWidth : mBaseDisplayHeight;
// Update application display metrics.
final DisplayCutout displayCutout = calculateDisplayCutoutForRotation(rotation);
final RoundedCorners roundedCorners = calculateRoundedCornersForRotation(rotation);
final DisplayShape displayShape = calculateDisplayShapeForRotation(rotation);
final Rect appFrame = mDisplayPolicy.getDecorInsetsInfo(rotation, dw, dh).mNonDecorFrame;
mDisplayInfo.rotation = rotation;
mDisplayInfo.logicalWidth = dw;
mDisplayInfo.logicalHeight = dh;
mDisplayInfo.logicalDensityDpi = mBaseDisplayDensity;
mDisplayInfo.physicalXDpi = mBaseDisplayPhysicalXDpi;
mDisplayInfo.physicalYDpi = mBaseDisplayPhysicalYDpi;
mDisplayInfo.appWidth = appFrame.width();
mDisplayInfo.appHeight = appFrame.height();
if (isDefaultDisplay) {
mDisplayInfo.getLogicalMetrics(mRealDisplayMetrics,
CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
}
mDisplayInfo.displayCutout = displayCutout.isEmpty() ? null : displayCutout;
mDisplayInfo.roundedCorners = roundedCorners;
mDisplayInfo.displayShape = displayShape;
mDisplayInfo.getAppMetrics(mDisplayMetrics);
if (mDisplayScalingDisabled) {
mDisplayInfo.flags |= Display.FLAG_SCALING_DISABLED;
} else {
mDisplayInfo.flags &= ~Display.FLAG_SCALING_DISABLED;
}
computeSizeRanges(mDisplayInfo, rotated, dw, dh, mDisplayMetrics.density, outConfig);
mWmService.mDisplayManagerInternal.setDisplayInfoOverrideFromWindowManager(mDisplayId,
mDisplayInfo);
if (isDefaultDisplay) {
mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(mDisplayMetrics,
mCompatDisplayMetrics);
}
onDisplayInfoChanged();
return mDisplayInfo;
}
frameworks/base/services/core/java/com/android/server/display/LogicalDisplay.java
/**
* Sets overridden logical display information from the window manager.
* This method can be used to adjust application insets, rotation, and other
* properties that the window manager takes care of.
*
* @param info The logical display information, may be null.
*/
public boolean setDisplayInfoOverrideFromWindowManagerLocked(DisplayInfo info) {
if (info != null) {
if (mOverrideDisplayInfo == null) {
mOverrideDisplayInfo = new DisplayInfo(info);
mInfo.set(null);
return true;
} else if (!mOverrideDisplayInfo.equals(info)) {
mOverrideDisplayInfo.copyFrom(info);
mInfo.set(null);
return true;
}
} else if (mOverrideDisplayInfo != null) {
mOverrideDisplayInfo = null;
mInfo.set(null);
return true;
}
return false;
}
RootWindowContainer.java#performSurfacePlacement()
RootWindowContainer.java#performSurfacePlacementNoTrace()
RootWindowContainer.java#applySurfaceChangesTransaction
mWmService.mDisplayManagerInternal.performTraversal(t)
DisplayManagerService.java#performTraversalLocked
DisplayManagerService.java#configureDisplayLocked
LogicalDisplay.java#configureDisplayLocked
主屏:1080x2160
mDisplayId=0; orientation=0; physWidth=1080; physHeight=2160; rotated=false [ displayDeviceInfo.rotation=0; displayDeviceInfo.width=1080; displayDeviceInfo.height=2160; displayInfo.rotation=0; displayInfo.logicalWidth=1080; displayInfo.logicalHeight=2160 ] mDisplayId=0; mTempDisplayRect=Rect(0, 0 - 1080, 2160); mTempLayerStackRect=Rect(0, 0 - 1080, 2160); orientation=0 mDisplayId=0; orientation=1; physWidth=2160; physHeight=1080; rotated=true [ displayDeviceInfo.rotation=0; displayDeviceInfo.width=1080; displayDeviceInfo.height=2160; displayInfo.rotation=1; displayInfo.logicalWidth=2160; displayInfo.logicalHeight=1080 ] mDisplayId=0; mTempDisplayRect=Rect(0, 0 - 2160, 1080); mTempLayerStackRect=Rect(0, 0 - 2160, 1080); orientation=1
副屏:1920x1080 (
修改处理?
)mDisplayId=2; orientation=0; physWidth=1920; physHeight=1080 [ displayDeviceInfo.rotation=0; displayDeviceInfo.width=1920; displayDeviceInfo.height=1080; displayInfo.rotation=0; displayInfo.logicalWidth=1920; displayInfo.logicalHeight=1080 ] mDisplayId=2; mTempDisplayRect=Rect(0, 0 - 1920, 1080); mTempLayerStackRect=Rect(0, 0 - 1920, 1080); orientation=0 mDisplayId=2; orientation=3; physWidth=1080; physHeight=1920; rotated=true [ displayDeviceInfo.rotation=3; displayDeviceInfo.width=1920; displayDeviceInfo.height=1080; displayInfo.rotation=0; displayInfo.logicalWidth=1920; displayInfo.logicalHeight=1080 ] mDisplayId=2; mTempDisplayRect=Rect(0, 0 - 1080, 1920); mTempLayerStackRect=Rect(0, 0 - 1080, 1920); orientation=3
frameworks/base/services/core/java/com/android/server/display/LogicalDisplay.java
/**
* Applies the layer stack and transformation to the given display device
* so that it shows the contents of this logical display.
*
* We know that the given display device is only ever showing the contents of
* a single logical display, so this method is expected to blow away all of its
* transformation properties to make it happen regardless of what the
* display device was previously showing.
*
* The caller must have an open Surface transaction.
*
* The display device may not be the primary display device, in the case
* where the display is being mirrored.
*
* @param device The display device to modify.
* @param isBlanked True if the device is being blanked.
*/
public void configureDisplayLocked(SurfaceControl.Transaction t,
DisplayDevice device,
boolean isBlanked) {
// Set the layer stack.
device.setLayerStackLocked(t, isBlanked ? BLANK_LAYER_STACK : mLayerStack, mDisplayId);
// Also inform whether the device is the same one sent to inputflinger for its layerstack.
// Prevent displays that are disabled from receiving input.
// TODO(b/188914255): Remove once input can dispatch against device vs layerstack.
device.setDisplayFlagsLocked(t,
(isEnabledLocked() && device.getDisplayDeviceInfoLocked().touch != TOUCH_NONE)
? SurfaceControl.DISPLAY_RECEIVES_INPUT
: 0);
// Set the color mode and allowed display mode.
if (device == mPrimaryDisplayDevice) {
device.setDesiredDisplayModeSpecsLocked(mDesiredDisplayModeSpecs);
device.setRequestedColorModeLocked(mRequestedColorMode);
} else {
// Reset to default for non primary displays
device.setDesiredDisplayModeSpecsLocked(
new DisplayModeDirector.DesiredDisplayModeSpecs());
device.setRequestedColorModeLocked(0);
}
device.setAutoLowLatencyModeLocked(mRequestedMinimalPostProcessing);
device.setGameContentTypeLocked(mRequestedMinimalPostProcessing);
// Only grab the display info now as it may have been changed based on the requests above.
final DisplayInfo displayInfo = getDisplayInfoLocked();
final DisplayDeviceInfo displayDeviceInfo = device.getDisplayDeviceInfoLocked();
// Set the viewport.
// This is the area of the logical display that we intend to show on the
// display device. For now, it is always the full size of the logical display.
mTempLayerStackRect.set(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
// Set the orientation.
// The orientation specifies how the physical coordinate system of the display
// is rotated when the contents of the logical display are rendered.
int orientation = Surface.ROTATION_0;
if ((displayDeviceInfo.flags & DisplayDeviceInfo.FLAG_ROTATES_WITH_CONTENT) != 0) {
orientation = displayInfo.rotation;
}
// Apply the physical rotation of the display device itself.
orientation = (orientation + displayDeviceInfo.rotation) % 4;
// Set the frame.
// The frame specifies the rotated physical coordinates into which the viewport
// is mapped. We need to take care to preserve the aspect ratio of the viewport.
// Currently we maximize the area to fill the display, but we could try to be
// more clever and match resolutions.
boolean rotated = (orientation == Surface.ROTATION_90
|| orientation == Surface.ROTATION_270);
int physWidth = rotated ? displayDeviceInfo.height : displayDeviceInfo.width;
int physHeight = rotated ? displayDeviceInfo.width : displayDeviceInfo.height;
Rect maskingInsets = getMaskingInsets(displayDeviceInfo);
InsetUtils.rotateInsets(maskingInsets, orientation);
// Don't consider the masked area as available when calculating the scaling below.
physWidth -= maskingInsets.left + maskingInsets.right;
physHeight -= maskingInsets.top + maskingInsets.bottom;
// Determine whether the width or height is more constrained to be scaled.
// physWidth / displayInfo.logicalWidth => letter box
// or physHeight / displayInfo.logicalHeight => pillar box
//
// We avoid a division (and possible floating point imprecision) here by
// multiplying the fractions by the product of their denominators before
// comparing them.
int displayRectWidth, displayRectHeight;
if ((displayInfo.flags & Display.FLAG_SCALING_DISABLED) != 0 || mDisplayScalingDisabled) {
displayRectWidth = displayInfo.logicalWidth;
displayRectHeight = displayInfo.logicalHeight;
} else if (physWidth * displayInfo.logicalHeight
< physHeight * displayInfo.logicalWidth) {
// Letter box.
displayRectWidth = physWidth;
displayRectHeight = displayInfo.logicalHeight * physWidth / displayInfo.logicalWidth;
} else {
// Pillar box.
displayRectWidth = displayInfo.logicalWidth * physHeight / displayInfo.logicalHeight;
displayRectHeight = physHeight;
}
int displayRectTop = (physHeight - displayRectHeight) / 2;
int displayRectLeft = (physWidth - displayRectWidth) / 2;
mTempDisplayRect.set(displayRectLeft, displayRectTop,
displayRectLeft + displayRectWidth, displayRectTop + displayRectHeight);
// Now add back the offset for the masked area.
mTempDisplayRect.offset(maskingInsets.left, maskingInsets.top);
if (orientation == Surface.ROTATION_0) {
mTempDisplayRect.offset(mDisplayOffsetX, mDisplayOffsetY);
} else if (orientation == Surface.ROTATION_90) {
mTempDisplayRect.offset(mDisplayOffsetY, -mDisplayOffsetX);
} else if (orientation == Surface.ROTATION_180) {
mTempDisplayRect.offset(-mDisplayOffsetX, -mDisplayOffsetY);
} else { // Surface.ROTATION_270
mTempDisplayRect.offset(-mDisplayOffsetY, mDisplayOffsetX);
}
mDisplayPosition.set(mTempDisplayRect.left, mTempDisplayRect.top);
device.setProjectionLocked(t, orientation, mTempLayerStackRect, mTempDisplayRect);
}
一般也就叫做
镜像模式
、异屏模式
。
主屏onVsyc
信号同步刷新时,在applySurfaceChangesTransaction()
中调用dc.applySurfaceChangesTransaction();
刷新,updateRecording() > setDisplayMirroring()
如果DisplayContent不再有内容,则开始录制。如果现在有内容或显示器未打开,请停止录制。如果内容已更改,请更新录制。
Android12 DisplayManagerService.java#configureDisplayLocked刷新
frameworks/base/services/core/java/com/android/server/wm/DisplayContent.java
/**
* Start recording if this DisplayContent no longer has content. Stop recording if it now
* has content or the display is not on. Update recording if the content has changed (for
* example, the user has granted consent to token re-use, so we can now start mirroring).
*/
void updateRecording() {
if (mContentRecorder == null || !mContentRecorder.isContentRecordingSessionSet()) {
if (!setDisplayMirroring()) {
return;
}
}
mContentRecorder.updateRecording();
}
/**
* This is to enable mirroring on virtual displays that specify the
* {@link android.hardware.display.DisplayManager#VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR} but don't
* mirror using MediaProjection. When done through MediaProjection API, the
* ContentRecordingSession will be created automatically.
*
* <p>This should only be called when there's no ContentRecordingSession already set for this
* display. The code will ask DMS if this display should enable display mirroring and which
* displayId to mirror from.
*
* @return true if the {@link ContentRecordingSession} was set for display mirroring using data
* from DMS, false if there was no ContentRecordingSession created.
*/
boolean setDisplayMirroring() {
int mirrorDisplayId = mWmService.mDisplayManagerInternal.getDisplayIdToMirror(mDisplayId);
if (mirrorDisplayId == INVALID_DISPLAY) {
return false;
}
if (mirrorDisplayId == mDisplayId) {
if (mDisplayId != DEFAULT_DISPLAY) {
ProtoLog.w(WM_DEBUG_CONTENT_RECORDING,
"Content Recording: Attempting to mirror self on %d", mirrorDisplayId);
}
return false;
}
// This is very unlikely, and probably impossible, but if the current display is
// DEFAULT_DISPLAY and the displayId to mirror results in an invalid display, we don't want
// to mirror the DEFAULT_DISPLAY so instead we just return
DisplayContent mirrorDc = mRootWindowContainer.getDisplayContentOrCreate(mirrorDisplayId);
if (mirrorDc == null && mDisplayId == DEFAULT_DISPLAY) {
ProtoLog.w(WM_DEBUG_CONTENT_RECORDING,
"Content Recording: Found no matching mirror display for id=%d for "
+ "DEFAULT_DISPLAY. Nothing to mirror.",
mirrorDisplayId);
return false;
}
if (mirrorDc == null) {
mirrorDc = mRootWindowContainer.getDefaultDisplay();
ProtoLog.w(WM_DEBUG_CONTENT_RECORDING,
"Content Recording: Attempting to mirror %d from %d but no DisplayContent "
+ "associated. Changing to mirror default display.",
mirrorDisplayId, mDisplayId);
}
// Create a session for mirroring the display content to this virtual display.
ContentRecordingSession session = ContentRecordingSession
.createDisplaySession(mirrorDc.getDisplayId())
.setVirtualDisplayId(mDisplayId);
setContentRecordingSession(session);
ProtoLog.v(WM_DEBUG_CONTENT_RECORDING,
"Content Recording: Successfully created a ContentRecordingSession for "
+ "displayId=%d to mirror content from displayId=%d",
mDisplayId, mirrorDisplayId);
return true;
}