powerms和ims,dms之间的关联关系

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值