DisplayManagerService是有SystemServer在startBootstrapServices引导阶段中通过startService启动,代码如下:
//frameworks/base/services/java/com/android/server/SystemServer.java
public final class SystemServer implements Dumpable {
private void startBootstrapServices(@NonNull TimingsTraceAndSlog t) {
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
......
// DisplayManagerService needs to setup android.display scheduling related policies
// since setSystemProcess() would have overridden policies due to setProcessGroup
mDisplayManagerService.setupSchedulerPolicies();
}
}
调用SystemServiceManager的startService方法启动DisplayManagerService,DisplayManagerService的构造方法如下:
//frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java
public final class DisplayManagerService extends SystemService {
// List of all currently registered display adapters.
private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();
DisplayManagerService(Context context, Injector injector) {
super(context);
mInjector = injector;
mContext = context;
mHandler = new DisplayManagerHandler(DisplayThread.get().getLooper()); // mHandler 用来发送 display 消息
mUiHandler = UiThread.getHandler();
mDisplayDeviceRepo = new DisplayDeviceRepository(mSyncRoot, mPersistentDataStore);
mLogicalDisplayMapper = new LogicalDisplayMapper(mContext, mDisplayDeviceRepo,
new LogicalDisplayListener(), mSyncRoot, mHandler, new DeviceStateToLayoutMap());
mDisplayModeDirector = new DisplayModeDirector(context, mHandler);
mBrightnessSynchronizer = new BrightnessSynchronizer(mContext);
Resources resources = mContext.getResources();
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);
mCurrentUserId = UserHandle.USER_SYSTEM;
ColorSpace[] colorSpaces = SurfaceControl.getCompositionColorSpaces();
mWideColorSpace = colorSpaces[1];
mAllowNonNativeRefreshRateOverride = mInjector.getAllowNonNativeRefreshRateOverride();
mSystemReady = false;
}
}
new DisplayAdapter
在DisplayManagerService类中创建DisplayAdapter,DisplayAdapter的构造方法如下:
//frameworks/base/services/core/java/com/android/server/display/DisplayAdapter.java
abstract class DisplayAdapter {
public DisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
Context context, Handler handler, Listener listener, String name) {
mSyncRoot = syncRoot;
mContext = context;
mHandler = handler;
mListener = listener;
mName = name;
}
}
DisplayManagerService onStart
DisplayManagerService的onStart方法主要加载持久化数据(主要是显示设备的宽高等),发送 MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS消息,对外公布Binder、Local Service等。onStart() 方法如下:
//frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java
public final class DisplayManagerService extends SystemService {
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();
}
mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS); //发送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();
//对外公布Binder、Local 服务
publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
true /*allowIsolated*/);
publishLocalService(DisplayManagerInternal.class, new LocalService());
}
}
发送MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS消息,消息在DisplayManagerHandler的handleMessage中处理:
//frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java
public final class DisplayManagerService extends SystemService {
private final class DisplayManagerHandler extends Handler {
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS:
//注册默认的显示适配器
registerDefaultDisplayAdapters();
break;
}
}
}
}
调用DisplayManagerService的registerDefaultDisplayAdapters方法:
//frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java
public final class DisplayManagerService extends SystemService {
private void registerDefaultDisplayAdapters() {
// Register default display adapters.
synchronized (mSyncRoot) {
// main display adapter
// 主要的显示适配器,注册本地适配器lock
registerDisplayAdapterLocked(new LocalDisplayAdapter(
mSyncRoot, mContext, mHandler, mDisplayDeviceRepo));
// Standalone VR devices rely on a virtual display as their primary display for
// 2D UI. We register virtual display adapter along side the main display adapter
// here so that it is ready by the time the system sends the home Intent for
// early apps like SetupWizard/Launcher. In particular, SUW is displayed using
// the virtual display inside VR before any VR-specific apps even run.
mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext,
mHandler, mDisplayDeviceRepo);
if (mVirtualDisplayAdapter != null) {
registerDisplayAdapterLocked(mVirtualDisplayAdapter);
}
}
}
}
调用DisplayManagerService的registerDisplayAdapterLocked方法:
//frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java
public final class DisplayManagerService extends SystemService {
private void registerDisplayAdapterLocked(DisplayAdapter adapter) {
mDisplayAdapters.add(adapter);
adapter.registerLocked();
}
}
调用adapter(DisplayAdapter)的registerLocked方法,LocalDisplayAdapter继承DisplayAdapter,调用LocalDisplayAdapter的registerLocked方法:
//frameworks/base/services/core/java/com/android/server/display/LocalDisplayAdapter.java
final class LocalDisplayAdapter extends DisplayAdapter {
public void registerLocked() {
super.registerLocked();
mInjector.setDisplayEventListenerLocked(getHandler().getLooper(),
new LocalDisplayEventListener());
for (long physicalDisplayId : mSurfaceControlProxy.getPhysicalDisplayIds()) {
tryConnectDisplayLocked(physicalDisplayId); //连接显示设备
}
}
}
调用LocalDisplayAdapter的tryConnectDisplayLocked方法:
//frameworks/base/services/core/java/com/android/server/display/LocalDisplayAdapter.java
final class LocalDisplayAdapter extends DisplayAdapter {
private final SurfaceControlProxy mSurfaceControlProxy;
private void tryConnectDisplayLocked(long physicalDisplayId) {
final IBinder displayToken =
mSurfaceControlProxy.getPhysicalDisplayToken(physicalDisplayId);
if (displayToken != null) {
SurfaceControl.StaticDisplayInfo staticInfo =
mSurfaceControlProxy.getStaticDisplayInfo(displayToken); //获取display staticInfo
if (staticInfo == null) {
Slog.w(TAG, "No valid static info found for display device " + physicalDisplayId);
return;
}
SurfaceControl.DynamicDisplayInfo dynamicInfo =
mSurfaceControlProxy.getDynamicDisplayInfo(displayToken);
if (dynamicInfo == null) {
Slog.w(TAG, "No valid dynamic info found for display device " + physicalDisplayId);
return;
}
if (dynamicInfo.supportedDisplayModes == null) {
// There are no valid modes for this device, so we can't use it
Slog.w(TAG, "No valid modes found for display device " + physicalDisplayId);
return;
}
if (dynamicInfo.activeDisplayModeId < 0) {
// There is no active mode, and for now we don't have the
// policy to set one.
Slog.w(TAG, "No valid active mode found for display device " + physicalDisplayId);
return;
}
if (dynamicInfo.activeColorMode < 0) {
// We failed to get the active color mode. We don't bail out here since on the next
// configuration pass we'll go ahead and set it to whatever it was set to last (or
// COLOR_MODE_NATIVE if this is the first configuration).
Slog.w(TAG, "No valid active color mode for display device " + physicalDisplayId);
dynamicInfo.activeColorMode = Display.COLOR_MODE_INVALID;
}
SurfaceControl.DesiredDisplayModeSpecs modeSpecs =
mSurfaceControlProxy.getDesiredDisplayModeSpecs(displayToken);
LocalDisplayDevice device = mDevices.get(physicalDisplayId);
if (device == null) {
// Display was added.
final boolean isFirstDisplay = mDevices.size() == 0;
device = new LocalDisplayDevice(displayToken, physicalDisplayId, staticInfo,
dynamicInfo, modeSpecs, isFirstDisplay);
mDevices.put(physicalDisplayId, device);
sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);
} else if (device.updateDisplayPropertiesLocked(staticInfo, dynamicInfo,
modeSpecs)) {
sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_CHANGED);
}
} else {
// The display is no longer available. Ignore the attempt to add it.
// If it was connected but has already been disconnected, we'll get a
// disconnect event that will remove it from mDevices.
}
}
}
上面方法主要处理如下:
1、调用SurfaceControlProxy的getStaticDisplayInfo方法,获取display staticInfo。
2、通过new的方式创建LocalDisplayDevice对象。
3、调用sendDisplayDeviceEventLocked方法。
下面分别进行介绍:
SurfaceControlProxy getStaticDisplayInfo
调用SurfaceControlProxy的getStaticDisplayInfo方法,获取display staticInfo:
//frameworks/base/services/core/java/com/android/server/display/LocalDisplayAdapter.java
final class LocalDisplayAdapter extends DisplayAdapter {
private final Injector mInjector;
LocalDisplayAdapter(DisplayManagerService.SyncRoot syncRoot,
Context context, Handler handler, Listener listener, Injector injector) {
super(syncRoot, context, handler, listener, TAG);
mInjector = injector;
mSurfaceControlProxy = mInjector.getSurfaceControlProxy();
mIsBootDisplayModeSupported = mSurfaceControlProxy.getBootDisplayModeSupport();
}
}
上面方法主要处理如下:
1、调用mInjector(mInjector)的getSurfaceControlProxy方法,获取SurfaceControlProxy对象。
2、调用SurfaceControlProxy的getBootDisplayModeSupport方法,获取BootDisplayModeSupport。
下面分别进行分析:
mInjector getSurfaceControlProxy
调用mInjector(mInjector)的getSurfaceControlProxy方法:
//frameworks/base/services/core/java/com/android/server/display/LocalDisplayAdapter.java
final class LocalDisplayAdapter extends DisplayAdapter {
public static class Injector {
// Native callback.
@SuppressWarnings("unused")
private ProxyDisplayEventReceiver mReceiver;
public void setDisplayEventListenerLocked(Looper looper, DisplayEventListener listener) {
mReceiver = new ProxyDisplayEventReceiver(looper, listener);
}
public SurfaceControlProxy getSurfaceControlProxy() {
return new SurfaceControlProxy(); //创建SurfaceControlProxy对象
}
}
}
SurfaceControlProxy getBootDisplayModeSupport
调用SurfaceControlProxy的getBootDisplayModeSupport方法,获取BootDisplayModeSupport:
//frameworks/base/services/core/java/com/android/server/display/LocalDisplayAdapter.java
final class LocalDisplayAdapter extends DisplayAdapter {
static class SurfaceControlProxy {
public boolean getBootDisplayModeSupport() {
Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "getBootDisplayModeSupport");
try {
return SurfaceControl.getBootDisplayModeSupport();
} finally {
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
}
}
}
SurfaceControl getBootDisplayModeSupport
通过调用SurfaceControl的getBootDisplayModeSupport方法获取BootDisplayModeSupport:
待更新
new LocalDisplayDevice
通过new的方式创建LocalDisplayDevice对象,LocalDisplayDevice是LocalDisplayAdapter的内部类,继承于DisplayDevice,LocalDisplayDevice的构造方法如下:
//frameworks/base/services/core/java/com/android/server/display/LocalDisplayAdapter.java
final class LocalDisplayAdapter extends DisplayAdapter {
private final class LocalDisplayDevice extends DisplayDevice {
LocalDisplayDevice(IBinder displayToken, long physicalDisplayId,
SurfaceControl.StaticDisplayInfo staticDisplayInfo,
SurfaceControl.DynamicDisplayInfo dynamicInfo,
SurfaceControl.DesiredDisplayModeSpecs modeSpecs, boolean isFirstDisplay) {
super(LocalDisplayAdapter.this, displayToken, UNIQUE_ID_PREFIX + physicalDisplayId,
getContext());
mPhysicalDisplayId = physicalDisplayId;
mIsFirstDisplay = isFirstDisplay;
updateDisplayPropertiesLocked(staticDisplayInfo, dynamicInfo, modeSpecs);
mSidekickInternal = LocalServices.getService(SidekickInternal.class);
mBacklightAdapter = new BacklightAdapter(displayToken, isFirstDisplay,
mSurfaceControlProxy);
mActiveDisplayModeAtStartId = dynamicInfo.activeDisplayModeId;
}
}
}
上面方法主要处理如下:
1、调用LocalDisplayDevice的updateDisplayPropertiesLocked方法,更新显示属性。
2、通过new的方式创建BacklightAdapter对象。
下分别进行分析:
LocalDisplayDevice updateDisplayPropertiesLocked
调用LocalDisplayDevice的updateDisplayPropertiesLocked方法,更新显示属性:
//frameworks/base/services/core/java/com/android/server/display/LocalDisplayAdapter.java
final class LocalDisplayAdapter extends DisplayAdapter {
static class BacklightAdapter {
BacklightAdapter(IBinder displayToken, boolean isFirstDisplay,
SurfaceControlProxy surfaceControlProxy) {
mDisplayToken = displayToken;
mSurfaceControlProxy = surfaceControlProxy;
mUseSurfaceControlBrightness = mSurfaceControlProxy
.getDisplayBrightnessSupport(mDisplayToken); //获取Display是否支持亮度调节
if (!mUseSurfaceControlBrightness && isFirstDisplay) {
LightsManager lights = LocalServices.getService(LightsManager.class); //取得LightsManager对象
mBacklight = lights.getLight(LightsManager.LIGHT_ID_BACKLIGHT); //获取显示器背光亮度
} else {
mBacklight = null;
}
}
}
}
LightsService LightsManager getLight
调用lights(LightsManager)的getLight方法,获取显示器背光亮度,getLight方法在LightsService内部类LightsManager中实现:
待更新
DisplayAdapter sendDisplayDeviceEventLocked
调用DisplayAdapter的sendDisplayDeviceEventLocked方法,发送DISPLAY_DEVICE_EVENT_ADDED消息:
//frameworks/base/services/core/java/com/android/server/display/DisplayAdapter.java
abstract class DisplayAdapter {
private final Listener mListener;
protected final void sendDisplayDeviceEventLocked(
final DisplayDevice device, final int event) {
mHandler.post(() -> mListener.onDisplayDeviceEvent(device, event));
}
}
调用DisplayAdapter.Listener的onDisplayDeviceEvent方法,DisplayDeviceRepository类继实现了DisplayAdapter.Listener接口:
//frameworks/base/services/core/java/com/android/server/display/DisplayDeviceRepository.java
class DisplayDeviceRepository implements DisplayAdapter.Listener {
public void onDisplayDeviceEvent(DisplayDevice device, int event) {
String tag = null;
if (DEBUG) {
tag = "DisplayDeviceRepository#onDisplayDeviceEvent (event=" + event + ")";
Trace.beginAsyncSection(tag, 0);
}
switch (event) {
case DISPLAY_DEVICE_EVENT_ADDED:
handleDisplayDeviceAdded(device);
break;
case DISPLAY_DEVICE_EVENT_CHANGED:
handleDisplayDeviceChanged(device);
break;
case DISPLAY_DEVICE_EVENT_REMOVED:
handleDisplayDeviceRemoved(device);
break;
}
if (DEBUG) {
Trace.endAsyncSection(tag, 0);
}
}
}
调用DisplayDeviceRepository的handleDisplayDeviceAdded方法:
//frameworks/base/services/core/java/com/android/server/display/DisplayDeviceRepository.java
class DisplayDeviceRepository implements DisplayAdapter.Listener {
private void handleDisplayDeviceAdded(DisplayDevice device) {
synchronized (mSyncRoot) {
DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
if (mDisplayDevices.contains(device)) {
Slog.w(TAG, "Attempted to add already added display device: " + info);
return;
}
Slog.i(TAG, "Display device added: " + info);
device.mDebugLastLoggedDeviceInfo = info;
mDisplayDevices.add(device);
sendEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);
}
}
}
发送DISPLAY_DEVICE_EVENT_ADDED消息,发送的消息在LogicalDisplayMapper的onDisplayDeviceEventLocked中处理:
//frameworks/base/services/core/java/com/android/server/display/LogicalDisplayMapper.java
class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
public void onDisplayDeviceEventLocked(DisplayDevice device, int event) {
switch (event) {
case DisplayDeviceRepository.DISPLAY_DEVICE_EVENT_ADDED:
if (DEBUG) {
Slog.d(TAG, "Display device added: " + device.getDisplayDeviceInfoLocked());
}
handleDisplayDeviceAddedLocked(device);
break;
case DisplayDeviceRepository.DISPLAY_DEVICE_EVENT_CHANGED:
if (DEBUG) {
Slog.d(TAG, "Display device changed: " + device.getDisplayDeviceInfoLocked());
}
finishStateTransitionLocked(false /*force*/);
updateLogicalDisplaysLocked();
break;
case DisplayDeviceRepository.DISPLAY_DEVICE_EVENT_REMOVED:
if (DEBUG) {
Slog.d(TAG, "Display device removed: " + device.getDisplayDeviceInfoLocked());
}
handleDisplayDeviceRemovedLocked(device);
updateLogicalDisplaysLocked();
break;
}
}
}
调用LogicalDisplayMapper的handleDisplayDeviceAddedLocked方法:
//frameworks/base/services/core/java/com/android/server/display/LogicalDisplayMapper.java
class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
private void handleDisplayDeviceAddedLocked(DisplayDevice device) {
DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked();
// The default Display needs to have additional initialization.
// This initializes a default dynamic display layout for the default
// device, which is used as a fallback in case no static layout definitions
// exist or cannot be loaded.
if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY) != 0) {
initializeDefaultDisplayDeviceLocked(device);
}
// Create a logical display for the new display device
// 为新显示设备创建逻辑显示
LogicalDisplay display = createNewLogicalDisplayLocked(
device, Layout.assignDisplayIdLocked(false /*isDefault*/));
applyLayoutLocked();
updateLogicalDisplaysLocked();
}
}
调用createNewLogicalDisplayLocked方法,创建显示器设备:
//frameworks/base/services/core/java/com/android/server/display/LogicalDisplayMapper.java
class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
private LogicalDisplay createNewLogicalDisplayLocked(DisplayDevice displayDevice,
int displayId) {
final int layerStack = assignLayerStackLocked(displayId);
final LogicalDisplay display = new LogicalDisplay(displayId, layerStack, displayDevice); //创建LogicalDisplay对象
display.updateLocked(mDisplayDeviceRepo); //根据可用的Device来更新logical display
mLogicalDisplays.put(displayId, display);
setDisplayPhase(display, LogicalDisplay.DISPLAY_PHASE_ENABLED); //设置显示阶段
return display;
}
}
上面方法主要处理如下:
1、通过new的方式创建LogicalDisplay对象。
2、调用display(LogicalDisplay)的updateLocked方法。
3、调用LogicalDisplayMapper的setDisplayPhase方法,设置显示阶段。
下面分别进行分析:
new LogicalDisplay
通过new的方式创建LogicalDisplay对象:
//frameworks/base/services/core/java/com/android/server/display/LogicalDisplay.java
final class LogicalDisplay {
public LogicalDisplay(int displayId, int layerStack, DisplayDevice primaryDisplayDevice) {
mDisplayId = displayId;
mLayerStack = layerStack;
mPrimaryDisplayDevice = primaryDisplayDevice;
mPendingFrameRateOverrideUids = new ArraySet<>();
mTempFrameRateOverride = new SparseArray<>();
}
}
LogicalDisplay updateLocked
调用display(LogicalDisplay)的updateLocked方法,根据可用的Device来更新logical display:
//frameworks/base/services/core/java/com/android/server/display/LogicalDisplay.java
final class LogicalDisplay {
public void updateLocked(DisplayDeviceRepository deviceRepo) {
// Nothing to update if already invalid.
if (mPrimaryDisplayDevice == null) {
return;
}
// Check whether logical display has become invalid.
// 检查逻辑显示是否失效。
if (!deviceRepo.containsLocked(mPrimaryDisplayDevice)) {
setPrimaryDisplayDeviceLocked(null);
return;
}
// Bootstrap the logical display using its associated primary physical display.
// We might use more elaborate configurations later. It's possible that the
// configuration of several physical displays might be used to determine the
// logical display that they are sharing. (eg. Adjust size for pixel-perfect
// mirroring over HDMI.)
// 使用逻辑显示关联的主物理显示引导逻辑显示。
// 我们稍后可能会使用更复杂的配置。 多个物理显示器的配置可能用于确定它们共享的逻辑显示器。 (例如。调整大小,通过 HDMI 实现像素完美的镜像。
DisplayDeviceInfo deviceInfo = mPrimaryDisplayDevice.getDisplayDeviceInfoLocked();
if (!Objects.equals(mPrimaryDisplayDeviceInfo, deviceInfo)) {
mBaseDisplayInfo.layerStack = mLayerStack;
mBaseDisplayInfo.flags = 0;
if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
mBaseDisplayInfo.flags |= Display.FLAG_SUPPORTS_PROTECTED_BUFFERS;
}
if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SECURE) != 0) {
mBaseDisplayInfo.flags |= Display.FLAG_SECURE;
}
if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_PRIVATE) != 0) {
mBaseDisplayInfo.flags |= Display.FLAG_PRIVATE;
// For private displays by default content is destroyed on removal.
mBaseDisplayInfo.removeMode = Display.REMOVE_MODE_DESTROY_CONTENT;
}
if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_DESTROY_CONTENT_ON_REMOVAL) != 0) {
mBaseDisplayInfo.removeMode = Display.REMOVE_MODE_DESTROY_CONTENT;
}
if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_PRESENTATION) != 0) {
mBaseDisplayInfo.flags |= Display.FLAG_PRESENTATION;
}
if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_ROUND) != 0) {
mBaseDisplayInfo.flags |= Display.FLAG_ROUND;
}
if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
mBaseDisplayInfo.flags |= Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD;
}
if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0) {
mBaseDisplayInfo.flags |= Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS;
}
if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_TRUSTED) != 0) {
mBaseDisplayInfo.flags |= Display.FLAG_TRUSTED;
}
if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_OWN_DISPLAY_GROUP) != 0) {
mBaseDisplayInfo.flags |= Display.FLAG_OWN_DISPLAY_GROUP;
}
if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_ALWAYS_UNLOCKED) != 0) {
mBaseDisplayInfo.flags |= Display.FLAG_ALWAYS_UNLOCKED;
}
if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_TOUCH_FEEDBACK_DISABLED) != 0) {
mBaseDisplayInfo.flags |= Display.FLAG_TOUCH_FEEDBACK_DISABLED;
}
Rect maskingInsets = getMaskingInsets(deviceInfo);
int maskedWidth = deviceInfo.width - maskingInsets.left - maskingInsets.right;
int maskedHeight = deviceInfo.height - maskingInsets.top - maskingInsets.bottom;
mBaseDisplayInfo.type = deviceInfo.type;
mBaseDisplayInfo.address = deviceInfo.address;
mBaseDisplayInfo.deviceProductInfo = deviceInfo.deviceProductInfo;
mBaseDisplayInfo.name = deviceInfo.name;
mBaseDisplayInfo.uniqueId = deviceInfo.uniqueId;
mBaseDisplayInfo.appWidth = maskedWidth;
mBaseDisplayInfo.appHeight = maskedHeight;
mBaseDisplayInfo.logicalWidth = maskedWidth;
mBaseDisplayInfo.logicalHeight = maskedHeight;
mBaseDisplayInfo.rotation = Surface.ROTATION_0;
mBaseDisplayInfo.modeId = deviceInfo.modeId;
mBaseDisplayInfo.defaultModeId = deviceInfo.defaultModeId;
mBaseDisplayInfo.supportedModes = Arrays.copyOf(
deviceInfo.supportedModes, deviceInfo.supportedModes.length);
mBaseDisplayInfo.colorMode = deviceInfo.colorMode;
mBaseDisplayInfo.supportedColorModes = Arrays.copyOf(
deviceInfo.supportedColorModes,
deviceInfo.supportedColorModes.length);
mBaseDisplayInfo.hdrCapabilities = deviceInfo.hdrCapabilities;
mBaseDisplayInfo.userDisabledHdrTypes = mUserDisabledHdrTypes;
mBaseDisplayInfo.minimalPostProcessingSupported =
deviceInfo.allmSupported || deviceInfo.gameContentTypeSupported;
mBaseDisplayInfo.logicalDensityDpi = deviceInfo.densityDpi;
mBaseDisplayInfo.physicalXDpi = deviceInfo.xDpi;
mBaseDisplayInfo.physicalYDpi = deviceInfo.yDpi;
mBaseDisplayInfo.appVsyncOffsetNanos = deviceInfo.appVsyncOffsetNanos;
mBaseDisplayInfo.presentationDeadlineNanos = deviceInfo.presentationDeadlineNanos;
mBaseDisplayInfo.state = deviceInfo.state;
mBaseDisplayInfo.smallestNominalAppWidth = maskedWidth;
mBaseDisplayInfo.smallestNominalAppHeight = maskedHeight;
mBaseDisplayInfo.largestNominalAppWidth = maskedWidth;
mBaseDisplayInfo.largestNominalAppHeight = maskedHeight;
mBaseDisplayInfo.ownerUid = deviceInfo.ownerUid;
mBaseDisplayInfo.ownerPackageName = deviceInfo.ownerPackageName;
boolean maskCutout =
(deviceInfo.flags & DisplayDeviceInfo.FLAG_MASK_DISPLAY_CUTOUT) != 0;
mBaseDisplayInfo.displayCutout = maskCutout ? null : deviceInfo.displayCutout;
mBaseDisplayInfo.displayId = mDisplayId;
mBaseDisplayInfo.displayGroupId = mDisplayGroupId;
updateFrameRateOverrides(deviceInfo);
mBaseDisplayInfo.brightnessMinimum = deviceInfo.brightnessMinimum;
mBaseDisplayInfo.brightnessMaximum = deviceInfo.brightnessMaximum;
mBaseDisplayInfo.brightnessDefault = deviceInfo.brightnessDefault;
mBaseDisplayInfo.roundedCorners = deviceInfo.roundedCorners;
mBaseDisplayInfo.installOrientation = deviceInfo.installOrientation;
mPrimaryDisplayDeviceInfo = deviceInfo;
mInfo.set(null);
}
}
}
LogicalDisplayMapper setDisplayPhase
调用LogicalDisplayMapper的setDisplayPhase方法,设置显示阶段:
//frameworks/base/services/core/java/com/android/server/display/LogicalDisplayMapper.java
class LogicalDisplayMapper implements DisplayDeviceRepository.Listener {
private void setDisplayPhase(LogicalDisplay display, @DisplayPhase int phase) {
final int displayId = display.getDisplayIdLocked();
final DisplayInfo info = display.getDisplayInfoLocked();
final boolean disallowSecondaryDisplay = mSingleDisplayDemoMode
&& (info.type != Display.TYPE_INTERNAL);
if (phase != LogicalDisplay.DISPLAY_PHASE_DISABLED && disallowSecondaryDisplay) {
Slog.i(TAG, "Not creating a logical display for a secondary display because single"
+ " display demo mode is enabled: " + display.getDisplayInfoLocked());
phase = LogicalDisplay.DISPLAY_PHASE_DISABLED;
}
display.setPhase(phase);
}
}
调用display(LogicalDisplay)的setPhase方法:
//frameworks/base/services/core/java/com/android/server/display/LogicalDisplay.java
final class LogicalDisplay {
public void setPhase(@DisplayPhase int phase) {
mPhase = phase;
}
}
DisplayManagerService onBootPhase
SystemServiceManager在启动DisplayManagerService过程中会调用DisplayManagerService的onBootPhase方法:
//frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java
public final class DisplayManagerService extends SystemService {
public void onBootPhase(int phase) {
if (phase == PHASE_WAIT_FOR_DEFAULT_DISPLAY) {
synchronized (mSyncRoot) {
long timeout = SystemClock.uptimeMillis()
+ mInjector.getDefaultDisplayDelayTimeout();
while (mLogicalDisplayMapper.getDisplayLocked(Display.DEFAULT_DISPLAY) == null
|| mVirtualDisplayAdapter == null) {
long delay = timeout - SystemClock.uptimeMillis();
if (delay <= 0) {
throw new RuntimeException("Timeout waiting for default display "
+ "to be initialized. DefaultDisplay="
+ mLogicalDisplayMapper.getDisplayLocked(Display.DEFAULT_DISPLAY)
+ ", mVirtualDisplayAdapter=" + mVirtualDisplayAdapter);
}
if (DEBUG) {
Slog.d(TAG, "waitForDefaultDisplay: waiting, timeout=" + delay);
}
try {
mSyncRoot.wait(delay);
} catch (InterruptedException ex) {
}
}
}
} else if (phase == PHASE_BOOT_COMPLETED) {
mDisplayModeDirector.onBootCompleted();
mLogicalDisplayMapper.onBootCompleted();
}
}
}
DisplayManagerService onUserSwitching
SystemServiceManager在启动DisplayManagerService过程中会调用DisplayManagerService的onUserSwitching方法:
//frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java
public final class DisplayManagerService extends SystemService {
private final SparseArray<DisplayPowerController> mDisplayPowerControllers =
new SparseArray<>();
public void onUserSwitching(@Nullable TargetUser from, @NonNull TargetUser to) {
final int newUserId = to.getUserIdentifier();
final int userSerial = getUserManager().getUserSerialNumber(newUserId);
synchronized (mSyncRoot) {
boolean userSwitching = mCurrentUserId != newUserId;
if (userSwitching) {
mCurrentUserId = newUserId;
}
mLogicalDisplayMapper.forEachLocked(logicalDisplay -> {
if (logicalDisplay.getDisplayInfoLocked().type != Display.TYPE_INTERNAL) {
return;
}
final DisplayPowerController dpc = mDisplayPowerControllers.get(
logicalDisplay.getDisplayIdLocked()); //获取DisplayPowerController对象
if (dpc == null) {
return;
}
if (userSwitching) {
BrightnessConfiguration config =
getBrightnessConfigForDisplayWithPdsFallbackLocked(
logicalDisplay.getPrimaryDisplayDeviceLocked().getUniqueId(),
userSerial); //获取亮度相关配置
dpc.setBrightnessConfiguration(config);
}
dpc.onSwitchUser(newUserId);
});
handleSettingsChange();
}
}
}
上面方法主要处理如下:
1、调用DisplayManagerService的getBrightnessConfigForDisplayWithPdsFallbackLocked方法,获取亮度相关配置。
2、调用DisplayPowerController的setBrightnessConfiguration方法。
下面分别进行分析:
DisplayManagerService getBrightnessConfigForDisplayWithPdsFallbackLocked
调用DisplayManagerService的getBrightnessConfigForDisplayWithPdsFallbackLocked方法,获取亮度相关配置:
//frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java
public final class DisplayManagerService extends SystemService {
private BrightnessConfiguration getBrightnessConfigForDisplayWithPdsFallbackLocked(
String uniqueId, int userSerial) {
BrightnessConfiguration config =
mPersistentDataStore.getBrightnessConfigurationForDisplayLocked(
uniqueId, userSerial);
if (config == null) {
// Get from global configurations
config = mPersistentDataStore.getBrightnessConfiguration(userSerial);
}
return config;
}
}
调用PersistentDataStore的getBrightnessConfiguration方法:
//frameworks/base/services/core/java/com/android/server/display/PersistentDataStore.java
final class PersistentDataStore {
public BrightnessConfiguration getBrightnessConfigurationForDisplayLocked(
String uniqueDisplayId, int userSerial) {
loadIfNeeded();
DisplayState state = mDisplayStates.get(uniqueDisplayId);
if (state != null) {
return state.getBrightnessConfiguration(userSerial);
}
return null;
}
}
上面方法主要处理如下:
1、调用loadIfNeeded方法,加载亮度设置。
2、调用PersistentDataStore内部类DisplayState的getBrightnessConfiguration方法。
下面分别进行分析:
loadIfNeeded
调用PersistentDataStore的loadIfNeeded方法,加载亮度设置:
//frameworks/base/services/core/java/com/android/server/display/PersistentDataStore.java
final class PersistentDataStore {
public void loadIfNeeded() {
if (!mLoaded) {
load();
mLoaded = true;
}
}
}
调用PersistentDataStore的load方法:
//frameworks/base/services/core/java/com/android/server/display/PersistentDataStore.java
final class PersistentDataStore {
private void load() {
synchronized (mFileAccessLock) {
clearState();
final InputStream is;
try {
is = mInjector.openRead();
} catch (FileNotFoundException ex) {
return;
}
TypedXmlPullParser parser;
try {
parser = Xml.resolvePullParser(is);
loadFromXml(parser);
} catch (IOException ex) {
Slog.w(TAG, "Failed to load display manager persistent store data.", ex);
clearState();
} catch (XmlPullParserException ex) {
Slog.w(TAG, "Failed to load display manager persistent store data.", ex);
clearState();
} finally {
IoUtils.closeQuietly(is);
}
}
}
}
DisplayState getBrightnessConfiguration
调用PersistentDataStore内部类DisplayState的getBrightnessConfiguration方法:
//frameworks/base/services/core/java/com/android/server/display/PersistentDataStore.java
final class PersistentDataStore {
private static final class DisplayState {
public BrightnessConfiguration getBrightnessConfiguration(int userSerial) {
return mDisplayBrightnessConfigurations.mConfigurations.get(userSerial); //返回BrightnessConfiguration对象
}
}
}
DisplayPowerController setBrightnessConfiguration
调用DisplayPowerController的setBrightnessConfiguration方法:
//frameworks/base/services/core/java/com/android/server/display/DisplayPowerController.java
final class DisplayPowerController implements AutomaticBrightnessController.Callbacks,
DisplayWhiteBalanceController.Callbacks {
public void setBrightnessConfiguration(BrightnessConfiguration brightnessConfiguration) {
mBgHandler.obtainMessage(MSG_BRIGHTNESS_CONFIG_CHANGED,
brightnessConfiguration).sendToTarget();
}
}
发送MSG_BRIGHTNESS_CONFIG_CHANGED消息,消息在BrightnessTracker的内部类TrackerHandler的handleMessage中处理:
//frameworks/base/services/core/java/com/android/server/display/BrightnessTracker.java
public class BrightnessTracker {
private final class TrackerHandler extends Handler {
public void handleMessage(Message msg) {
case MSG_BRIGHTNESS_CONFIG_CHANGED:
mBrightnessConfiguration = (BrightnessConfiguration) msg.obj;
boolean shouldCollectColorSamples =
mBrightnessConfiguration != null
&& mBrightnessConfiguration.shouldCollectColorSamples();
if (shouldCollectColorSamples && !mColorSamplingEnabled) {
enableColorSampling();
} else if (!shouldCollectColorSamples && mColorSamplingEnabled) {
disableColorSampling();
}
break;
}
}
}
}
BrightnessTracker enableColorSampling
调用BrightnessTracker的enableColorSampling方法:
//frameworks/base/services/core/java/com/android/server/display/BrightnessTracker.java
public class BrightnessTracker {
private void enableColorSampling() {
if (!mInjector.isBrightnessModeAutomatic(mContentResolver)
|| !mInjector.isInteractive(mContext)
|| mColorSamplingEnabled
|| mBrightnessConfiguration == null
|| !mBrightnessConfiguration.shouldCollectColorSamples()) {
return;
}
mFrameRate = mInjector.getFrameRate(mContext);
if (mFrameRate <= 0) {
Slog.wtf(TAG, "Default display has a zero or negative framerate.");
return;
}
mNoFramesToSample = (int) (mFrameRate * COLOR_SAMPLE_DURATION);
DisplayedContentSamplingAttributes attributes = mInjector.getSamplingAttributes();
if (DEBUG && attributes != null) {
Slog.d(TAG, "Color sampling"
+ " mask=0x" + Integer.toHexString(attributes.getComponentMask())
+ " dataSpace=0x" + Integer.toHexString(attributes.getDataspace())
+ " pixelFormat=0x" + Integer.toHexString(attributes.getPixelFormat()));
}
// Do we support sampling the Value component of HSV
if (attributes != null && attributes.getPixelFormat() == PixelFormat.HSV_888
&& (attributes.getComponentMask() & COLOR_SAMPLE_COMPONENT_MASK) != 0) {
mColorSamplingEnabled = mInjector.enableColorSampling(/* enable= */true,
mNoFramesToSample);
if (DEBUG) {
Slog.i(TAG, "turning on color sampling for "
+ mNoFramesToSample + " frames, success=" + mColorSamplingEnabled);
}
}
if (mColorSamplingEnabled && mDisplayListener == null) {
mDisplayListener = new DisplayListener();
mInjector.registerDisplayListener(mContext, mDisplayListener, mBgHandler);
}
}
}