DisplayManagerService启动及主屏添加-Android13

DisplayManagerService启动及主屏添加-Android13

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_INTERNALDisplay.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.3 HIDL 接口 (android.hardware.graphics.composer@2.3::IComposerClient) 的 getDisplayIdentificationData 方法,或者针对较旧的 libhardware 实现情况实现相应的 hardware/hwcomposer2.h 函数

  • sf 创建DisplayDeviceSurfaceFlinger::setupNewDisplayDeviceInternal
  • DMS 创建DisplayDevice、DisplayDeviceInfotryConnectDisplayLockedgetDisplayDeviceInfoLocked()

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());
}
相关推荐
Dnelic-33 分钟前
【单元测试】【Android】JUnit 4 和 JUnit 5 的差异记录
android·junit·单元测试·android studio·自学笔记
Eastsea.Chen3 小时前
MTK Android12 user版本MtkLogger
android·framework
长亭外的少年10 小时前
Kotlin 编译失败问题及解决方案:从守护进程到 Gradle 配置
android·开发语言·kotlin
建群新人小猿13 小时前
会员等级经验问题
android·开发语言·前端·javascript·php
1024小神14 小时前
tauri2.0版本开发苹果ios和安卓android应用,环境搭建和最后编译为apk
android·ios·tauri
兰琛14 小时前
20241121 android中树结构列表(使用recyclerView实现)
android·gitee
Y多了个想法15 小时前
RK3568 android11 适配敦泰触摸屏 FocalTech-ft5526
android·rk3568·触摸屏·tp·敦泰·focaltech·ft5526
NotesChapter16 小时前
Android吸顶效果,并有着ViewPager左右切换
android
_祝你今天愉快17 小时前
分析android :The binary version of its metadata is 1.8.0, expected version is 1.5.
android
暮志未晚Webgl17 小时前
109. UE5 GAS RPG 实现检查点的存档功能
android·java·ue5