本文从Android Java层讲解Android Display相关类的初始化。
整体流程如下:
Display Device Discover
1. DisplayAdapter获得DisplayDevice
DisplayManagerService中取得DisplayDevice
LocalDisplayAdapter从BUILT_IN_DISPLAY_IDS_TO_SCAN中获得DISPLAY ID往SurfaceFlinger中查询Display信息(tryConnectDisplayLocked)
private static final int[] BUILT_IN_DISPLAY_IDS_TO_SCAN = new int[] {
SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN,
SurfaceControl.BUILT_IN_DISPLAY_ID_HDMI,
};
private void tryConnectDisplayLocked(int builtInDisplayId) {
//通过display id号去SurfaceFlinger里获得对应的Binder token号
IBinder displayToken = SurfaceControl.getBuiltInDisplay(builtInDisplayId);
if (displayToken != null) {
//通过token号再去SurfaceFlinger获得物理显示器的相关信息
SurfaceControl.PhysicalDisplayInfo[] configs =
SurfaceControl.getDisplayConfigs(displayToken);
int activeConfig = SurfaceControl.getActiveConfig(displayToken);
int activeColorMode = SurfaceControl.getActiveColorMode(displayToken);
int[] colorModes = SurfaceControl.getDisplayColorModes(displayToken);
LocalDisplayDevice device = mDevices.get(builtInDisplayId);
if (device == null) {
// Display was added.
device = new LocalDisplayDevice(displayToken, builtInDisplayId,
configs, activeConfig, colorModes, activeColorMode);
mDevices.put(builtInDisplayId, device);
sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);
} else {
...
}
} else {
...
}
}
系统启动时,LocalDisplayAdapter的mDevices并没有保存相关DisplayDevice的信息,所以tryConnectDisplayLocked会直接生成一个新的DisplayDevice,然后加入到LocalDisplayAdapter.mDevices中去, 如 图中标注1 所示, 最后发送一个DISPLAY_DEVICE_EVENT_ADDED信号通过Display已经加入了。
接下来看下LocalDisplayDevice的初始化函数
public LocalDisplayDevice(IBinder displayToken, int builtInDisplayId,
SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo,
int[] colorModes, int activeColorMode) {
//储存信息
super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + builtInDisplayId);
//当前LocalDisplayDevice的Display ID号是多少
mBuiltInDisplayId = builtInDisplayId;
updatePhysicalDisplayInfoLocked(physicalDisplayInfos, activeDisplayInfo,
colorModes, activeColorMode);
...
}
LocalDisplayDevice继承于DisplayDevice, 首先通过super函数将一些信息存储在DisplayDevice中,比如与SurfaceFlinger通信的Display Token, uniq ID等
然后又通过updatePhysicalDisplayInfoLocked去更新物理显示屏的信息到具体的类中, 如 图中标注2 所示。
public boolean updatePhysicalDisplayInfoLocked(
SurfaceControl.PhysicalDisplayInfo[] physicalDisplayInfos, int activeDisplayInfo,
int[] colorModes, int activeColorMode) {
//将从SurfaceFlinger获得的物理显示屏的信息全部保存在mDisplayInfos里
mDisplayInfos = Arrays.copyOf(physicalDisplayInfos, physicalDisplayInfos.length);
// mActivePhysIndex 指的是当前 Activity 的配置
mActivePhysIndex = activeDisplayInfo;
ArrayList records = new ArrayList();
boolean modesAdded = false;
f