powerms和ims,dms之间的关联关系
最近工作中遇到的一些powerms和ims,dms之间的关联关系随手整理下
问题1:powerGroup.setLastUserActivityTimeLocked(eventTime)何时调用?
InputDispatcher 大部分的工作在 dispatcherOnce 里完成。首先从mInBoundQueue 中读出队列头部的事件 mPendingEvent, 然后调用 pokeUserActivity().
/frameworks/native/services/inputflinger/dispatcher/InputDispatcher.cpp
602 void InputDispatcher::dispatchOnce() {
603 nsecs_t nextWakeupTime = LONG_LONG_MAX;
604 { // acquire lock
605 std::scoped_lock _l(mLock);
606 mDispatcherIsAlive.notify_all();
607
608 // Run a dispatch loop if there are no pending commands.
609 // The dispatch loop might enqueue commands to run afterwards.
610 if (!haveCommandsLocked()) {
611 dispatchOnceInnerLocked(&nextWakeupTime);
612 }
613
614 // Run all pending commands if there are any.
615 // If any commands were run then force the next poll to wake up immediately.
616 if (runCommandsLockedInterruptable()) {
617 nextWakeupTime = LONG_LONG_MIN;
618 }
619
620 // If we are still waiting for ack on some events,
621 // we might have to wake up earlier to check if an app is anr'ing.
622 const nsecs_t nextAnrCheck = processAnrsLocked();
623 nextWakeupTime = std::min(nextWakeupTime, nextAnrCheck);
624
625 // We are about to enter an infinitely long sleep, because we have no commands or
626 // pending or queued events
627 if (nextWakeupTime == LONG_LONG_MAX) {
628 mDispatcherEnteredIdle.notify_all();
629 }
630 } // release lock
631
632 // Wait for callback or timeout or wake. (make sure we round up, not down)
633 nsecs_t currentTime = now();
634 int timeoutMillis = toMillisecondTimeoutDelay(currentTime, nextWakeupTime);
635 mLooper->pollOnce(timeoutMillis);
636 }
533 void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
...
586 // Inbound queue has at least one entry.
587 mPendingEvent = mInboundQueue.front();
588 mInboundQueue.pop_front();
...
613 switch (mPendingEvent->type) {
637 case EventEntry::Type::KEY: {
653 done = dispatchKeyLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
...
657 case EventEntry::Type::MOTION: {
658 MotionEntry* typedEntry = static_cast<MotionEntry*>(mPendingEvent);
668 done = dispatchMotionLocked(currentTime, typedEntry, &dropReason, nextWakeupTime);
...
1214 bool InputDispatcher::runCommandsLockedInterruptable() {
1215 if (mCommandQueue.empty()) {
1216 return false;
1217 }
1218
1219 do {
1220 auto command = std::move(mCommandQueue.front());
1221 mCommandQueue.pop_front();
1222 // Commands are run with the lock held, but may release and re-acquire the lock from within.
1223 command();
1224 } while (!mCommandQueue.empty());
1225 return true;
1226 }
1753 void InputDispatcher::dispatchEventLocked(nsecs_t currentTime,
1754 std::shared_ptr<EventEntry> eventEntry,
1755 const std::vector<InputTarget>& inputTargets) {
1756 ATRACE_CALL();
1757 if (DEBUG_DISPATCH_CYCLE) {
1758 ALOGD("dispatchEventToCurrentInputTargets");
1759 }
1760
1761 updateInteractionTokensLocked(*eventEntry, inputTargets);
1762
1763 ALOG_ASSERT(eventEntry->dispatchInProgress); // should already have been set to true
1764
1765 pokeUserActivityLocked(*eventEntry);
1766
1767 for (const InputTarget& inputTarget : inputTargets) {
1768 sp<Connection> connection =
1769 getConnectionLocked(inputTarget.inputChannel->getConnectionToken());
1770 if (connection != nullptr) {
1771 prepareDispatchCycleLocked(currentTime, connection, eventEntry, inputTarget);
1772 } else {
1773 if (DEBUG_FOCUS) {
1774 ALOGD("Dropping event delivery to target with channel '%s' because it "
1775 "is no longer registered with the input dispatcher.",
1776 inputTarget.inputChannel->getName().c_str());
1777 }
1778 }
1779 }
1780 }
2834 void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
2835 if (!isUserActivityEvent(eventEntry)) {
2836 // Not poking user activity if the event type does not represent a user activity
2837 return;
2838 }
2839 int32_t displayId = getTargetDisplayId(eventEntry);
2840 sp<WindowInfoHandle> focusedWindowHandle = getFocusedWindowHandleLocked(displayId);
2841 if (focusedWindowHandle != nullptr) {
2842 const WindowInfo* info = focusedWindowHandle->getInfo();
2843 if (info->inputConfig.test(WindowInfo::InputConfig::DISABLE_USER_ACTIVITY)) {
2844 if (DEBUG_DISPATCH_CYCLE) {
2845 ALOGD("Not poking user activity: disabled by window '%s'.", info->name.c_str());
2846 }
2847 return;
2848 }
2849 }
2850
2851 int32_t eventType = USER_ACTIVITY_EVENT_OTHER;
2852 switch (eventEntry.type) {
2853 case EventEntry::Type::MOTION: {
2854 const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
2855 if (motionEntry.action == AMOTION_EVENT_ACTION_CANCEL) {
2856 return;
2857 }
2858
2859 if (MotionEvent::isTouchEvent(motionEntry.source, motionEntry.action)) {
2860 eventType = USER_ACTIVITY_EVENT_TOUCH;
2861 }
2862 break;
2863 }
2864 case EventEntry::Type::KEY: {
2865 const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
2866 if (keyEntry.flags & AKEY_EVENT_FLAG_CANCELED) {
2867 return;
2868 }
2869 eventType = USER_ACTIVITY_EVENT_BUTTON;
2870 break;
2871 }
2872 default: {
2873 LOG_ALWAYS_FATAL("%s events are not user activity",
2874 ftl::enum_string(eventEntry.type).c_str());
2875 break;
2876 }
2877 }
2878
2879 auto command = [this, eventTime = eventEntry.eventTime, eventType, displayId]()
2880 REQUIRES(mLock) {
2881 scoped_unlock unlock(mLock);
// 这里的policy 就是NativeInputManager
2882 mPolicy->pokeUserActivity(eventTime, eventType, displayId);
2883 };
2884 postCommandLocked(std::move(command));
2885 }
/frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
251 class NativeInputManager : public virtual RefBase,
252 public virtual InputReaderPolicyInterface,
253 public virtual InputDispatcherPolicyInterface,
254 public virtual PointerControllerPolicyInterface
1376 void NativeInputManager::pokeUserActivity(nsecs_t eventTime, int32_t eventType, int32_t displayId) {
1377 ATRACE_CALL();
1378 android_server_PowerManagerService_userActivity(eventTime, eventType, displayId);
1379 }
108 void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t eventType,
109 int32_t displayId) {
110 if (gPowerManagerServiceObj) {
111 // Throttle calls into user activity by event type.
112 // We're a little conservative about argument checking here in case the caller
113 // passes in bad data which could corrupt system state.
114 if (eventType >= 0 && eventType <= USER_ACTIVITY_EVENT_LAST) {
115 nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
116 if (eventTime > now) {
117 eventTime = now;
118 }
119
120 if (gLastEventTime[eventType] + MIN_TIME_BETWEEN_USERACTIVITIES > eventTime) {
121 return;
122 }
123 gLastEventTime[eventType] = eventTime;
124
125 // Tell the power HAL when user activity occurs.
126 setPowerBoost(Boost::INTERACTION, 0);
127 }
128
129 JNIEnv* env = AndroidRuntime::getJNIEnv();
130
131 env->CallVoidMethod(gPowerManagerServiceObj,
132 gPowerManagerServiceClassInfo.userActivityFromNative,
133 nanoseconds_to_milliseconds(eventTime), eventType, displayId, 0);
134 checkAndClearExceptionFromCallback(env, "userActivityFromNative");
135 }
136 }
1888 // Called from native code.
1889 @SuppressWarnings("unused")
1890 private void userActivityFromNative(long eventTime, int event, int displayId, int flags) {
1891 userActivityInternal(displayId, eventTime, event, flags, Process.SYSTEM_UID);
1892 }
1894 private void userActivityInternal(int displayId, long eventTime, int event, int flags,
1895 int uid) {
1896 synchronized (mLock) {
1897 if (displayId == Display.INVALID_DISPLAY) {
1898 if (userActivityNoUpdateLocked(eventTime, event, flags, uid)) {
1899 updatePowerStateLocked();
1900 }
1901 return;
1902 }
1903
1904 final DisplayInfo displayInfo = mDisplayManagerInternal.getDisplayInfo(displayId);
1905 if (displayInfo == null) {
1906 return;
1907 }
1908 final int groupId = displayInfo.displayGroupId;
1909 if (groupId == Display.INVALID_DISPLAY_GROUP) {
1910 return;
1911 }
1912 if (userActivityNoUpdateLocked(mPowerGroups.get(groupId), eventTime, event, flags,
1913 uid)) {
1914 updatePowerStateLocked();
1915 }
1916 }
1917 }
1944 @GuardedBy("mLock")
1945 private boolean userActivityNoUpdateLocked(final PowerGroup powerGroup, long eventTime,
1946 int event, int flags, int uid) {
1947 final int groupId = powerGroup.getGroupId();
1948 if (DEBUG_SPEW) {
1949 Slog.d(TAG, "userActivityNoUpdateLocked: groupId=" + groupId
1950 + ", eventTime=" + eventTime + ", event=" + event
1951 + ", flags=0x" + Integer.toHexString(flags) + ", uid=" + uid);
1952 }
1953
1954 if (eventTime < powerGroup.getLastSleepTimeLocked()
1955 || eventTime < powerGroup.getLastWakeTimeLocked() || !mSystemReady) {
1956 return false;
1957 }
1958
1959 Trace.traceBegin(Trace.TRACE_TAG_POWER, "userActivity");
1960 try {
1961 if (eventTime > mLastInteractivePowerHintTime) {
1962 setPowerBoostInternal(Boost.INTERACTION, 0);
1963 mLastInteractivePowerHintTime = eventTime;
1964 }
1965
1966 mNotifier.onUserActivity(powerGroup.getGroupId(), event, uid);
1967 mAttentionDetector.onUserActivity(eventTime, event);
1968
1969 if (mUserInactiveOverrideFromWindowManager) {
1970 mUserInactiveOverrideFromWindowManager = false;
1971 mOverriddenTimeout = -1;
1972 }
1973 final int wakefulness = powerGroup.getWakefulnessLocked();
1974 if (wakefulness == WAKEFULNESS_ASLEEP
1975 || wakefulness == WAKEFULNESS_DOZING
1976 || (flags & PowerManager.USER_ACTIVITY_FLAG_INDIRECT) != 0) {
1977 return false;
1978 }
1979
1980 maybeUpdateForegroundProfileLastActivityLocked(eventTime);
1981
1982 if ((flags & PowerManager.USER_ACTIVITY_FLAG_NO_CHANGE_LIGHTS) != 0) {
1983 if (eventTime > powerGroup.getLastUserActivityTimeNoChangeLightsLocked()
1984 && eventTime > powerGroup.getLastUserActivityTimeLocked()) {
1985 powerGroup.setLastUserActivityTimeNoChangeLightsLocked(eventTime);
1986 mDirty |= DIRTY_USER_ACTIVITY;
1987 if (event == PowerManager.USER_ACTIVITY_EVENT_BUTTON) {
1988 mDirty |= DIRTY_QUIESCENT;
1989 }
1990
1991 return true;
1992 }
1993 } else {
1994 if (eventTime > powerGroup.getLastUserActivityTimeLocked()) {
1995 powerGroup.setLastUserActivityTimeLocked(eventTime);
1996 mDirty |= DIRTY_USER_ACTIVITY;
1997 if (event == PowerManager.USER_ACTIVITY_EVENT_BUTTON) {
1998 mDirty |= DIRTY_QUIESCENT;
1999 }
2000 return true;
2001 }
2002 }
2003 } finally {
2004 Trace.traceEnd(Trace.TRACE_TAG_POWER);
2005 }
2006 return false;
2007 }
问题2:displaygroup 和 powergroup之间的关系
195 public final class DisplayManagerService extends SystemService {
196 private static final String TAG = "DisplayManagerService";
197 private static final boolean DEBUG = false;
522 @Override
523 public void onStart() {
524 // We need to pre-load the persistent data store so it's ready before the default display
525 // adapter is up so that we have it's configuration. We could load it lazily, but since
526 // we're going to have to read it in eventually we may as well do it here rather than after
527 // we've waited for the display to register itself with us.
528 synchronized (mSyncRoot) {
529 mPersistentDataStore.loadIfNeeded();
530 loadStableDisplayValuesLocked();
531 }
532 mHandler.sendEmptyMessage(MSG_REGISTER_DEFAULT_DISPLAY_ADAPTERS);
533
534 // If there was a runtime restart then we may have stale caches left around, so we need to
535 // make sure to invalidate them upon every start.
536 DisplayManagerGlobal.invalidateLocalDisplayInfoCaches();
537
538 publishBinderService(Context.DISPLAY_SERVICE, new BinderService(),
539 true /*allowIsolated*/);
540 publishLocalService(DisplayManagerInternal.class, new LocalService());
541 }
1456 private void registerDefaultDisplayAdapters() {
1457 // Register default display adapters.
1458 synchronized (mSyncRoot) {
1459 // main display adapter
1460 registerDisplayAdapterLocked(new LocalDisplayAdapter(
1461 mSyncRoot, mContext, mHandler, mDisplayDeviceRepo));
1462
1463 // Standalone VR devices rely on a virtual display as their primary display for
1464 // 2D UI. We register virtual display adapter along side the main display adapter
1465 // here so that it is ready by the time the system sends the home Intent for
1466 // early apps like SetupWizard/Launcher. In particular, SUW is displayed using
1467 // the virtual display inside VR before any VR-specific apps even run.
1468 mVirtualDisplayAdapter = mInjector.getVirtualDisplayAdapter(mSyncRoot, mContext,
1469 mHandler, mDisplayDeviceRepo);
1470 if (mVirtualDisplayAdapter != null) {
1471 registerDisplayAdapterLocked(mVirtualDisplayAdapter);
1472 }
1473 }
1474 }
1511 private void registerDisplayAdapterLocked(DisplayAdapter adapter) {
1512 mDisplayAdapters.add(adapter);
1513 adapter.registerLocked();
1514 }
/frameworks/base/services/core/java/com/android/server/display/LocalDisplayAdapter.java
97 @Override
98 public void registerLocked() {
99 super.registerLocked();
100
101 mInjector.setDisplayEventListenerLocked(getHandler().getLooper(),
102 new LocalDisplayEventListener());
103
104 for (long physicalDisplayId : mSurfaceControlProxy.getPhysicalDisplayIds()) {
105 tryConnectDisplayLocked(physicalDisplayId);
106 }
107 }
109 private void tryConnectDisplayLocked(long physicalDisplayId) {
110 final IBinder displayToken =
111 mSurfaceControlProxy.getPhysicalDisplayToken(physicalDisplayId);
112 if (displayToken != null) {
113 SurfaceControl.StaticDisplayInfo staticInfo =
114 mSurfaceControlProxy.getStaticDisplayInfo(displayToken);
115 if (staticInfo == null) {
116 Slog.w(TAG, "No valid static info found for display device " + physicalDisplayId);
117 return;
118 }
119 SurfaceControl.DynamicDisplayInfo dynamicInfo =
120 mSurfaceControlProxy.getDynamicDisplayInfo(displayToken);
121 if (dynamicInfo == null) {
122 Slog.w(TAG, "No valid dynamic info found for display device " + physicalDisplayId);
123 return;
124 }
125 if (dynamicInfo.supportedDisplayModes == null) {
126 // There are no valid modes for this device, so we can't use it
127 Slog.w(TAG, "No valid modes found for display device " + physicalDisplayId);
128 return;
129 }
130 if (dynamicInfo.activeDisplayModeId < 0) {
131 // There is no active mode, and for now we don't have the
132 // policy to set one.
133 Slog.w(TAG, "No valid active mode found for display device " + physicalDisplayId);
134 return;
135 }
136 if (dynamicInfo.activeColorMode < 0) {
137 // We failed to get the active color mode. We don't bail out here since on the next
138 // configuration pass we'll go ahead and set it to whatever it was set to last (or
139 // COLOR_MODE_NATIVE if this is the first configuration).
140 Slog.w(TAG, "No valid active color mode for display device " + physicalDisplayId);
141 dynamicInfo.activeColorMode = Display.COLOR_MODE_INVALID;
142 }
143 SurfaceControl.DesiredDisplayModeSpecs modeSpecs =
144 mSurfaceControlProxy.getDesiredDisplayModeSpecs(displayToken);
145 LocalDisplayDevice device = mDevices.get(physicalDisplayId);
146 if (device == null) {
147 // Display was added.
148 final boolean isFirstDisplay = mDevices.size() == 0;
149 device = new LocalDisplayDevice(displayToken, physicalDisplayId, staticInfo,
150 dynamicInfo, modeSpecs, isFirstDisplay);
151 mDevices.put(physicalDisplayId, device);
// 告知对物理屏改变感兴趣的监听器
152 sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);
153 } else if (device.updateDisplayPropertiesLocked(staticInfo, dynamicInfo,
154 modeSpecs)) {
155 sendDisplayDeviceEventLocked(device, DISPLAY_DEVICE_EVENT_CHANGED);
156 }
157 } else {
158 // The display is no longer available. Ignore the attempt to add it.
159 // If it was connected but has already been disconnected, we'll get a
160 // disconnect event that will remove it from mDevices.
161 }
162 }
frameworks/base/services/core/java/com/android/server/display/DisplayDeviceRepository.java
32 /**
33 * Container for all the display devices present in the system. If an object wants to get events
34 * about all the DisplayDevices without needing to listen to all of the DisplayAdapters, they can
35 * listen and interact with the instance of this class.
36 * <p>
37 * The collection of {@link DisplayDevice}s and their usage is protected by the provided
38 * {@link DisplayManagerService.SyncRoot} lock object.
39 */
40 class DisplayDeviceRepository implements DisplayAdapter.Listener {
78 @Override
79 public void onDisplayDeviceEvent(DisplayDevice device, int event) {
80 String tag = null;
81 if (DEBUG) {
82 tag = "DisplayDeviceRepository#onDisplayDeviceEvent (event=" + event + ")";
83 Trace.beginAsyncSection(tag, 0);
84 }
85 switch (event) {
86 case DISPLAY_DEVICE_EVENT_ADDED:
87 handleDisplayDeviceAdded(device);
88 break;
89
90 case DISPLAY_DEVICE_EVENT_CHANGED:
91 handleDisplayDeviceChanged(device);
92 break;
93
94 case DISPLAY_DEVICE_EVENT_REMOVED:
95 handleDisplayDeviceRemoved(device);
96 break;
97 }
98 if (DEBUG) {
99 Trace.endAsyncSection(tag, 0);
100 }
101 }
147 private void handleDisplayDeviceAdded(DisplayDevice device) {
148 synchronized (mSyncRoot) {
149 DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
150 if (mDisplayDevices.contains(device)) {
151 Slog.w(TAG, "Attempted to add already added display device: " + info);
152 return;
153 }
154 Slog.i(TAG, "Display device added: " + info);
155 device.mDebugLastLoggedDeviceInfo = info;
156
157 mDisplayDevices.add(device);
158 sendEventLocked(device, DISPLAY_DEVICE_EVENT_ADDED);
159 }
160 }
211 private void sendEventLocked(DisplayDevice device, int event) {
212 final int size = mListeners.size();
213 for (int i = 0; i < size; i++) {
214 mListeners.get(i).onDisplayDeviceEventLocked(device, event);
215 }
216 }
/frameworks/base/services/core/java/com/android/server/display/LogicalDisplayMapper.java
171 LogicalDisplayMapper(@NonNull Context context, @NonNull DisplayDeviceRepository repo,
172 @NonNull Listener listener, @NonNull DisplayManagerService.SyncRoot syncRoot,
173 @NonNull Handler handler, @NonNull DeviceStateToLayoutMap deviceStateToLayoutMap) {
174 mSyncRoot = syncRoot;
119 /**
120 * Map of all logical displays indexed by logical display id.
121 * Any modification to mLogicalDisplays must invalidate the DisplayManagerGlobal cache.
122 * TODO: multi-display - Move the aforementioned comment?
123 */
124 private final SparseArray<LogicalDisplay> mLogicalDisplays =
125 new SparseArray<LogicalDisplay>();
126
191 @Override
192 public void onDisplayDeviceEventLocked(DisplayDevice device, int event) {
193 switch (event) {
194 case DisplayDeviceRepository.DISPLAY_DEVICE_EVENT_ADDED:
195 if (DEBUG) {
196 Slog.d(TAG, "Display device added: " + device.getDisplayDeviceInfoLocked());
197 }
198 handleDisplayDeviceAddedLocked(device);
199 break;
200
201 case DisplayDeviceRepository.DISPLAY_DEVICE_EVENT_CHANGED:
202 if (DEBUG) {
203 Slog.d(TAG, "Display device changed: " + device.getDisplayDeviceInfoLocked());
204 }
205 finishStateTransitionLocked(false /*force*/);
206 updateLogicalDisplaysLocked();
207 break;
208
209 case DisplayDeviceRepository.DISPLAY_DEVICE_EVENT_REMOVED:
210 if (DEBUG) {
211 Slog.d(TAG, "Display device removed: " + device.getDisplayDeviceInfoLocked());
212 }
213 handleDisplayDeviceRemovedLocked(device);
214 updateLogicalDisplaysLocked();
215 break;
216 }
217 }
574 private void handleDisplayDeviceAddedLocked(DisplayDevice device) {
575 DisplayDeviceInfo deviceInfo = device.getDisplayDeviceInfoLocked();
576 // The default Display needs to have additional initialization.
577 // This initializes a default dynamic display layout for the default
578 // device, which is used as a fallback in case no static layout definitions
579 // exist or cannot be loaded.
580 if ((deviceInfo.flags & DisplayDeviceInfo.FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY) != 0) {
581 initializeDefaultDisplayDeviceLocked(device);
582 }
583
584 // Create a logical display for the new display device
585 LogicalDisplay display = createNewLogicalDisplayLocked(
586 device, Layout.assignDisplayIdLocked(false /*isDefault*/));
587
588 applyLayoutLocked();
589 updateLogicalDisplaysLocked();
590 }
1014 private void initializeDefaultDisplayDeviceLocked(DisplayDevice device) {
1015 // We always want to make sure that our default layout creates a logical
1016 // display for the default display device that is found.
1017 // To that end, when we are notified of a new default display, we add it to
1018 // the default layout definition if it is not already there.
1019 final Layout layout = mDeviceStateToLayoutMap.get(DeviceStateToLayoutMap.STATE_DEFAULT);
1020 if (layout.getById(DEFAULT_DISPLAY) != null) {
1021 // The layout should only have one default display
1022 return;
1023 }
1024 final DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
// 此处通过layout创建一个layout里面的display,这个display关联了物理屏幕的地址,并 加入layout中的display列表
1025 layout.createDisplayLocked(info.address, /* isDefault= */ true, /* isEnabled= */ true);
1026 }
928 /**
929 * Apply (or reapply) the currently selected display layout.
930 */
931 private void applyLayoutLocked() {
932 final Layout oldLayout = mCurrentLayout;
933 mCurrentLayout = mDeviceStateToLayoutMap.get(mDeviceState);
934 Slog.i(TAG, "Applying layout: " + mCurrentLayout + ", Previous layout: " + oldLayout);
935
936 // Go through each of the displays in the current layout set.
937 final int size = mCurrentLayout.size();
// 遍历layout中的display列表
938 for (int i = 0; i < size; i++) {
939 final Layout.Display displayLayout = mCurrentLayout.getAt(i);
940
941 // If the underlying display-device we want to use for this display
942 // doesn't exist, then skip it. This can happen at startup as display-devices
943 // trickle in one at a time. When the new display finally shows up, the layout is
944 // recalculated so that the display is properly added to the current layout.
// 拿到物理屏幕
945 final DisplayAddress address = displayLayout.getAddress();
946 final DisplayDevice device = mDisplayDeviceRepo.getByAddressLocked(address);
947 if (device == null) {
948 Slog.w(TAG, "The display device (" + address + "), is not available"
949 + " for the display state " + mDeviceState);
950 continue;
951 }
952
953 // Now that we have a display-device, we need a LogicalDisplay to map it to. Find the
954 // right one, if it doesn't exist, create a new one.
// 默认屏display的displayid为0,0此时没有对应逻辑屏,需要新建
955 final int logicalDisplayId = displayLayout.getLogicalDisplayId();
956 LogicalDisplay newDisplay =
957 getDisplayLocked(logicalDisplayId, /* includeDisabled= */ true);
958 if (newDisplay == null) {
959 newDisplay = createNewLogicalDisplayLocked(
960 /* displayDevice= */ null, logicalDisplayId);
961 }
962
963 // Now swap the underlying display devices between the old display and the new display
// 根据物理屏获得逻辑屏oldDisplay,该oldDisplay的displayid为2
964 final LogicalDisplay oldDisplay = getDisplayLocked(device, /* includeDisabled= */ true);
// 因为不相等,此时会做一次交换,将displayid为2的逻辑屏对应的物理屏绑定到 displayid为0的逻辑屏上
965 if (newDisplay != oldDisplay) {
966 newDisplay.swapDisplaysLocked(oldDisplay);
967 }
968
969 if (!displayLayout.isEnabled()) {
970 setDisplayPhase(newDisplay, LogicalDisplay.DISPLAY_PHASE_DISABLED);
971 }
972 }
973
974 }
624 /**
625 * Updates the rest of the display system once all the changes are applied for display
626 * devices and logical displays. The includes releasing invalid/empty LogicalDisplays,
627 * creating/adjusting/removing DisplayGroups, and notifying the rest of the system of the
628 * relevant changes.
629 */
630 private void updateLogicalDisplaysLocked() {
631 // Go through all the displays and figure out if they need to be updated.
632 // Loops in reverse so that displays can be removed during the loop without affecting the
633 // rest of the loop.
634 for (int i = mLogicalDisplays.size() - 1; i >= 0; i--) {
635 final int displayId = mLogicalDisplays.keyAt(i);
636 LogicalDisplay display = mLogicalDisplays.valueAt(i);
637
638 mTempDisplayInfo.copyFrom(display.getDisplayInfoLocked());
639 display.getNonOverrideDisplayInfoLocked(mTempNonOverrideDisplayInfo);
640
641 display.updateLocked(mDisplayDeviceRepo);
642 DisplayInfo newDisplayInfo = display.getDisplayInfoLocked();
643
644 final int storedState = mUpdatedLogicalDisplays.get(displayId, UPDATE_STATE_NEW);
645 final int updateState = storedState & UPDATE_STATE_MASK;
646 final boolean isTransitioning = (storedState & UPDATE_STATE_FLAG_TRANSITION) != 0;
647 final boolean wasPreviouslyUpdated = updateState == UPDATE_STATE_UPDATED;
648
649 // The display is no longer valid and needs to be removed.
650 if (!display.isValidLocked()) {
651 mUpdatedLogicalDisplays.delete(displayId);
652
653 // Remove from group
654 final DisplayGroup displayGroup = getDisplayGroupLocked(
655 getDisplayGroupIdFromDisplayIdLocked(displayId));
656 if (displayGroup != null) {
657 displayGroup.removeDisplayLocked(display);
658 }
659
660 if (wasPreviouslyUpdated) {
661 // The display isn't actually removed from our internal data structures until
662 // after the notification is sent; see {@link #sendUpdatesForDisplaysLocked}.
663 Slog.i(TAG, "Removing display: " + displayId);
664 mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_REMOVED);
665 } else {
666 // This display never left this class, safe to remove without notification
667 mLogicalDisplays.removeAt(i);
668 }
669 continue;
670
671 // The display has been newly disabled, we report this as a removed display but
672 // don't actually remove it from our internal list in LogicalDisplayMapper. The reason
673 // is that LogicalDisplayMapper assumes and relies on the fact that every DisplayDevice
674 // has a LogicalDisplay wrapper, but certain displays that are unusable (like the inner
675 // display on a folded foldable device) are not available for use by the system and
676 // we keep them hidden. To do this, we mark those LogicalDisplays as "disabled".
677 // Also, if the display is in TRANSITION but was previously reported as disabled
678 // then keep it unreported.
679 } else if (!display.isEnabled()
680 || (display.getPhase() == LogicalDisplay.DISPLAY_PHASE_LAYOUT_TRANSITION
681 && updateState == UPDATE_STATE_DISABLED)) {
682 mUpdatedLogicalDisplays.put(displayId, UPDATE_STATE_DISABLED);
683
684 // If we never told anyone about this display, nothing to do
685 if (!wasPreviouslyUpdated) {
686 continue;
687 }
688
689 // Remove from group
// 失效找到display所属的DisplayGroup,再把它从group中删除
690 final DisplayGroup displayGroup = getDisplayGroupLocked(
691 getDisplayGroupIdFromDisplayIdLocked(displayId));
692 if (displayGroup != null) {
693 displayGroup.removeDisplayLocked(display);
694 }
695
696 Slog.i(TAG, "Removing (disabled) display: " + displayId);
697 mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_REMOVED);
698 continue;
699
700 // The display is new.
// 新逻辑屏,之前没有更新,做添加操作。
701 } else if (!wasPreviouslyUpdated) {
702 Slog.i(TAG, "Adding new display: " + displayId + ": " + newDisplayInfo);
703 assignDisplayGroupLocked(display);
704 mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_ADDED);
705
706 // Underlying displays device has changed to a different one.
// 底层显示设备已更改为另一种。
707 } else if (!TextUtils.equals(mTempDisplayInfo.uniqueId, newDisplayInfo.uniqueId)) {
708 // FLAG_OWN_DISPLAY_GROUP could have changed, recalculate just in case
709 assignDisplayGroupLocked(display);
710 mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_SWAPPED);
711
712 // Something about the display device has changed.
713 } else if (!mTempDisplayInfo.equals(newDisplayInfo)) {
714 // FLAG_OWN_DISPLAY_GROUP could have changed, recalculate just in case
715 assignDisplayGroupLocked(display);
716 mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_CHANGED);
717
718 // The display is involved in a display layout transition
719 } else if (isTransitioning) {
720 mLogicalDisplaysToUpdate.put(displayId,
721 LOGICAL_DISPLAY_EVENT_DEVICE_STATE_TRANSITION);
722
723 // Display frame rate overrides changed.
724 } else if (!display.getPendingFrameRateOverrideUids().isEmpty()) {
725 mLogicalDisplaysToUpdate.put(
726 displayId, LOGICAL_DISPLAY_EVENT_FRAME_RATE_OVERRIDES_CHANGED);
727
728 // Non-override display values changed.
729 } else {
730 // While application shouldn't know nor care about the non-overridden info, we
731 // still need to let WindowManager know so it can update its own internal state for
732 // things like display cutouts.
733 display.getNonOverrideDisplayInfoLocked(mTempDisplayInfo);
734 if (!mTempNonOverrideDisplayInfo.equals(mTempDisplayInfo)) {
735 mLogicalDisplaysToUpdate.put(displayId, LOGICAL_DISPLAY_EVENT_CHANGED);
736 }
737 }
738
739 mUpdatedLogicalDisplays.put(displayId, UPDATE_STATE_UPDATED);
740 }
741
742 // Go through the groups and do the same thing. We do this after displays since group
743 // information can change in the previous loop.
744 // Loops in reverse so that groups can be removed during the loop without affecting the
745 // rest of the loop.
//遍历分组并执行相同的操作.我们在显示之后这样做,是因为组信息可以在前一个循环中更改。这 样就可以在循环期间删除分组,而不会影响循环的其余部分。
746 for (int i = mDisplayGroups.size() - 1; i >= 0; i--) {
747 final int groupId = mDisplayGroups.keyAt(i);
748 final DisplayGroup group = mDisplayGroups.valueAt(i);
749 final boolean wasPreviouslyUpdated = mUpdatedDisplayGroups.indexOfKey(groupId) > -1;
750 final int changeCount = group.getChangeCountLocked();
751
752 if (group.isEmptyLocked()) {
753 mUpdatedDisplayGroups.delete(groupId);
754 if (wasPreviouslyUpdated) {
755 mDisplayGroupsToUpdate.put(groupId, DISPLAY_GROUP_EVENT_REMOVED);
756 }
757 continue;
758 } else if (!wasPreviouslyUpdated) {
759 mDisplayGroupsToUpdate.put(groupId, DISPLAY_GROUP_EVENT_ADDED);
760 } else if (mUpdatedDisplayGroups.get(groupId) != changeCount) {
761 mDisplayGroupsToUpdate.put(groupId, DISPLAY_GROUP_EVENT_CHANGED);
762 }
763 mUpdatedDisplayGroups.put(groupId, changeCount);
764 }
765
766 // Send the display and display group updates in order by message type. This is important
767 // to ensure that addition and removal notifications happen in the right order.
768 sendUpdatesForDisplaysLocked(LOGICAL_DISPLAY_EVENT_DEVICE_STATE_TRANSITION);
769 sendUpdatesForGroupsLocked(DISPLAY_GROUP_EVENT_ADDED);
770 sendUpdatesForDisplaysLocked(LOGICAL_DISPLAY_EVENT_REMOVED);
771 sendUpdatesForDisplaysLocked(LOGICAL_DISPLAY_EVENT_CHANGED);
772 sendUpdatesForDisplaysLocked(LOGICAL_DISPLAY_EVENT_FRAME_RATE_OVERRIDES_CHANGED);
773 sendUpdatesForDisplaysLocked(LOGICAL_DISPLAY_EVENT_SWAPPED);
774 sendUpdatesForDisplaysLocked(LOGICAL_DISPLAY_EVENT_ADDED);
775 sendUpdatesForGroupsLocked(DISPLAY_GROUP_EVENT_CHANGED);
776 sendUpdatesForGroupsLocked(DISPLAY_GROUP_EVENT_REMOVED);
777
778 mLogicalDisplaysToUpdate.clear();
779 mDisplayGroupsToUpdate.clear();
780 }
829 private void assignDisplayGroupLocked(LogicalDisplay display) {
830 final int displayId = display.getDisplayIdLocked();
831
832 // Get current display group data
833 int groupId = getDisplayGroupIdFromDisplayIdLocked(displayId);
834 final DisplayGroup oldGroup = getDisplayGroupLocked(groupId);
835
836 // Get the new display group if a change is needed
837 final DisplayInfo info = display.getDisplayInfoLocked();
838 final boolean needsOwnDisplayGroup = (info.flags & Display.FLAG_OWN_DISPLAY_GROUP) != 0;
839 final boolean hasOwnDisplayGroup = groupId != Display.DEFAULT_DISPLAY_GROUP;
840 if (groupId == Display.INVALID_DISPLAY_GROUP
841 || hasOwnDisplayGroup != needsOwnDisplayGroup) {
842 groupId = assignDisplayGroupIdLocked(needsOwnDisplayGroup);
843 }
844
845 // Create a new group if needed
846 DisplayGroup newGroup = getDisplayGroupLocked(groupId);
847 if (newGroup == null) {
// 如果原来没有就创建新组
848 newGroup = new DisplayGroup(groupId);
849 mDisplayGroups.append(groupId, newGroup);
850 }
851 if (oldGroup != newGroup) {
852 if (oldGroup != null) {
853 oldGroup.removeDisplayLocked(display);
854 }
855 newGroup.addDisplayLocked(display);
856 display.updateDisplayGroupIdLocked(groupId);
857 Slog.i(TAG, "Setting new display group " + groupId + " for display "
858 + displayId + ", from previous group: "
859 + (oldGroup != null ? oldGroup.getGroupId() : "null"));
860 }
861 }
782 /**
783 * Send the specified message for all relevant displays in the specified display-to-message map.
784 */
785 private void sendUpdatesForDisplaysLocked(int msg) {
786 for (int i = mLogicalDisplaysToUpdate.size() - 1; i >= 0; --i) {
787 final int currMsg = mLogicalDisplaysToUpdate.valueAt(i);
788 if (currMsg != msg) {
789 continue;
790 }
791
792 final int id = mLogicalDisplaysToUpdate.keyAt(i);
793 final LogicalDisplay display = getDisplayLocked(id, /* includeDisabled= */ true);
794 if (DEBUG) {
795 final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
796 final String uniqueId = device == null ? "null" : device.getUniqueId();
797 Slog.d(TAG, "Sending " + displayEventToString(msg) + " for display=" + id
798 + " with device=" + uniqueId);
799 }
800 mListener.onLogicalDisplayEventLocked(display, msg);
801 if (msg == LOGICAL_DISPLAY_EVENT_REMOVED && !display.isValidLocked()) {
802 // We wait until we sent the EVENT_REMOVED event before actually removing the
803 // display.
804 mLogicalDisplays.delete(id);
805 }
806 }
807 }
/frameworks/base/services/core/java/com/android/server/display/DisplayManagerService.java
2694 private final class LogicalDisplayListener implements LogicalDisplayMapper.Listener {
2695 @Override
2696 public void onLogicalDisplayEventLocked(LogicalDisplay display, int event) {
2697 switch (event) {
2698 case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_ADDED:
2699 handleLogicalDisplayAddedLocked(display);
2700 break;
2701
2702 case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_CHANGED:
2703 handleLogicalDisplayChangedLocked(display);
2704 break;
2705
2706 case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_REMOVED:
2707 handleLogicalDisplayRemovedLocked(display);
2708 break;
2709
2710 case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_SWAPPED:
2711 handleLogicalDisplaySwappedLocked(display);
2712 break;
2713
2714 case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_FRAME_RATE_OVERRIDES_CHANGED:
2715 handleLogicalDisplayFrameRateOverridesChangedLocked(display);
2716 break;
2717
2718 case LogicalDisplayMapper.LOGICAL_DISPLAY_EVENT_DEVICE_STATE_TRANSITION:
2719 handleLogicalDisplayDeviceStateTransitionLocked(display);
2720 break;
2721 }
2722 }
2723
2724 @Override
2725 public void onDisplayGroupEventLocked(int groupId, int event) {
2726 sendDisplayGroupEvent(groupId, event);
2727 }
2728
2729 @Override
2730 public void onTraversalRequested() {
2731 synchronized (mSyncRoot) {
2732 scheduleTraversalLocked(false);
2733 }
2734 }
2735 }
1516 private void handleLogicalDisplayAddedLocked(LogicalDisplay display) {
1517 final DisplayDevice device = display.getPrimaryDisplayDeviceLocked();
1518 final int displayId = display.getDisplayIdLocked();
1519 final boolean isDefault = displayId == Display.DEFAULT_DISPLAY;
1520 configureColorModeLocked(display, device);
1521 if (!mAreUserDisabledHdrTypesAllowed) {
1522 display.setUserDisabledHdrTypes(mUserDisabledHdrTypes);
1523 }
1524 if (isDefault) {
1525 recordStableDisplayStatsIfNeededLocked(display);
1526 recordTopInsetLocked(display);
1527 }
1528 if (mUserPreferredMode != null) {
1529 device.setUserPreferredDisplayModeLocked(mUserPreferredMode);
1530 } else {
1531 configurePreferredDisplayModeLocked(display);
1532 }
// 以上方法主要是为新添加的逻辑屏创建DisplayPowerController,每一个逻辑屏都对应一个 自己的dpc,这样可以确保可以独立控制每个屏幕的亮度和显示状态.
1533 addDisplayPowerControllerLocked(display);
1534
1535 mDisplayStates.append(displayId, Display.STATE_UNKNOWN);
1536
1537 final float brightnessDefault = display.getDisplayInfoLocked().brightnessDefault;
1538 mDisplayBrightnesses.append(displayId,
1539 new BrightnessPair(brightnessDefault, brightnessDefault));
1540
1541 DisplayManagerGlobal.invalidateLocalDisplayInfoCaches();
1542
1543 // Wake up waitForDefaultDisplay.
1544 if (isDefault) {
1545 mSyncRoot.notifyAll();
1546 }
1547
1548 sendDisplayEventLocked(displayId, DisplayManagerGlobal.EVENT_DISPLAY_ADDED);
1549
1550 Runnable work = updateDisplayStateLocked(device);
1551 if (work != null) {
1552 work.run();
1553 }
1554 scheduleTraversalLocked(false);
1555 }
/frameworks/base/services/core/java/com/android/server/power/PowerManagerService.java
1256 mDisplayManagerInternal.registerDisplayGroupListener(displayGroupPowerChangeListener);
695 private final class DisplayGroupPowerChangeListener implements
696 DisplayManagerInternal.DisplayGroupListener {
697
698 static final int DISPLAY_GROUP_ADDED = 0;
699 static final int DISPLAY_GROUP_REMOVED = 1;
700 static final int DISPLAY_GROUP_CHANGED = 2;
701
702 @Override
703 public void onDisplayGroupAdded(int groupId) {
704 synchronized (mLock) {
705 if (mPowerGroups.contains(groupId)) {
706 Slog.e(TAG, "Tried to add already existing group:" + groupId);
707 return;
708 }
709 // For now, only the default group supports sandman (dream/AOD).
// 可以看到只有主屏目前支持sandman
710 final boolean supportsSandman = groupId == Display.DEFAULT_DISPLAY_GROUP;
711 final PowerGroup powerGroup = new PowerGroup(
712 groupId,
713 mPowerGroupWakefulnessChangeListener,
714 mNotifier,
715 mDisplayManagerInternal,
716 WAKEFULNESS_AWAKE,
717 /* ready= */ false,
718 supportsSandman,
719 mClock.uptimeMillis());
// 并且电源组和屏幕组靠groupid 一一对应
720 mPowerGroups.append(groupId, powerGroup);
721 onPowerGroupEventLocked(DISPLAY_GROUP_ADDED, powerGroup);
722 }
723 }