DisplayManagerService启动及主屏添加-Android13
DisplayManagerService启动及主屏添加-Android13
- 1、DisplayManagerService启动
- 1.1 简要时序图
- 2、DEFAULT_DISPLAY主屏幕添加
- 2.1 物理屏热插拔监听
- 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主屏幕添加
AOSP > 文档 > 核心主题 > 显示屏支持
在 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
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 itSlog.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.3
HIDL 接口 (android.hardware.graphics.composer@2.3::IComposerClient
) 的getDisplayIdentificationData
方法,或者针对较旧的libhardware
实现情况实现相应的hardware/hwcomposer2.h
函数
sf
创建DisplayDevice:SurfaceFlinger::setupNewDisplayDeviceInternal
DMS
创建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
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());
}