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());
}
相关推荐
Dingdangr2 小时前
Android中的Intent的作用
android
技术无疆2 小时前
快速开发与维护:探索 AndroidAnnotations
android·java·android studio·android-studio·androidx·代码注入
GEEKVIP2 小时前
Android 恢复挑战和解决方案:如何从 Android 设备恢复删除的文件
android·笔记·安全·macos·智能手机·电脑·笔记本电脑
Jouzzy9 小时前
【Android安全】Ubuntu 16.04安装GDB和GEF
android·ubuntu·gdb
极客先躯10 小时前
java和kotlin 可以同时运行吗
android·java·开发语言·kotlin·同时运行
Good_tea_h12 小时前
Android中的单例模式
android·单例模式
计算机源码社17 小时前
分享一个基于微信小程序的居家养老服务小程序 养老服务预约安卓app uniapp(源码、调试、LW、开题、PPT)
android·微信小程序·uni-app·毕业设计项目·毕业设计源码·计算机课程设计·计算机毕业设计开题
丶白泽17 小时前
重修设计模式-结构型-门面模式
android
晨春计19 小时前
【git】
android·linux·git
标标大人20 小时前
c语言中的局部跳转以及全局跳转
android·c语言·开发语言