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.FrameRateOverride0
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());
}
相关推荐
恋猫de小郭19 小时前
AndroidX 新增 Security State ,支持可编程的系统安全状态查询
android·前端·flutter
AFinalStone19 小时前
Android7 SystemUI 源码解析(六)QuickSettings快捷设置面板
android·systemui
Kapaseker19 小时前
你有搞明白 Volatile 什么意思吗?
android·kotlin
美狐美颜SDK开放平台19 小时前
直播APP源码与视频美颜sdk如何配合?一套完整开发思路
android·人工智能·计算机视觉·音视频·直播美颜sdk
心平气和量大福大20 小时前
android-权限
android·java
2501_9160088920 小时前
怎么用 Godot 导出 iOS 应用并上架 App Store?签名字段该填什么?
android·ios·小程序·https·uni-app·iphone·webview
智慧物业老杨1 天前
物业日常巡查的数智化重构:从“打卡式巡检“到“闭环式风控“
android·java·人工智能·系统架构·rxjava
alexhilton1 天前
藏在设备上的秘密,终究藏不住
android·kotlin·android jetpack
hai_android1 天前
Kotlin / Android 常用函数使用示例手册
android·java·kotlin
hai_android1 天前
Android MeasureSpec 详解
android·java·kotlin