diff options
| author | Jeff Brown <jeffbrown@google.com> | 2012-09-07 16:01:36 -0700 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-09-07 16:01:37 -0700 |
| commit | 72018294cc4e3cc5feb7affdec4bf4bb2368ac41 (patch) | |
| tree | add91a7ce260c33d8fc72acd56606d5719e749b4 | |
| parent | 7017e48380ab0c1be033594bb2a9331898ad5be8 (diff) | |
| parent | 722285e199a9fc74b9b3343b7505c00666848c88 (diff) | |
| download | frameworks_base-72018294cc4e3cc5feb7affdec4bf4bb2368ac41.zip frameworks_base-72018294cc4e3cc5feb7affdec4bf4bb2368ac41.tar.gz frameworks_base-72018294cc4e3cc5feb7affdec4bf4bb2368ac41.tar.bz2 | |
Merge "Make mirroring automatic based on Windows on display." into jb-mr1-dev
4 files changed, 150 insertions, 19 deletions
diff --git a/services/java/com/android/server/display/DisplayManagerService.java b/services/java/com/android/server/display/DisplayManagerService.java index ae958df..dc85d3f 100644 --- a/services/java/com/android/server/display/DisplayManagerService.java +++ b/services/java/com/android/server/display/DisplayManagerService.java @@ -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 @@ -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) { @@ -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); @@ -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(); } diff --git a/services/java/com/android/server/display/LogicalDisplay.java b/services/java/com/android/server/display/LogicalDisplay.java index c864189..e0f63dd 100644 --- a/services/java/com/android/server/display/LogicalDisplay.java +++ b/services/java/com/android/server/display/LogicalDisplay.java @@ -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(); @@ -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. * @@ -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 ? diff --git a/services/java/com/android/server/wm/DisplayContent.java b/services/java/com/android/server/wm/DisplayContent.java index 0ea051f..4df692b 100644 --- a/services/java/com/android/server/wm/DisplayContent.java +++ b/services/java/com/android/server/wm/DisplayContent.java @@ -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"); @@ -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(); } } diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index a668efb..18e793d 100755 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -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; @@ -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; @@ -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()} */ @@ -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); @@ -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; @@ -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); @@ -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"); @@ -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"); @@ -9441,6 +9477,7 @@ public class WindowManagerService extends IWindowManager.Stub } } + @Override public void requestTraversal() { synchronized (mWindowMap) { requestTraversalLocked(); @@ -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); @@ -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) { @@ -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(); + } + } } |
