我是靠谱客的博主 温暖美女,最近开发中收集的这篇文章主要介绍Android P图形架构之DisplayManagerService解析,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

顾名思义,DisplayManagerService是一个用于管理显示的服务。

源码:
frameworksbaseservicesjavacomandroidserverSystemServer.java
frameworksbaseservicescorejavacomandroidserverdisplayDisplayManagerService.java
frameworksbaseservicescorejavacomandroidserverdisplayDisplayDevice.java
frameworksbaseservicescorejavacomandroidserverdisplayLogicalDisplay.java

作用:

  • 管理显示器的全局生命周期, 决定如何根据当前连接的物理显示设备配置逻辑显示,在状态更改时向系统和应用程序发送通知等
  • 显示管理服务依赖于DisplayAdapter(LocalDisplayAdapter,OverlayDisplayAdapter,WifiDisplayAdapter)用于发现和配置连接到系统的物理显示设备
  • 设备连接的方式都有单独的DisplayAdapter,一个本地显示器的适配器,用于模拟无头系统(不接显示器)的非功能显示;一个用于开发的模拟overlay显示器;一个用wifi显示器
  • 显示适配器仅与显示管理器服务弱耦合
  • 显示适配器通过显示管理器服务注册的DisplayAdapter.Listener异步地将显示设备状态的变化传送到显示管理器服务

启动过程:
DisplayManagerService是在SystemServer中启动的。
frameworksbaseservicesjavacomandroidserverSystemServer.java

private void startBootstrapServices() {
	//...
	
	// Display manager is needed to provide display metrics before package manager
	// starts up.
	traceBeginAndSlog("StartDisplayManager");
	mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
	traceEnd();

	//...
}

代码分析:

LocalDisplayAdapter

DisplayManagerService的onStart()中发送了消息MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS,去执行了registerDefaultDisplayAdapters(),初始化了主屏显示器适配器LocalDisplayAdapter

@Override
public void onStart() {
    // We need to pre-load the persistent data store so it's ready before the default display
    // adapter is up so that we have it's configuration. We could load it lazily, but since
    // we're going to have to read it in eventually we may as well do it here rather than after
    // we've waited for the display to register itself with us.
synchronized(mSyncRoot) {
mPersistentDataStore.loadIfNeeded();
loadStableDisplayValuesLocked();
    }
    mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS);

    publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
            true /*allowIsolated*/);
    publishLocalService(DisplayManagerInternal.class, new LocalService());
    publishLocalService(DisplayTransformManager.class, new DisplayTransformManager());
}

//加载LocalDisplayAdapter和getVirtualDisplayAdapter
private void registerDefaultDisplayAdapters() {
    // Register default display adapters.
    synchronized (mSyncRoot) {
        // main display adapter
        registerDisplayAdapterLocked(new LocalDisplayAdapter(
                mSyncRoot, mContext, mHandler, mDisplayAdapterListener));

        // Standalone VR devices rely on a virtual display as their primary display for
        // 2D UI. We register virtual display adapter along side the main display adapter
        // here so that it is ready by the time the system sends the home Intent for
        // early apps like SetupWizard/Launcher. In particular, SUW is displayed using
        // the virtual display inside VR before any VR-specific apps even run.
        mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext,
                mHandler, mDisplayAdapterListener);
        if (mVirtualDisplayAdapter != null) {
            registerDisplayAdapterLocked(mVirtualDisplayAdapter);
        }
    }
}

registerDisplayAdapterLocked把适配器放入了mDisplayAdapters中,并且执行了LocalDisplayAdapter的registerLocked();

// List of all currently registered display adapters.
private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();

private void registerDisplayAdapterLocked(DisplayAdapter adapter) {
    mDisplayAdapters.add(adapter);
    adapter.registerLocked();
}

LocalDisplayAdapter中则去调用SurfaceFlinger获取物理显示屏的信息,并返回给DisplayManagerService,最终执行了handleDisplayDeviceAddedLocked(),来添加显示器设备。
frameworksbaseservicescorejavacomandroidserverdisplayLocalDisplayAdapter.java

@Override
public void registerLocked() {
    super.registerLocked();

    mHotplugReceiver = new HotplugDisplayEventReceiver(getHandler().getLooper());

    for (int builtInDisplayId : BUILT_IN_DISPLAY_IDS_TO_SCAN) {
        tryConnectDisplayLocked(builtInDisplayId);
    }
}

添加显示器:

// List of all currently connected display devices.
private final ArrayList<DisplayDevice> mDisplayDevices = new ArrayList<DisplayDevice>();

private void handleDisplayDeviceAddedLocked(DisplayDevice device) {
    DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
    if (mDisplayDevices.contains(device)) {
        Slog.w(TAG, "Attempted to add already added display device: " + info);
        return;
    }

    Slog.i(TAG, "Display device added: " + info);
    
    device.mDebugLastLoggedDeviceInfo = info;

    mDisplayDevices.add(device);
    LogicalDisplay display = addLogicalDisplayLocked(device);
    Runnable work = updateDisplayStateLocked(device);
    if (work != null) {
        work.run();
    }
    scheduleTraversalLocked(false);
}

handleDisplayDeviceAddedLocked()会将显示器设备统一放到mDisplayDevices中,并且执行了addLogicalDisplayLocked(),作用是在一个显示设备中添加逻辑显示,assignDisplayIdLocked()分配一个displayId,并且放入mLogicalDisplays中。

