「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战」。
Java层DisplayDevice和Native层DisplayDevice关联流程
在上一篇默认DisplayDevice显示设备加载流程分析中,我们分析了Native层的DisplayDevice显示设备在SurfaceFlinger中的加载,那么在frameworks的Java层,是如何跟这个DisplayDevice进行关联的呢?
我们知道,安卓系统启动中,通过init进程启动zygote进程后,zygote进程会初始化JAVA世界,Java世界的入口是SystemServer对象,在SystemServer对象中会初始化很多系统服务,其中DisplayManagerService服务就是在此时初始化的
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
系统启动流程分析中,我们分析过SystemServiceManager.startService函数,可知,在这个函数中主要是做了
- 调用DisplayManagerService的单参(Context)构造函数来初始化DisplayManagerService对象
- 将上述初始化的DisplayManagerService对象注册到SystemServiceManager.mServices中
- 调用DisplayManagerService的onStart函数
如下,我们重点分析第一/三条步骤
DisplayManagerService对象初始化
public DisplayManagerService(Context context) {
this(context, new Injector());
}
DisplayManagerService(Context context, Injector injector) {
super(context);
mInjector = injector;
mContext = context;
// 初始化DisplayManagerHandler对象
// DisplayManagerHandler类继承自Handler类,注意其传入参数为DisplayThread线程的Looper
mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper());
// 获取Handler对象,这边的Handler对象的Looper为UiThread的Looper
mUiHandler = UiThread.getHandler();
// 初始化DisplayAdapterListener监听显示设备的变化
mDisplayAdapterListener = new DisplayAdapterListener();
// 初始化DisplayModeDirector对象
mDisplayModeDirector = new DisplayModeDirector(context, mHandler);
mSingleDisplayDemoMode = SystemProperties.getBoolean("persist.demo.singledisplay", false);
Resources resources = mContext.getResources();
// 默认值为0
mDefaultDisplayDefaultColorMode = mContext.getResources().getInteger(
com.android.internal.R.integer.config_defaultDisplayDefaultColorMode);
mDefaultDisplayTopInset = SystemProperties.getInt(PROP_DEFAULT_DISPLAY_TOP_INSET, -1);
float[] lux = getFloatArray(resources.obtainTypedArray(
com.android.internal.R.array.config_minimumBrightnessCurveLux));
float[] nits = getFloatArray(resources.obtainTypedArray(
com.android.internal.R.array.config_minimumBrightnessCurveNits));
mMinimumBrightnessCurve = new Curve(lux, nits);
mMinimumBrightnessSpline = Spline.createSpline(lux, nits);
// 获取默认背光亮度
PowerManager pm = mContext.getSystemService(PowerManager.class);
mGlobalDisplayBrightness = pm.getBrightnessConstraint(
PowerManager.BRIGHTNESS_CONSTRAINT_TYPE_DEFAULT);
mCurrentUserId = UserHandle.USER_SYSTEM;
// 从Native层获取data color spaces
ColorSpace[] colorSpaces = SurfaceControl.getCompositionColorSpaces();
mWideColorSpace = colorSpaces[1];
mSystemReady = false;
}
可以看到,在这个函数中主要初始化一些参数,其中的类图关系如下
classDiagram
SystemService <|-- DisplayManagerService
DisplayManagerService o-- Handler
Handler <|-- DisplayModeDirectorHandler
Handler <|-- DisplayManagerHandler
DisplayManagerService o-- DisplayManagerHandler
DisplayManagerService o-- Injector
DisplayManagerService o-- DisplayAdapterListener
DisplayManagerService o-- DisplayModeDirector
Listener <-- DisplayAdapterListener
DisplayAdapter *-- Listener
DisplayModeDirector *-- DisplayModeDirectorHandler
DisplayModeDirector o-- DeviceConfigDisplaySettings
DisplayModeDirector o-- RealInjector
DisplayModeDirector o-- DisplayObserver
DisplayModeDirector o-- BrightnessObserver
DisplayModeDirector o-- SettingsObserver
DisplayModeDirector *-- 2_Injector
OnPropertiesChangedListener <|-- DeviceConfigDisplaySettings
<<interface>> OnPropertiesChangedListener
DeviceConfig *-- OnPropertiesChangedListener
2_Injector <|-- RealInjector
DisplayListener <|-- DisplayObserver
DisplayManager *-- DisplayListener
<<interface>> DisplayListener
ContentObserver <|-- SettingsObserver
ContentObserver <|-- BrightnessObserver
class Injector {
#getVirtualDisplayAdapter(SyncRoot, Context, Handler, DisplayAdapter.Listener)
#getDefaultDisplayDelayTimeout()
}
class DisplayManagerService {
-Injector:mInjector
-Context:mContext
-Handler:mUiHandler
-DisplayManagerHandler:mHandler
-DisplayModeDirector:mDisplayModeDirector
-DisplayAdapterListener:mDisplayAdapterListener
}
class DisplayAdapterListener {
+onDisplayDeviceEvent(DisplayDevice device, int event)
+onTraversalRequested()
}
class UiThread {
-Handler:sHandler
}
class DisplayModeDirector {
-Injector:mInjector
-DisplayModeDirectorHandler:mHandler
-SettingsObserver:mSettingsObserver
-BrightnessObserver:mBrightnessObserver
-DeviceConfigDisplaySettings:mDeviceConfigDisplaySettings
}
class RealInjector {
+getDeviceConfig()
+registerBrightnessObserver(@NonNull ContentResolver, @NonNull ContentObserver
+unregisterBrightnessObserver(@NonNull ContentResolver, @NonNull ContentObserver))
+registerPeakRefreshRateObserver(@NonNull ContentResolver, @NonNull ContentObserver)
}
DisplayManagerService.onStart函数调用
接下来,调用DisplayManagerService的onStart函数来启动服务
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();
}
// 发送注册默认Display的Adapter
mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS);
// If there was a runtime restart then we may have stale caches left around, so we need to
// make sure to invalidate them upon every start.
DisplayManagerGlobal.invalidateLocalDisplayInfoCaches();
// 注册BinderService和LocalService到ServiceManager中
publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
true /*allowIsolated*/);
publishLocalService(DisplayManagerInternal.class, new LocalService());
}
如上代码,我们重点需要关注的是注册默认DisplayAdapters
mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS);
private final class DisplayManagerHandler extends Handler {
public DisplayManagerHandler(Looper looper) {
super(looper, null, true /*async*/);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS:
registerDefaultDisplayAdapters();
break;
// ...... 其他分支代码暂时不会进入,此处省略
}
}
}
private void registerDefaultDisplayAdapters() {
// Register default display adapters.
synchronized (mSyncRoot) {
// main display adapter
// 初始化一个LocalDisplayAdapter,然后注册它
registerDisplayAdapterLocked(new LocalDisplayAdapter(
mSyncRoot, mContext, mHandler, mDisplayAdapterListener));
// ...... 虚拟设备,暂时不看,此处省略
}
}
private void registerDisplayAdapterLocked(DisplayAdapter adapter) {
// 注册到DisplayManagerService.mDisplayAdapters中
mDisplayAdapters.add(adapter);
// 调用LocalDisplayAdapter.registerLocked函数
adapter.registerLocked();
}
可以看到,此处首先将初始化的LocalDisplayAdapter对象注册到DisplayManagerService.mDisplayAdapter 然后调用LocalDisplayAdapter.registerLocked函数继续注册,看其代码
@Override
public void registerLocked() {
super.registerLocked();
// 初始化一个PhysicalDisplayEventReceiver对象
// 注意此处的参数为DisplayManagerService.DisplayManagerHandler对象获取到的Looper
// 响应显示设备变化时的回调函数
mPhysicalDisplayEventReceiver = new PhysicalDisplayEventReceiver(getHandler().getLooper());
// 从Naitve层获取到对应的DisplayIds,然后尝试去连接
for (long physicalDisplayId : SurfaceControl.getPhysicalDisplayIds()) {
tryConnectDisplayLocked(physicalDisplayId);
}
}
此处重点看下for循环中具体做了什么
获取Native层的所有显示设备的DisplayId
public static long[] getPhysicalDisplayIds() {
return nativeGetPhysicalDisplayIds();
}
private static native long[] nativeGetPhysicalDisplayIds();
调用native层的函数nativeGetPhysicalDisplayIds函数,这个函数的注册在
int register_android_view_SurfaceControl(JNIEnv* env)
{
int err = RegisterMethodsOrDie(env, "android/view/SurfaceControl",
sSurfaceControlMethods, NELEM(sSurfaceControlMethods));
// ...... 其他代码和此功能无关,省略
}
static const JNINativeMethod sSurfaceControlMethods[] = {
// ...... 其他函数和此功能无关,省略
{"nativeGetPhysicalDisplayIds", "()[J",
(void*)nativeGetPhysicalDisplayIds },
// ...... 其他函数和此功能无关,省略
};
static jlongArray nativeGetPhysicalDisplayIds(JNIEnv* env, jclass clazz) {
// 调用SurfaceComposerClient的getPhysicalDisplayIds函数
const auto displayIds = SurfaceComposerClient::getPhysicalDisplayIds();
// ...... 其他代码暂时无关,省略
}
std::vector<PhysicalDisplayId> SurfaceComposerClient::getPhysicalDisplayIds() {
return ComposerService::getComposerService()->getPhysicalDisplayIds();
}
还记得我们此前分析过ComposerService::getComposerService函数么?参见Binder在显示图形系统中的应用 这个函数主要工作是:
- ComposerService中包含一个mComposerService参数指向一个BpSurfaceComposer对象,
- 这个BpSurfaceComposer对象中包含了一个参数名为mRemote的指针指向的是SurfaceFlinger对象,
- 且ComposerService中的BpSurfaceComposer指针对象参数mComposerService和这个ComposerService实现了同生共死状态
- 最终ComposerService.getComposerService函数返回的是一个BpSurfaceComposer指针对象
也就是说,此处会调用BpSurfaceComposer指针对象的getPhysicalDisplayIds函数
virtual std::vector<PhysicalDisplayId> getPhysicalDisplayIds() const {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
if (remote()->transact(BnSurfaceComposer::GET_PHYSICAL_DISPLAY_IDS, data, &reply) ==
NO_ERROR) {
std::vector<PhysicalDisplayId> displayIds;
if (reply.readUint64Vector(&displayIds) == NO_ERROR) {
return displayIds;
}
}
return {};
}
因此,最终会通过BnSurfaceComposer的onTransact函数,调用到SurfaceFlinger的transact函数,来获取对应的DisplayId,从而从Native层中获取到对应的DisplayId,Native层的DisplayId的初始化可以参见默认DisplayDevice显示设备加载流程分析文章 综上,DisplayManagerService对象初始化时注册的DisplayAdapter对象,最终会从Native层的SurfaceFlinger服务中获取到对应的创建的默认显示设备对应的DisplayIds
尝试连接Native层的显示设备
当从Native层获取到DisplayId之后,对应地Java层的DisplayDevice需要和Native层的DisplayDevice进行一一关联,因此需要连接
private void tryConnectDisplayLocked(long physicalDisplayId) {
// 根据上述的分析,此处调用SurfaceConrol对象的getPhysicalDisplayToken,
// 最终会调用到Native层的SurfaceFlinger服务,
// 并通过其getPhysicalDisplayToken函数获取到DisplayDevice的对应BBinder的Key值
final IBinder displayToken = SurfaceControl.getPhysicalDisplayToken(physicalDisplayId);
if (displayToken != null) {
// 一样地,获取对应的DisplayInfo
SurfaceControl.DisplayInfo info = SurfaceControl.getDisplayInfo(displayToken);
// ...... 判空操作,此处不考略,省略
// 获取显示设备配置
SurfaceControl.DisplayConfig[] configs = SurfaceControl.getDisplayConfigs(displayToken);
// ...... 判空操作,此处不考略,省略
// 获取有效的显示设备配置
int activeConfig = SurfaceControl.getActiveConfig(displayToken);
// ...... 判空操作,此处不考略,省略
// 获取有效的ColorMode
int activeColorMode = SurfaceControl.getActiveColorMode(displayToken);
// ...... 判空操作,此处不考略,省略
// 获取Native层显示设备的设备信息
SurfaceControl.DesiredDisplayConfigSpecs configSpecs =
SurfaceControl.getDesiredDisplayConfigSpecs(displayToken);
int[] colorModes = SurfaceControl.getDisplayColorModes(displayToken);
Display.HdrCapabilities hdrCapabilities =
SurfaceControl.getHdrCapabilities(displayToken);
LocalDisplayDevice device = mDevices.get(physicalDisplayId);
if (device == null) {
// Display was added.
// 同步Native层的显示设备信息到Java层和注册
final boolean isDefaultDisplay = mDevices.size() == 0;
device = new LocalDisplayDevice(displayToken, physicalDisplayId, info,
configs, activeConfig, configSpecs, colorModes, activeColorMode,
hdrCapabilities, isDefaultDisplay);
mDevices.put(physicalDisplayId, device);
// 发送显示设备变化事件
sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);
}
// ...... 第一次进入无法进入else分支,省略
}
// ...... 无关代码,省略
}
可以看到,此处主要将Native层的DisplayDevice信息同步到Java层,并且调用设备添加回调函数,最终会回调DisplayManagerService.DisplayAdapterListener.onDisplayDeviceEvent
private final class DisplayAdapterListener implements DisplayAdapter.Listener {
@Override
public void onDisplayDeviceEvent(DisplayDevice device, int event) {
switch (event) {
case DisplayAdapter.DISPLAY_DEVICE_EVENT_ADDED:
handleDisplayDeviceAdded(device);
break;
......
}
}
......
}
private void handleDisplayDeviceAdded(DisplayDevice device) {
synchronized (mSyncRoot) {
handleDisplayDeviceAddedLocked(device);
}
}
private void handleDisplayDeviceAddedLocked(DisplayDevice device) {
DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
// ...... 无关代码,省略
device.mDebugLastLoggedDeviceInfo = info;
// 注册DisplayDevice信息
mDisplayDevices.add(device);
LogicalDisplay display = addLogicalDisplayLocked(device);
Runnable work = updateDisplayStateLocked(device);
if (work != null) {
work.run();
}
scheduleTraversalLocked(false);
}
如此,Java层的DisplayDevice和Native层的DisplayDevice就关联在一起了
对应的函数调用关系如下: