Merge "Make mirroring automatic based on Windows on display." into jb-mr1-dev
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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 ?
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user