Loading services/java/com/android/server/display/DisplayManagerService.java +32 −11 Original line number Diff line number Diff line Loading @@ -58,7 +58,7 @@ import java.util.ArrayList; * </p><p> * Display adapters are only weakly coupled to the display manager service. * Display adapters communicate changes in display device state to the display manager * service asynchronously via a {@link DisplayAdapter.DisplayAdapterListener} registered * service asynchronously via a {@link DisplayAdapter.Listener} registered * by the display manager service. This separation of concerns is important for * two main reasons. First, it neatly encapsulates the responsibilities of these * two classes: display adapters handle individual display devices whereas Loading Loading @@ -254,8 +254,8 @@ public final class DisplayManagerService extends IDisplayManager.Stub { * Returns information about the specified logical display. * * @param displayId The logical display id. * @param The logical display info, or null if the display does not exist. * This object must be treated as immutable. * @return The logical display info, or null if the display does not exist. The * returned object must be treated as immutable. */ @Override // Binder call public DisplayInfo getDisplayInfo(int displayId) { Loading Loading @@ -481,14 +481,34 @@ public final class DisplayManagerService extends IDisplayManager.Stub { } } private void configureDisplayInTransactionLocked(DisplayDevice device) { // TODO: add a proper per-display mirroring control boolean isMirroring = SystemProperties.getBoolean("debug.display.mirror", true); /** * Tells the display manager whether there is interesting unique content on the * specified logical display. This is used to control automatic mirroring. * <p> * If the display has unique content, then the display manager arranges for it * to be presented on a physical display if appropriate. Otherwise, the display manager * may choose to make the physical display mirror some other logical display. * </p> * * @param displayId The logical display id to update. * @param hasContent True if the logical display has content. */ public void setDisplayHasContent(int displayId, boolean hasContent) { synchronized (mSyncRoot) { LogicalDisplay display = mLogicalDisplays.get(displayId); if (display != null && display.hasContentLocked() != hasContent) { display.setHasContentLocked(hasContent); scheduleTraversalLocked(); } } } private void configureDisplayInTransactionLocked(DisplayDevice device) { // Find the logical display that the display device is showing. LogicalDisplay display = null; if (!isMirroring) { display = findLogicalDisplayForDeviceLocked(device); LogicalDisplay display = findLogicalDisplayForDeviceLocked(device); if (display != null && !display.hasContentLocked()) { display = null; } if (display == null) { display = mLogicalDisplays.get(Display.DEFAULT_DISPLAY); Loading Loading @@ -611,8 +631,9 @@ public final class DisplayManagerService extends IDisplayManager.Stub { */ public interface WindowManagerFuncs { /** * Request that the window manager call {@link #performTraversalInTransaction} * within a surface transaction at a later time. * Request that the window manager call * {@link #performTraversalInTransactionFromWindowManager} within a surface * transaction at a later time. */ void requestTraversal(); } Loading services/java/com/android/server/display/LogicalDisplay.java +27 −1 Original line number Diff line number Diff line Loading @@ -63,6 +63,9 @@ final class LogicalDisplay { private DisplayDevice mPrimaryDisplayDevice; private DisplayDeviceInfo mPrimaryDisplayDeviceInfo; // True if the logical display has unique content. private boolean mHasContent; // Temporary rectangle used when needed. private final Rect mTempLayerStackRect = new Rect(); private final Rect mTempDisplayRect = new Rect(); Loading Loading @@ -126,7 +129,7 @@ final class LogicalDisplay { /** * Returns true if the logical display is in a valid state. * This method should be checked after calling {@link #update} to handle the * This method should be checked after calling {@link #updateLocked} to handle the * case where a logical display should be removed because all of its associated * display devices are gone or if it is otherwise no longer needed. * Loading Loading @@ -256,6 +259,29 @@ final class LogicalDisplay { device.setProjectionInTransactionLocked(orientation, mTempLayerStackRect, mTempDisplayRect); } /** * Returns true if the logical display has unique content. * <p> * If the display has unique content then we will try to ensure that it is * visible on at least its primary display device. Otherwise we will ignore the * logical display and perhaps show mirrored content on the primary display device. * </p> * * @return True if the display has unique content. */ public boolean hasContentLocked() { return mHasContent; } /** * Sets whether the logical display has unique content. * * @param hasContent True if the display has unique content. */ public void setHasContentLocked(boolean hasContent) { mHasContent = hasContent; } public void dumpLocked(PrintWriter pw) { pw.println("mLayerStack=" + mLayerStack); pw.println("mPrimaryDisplayDevice=" + (mPrimaryDisplayDevice != null ? Loading services/java/com/android/server/wm/DisplayContent.java +5 −2 Original line number Diff line number Diff line Loading @@ -94,10 +94,13 @@ class DisplayContent { } DisplayInfo getDisplayInfo() { // TODO: Add a listener for changes to Display and update mDisplayInfo when appropriate. return mDisplayInfo; } public void updateDisplayInfo() { mDisplay.getDisplayInfo(mDisplayInfo); } public void dump(PrintWriter pw) { pw.print(" Display: mDisplayId="); pw.println(mDisplayId); pw.print(" init="); pw.print(mInitialDisplayWidth); pw.print("x"); Loading @@ -121,7 +124,7 @@ class DisplayContent { pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth); pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight); pw.print(" layoutNeeded="); pw.println(layoutNeeded); pw.print("magnificationSpec="); pw.println(mMagnificationSpec.toString()); pw.print("magnificationSpec="); pw.println(mMagnificationSpec); pw.println(); } } services/java/com/android/server/wm/WindowManagerService.java +86 −5 Original line number Diff line number Diff line Loading @@ -165,7 +165,7 @@ import java.util.NoSuchElementException; /** {@hide} */ public class WindowManagerService extends IWindowManager.Stub implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs, DisplayManagerService.WindowManagerFuncs { DisplayManagerService.WindowManagerFuncs, DisplayManager.DisplayListener { static final String TAG = "WindowManager"; static final boolean DEBUG = false; static final boolean DEBUG_ADD_REMOVE = false; Loading Loading @@ -782,9 +782,15 @@ public class WindowManagerService extends IWindowManager.Stub mLimitedAlphaCompositing = context.getResources().getBoolean( com.android.internal.R.bool.config_sf_limitedAlpha); mDisplayManagerService = displayManager; mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE); mHeadless = displayManager.isHeadless(); mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE); mDisplayManager.registerDisplayListener(this, null); Display[] displays = mDisplayManager.getDisplays(); for (Display display : displays) { createDisplayContent(display); } mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy); mPowerManager = pm; Loading Loading @@ -1120,6 +1126,10 @@ public class WindowManagerService extends IWindowManager.Stub if (win.mAppToken != null && addToToken) { win.mAppToken.allAppWindows.add(win); } if (windows.size() == 1) { mDisplayManagerService.setDisplayHasContent(win.getDisplayId(), true); } } /** TODO(cmautner): Is this the same as {@link WindowState#canReceiveKeys()} */ Loading Loading @@ -2408,6 +2418,9 @@ public class WindowManagerService extends IWindowManager.Stub final WindowList windows = win.getWindowList(); windows.remove(win); if (windows.isEmpty()) { mDisplayManagerService.setDisplayHasContent(win.getDisplayId(), false); } mPendingRemove.remove(win); mWindowsChanged = true; if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win); Loading Loading @@ -7194,6 +7207,10 @@ public class WindowManagerService extends IWindowManager.Stub public static final int NOTIFY_WINDOW_TRANSITION = 29; public static final int NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED = 30; public static final int DO_DISPLAY_ADDED = 31; public static final int DO_DISPLAY_REMOVED = 32; public static final int DO_DISPLAY_CHANGED = 33; public static final int ANIMATOR_WHAT_OFFSET = 100000; public static final int SET_TRANSPARENT_REGION = ANIMATOR_WHAT_OFFSET + 1; public static final int CLEAR_PENDING_ACTIONS = ANIMATOR_WHAT_OFFSET + 2; Loading Loading @@ -7631,18 +7648,21 @@ public class WindowManagerService extends IWindowManager.Stub } break; } case NOTIFY_ROTATION_CHANGED: { final int displayId = msg.arg1; final int rotation = msg.arg2; handleNotifyRotationChanged(displayId, rotation); break; } case NOTIFY_WINDOW_TRANSITION: { final int transition = msg.arg1; WindowInfo info = (WindowInfo) msg.obj; handleNotifyWindowTranstion(transition, info); break; } case NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED: { final int displayId = msg.arg1; final boolean immediate = (msg.arg2 == 1); Loading @@ -7650,6 +7670,24 @@ public class WindowManagerService extends IWindowManager.Stub handleNotifyRectangleOnScreenRequested(displayId, rectangle, immediate); break; } case DO_DISPLAY_ADDED: synchronized (mWindowMap) { handleDisplayAddedLocked(msg.arg1); } break; case DO_DISPLAY_REMOVED: synchronized (mWindowMap) { handleDisplayRemovedLocked(msg.arg1); } break; case DO_DISPLAY_CHANGED: synchronized (mWindowMap) { handleDisplayChangedLocked(msg.arg1); } break; } if (DEBUG_WINDOW_TRACE) { Slog.v(TAG, "handleMessage: exit"); Loading Loading @@ -8866,8 +8904,6 @@ public class WindowManagerService extends IWindowManager.Stub final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo(); final int defaultDw = defaultInfo.logicalWidth; final int defaultDh = defaultInfo.logicalHeight; final int defaultInnerDw = defaultInfo.appWidth; final int defaultInnerDh = defaultInfo.appHeight; if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces"); Loading Loading @@ -9441,6 +9477,7 @@ public class WindowManagerService extends IWindowManager.Stub } } @Override public void requestTraversal() { synchronized (mWindowMap) { requestTraversalLocked(); Loading Loading @@ -10465,7 +10502,7 @@ public class WindowManagerService extends IWindowManager.Stub boolean dumpWindows(PrintWriter pw, String name, String[] args, int opti, boolean dumpAll) { ArrayList<WindowState> windows = new ArrayList<WindowState>(); WindowList windows = new WindowList(); if ("visible".equals(name)) { synchronized(mWindowMap) { final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR); Loading Loading @@ -10673,6 +10710,14 @@ public class WindowManagerService extends IWindowManager.Stub } } public void createDisplayContent(final Display display) { if (display == null) { throw new IllegalArgumentException("getDisplayContent: display must not be null"); } final DisplayContent displayContent = new DisplayContent(display); mDisplayContents.put(display.getDisplayId(), displayContent); } public DisplayContent getDisplayContent(final int displayId) { DisplayContent displayContent = mDisplayContents.get(displayId); if (displayContent == null) { Loading Loading @@ -10780,4 +10825,40 @@ public class WindowManagerService extends IWindowManager.Stub public WindowList getWindowList(final Display display) { return getDisplayContent(display.getDisplayId()).getWindowList(); } @Override public void onDisplayAdded(int displayId) { mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_ADDED, displayId, 0)); } private void handleDisplayAddedLocked(int displayId) { createDisplayContent(mDisplayManager.getDisplay(displayId)); } @Override public void onDisplayRemoved(int displayId) { mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_REMOVED, displayId, 0)); } private void handleDisplayRemovedLocked(int displayId) { final DisplayContent displayContent = getDisplayContent(displayId); mDisplayContents.delete(displayId); WindowList windows = displayContent.getWindowList(); for (int i = windows.size() - 1; i >= 0; --i) { final WindowState win = windows.get(i); removeWindowLocked(win.mSession, win); } } @Override public void onDisplayChanged(int displayId) { mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_CHANGED, displayId, 0)); } private void handleDisplayChangedLocked(int displayId) { final DisplayContent displayContent = getDisplayContent(displayId); if (displayContent != null) { displayContent.updateDisplayInfo(); } } } Loading
services/java/com/android/server/display/DisplayManagerService.java +32 −11 Original line number Diff line number Diff line Loading @@ -58,7 +58,7 @@ import java.util.ArrayList; * </p><p> * Display adapters are only weakly coupled to the display manager service. * Display adapters communicate changes in display device state to the display manager * service asynchronously via a {@link DisplayAdapter.DisplayAdapterListener} registered * service asynchronously via a {@link DisplayAdapter.Listener} registered * by the display manager service. This separation of concerns is important for * two main reasons. First, it neatly encapsulates the responsibilities of these * two classes: display adapters handle individual display devices whereas Loading Loading @@ -254,8 +254,8 @@ public final class DisplayManagerService extends IDisplayManager.Stub { * Returns information about the specified logical display. * * @param displayId The logical display id. * @param The logical display info, or null if the display does not exist. * This object must be treated as immutable. * @return The logical display info, or null if the display does not exist. The * returned object must be treated as immutable. */ @Override // Binder call public DisplayInfo getDisplayInfo(int displayId) { Loading Loading @@ -481,14 +481,34 @@ public final class DisplayManagerService extends IDisplayManager.Stub { } } private void configureDisplayInTransactionLocked(DisplayDevice device) { // TODO: add a proper per-display mirroring control boolean isMirroring = SystemProperties.getBoolean("debug.display.mirror", true); /** * Tells the display manager whether there is interesting unique content on the * specified logical display. This is used to control automatic mirroring. * <p> * If the display has unique content, then the display manager arranges for it * to be presented on a physical display if appropriate. Otherwise, the display manager * may choose to make the physical display mirror some other logical display. * </p> * * @param displayId The logical display id to update. * @param hasContent True if the logical display has content. */ public void setDisplayHasContent(int displayId, boolean hasContent) { synchronized (mSyncRoot) { LogicalDisplay display = mLogicalDisplays.get(displayId); if (display != null && display.hasContentLocked() != hasContent) { display.setHasContentLocked(hasContent); scheduleTraversalLocked(); } } } private void configureDisplayInTransactionLocked(DisplayDevice device) { // Find the logical display that the display device is showing. LogicalDisplay display = null; if (!isMirroring) { display = findLogicalDisplayForDeviceLocked(device); LogicalDisplay display = findLogicalDisplayForDeviceLocked(device); if (display != null && !display.hasContentLocked()) { display = null; } if (display == null) { display = mLogicalDisplays.get(Display.DEFAULT_DISPLAY); Loading Loading @@ -611,8 +631,9 @@ public final class DisplayManagerService extends IDisplayManager.Stub { */ public interface WindowManagerFuncs { /** * Request that the window manager call {@link #performTraversalInTransaction} * within a surface transaction at a later time. * Request that the window manager call * {@link #performTraversalInTransactionFromWindowManager} within a surface * transaction at a later time. */ void requestTraversal(); } Loading
services/java/com/android/server/display/LogicalDisplay.java +27 −1 Original line number Diff line number Diff line Loading @@ -63,6 +63,9 @@ final class LogicalDisplay { private DisplayDevice mPrimaryDisplayDevice; private DisplayDeviceInfo mPrimaryDisplayDeviceInfo; // True if the logical display has unique content. private boolean mHasContent; // Temporary rectangle used when needed. private final Rect mTempLayerStackRect = new Rect(); private final Rect mTempDisplayRect = new Rect(); Loading Loading @@ -126,7 +129,7 @@ final class LogicalDisplay { /** * Returns true if the logical display is in a valid state. * This method should be checked after calling {@link #update} to handle the * This method should be checked after calling {@link #updateLocked} to handle the * case where a logical display should be removed because all of its associated * display devices are gone or if it is otherwise no longer needed. * Loading Loading @@ -256,6 +259,29 @@ final class LogicalDisplay { device.setProjectionInTransactionLocked(orientation, mTempLayerStackRect, mTempDisplayRect); } /** * Returns true if the logical display has unique content. * <p> * If the display has unique content then we will try to ensure that it is * visible on at least its primary display device. Otherwise we will ignore the * logical display and perhaps show mirrored content on the primary display device. * </p> * * @return True if the display has unique content. */ public boolean hasContentLocked() { return mHasContent; } /** * Sets whether the logical display has unique content. * * @param hasContent True if the display has unique content. */ public void setHasContentLocked(boolean hasContent) { mHasContent = hasContent; } public void dumpLocked(PrintWriter pw) { pw.println("mLayerStack=" + mLayerStack); pw.println("mPrimaryDisplayDevice=" + (mPrimaryDisplayDevice != null ? Loading
services/java/com/android/server/wm/DisplayContent.java +5 −2 Original line number Diff line number Diff line Loading @@ -94,10 +94,13 @@ class DisplayContent { } DisplayInfo getDisplayInfo() { // TODO: Add a listener for changes to Display and update mDisplayInfo when appropriate. return mDisplayInfo; } public void updateDisplayInfo() { mDisplay.getDisplayInfo(mDisplayInfo); } public void dump(PrintWriter pw) { pw.print(" Display: mDisplayId="); pw.println(mDisplayId); pw.print(" init="); pw.print(mInitialDisplayWidth); pw.print("x"); Loading @@ -121,7 +124,7 @@ class DisplayContent { pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth); pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight); pw.print(" layoutNeeded="); pw.println(layoutNeeded); pw.print("magnificationSpec="); pw.println(mMagnificationSpec.toString()); pw.print("magnificationSpec="); pw.println(mMagnificationSpec); pw.println(); } }
services/java/com/android/server/wm/WindowManagerService.java +86 −5 Original line number Diff line number Diff line Loading @@ -165,7 +165,7 @@ import java.util.NoSuchElementException; /** {@hide} */ public class WindowManagerService extends IWindowManager.Stub implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs, DisplayManagerService.WindowManagerFuncs { DisplayManagerService.WindowManagerFuncs, DisplayManager.DisplayListener { static final String TAG = "WindowManager"; static final boolean DEBUG = false; static final boolean DEBUG_ADD_REMOVE = false; Loading Loading @@ -782,9 +782,15 @@ public class WindowManagerService extends IWindowManager.Stub mLimitedAlphaCompositing = context.getResources().getBoolean( com.android.internal.R.bool.config_sf_limitedAlpha); mDisplayManagerService = displayManager; mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE); mHeadless = displayManager.isHeadless(); mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE); mDisplayManager.registerDisplayListener(this, null); Display[] displays = mDisplayManager.getDisplays(); for (Display display : displays) { createDisplayContent(display); } mKeyguardDisableHandler = new KeyguardDisableHandler(mContext, mPolicy); mPowerManager = pm; Loading Loading @@ -1120,6 +1126,10 @@ public class WindowManagerService extends IWindowManager.Stub if (win.mAppToken != null && addToToken) { win.mAppToken.allAppWindows.add(win); } if (windows.size() == 1) { mDisplayManagerService.setDisplayHasContent(win.getDisplayId(), true); } } /** TODO(cmautner): Is this the same as {@link WindowState#canReceiveKeys()} */ Loading Loading @@ -2408,6 +2418,9 @@ public class WindowManagerService extends IWindowManager.Stub final WindowList windows = win.getWindowList(); windows.remove(win); if (windows.isEmpty()) { mDisplayManagerService.setDisplayHasContent(win.getDisplayId(), false); } mPendingRemove.remove(win); mWindowsChanged = true; if (DEBUG_WINDOW_MOVEMENT) Slog.v(TAG, "Final remove of window: " + win); Loading Loading @@ -7194,6 +7207,10 @@ public class WindowManagerService extends IWindowManager.Stub public static final int NOTIFY_WINDOW_TRANSITION = 29; public static final int NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED = 30; public static final int DO_DISPLAY_ADDED = 31; public static final int DO_DISPLAY_REMOVED = 32; public static final int DO_DISPLAY_CHANGED = 33; public static final int ANIMATOR_WHAT_OFFSET = 100000; public static final int SET_TRANSPARENT_REGION = ANIMATOR_WHAT_OFFSET + 1; public static final int CLEAR_PENDING_ACTIONS = ANIMATOR_WHAT_OFFSET + 2; Loading Loading @@ -7631,18 +7648,21 @@ public class WindowManagerService extends IWindowManager.Stub } break; } case NOTIFY_ROTATION_CHANGED: { final int displayId = msg.arg1; final int rotation = msg.arg2; handleNotifyRotationChanged(displayId, rotation); break; } case NOTIFY_WINDOW_TRANSITION: { final int transition = msg.arg1; WindowInfo info = (WindowInfo) msg.obj; handleNotifyWindowTranstion(transition, info); break; } case NOTIFY_RECTANGLE_ON_SCREEN_REQUESTED: { final int displayId = msg.arg1; final boolean immediate = (msg.arg2 == 1); Loading @@ -7650,6 +7670,24 @@ public class WindowManagerService extends IWindowManager.Stub handleNotifyRectangleOnScreenRequested(displayId, rectangle, immediate); break; } case DO_DISPLAY_ADDED: synchronized (mWindowMap) { handleDisplayAddedLocked(msg.arg1); } break; case DO_DISPLAY_REMOVED: synchronized (mWindowMap) { handleDisplayRemovedLocked(msg.arg1); } break; case DO_DISPLAY_CHANGED: synchronized (mWindowMap) { handleDisplayChangedLocked(msg.arg1); } break; } if (DEBUG_WINDOW_TRACE) { Slog.v(TAG, "handleMessage: exit"); Loading Loading @@ -8866,8 +8904,6 @@ public class WindowManagerService extends IWindowManager.Stub final DisplayInfo defaultInfo = defaultDisplay.getDisplayInfo(); final int defaultDw = defaultInfo.logicalWidth; final int defaultDh = defaultInfo.logicalHeight; final int defaultInnerDw = defaultInfo.appWidth; final int defaultInnerDh = defaultInfo.appHeight; if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces"); Loading Loading @@ -9441,6 +9477,7 @@ public class WindowManagerService extends IWindowManager.Stub } } @Override public void requestTraversal() { synchronized (mWindowMap) { requestTraversalLocked(); Loading Loading @@ -10465,7 +10502,7 @@ public class WindowManagerService extends IWindowManager.Stub boolean dumpWindows(PrintWriter pw, String name, String[] args, int opti, boolean dumpAll) { ArrayList<WindowState> windows = new ArrayList<WindowState>(); WindowList windows = new WindowList(); if ("visible".equals(name)) { synchronized(mWindowMap) { final AllWindowsIterator iterator = new AllWindowsIterator(REVERSE_ITERATOR); Loading Loading @@ -10673,6 +10710,14 @@ public class WindowManagerService extends IWindowManager.Stub } } public void createDisplayContent(final Display display) { if (display == null) { throw new IllegalArgumentException("getDisplayContent: display must not be null"); } final DisplayContent displayContent = new DisplayContent(display); mDisplayContents.put(display.getDisplayId(), displayContent); } public DisplayContent getDisplayContent(final int displayId) { DisplayContent displayContent = mDisplayContents.get(displayId); if (displayContent == null) { Loading Loading @@ -10780,4 +10825,40 @@ public class WindowManagerService extends IWindowManager.Stub public WindowList getWindowList(final Display display) { return getDisplayContent(display.getDisplayId()).getWindowList(); } @Override public void onDisplayAdded(int displayId) { mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_ADDED, displayId, 0)); } private void handleDisplayAddedLocked(int displayId) { createDisplayContent(mDisplayManager.getDisplay(displayId)); } @Override public void onDisplayRemoved(int displayId) { mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_REMOVED, displayId, 0)); } private void handleDisplayRemovedLocked(int displayId) { final DisplayContent displayContent = getDisplayContent(displayId); mDisplayContents.delete(displayId); WindowList windows = displayContent.getWindowList(); for (int i = windows.size() - 1; i >= 0; --i) { final WindowState win = windows.get(i); removeWindowLocked(win.mSession, win); } } @Override public void onDisplayChanged(int displayId) { mH.sendMessage(mH.obtainMessage(H.DO_DISPLAY_CHANGED, displayId, 0)); } private void handleDisplayChangedLocked(int displayId) { final DisplayContent displayContent = getDisplayContent(displayId); if (displayContent != null) { displayContent.updateDisplayInfo(); } } }