Android13 DisplayManagerService启动流程分析

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);
        }
    }
}
  • 20
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值