// List of all logical displays indexed by logical display id.
private final SparseArray<LogicalDisplay> mLogicalDisplays = new SparseArray<LogicalDisplay>();

// Adds a new logical display based on the given display device.
// Sends notifications if needed.
private LogicalDisplay addLogicalDisplayLocked(DisplayDevice device) {
    DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked();
    boolean isDefault = (deviceInfo.flags
            & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0;
    if (isDefault && mLogicalDisplays.get(Display.DEFAULT_DISPLAY) != null) {
        Slog.w(TAG, "Ignoring attempt to add a second default display: " + deviceInfo);
        isDefault = false;
    }

    if (!isDefault && mSingleDisplayDemoMode) {
        Slog.i(TAG, "Not creating a logical display for a secondary display "
                + " because single display demo mode is enabled: " + deviceInfo);
        return null;
    }

    final int displayId = assignDisplayIdLocked(isDefault);
    final int layerStack = assignLayerStackLocked(displayId);

    LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device);
    display.updateLocked(mDisplayDevices);
    if (!display.isValidLocked()) {
        // This should never happen currently.
        Slog.w(TAG, "Ignoring display device because the logical display "
                + "created from it was not considered valid: " + deviceInfo);
        return null;
    }

    configureColorModeLocked(display, device);
    if (isDefault) {
        recordStableDisplayStatsIfNeededLocked(display);
        recordTopInsetLocked(display);
    }

    mLogicalDisplays.put(displayId, display);

    // Wake up waitForDefaultDisplay.
    if (isDefault) {
        mSyncRoot.notifyAll();
    }

    sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED);
    return display;
}

OverlayDisplayAdapter、WifiDisplayAdapter

DisplayManagerService的systemReady()中,发送了MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS,并执行了registerAdditionalDisplayAdapters(),在registerAdditionalDisplayAdapters中完成了OverlayDisplayAdapter和WifiDisplayAdapter的注册。

/**
 * Called when the system is ready to go.
 */
public void systemReady(boolean safeMode, boolean onlyCore) {
    synchronized (mSyncRoot) {
        mSafeMode = safeMode;
        mOnlyCore = onlyCore;
        mSystemReady = true;
        // Just in case the top inset changed before the system was ready. At this point, any
        // relevant configuration should be in place.
        recordTopInsetLocked(mLogicalDisplays.get(Display.DEFAULT_DISPLAY));
    }

    mHandler.sendEmptyMessage(MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS);
    mHandler.sendEmptyMessage(MSG_REGISTER_BRIGHTNESS_TRACKER);
}

private void registerAdditionalDisplayAdapters() {
    synchronized (mSyncRoot) {
        if (shouldRegisterNonEssentialDisplayAdaptersLocked()) {
            registerOverlayDisplayAdapterLocked();
            registerWifiDisplayAdapterLocked();
        }
    }
}

跟LocalDisplayAdapter流程类似:

private void registerOverlayDisplayAdapterLocked() {
    registerDisplayAdapterLocked(new OverlayDisplayAdapter(
            mSyncRoot, mContext, mHandler, mDisplayAdapterListener, mUiHandler));
}

private void registerWifiDisplayAdapterLocked() {
    if (mContext.getResources().getBoolean(
            com.android.internal.R.bool.config_enableWifiDisplay)
            || SystemProperties.getInt(FORCE_WIFI_DISPLAY_ENABLE, -1) == 1) {
        mWifiDisplayAdapter = new WifiDisplayAdapter(
                mSyncRoot, mContext, mHandler, mDisplayAdapterListener,
                mPersistentDataStore);
        registerDisplayAdapterLocked(mWifiDisplayAdapter);
    }
}

VirtualDisplayAdapter

在加载LocalDisplayAdapter的时候就加载了虚拟显示适配器,因为虚拟显示必须依赖于物理屏。
DisplayManagerService的onstart()中执行的,getVirtualDisplayAdapter(),加载虚拟屏。

private void registerDefaultDisplayAdapters() {
    // Register default display adapters.
    synchronized (mSyncRoot) {
        // main display adapter
        registerDisplayAdapterLocked(new LocalDisplayAdapter(
                mSyncRoot, mContext, mHandler, mDisplayAdapterListener));

        // Standalone VR devices rely on a virtual display as their primary display for
        // 2D UI. We register virtual display adapter along side the main display adapter
        // here so that it is ready by the time the system sends the home Intent for
        // early apps like SetupWizard/Launcher. In particular, SUW is displayed using
        // the virtual display inside VR before any VR-specific apps even run.
        mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext,
                mHandler, mDisplayAdapterListener);
        if (mVirtualDisplayAdapter != null) {
            registerDisplayAdapterLocked(mVirtualDisplayAdapter);
        }
    }
}

@VisibleForTesting
static class Injector {
    VirtualDisplayAdapter getVirtualDisplayAdapter(SyncRoot syncRoot, Context context,
            Handler handler, DisplayAdapter.Listener displayAdapterListener) {
        return new VirtualDisplayAdapter(syncRoot, context, handler, displayAdapterListener);
    }

    long getDefaultDisplayDelayTimeout() {
        return WAIT_FOR_DEFAULT_DISPLAY_TIMEOUT;
    }
}

最后

以上就是温暖美女为你收集整理的Android P图形架构之DisplayManagerService解析的全部内容,希望文章能够帮你解决Android P图形架构之DisplayManagerService解析所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(65)

评论列表共有 0 条评论

立即
投稿
返回
顶部