diff options
author | Jeff Brown <jeffbrown@google.com> | 2012-12-04 14:04:28 -0800 |
---|---|---|
committer | Jeff Brown <jeffbrown@google.com> | 2012-12-04 14:40:23 -0800 |
commit | 7f3994ec2a5dce1a037f04714b1f25cab85affb6 (patch) | |
tree | 28ebf44ea836cfdcbe41ead53943104a1d026b8d /services/java/com/android/server/display/DisplayManagerService.java | |
parent | e0a676a3bb0e7b9aced9359a021e4c5d2ffef752 (diff) |
Pin electron beam surface to natural orientation.
If a rotation occurred while the electron beam surface was showing,
the surface may have appeared in the wrong orientation. We fix this
problem by adjusting the transformation matrix of the electron beam
surface according to the display orientation whenever a display
transaction occurs.
The rotation itself is allowed to proceed but it is not visible
to the user. We must let this happen so that the lock screen
is correctly oriented when the screen is turned back on.
Note that the electron beam surface serves two purposes.
First, it is used to play the screen off animation.
When the animation is finished, the surface remains visible but is
solid black. Then we turn the screen off.
Second, when we turn the screen back on we leave the electron beam
surface showing until the window manager is ready to show the
new content. This prevents the user from seeing a flash of the
old content while the screen is being turned on. When everything is
ready, we dismiss the electron beam.
It's important for the electron beam to remain visible for
the entire duration from just before the screen is turned off until
after the screen is turned on and is ready to be seen. This is
why we cannot fix the bug by deferring rotation or otherwise
getting in the way of the window manager doing what it needs
to do to get the screen ready when the screen is turned on again.
Bug: 7479740
Change-Id: I2fcf35114ad9b2e00fdfc67793be6df62c8dc4c3
Diffstat (limited to 'services/java/com/android/server/display/DisplayManagerService.java')
-rw-r--r-- | services/java/com/android/server/display/DisplayManagerService.java | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/services/java/com/android/server/display/DisplayManagerService.java b/services/java/com/android/server/display/DisplayManagerService.java index e58a0a5cb04d..e09970e93ae8 100644 --- a/services/java/com/android/server/display/DisplayManagerService.java +++ b/services/java/com/android/server/display/DisplayManagerService.java @@ -41,6 +41,7 @@ import android.view.DisplayInfo; import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; +import java.util.concurrent.CopyOnWriteArrayList; /** * Manages attached displays. @@ -152,6 +153,10 @@ public final class DisplayManagerService extends IDisplayManager.Stub { new SparseArray<LogicalDisplay>(); private int mNextNonDefaultDisplayId = Display.DEFAULT_DISPLAY + 1; + // List of all display transaction listeners. + private final CopyOnWriteArrayList<DisplayTransactionListener> mDisplayTransactionListeners = + new CopyOnWriteArrayList<DisplayTransactionListener>(); + // Set to true if all displays have been blanked by the power manager. private int mAllDisplayBlankStateFromPowerManager; @@ -261,6 +266,36 @@ public final class DisplayManagerService extends IDisplayManager.Stub { } /** + * Registers a display transaction listener to provide the client a chance to + * update its surfaces within the same transaction as any display layout updates. + * + * @param listener The listener to register. + */ + public void registerDisplayTransactionListener(DisplayTransactionListener listener) { + if (listener == null) { + throw new IllegalArgumentException("listener must not be null"); + } + + // List is self-synchronized copy-on-write. + mDisplayTransactionListeners.add(listener); + } + + /** + * Unregisters a display transaction listener to provide the client a chance to + * update its surfaces within the same transaction as any display layout updates. + * + * @param listener The listener to unregister. + */ + public void unregisterDisplayTransactionListener(DisplayTransactionListener listener) { + if (listener == null) { + throw new IllegalArgumentException("listener must not be null"); + } + + // List is self-synchronized copy-on-write. + mDisplayTransactionListeners.remove(listener); + } + + /** * Overrides the display information of a particular logical display. * This is used by the window manager to control the size and characteristics * of the default display. It is expected to apply the requested change @@ -298,6 +333,11 @@ public final class DisplayManagerService extends IDisplayManager.Stub { performTraversalInTransactionLocked(); } + + // List is self-synchronized copy-on-write. + for (DisplayTransactionListener listener : mDisplayTransactionListeners) { + listener.onDisplayTransaction(); + } } /** |