DisplayManagerService启动及主屏添加-Android13
- 1、DisplayManagerService启动
-
- [1.1 简要时序图](#1.1 简要时序图)
- 2、DEFAULT_DISPLAY主屏幕添加
-
- [2.1 物理屏热插拔监听](#2.1 物理屏热插拔监听)
- [2.2 物理屏信息](#2.2 物理屏信息)
- 3、默认屏幕亮度
1、DisplayManagerService启动
1.1 简要时序图
代码位置:frameworks/base/services/core/java/com/android/server/display
frameworks/native/services/displayservice
frameworks/native/services/surfaceflinger
1、多屏幕相关:DisplayDeviceRepository.java、LogicalDisplayMapper.java、LocalDisplayAdapter.java、DisplayEventReceiver.java
屏幕类型 静态屏幕标识符 相关类 本地 local:<stable-id> LocalDisplayAdapter.java 网络 network:<mac-address> WifiDisplayAdapter.java 虚拟 virtual:<package-name-and-name> VirtualDisplayAdapter.java 叠加 overlay:<number> OverlayDisplayAdapter.java,开发者选项中模拟辅助显示设备开启 2、屏幕亮度相关:BrightnessSynchronizer.java

2、DEFAULT_DISPLAY主屏幕添加
在 Android 11 中, 启动期间报告的第一个屏幕是主屏幕。这与连接类型是内部还是外部并不相关。 不过,主屏幕是不能断开连接的,由此可见,实际操作中的主屏幕必须是内部屏幕。请注意,一些可折叠手机有多个内部屏幕。
辅助屏幕已正确分类为
Display.TYPE_INTERNAL或Display.TYPE_EXTERNAL(以前分别称为 Display.TYPE_BUILT_IN 和 Display.TYPE_HDMI),具体取决于连接类型。在 Android 9 及更低版本中,屏幕使用 32 位 ID 表示 ,其中 0 表示内部屏幕,1 表示外部屏幕,[2, INT32_MAX] 表示 HWC 虚拟屏幕,而 -1 表示无效屏幕或非 HWC 虚拟屏幕。
从 Android 10 开始,屏幕会获得稳定持久的 ID,从而使 SurfaceFlinger 和 DisplayManagerService 可以跟踪两个以上的屏幕并识别以前看到的屏幕。如果 HWC 支持 IComposerClient.getDisplayIdentificationData 并提供屏幕标识数据,SurfaceFlinger 将会解析 EDID 结构并为物理屏幕和 HWC 虚拟屏幕分配稳定的 64 位屏幕 ID。系统会使用选项类型表示 ID,其中 null 值表示无效屏幕或非 HWC 虚拟屏幕。如果 HWC 不支持,SurfaceFlinger 会回退到最多只存在两个物理屏幕的旧版行为。
2.1 物理屏热插拔监听
1、启动注册 LocalDisplayAdapter.registerLocked 时查看添加
tryConnectDisplayLocked(physicalDisplayId)2、
DisplayEventReceiver监听添加屏幕tryConnectDisplayLocked(physicalDisplayId):
- DisplayEventListener监听注册流程
LocalDisplayAdapter.java#mInjector.setDisplayEventListenerLocked(getHandler().getLooper(), new LocalDisplayEventListener()) > DisplayEventReceiver.java#nativeInit > android_view_DisplayEventReceiver.cpp::nativeInit > DisplayEventDispatcher.cpp::mReceiver > DisplayEventReceiver.cpp::mEventConnection > SurfaceFlinger.cpp::createDisplayEventConnection > Scheduler.cpp::createDisplayEventConnection > EventThread.cpp::createEventConnection > new EventThreadConnection- DisplayEventReceiver监听接受流程
HWC::onHotplug > SurfaceFlinger.cpp::dispatchDisplayHotplugEvent > Scheduler.cpp::onHotplugReceived > EventThread.cpp::onHotplugReceived > EventThread::threadMain > EventThread::dispatchEvent > EventThreadConnection::postEvent > DisplayEventReceiver.cpp::sendEvents > gui::BitTube::sendObjects(dataChannel, events, count) > ==LooperCallback== DisplayEventDispatcher.cpp::handleEvent > DisplayEventDispatcher::processPendingEvents > android_view_DisplayEventReceiver.cpp::NativeDisplayEventReceiver::dispatchHotplug > LocalDisplayAdapter.java#ProxyDisplayEventReceiver#onHotplug > LocalDisplayEventListener#onHotplug > LocalDisplayAdapter.java#tryConnectDisplayLocked

frameworks/base/services/core/java/com/android/server/display/LocalDisplayAdapter.java
java
private void tryConnectDisplayLocked(long physicalDisplayId) {
final IBinder displayToken =
mSurfaceControlProxy.getPhysicalDisplayToken(physicalDisplayId);
if (displayToken != null) {
SurfaceControl.StaticDisplayInfo staticInfo =
mSurfaceControlProxy.getStaticDisplayInfo(displayToken);
if (staticInfo == null) {
Slog.w(TAG, "No valid static info found for display device " + physicalDisplayId);
return;
}
SurfaceControl.DynamicDisplayInfo dynamicInfo =
mSurfaceControlProxy.getDynamicDisplayInfo(displayToken);
if (dynamicInfo == null) {
Slog.w(TAG, "No valid dynamic info found for display device " + physicalDisplayId);
return;
}
if (dynamicInfo.supportedDisplayModes == null) {
// There are no valid modes for this device, so we can't use it
Slog.w(TAG, "No valid modes found for display device " + physicalDisplayId);
return;
}
if (dynamicInfo.activeDisplayModeId < 0) {
// There is no active mode, and for now we don't have the
// policy to set one.
Slog.w(TAG, "No valid active mode found for display device " + physicalDisplayId);
return;
}
if (dynamicInfo.activeColorMode < 0) {
// We failed to get the active color mode. We don't bail out here since on the next
// configuration pass we'll go ahead and set it to whatever it was set to last (or
// COLOR_MODE_NATIVE if this is the first configuration).
Slog.w(TAG, "No valid active color mode for display device " + physicalDisplayId);
dynamicInfo.activeColorMode = Display.COLOR_MODE_INVALID;
}
SurfaceControl.DesiredDisplayModeSpecs modeSpecs =
mSurfaceControlProxy.getDesiredDisplayModeSpecs(displayToken);
LocalDisplayDevice device = mDevices.get(physicalDisplayId);
if (device == null) {
// Display was added.
final boolean isFirstDisplay = mDevices.size() == 0;
device = new LocalDisplayDevice(displayToken, physicalDisplayId, staticInfo,
dynamicInfo, modeSpecs, isFirstDisplay);
mDevices.put(physicalDisplayId, device);
sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);
} else if (device.updateDisplayPropertiesLocked(staticInfo, dynamicInfo,
modeSpecs)) {
sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_CHANGED);
}
} else {
// The display is no longer available. Ignore the attempt to add it.
// If it was connected but has already been disconnected, we'll get a
// disconnect event that will remove it from mDevices.
}
}
2.2 物理屏信息
硬件插入显示器
HWC::onHotplug,依赖于Hardware Composer API。设备制造商必须实现IComposerClient 2.3HIDL 接口 (android.hardware.graphics.composer@2.3::IComposerClient) 的getDisplayIdentificationData方法,或者针对较旧的libhardware实现情况实现相应的hardware/hwcomposer2.h函数
sf创建DisplayDevice :SurfaceFlinger::setupNewDisplayDeviceInternalDMS创建DisplayDevice、DisplayDeviceInfo :tryConnectDisplayLocked、getDisplayDeviceInfoLocked()
frameworks/base/services/core/java/com/android/server/display/DisplayDevice.java
frameworks/base/services/core/java/com/android/server/display/DisplayDeviceInfo.java
frameworks/base/services/core/java/com/android/server/display/LogicalDisplay.java
frameworks/base/core/java/android/view/DisplayInfo.java
| DisplayDevice.java | DisplayDeviceInfo.java |
|---|---|
| IBinder mDisplayToken | String name |
| String mUniqueId | String uniqueId |
| DisplayDeviceConfig mDisplayDeviceConfig | int width |
| int mCurrentLayerStack = -1 | int height |
| int mCurrentFlags = 0 | int modeId |
| int mCurrentOrientation = -1 | int defaultModeId |
| Rect mCurrentLayerStackRect | Display.Mode[] supportedModes = Display.Mode.EMPTY_ARRAY |
| Rect mCurrentDisplayRect | int colorMode |
| Context mContext | int[] supportedColorModes = { Display.COLOR_MODE_DEFAULT } |
| Surface mCurrentSurface | Display.HdrCapabilities hdrCapabilities |
| DisplayDeviceInfo mDebugLastLoggedDeviceInfo | boolean allmSupported |
| boolean gameContentTypeSupported | |
| int densityDpi | |
| float xDpi | |
| float yDpi | |
| long appVsyncOffsetNanos | |
| long presentationDeadlineNanos | |
| int flags | |
| DisplayCutout displayCutout | |
| RoundedCorners roundedCorners | |
| int touch | |
| int rotation = Surface.ROTATION_0 | |
| int type | |
| DisplayAddress address | |
| DeviceProductInfo deviceProductInfo | |
| int state = Display.STATE_ON | |
| int ownerUid | |
| String ownerPackageName | |
| DisplayEventReceiver.FrameRateOverride[] frameRateOverrides = new DisplayEventReceiver.FrameRateOverride[0] | |
| float brightnessMinimum | |
| float brightnessMaximum | |
| float brightnessDefault | |
| int installOrientation = Surface.ROTATION_0 |
frameworks/native/libs/ui/include/ui/DisplayIdentification.h
frameworks/native/libs/ui/include/ui/DisplayId.h
frameworks/native/services/surfaceflinger/DisplayDevice.h
frameworks/native/services/surfaceflinger/CompositionEngine/include/compositionengine/DisplayCreationArgs.h
frameworks/native/libs/ui/include/ui/StaticDisplayInfo.h
frameworks/native/libs/ui/include/ui/DynamicDisplayInfo.h
| DisplayIdentificationInfo | DisplayDeviceState | DisplayCreationArgs | DisplayDevice | StaticDisplayInfo | DynamicDisplayInfo |
|---|---|---|---|---|---|
| PhysicalDisplayId id | struct Physical | DisplayId id | constexpr static float sDefaultMinLumiance = 0.0 | DisplayConnectionType connectionType = DisplayConnectionType::Internal | std::vector<ui::DisplayMode> supportedDisplayModes |
| std::string name | int32_t sequenceId = sNextSequenceId++ | ui::Size pixels = ui::kInvalidSize | constexpr static float sDefaultMaxLumiance = 500.0 | float density = 0.f | ui::DisplayModeId activeDisplayModeId |
| std::optional<DeviceProductInfo> deviceProductInfo | std::optional<Physical> physical | bool isSecure = false | const sp<SurfaceFlinger> mFlinger | bool secure = false | std::vector<ui::ColorMode> supportedColorModes |
| sp<IGraphicBufferProducer> surface | Hwc2::PowerAdvisor* powerAdvisor = nullptr | HWComposer& mHwComposer | std::optional<DeviceProductInfo> deviceProductInfo | ||
| ui::LayerStack layerStack | std::string name | const wp<IBinder> mDisplayToken | Rotation installOrientation = ROTATION_0 | ui::ColorMode activeColorMode | |
| uint32_t flags = 0 | const int32_t mSequenceId | HdrCapabilities hdrCapabilities | |||
| Rect layerStackSpaceRect | const std::optional<ui::DisplayConnectionType> mConnectionType | bool autoLowLatencyModeSupported | |||
| Rect orientedDisplaySpaceRect | const std::shared_ptr<compositionengine::Display> mCompositionDisplay | bool gameContentTypeSupported | |||
| ui::Rotation orientation = ui::ROTATION_0 | std::string mDisplayName | ui::DisplayModeId preferredBootDisplayMode | |||
| uint32_t width = 0 | std::string mActiveModeFPSTrace | std::optional<ui::DisplayMode> getActiveDisplayMode() const | |||
| uint32_t height = 0 | std::string mActiveModeFPSHwcTrace | ||||
| std::string displayName | const ui::Rotation mPhysicalOrientation | ||||
| bool isSecure = false | ui::Rotation mOrientation = ui::ROTATION_0 | ||||
| static std::atomic<int32_t> sNextSequenceId | static ui::Transform::RotationFlags sPrimaryDisplayRotationFlags | ||||
| hardware::graphics::composer::hal::PowerMode mPowerMode = hardware::graphics::composer::hal::PowerMode::OFF | |||||
| DisplayModePtr mActiveMode | |||||
| std::optional<float> mStagedBrightness = std::nullopt | |||||
| float mBrightness = -1.f | |||||
| const DisplayModes mSupportedModes | |||||
| std::atomic<nsecs_t> mLastHwVsync = 0 | |||||
| const bool mIsPrimary | |||||
| uint32_t mFlags = 0 | |||||
| std::optional<DeviceProductInfo> mDeviceProductInfo | |||||
| std::vector<ui::Hdr> mOverrideHdrTypes | |||||
| std::shared_ptr<scheduler::RefreshRateConfigs> mRefreshRateConfigs | |||||
| std::unique_ptr<RefreshRateOverlay> mRefreshRateOverlay | |||||
| mutable std::mutex mActiveModeLock | |||||
| ActiveModeInfo mDesiredActiveMode GUARDED_BY(mActiveModeLock) | |||||
| TracedOrdinal<bool> mDesiredActiveModeChanged GUARDED_BY(mActiveModeLock) = {"DesiredActiveModeChanged", false} | |||||
| ActiveModeInfo mUpcomingActiveMode GUARDED_BY(kMainThreadContext) |
3、默认屏幕亮度
frameworks/base/core/java/com/android/internal/display/BrightnessSynchronizer.java
java
public void startSynchronizing() {
if (mDisplayManager == null) {
mDisplayManager = mContext.getSystemService(DisplayManager.class);
}
if (mBrightnessSyncObserver.isObserving()) {
Slog.wtf(TAG, "Brightness sync observer requesting synchronization a second time.");
return;
}
mLatestFloatBrightness = getScreenBrightnessFloat();
mLatestIntBrightness = getScreenBrightnessInt();
Slog.i(TAG, "Initial brightness readings: " + mLatestIntBrightness + "(int), "
+ mLatestFloatBrightness + "(float)");
if (!Float.isNaN(mLatestFloatBrightness)) {
mPendingUpdate = new BrightnessUpdate(BrightnessUpdate.TYPE_FLOAT,
mLatestFloatBrightness);
} else if (mLatestIntBrightness != PowerManager.BRIGHTNESS_INVALID) {
mPendingUpdate = new BrightnessUpdate(BrightnessUpdate.TYPE_INT,
mLatestIntBrightness);
} else {
final float defaultBrightness = mContext.getResources().getFloat(
com.android.internal.R.dimen.config_screenBrightnessSettingDefaultFloat);
mPendingUpdate = new BrightnessUpdate(BrightnessUpdate.TYPE_FLOAT, defaultBrightness);
Slog.i(TAG, "Setting initial brightness to default value of: " + defaultBrightness);
}
mBrightnessSyncObserver.startObserving();
mHandler.sendEmptyMessageAtTime(MSG_RUN_UPDATE, mClock.uptimeMillis());
}