相关源码:
\frameworks\base\core\java\android\view\SurfaceControl.java
\frameworks\base\services\core\java\com\android\server\display\LocalDisplayAdapter.java
\frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp
frameworks\native\services\surfaceflinger\DisplayHardware\HWComposer.h
\hardware\libhardware\include\hardware\hwcomposer_defs.h
\vendor\nxp-opensource\imx\display\hwcomposer_v20\hwcomposer.cpp
\vendor\nxp-opensource\imx\display\display\DisplayManager.cpp

我们都知道安卓支持多屏异显。但是android 9.0系统中,默认只加载了两个物理屏和一个虚拟屏。

具体资料可以参考谷歌官方资料:
https://developer.android.com/guide/topics/ui/multi-window
https://developer.android.com/about/versions/oreo/android-8.0

参考文章:
《Android P实现双屏异显》
《Android P图形架构之SurfaceFlinger加载显示屏流程》

android 9.0显示屏的定义:

  • display 0 主屏
  • display 1 副屏(辅助屏)
  • display 2 虚拟屏(显示display 1上)

增加第三块屏后的定义:

  • display 0 主屏
  • display 1 副屏(辅助屏)
  • display 2 扩展屏(第三块屏)
  • display 3 虚拟屏(显示display 1或者display 2上)

Framework层

1、SurfaceControl中,增加第三块屏的定义:
\frameworks\base\core\java\android\view\SurfaceControl.java

/** * Built-in physical display id: Main display. * Use only with {@link SurfaceControl#getBuiltInDisplay(int)}. */public static final int BUILT_IN_DISPLAY_ID_MAIN = 0;/*** Built-in physical display id: Attached HDMI display.* Use only with {@link SurfaceControl#getBuiltInDisplay(int)}.*/public static final int BUILT_IN_DISPLAY_ID_HDMI = 1;//add by sunxiaolin 20190906public static final int BUILT_IN_DISPLAY_ID_THIRD = 2;2、LocalDisplayAdapter中,增加第三块屏的逻辑处理:\frameworks\base\services\core\java\com\android\server\display\LocalDisplayAdapter.javaprivate static final int[] BUILT_IN_DISPLAY_IDS_TO_SCAN = new int[] {        SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN,        SurfaceControl.BUILT_IN_DISPLAY_ID_HDMI,        SurfaceControl.BUILT_IN_DISPLAY_ID_THIRD,//add by sunxiaolin 20190906};@Overridepublic void registerLocked() {    super.registerLocked();    mHotplugReceiver = new HotplugDisplayEventReceiver(getHandler().getLooper());    for (int builtInDisplayId : BUILT_IN_DISPLAY_IDS_TO_SCAN) {        tryConnectDisplayLocked(builtInDisplayId);    }}

3、SurfaceFlinger中,增加第三块屏的逻辑处理:
\frameworks\native\services\surfaceflinger\SurfaceFlinger.cpp

DisplayDevice::DisplayType SurfaceFlinger::determineDisplayType(hwc2_display_t display,                                                                HWC2::Connection connection) const {    // Figure out whether the event is for the primary display or an    // external display by matching the Hwc display id against one for a    // connected display. If we did not find a match, we then check what    // displays are not already connected to determine the type. If we don't    // have a connected primary display, we assume the new display is meant to    // be the primary display, and then if we don't have an external display,    // we assume it is that.    ALOGI("sunxiaolin determineDisplayType");    const auto primaryDisplayId = getBE().mHwc->getHwcDisplayId(DisplayDevice::DISPLAY_PRIMARY);    const auto externalDisplayId = getBE().mHwc->getHwcDisplayId(DisplayDevice::DISPLAY_EXTERNAL);    const auto thirdDisplayId = getBE().mHwc->getHwcDisplayId(DisplayDevice::DISPLAY_THIRD);    if (primaryDisplayId && primaryDisplayId == display) {ALOGI("sunxiaolin determineDisplayType primaryDisplayId");        return DisplayDevice::DISPLAY_PRIMARY;    } else if (externalDisplayId && externalDisplayId == display) {ALOGI("sunxiaolin determineDisplayType externalDisplayId");        return  DisplayDevice::DISPLAY_EXTERNAL;    } else if (thirdDisplayId && thirdDisplayId == display) {ALOGI("sunxiaolin determineDisplayType thirdDisplayId");        return  DisplayDevice::DISPLAY_THIRD;    } else if (connection == HWC2::Connection::Connected && !primaryDisplayId) {ALOGI("sunxiaolin determineDisplayType primaryDisplayId2");        return DisplayDevice::DISPLAY_PRIMARY;    } else if (connection == HWC2::Connection::Connected && !externalDisplayId) {ALOGI("sunxiaolin determineDisplayType externalDisplayId2");        return DisplayDevice::DISPLAY_EXTERNAL;    } else if (connection == HWC2::Connection::Connected && !thirdDisplayId) {ALOGI("sunxiaolin determineDisplayType thirdDisplayId2");        return DisplayDevice::DISPLAY_THIRD;    }    return DisplayDevice::DISPLAY_ID_INVALID;}void SurfaceFlinger::processDisplayHotplugEventsLocked() {    for (const auto& event : mPendingHotplugEvents) {        auto displayType = determineDisplayType(event.display, event.connection);        if (displayType == DisplayDevice::DISPLAY_ID_INVALID) {            ALOGW("Unable to determine the display type for display %" PRIu64, event.display);            continue;        }        if (getBE().mHwc->isUsingVrComposer() && displayType == DisplayDevice::DISPLAY_EXTERNAL) {            ALOGE("External displays are not supported by the vr hardware composer.");            continue;        }        getBE().mHwc->onHotplug(event.display, displayType, event.connection);ALOGI("sunxiaolin processDisplayHotplugEventsLocked displayType=%d",displayType);        if (event.connection == HWC2::Connection::Connected) {            if (!mBuiltinDisplays[displayType].get()) {                ALOGV("sunxiaolin,Creating built in display %d", displayType);                mBuiltinDisplays[displayType] = new BBinder();                // All non-virtual displays are currently considered secure.                DisplayDeviceState info(displayType, true);                //处理第三块屏                if( displayType == DisplayDevice::DISPLAY_THIRD ){info.displayName = "THIRD Screen";}else{ info.displayName = displayType == DisplayDevice::DISPLAY_PRIMARY ?                        "Built-in Screen" : "External Screen";}                mCurrentState.displays.add(mBuiltinDisplays[displayType], info);                mInterceptor->saveDisplayCreation(info);            }        } else {            ALOGV("Removing built in display %d", displayType);            ssize_t idx = mCurrentState.displays.indexOfKey(mBuiltinDisplays[displayType]);            if (idx >= 0) {                const DisplayDeviceState& info(mCurrentState.displays.valueAt(idx));                mInterceptor->saveDisplayDeletion(info.displayId);                mCurrentState.displays.removeItemsAt(idx);            }            mBuiltinDisplays[displayType].clear();        }        processDisplayChangesLocked();    }    mPendingHotplugEvents.clear();}

4、修改虚拟屏的判断,增加一块屏将2改成3,即display 3是虚拟屏

 static const int32_t VIRTUAL_DISPLAY_ID_BASE = 3;

HAL层

HAL层中,也需要修改显示屏的定义,即display 0,1,2修改成display 0,1,2,3:
源码:hardware\libhardware\include\hardware\hwcomposer_defs.h

/* Display types and associated mask bits. */enum {    HWC_DISPLAY_PRIMARY     = 0,    HWC_DISPLAY_EXTERNAL    = 1,    // HDMI, DP, etc.        //add by sunxiaolin 20190906    HWC_DISPLAY_THIRD       = 2,// the third display     HWC_DISPLAY_VIRTUAL     = 3,//modiy start by sunxiaolin 20190906    HWC_NUM_PHYSICAL_DISPLAY_TYPES = 3, // value 2 --> 3    HWC_NUM_DISPLAY_TYPES          = 4,// value 3 --> 4    //modiy end by sunxiaolin 20190906};

驱动层

最终是驱动层将屏的相关信息,通过HAL层,发送给SurfaceFlinger中。

display中获取显示屏的处理:
\vendor\nxp-opensource\imx\display\hwcomposer_v20\hwcomposer.cpp

//主屏的初始化,回调给SurfaceFlingerstatic int hwc2_register_callback(hwc2_device_t* device, int32_t descriptor,                                  hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer){    if (!device) {        ALOGE("%s invalid device", __func__);        return HWC2_ERROR_BAD_PARAMETER;    }    struct hwc2_context_t *ctx = (struct hwc2_context_t*)device;    switch (descriptor) {        case HWC2_CALLBACK_HOTPLUG:            ctx->mHotplug = reinterpret_cast<HWC2_PFN_HOTPLUG>(pointer);            ctx->mHotplugData = callbackData;            break;        case HWC2_CALLBACK_REFRESH:            ctx->mRefresh = reinterpret_cast<HWC2_PFN_REFRESH>(pointer);            ctx->mRefreshData = callbackData;            break;        case HWC2_CALLBACK_VSYNC:            ctx->mVsync = reinterpret_cast<HWC2_PFN_VSYNC>(pointer);            ctx->mVsyncData = callbackData;            break;    }    DisplayManager::getInstance()->setCallback(ctx->mListener);    if (descriptor == HWC2_CALLBACK_HOTPLUG && pointer != NULL) {ALOGI("sunxiaolin,hwc2_register_callback HWC_DISPLAY_PRIMARY");        ctx->mListener->onHotplug(HWC_DISPLAY_PRIMARY, true);    }    return HWC2_ERROR_NONE;}//副屏的初始化,回调给SurfaceFlingerstatic int hwc2_present_display(hwc2_device_t* device, hwc2_display_t display,                                int32_t* outPresentFence){    if (!device) {        ALOGE("%s invalid device", __func__);        return HWC2_ERROR_BAD_PARAMETER;    }    Display* pDisplay = NULL;    DisplayManager* displayManager = DisplayManager::getInstance();    pDisplay = displayManager->getDisplay(display);    if (pDisplay == NULL) {        ALOGE("%s invalid display id:%" PRId64, __func__, display);        return HWC2_ERROR_BAD_DISPLAY;    }    pDisplay->composeLayers();    pDisplay->updateScreen();    if (outPresentFence != NULL) {        pDisplay->getPresentFence(outPresentFence);    }    struct hwc2_context_t *ctx = (struct hwc2_context_t*)device;    if (ctx->checkHDMI && ctx->mHotplug != NULL && ctx->mVsync != NULL) {        ctx->checkHDMI = false;        Display* fb = displayManager->getPhysicalDisplay(HWC_DISPLAY_EXTERNAL);        ALOGI("sunxiaolin,hwc2_present_display HWC_DISPLAY_EXTERNAL");        ctx->mListener->onHotplug(HWC_DISPLAY_EXTERNAL, fb->connected());                //增加第三块屏(扩展平),回调给SurfaceFlinger        ctx->checkHDMI = false;        Display* fb2 = displayManager->getPhysicalDisplay(HWC_DISPLAY_THIRD);        ALOGI("sunxiaolin,hwc2_present_display HWC_DISPLAY_THIRD");        ctx->mListener->onHotplug(HWC_DISPLAY_THIRD, fb2->connected());    }    return HWC2_ERROR_NONE;}//回调给HAL层,在给到SurfaceFlinger.sovoid DisplayListener::onHotplug(int disp, bool connected){ALOGI("sunxiaolin,onHotplug disp=%d,connected=%d",disp,connected);    if (mCtx == NULL || mCtx->mHotplug == NULL) {        return;    }    hwc2_connection_t connection = connected ? HWC2_CONNECTION_CONNECTED                                             : HWC2_CONNECTION_DISCONNECTED;    mCtx->mHotplug(mCtx->mHotplugData, disp, connection);}

重点:
Display* fb = displayManager->getPhysicalDisplay(HWC_DISPLAY_EXTERNAL);
Display* fb2 = displayManager->getPhysicalDisplay(HWC_DISPLAY_THIRD);

DisplayManager中管理者显示屏,前提是kernel里已经加载了第三块显示屏驱动:
\vendor\nxp-opensource\imx\display\display\DisplayManager.cpp

#define MAX_PHYSICAL_DISPLAY 10#define MAX_VIRTUAL_DISPLAY  16Display* DisplayManager::getPhysicalDisplay(int id){    Mutex::Autolock _l(mLock);    if (id < 0 || id >= MAX_PHYSICAL_DISPLAY) {        ALOGE("%s invalid id %d", __func__, __LINE__);        return NULL;    }ALOGI("%s %d sunxiaolin id=%d", __func__, __LINE__,id);    if (mDrmMode) {        return mKmsDisplays[id];    }    return mFbDisplays[id];}

更多相关文章

  1. Android(安卓)Studio 创建虚拟机失败 Failed to load 解决办法
  2. Android(安卓)tp的虚拟按键(virtual key)处理
  3. Android(安卓)平台简介
  4. Android的系统构架
  5. 《Android(安卓)Dev Guide》系列教程1:什么是Android?
  6. 隐藏Android底部的虚拟按键
  7. android:inputType标签
  8. jdk及android studio环境变量配置
  9. android:inputType标签

随机推荐

  1. android中ColorStateList及StateListDraw
  2. android对象池之Message
  3. Android Framework 修改设备连接电脑时的
  4. 【Android笔记】探究活动②使用Intent在
  5. Android SVG 兼容低版本API
  6. android studio 删除、导入jar包
  7. eclipse下 Failed to find an AVD compat
  8. Android对话框
  9. eclipse android 错误列表
  10. android从xml创建控件(按钮)或直接创建控件