问题现象

629e1c4f-298b-43da-8da5-e999c98749fb.jpeg

HUD 屏幕上的地图信息显示在主屏。

Issue-Id: http://jira.it.chehejia.com/browse/XHMI-72353

问题分析

直接原因

HUD 屏幕上内容由 HUD 应用显示,它在一个 Activity 上使用两个 SurfaceView 分别显示了地图信息的 EID 信息。

问题发生时地图信息在主屏上显示,说明显示地图的 SurfaceView 的 layer stack(屏幕信息)错了。获取 layer stack 的实现是,如果该 layer 存在父 layer,则获取父 layer 的 layer stack,直到没有父 layer。

ui::LayerStack Layer::getLayerStack()const {
    if (constauto parent = mDrawingParent.promote()) {
        return parent->getLayerStack();
    }
    return getDrawingState().layerStack;
}

同时,如果一个 layer 存在父 layer,则不能给该 layer 设置 layer stack。

uint32_t SurfaceFlinger::setClientStateLocked(const FrameTimelineInfo&frameTimelineInfo,
                                              ComposerState&composerState,
int64_tdesiredPresentTime,boolisAutoTimestamp,
int64_tpostTime,uint32_tpermissions) {
    ...
    if (what &layer_state_t::eLayerStackChanged) {
ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
// We only allow setting layer stacks for top level layers,// everything else inherits layer stack from its parent.
        if (layer->hasParent()) {
            ALOGE("Attempt to set layer stack on layer with parent (%s) is invalid",
                  layer->getDebugName());
        } ...

因此,HUD 上的 SurfaceView 的 layer 的 layer stack 是默认值,即 0。它是因为 layer 的组织结构在显示在 HUD 屏(ID 是 2)上的,如下所示:

HUD Display layer (layer stack 2) -> HUD Activity layer -> SurfaceView layer

HUD 设置

在车辆设置中的 HUD 模式由 4 种:车速、地图、环境和全部。当选择车速模式时,HUD 会把两个 SurfaceView 先设置隐藏,再把宽度设置为 0。当设置隐藏时会销毁 SurfaceView 的 layer。再次选择其他模式时,重新新建 SurfaceView 的 layer。

操作步骤

根据 log 复现问题时的操作步骤如下: