HUD 屏幕上的地图信息显示在主屏。
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 模式由 4 种:车速、地图、环境和全部。当选择车速模式时,HUD 会把两个 SurfaceView 先设置隐藏,再把宽度设置为 0。当设置隐藏时会销毁 SurfaceView 的 layer。再次选择其他模式时,重新新建 SurfaceView 的 layer。
根据 log 复现问题时的操作步骤如下: