Loading core/java/android/view/DisplayInfo.java +10 −0 Original line number Diff line number Diff line Loading @@ -285,6 +285,16 @@ public final class DisplayInfo implements Parcelable { getMetricsWithSize(outMetrics, cih, logicalWidth, logicalHeight); } public int getNaturalWidth() { return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ? logicalWidth : logicalHeight; } public int getNaturalHeight() { return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ? logicalHeight : logicalWidth; } private void getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfoHolder cih, int width, int height) { outMetrics.densityDpi = outMetrics.noncompatDensityDpi = logicalDensityDpi; Loading services/java/com/android/server/display/DisplayManagerService.java +40 −0 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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; Loading Loading @@ -260,6 +265,36 @@ public final class DisplayManagerService extends IDisplayManager.Stub { return mHeadless; } /** * 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 Loading Loading @@ -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(); } } /** Loading services/java/com/android/server/display/DisplayTransactionListener.java 0 → 100644 +26 −0 Original line number Diff line number Diff line /* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.display; /** * Called within a Surface transaction whenever the size or orientation of a * display may have changed. Provides an opportunity for the client to * update the position of its surfaces as part of the same transaction. */ public interface DisplayTransactionListener { void onDisplayTransaction(); } services/java/com/android/server/power/DisplayPowerController.java +5 −6 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.server.power; import com.android.server.LightsService; import com.android.server.TwilightService; import com.android.server.TwilightService.TwilightState; import com.android.server.display.DisplayManagerService; import android.animation.Animator; import android.animation.ObjectAnimator; Loading @@ -29,7 +30,6 @@ import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.hardware.SystemSensorManager; import android.hardware.display.DisplayManager; import android.os.Handler; import android.os.Looper; import android.os.Message; Loading @@ -40,7 +40,6 @@ import android.util.FloatMath; import android.util.Slog; import android.util.Spline; import android.util.TimeUtils; import android.view.Display; import java.io.PrintWriter; Loading Loading @@ -183,7 +182,7 @@ final class DisplayPowerController { private final TwilightService mTwilight; // The display manager. private final DisplayManager mDisplayManager; private final DisplayManagerService mDisplayManager; // The sensor manager. private final SensorManager mSensorManager; Loading Loading @@ -346,6 +345,7 @@ final class DisplayPowerController { */ public DisplayPowerController(Looper looper, Context context, Notifier notifier, LightsService lights, TwilightService twilight, DisplayManagerService displayManager, DisplayBlanker displayBlanker, Callbacks callbacks, Handler callbackHandler) { mHandler = new DisplayControllerHandler(looper); Loading @@ -357,7 +357,7 @@ final class DisplayPowerController { mLights = lights; mTwilight = twilight; mSensorManager = new SystemSensorManager(mHandler.getLooper()); mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE); mDisplayManager = displayManager; final Resources resources = context.getResources(); Loading Loading @@ -518,9 +518,8 @@ final class DisplayPowerController { } private void initialize() { Display display = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY); mPowerState = new DisplayPowerState( new ElectronBeam(display), mDisplayBlanker, new ElectronBeam(mDisplayManager), mDisplayBlanker, mLights.getLight(LightsService.LIGHT_ID_BACKLIGHT)); mElectronBeamOnAnimator = ObjectAnimator.ofFloat( Loading services/java/com/android/server/power/ElectronBeam.java +71 −36 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.server.power; import com.android.server.display.DisplayManagerService; import com.android.server.display.DisplayTransactionListener; import android.graphics.Bitmap; import android.graphics.PixelFormat; import android.opengl.EGL14; Loading Loading @@ -72,14 +75,13 @@ final class ElectronBeam { private boolean mPrepared; private int mMode; private final Display mDisplay; private final DisplayInfo mDisplayInfo = new DisplayInfo(); private final DisplayManagerService mDisplayManager; private int mDisplayLayerStack; // layer stack associated with primary display private int mDisplayRotation; private int mDisplayWidth; // real width, not rotated private int mDisplayHeight; // real height, not rotated private SurfaceSession mSurfaceSession; private Surface mSurface; private NaturalSurfaceLayout mSurfaceLayout; private EGLDisplay mEglDisplay; private EGLConfig mEglConfig; private EGLContext mEglContext; Loading Loading @@ -111,8 +113,8 @@ final class ElectronBeam { */ public static final int MODE_FADE = 2; public ElectronBeam(Display display) { mDisplay = display; public ElectronBeam(DisplayManagerService displayManager) { mDisplayManager = displayManager; } /** Loading @@ -129,18 +131,12 @@ final class ElectronBeam { mMode = mode; // Get the display size and adjust it for rotation. mDisplay.getDisplayInfo(mDisplayInfo); mDisplayLayerStack = mDisplay.getLayerStack(); mDisplayRotation = mDisplayInfo.rotation; if (mDisplayRotation == Surface.ROTATION_90 || mDisplayRotation == Surface.ROTATION_270) { mDisplayWidth = mDisplayInfo.logicalHeight; mDisplayHeight = mDisplayInfo.logicalWidth; } else { mDisplayWidth = mDisplayInfo.logicalWidth; mDisplayHeight = mDisplayInfo.logicalHeight; } // Get the display size and layer stack. // This is not expected to change while the electron beam surface is showing. DisplayInfo displayInfo = mDisplayManager.getDisplayInfo(Display.DEFAULT_DISPLAY); mDisplayLayerStack = displayInfo.layerStack; mDisplayWidth = displayInfo.getNaturalWidth(); mDisplayHeight = displayInfo.getNaturalHeight(); // Prepare the surface for drawing. if (!tryPrepare()) { Loading Loading @@ -551,24 +547,8 @@ final class ElectronBeam { mSurface.setLayerStack(mDisplayLayerStack); mSurface.setSize(mDisplayWidth, mDisplayHeight); switch (mDisplayRotation) { case Surface.ROTATION_0: mSurface.setPosition(0, 0); mSurface.setMatrix(1, 0, 0, 1); break; case Surface.ROTATION_90: mSurface.setPosition(0, mDisplayWidth); mSurface.setMatrix(0, -1, 1, 0); break; case Surface.ROTATION_180: mSurface.setPosition(mDisplayWidth, mDisplayHeight); mSurface.setMatrix(-1, 0, 0, -1); break; case Surface.ROTATION_270: mSurface.setPosition(mDisplayHeight, 0); mSurface.setMatrix(0, 1, -1, 0); break; } mSurfaceLayout = new NaturalSurfaceLayout(mDisplayManager, mSurface); mSurfaceLayout.onDisplayTransaction(); } finally { Surface.closeTransaction(); } Loading Loading @@ -601,6 +581,8 @@ final class ElectronBeam { private void destroySurface() { if (mSurface != null) { mSurfaceLayout.dispose(); mSurfaceLayout = null; Surface.openTransaction(); try { mSurface.destroy(); Loading Loading @@ -711,10 +693,63 @@ final class ElectronBeam { pw.println(" mPrepared=" + mPrepared); pw.println(" mMode=" + mMode); pw.println(" mDisplayLayerStack=" + mDisplayLayerStack); pw.println(" mDisplayRotation=" + mDisplayRotation); pw.println(" mDisplayWidth=" + mDisplayWidth); pw.println(" mDisplayHeight=" + mDisplayHeight); pw.println(" mSurfaceVisible=" + mSurfaceVisible); pw.println(" mSurfaceAlpha=" + mSurfaceAlpha); } /** * Keeps a surface aligned with the natural orientation of the device. * Updates the position and transformation of the matrix whenever the display * is rotated. This is a little tricky because the display transaction * callback can be invoked on any thread, not necessarily the thread that * owns the electron beam. */ private static final class NaturalSurfaceLayout implements DisplayTransactionListener { private final DisplayManagerService mDisplayManager; private Surface mSurface; public NaturalSurfaceLayout(DisplayManagerService displayManager, Surface surface) { mDisplayManager = displayManager; mSurface = surface; mDisplayManager.registerDisplayTransactionListener(this); } public void dispose() { synchronized (this) { mSurface = null; } mDisplayManager.unregisterDisplayTransactionListener(this); } @Override public void onDisplayTransaction() { synchronized (this) { if (mSurface == null) { return; } DisplayInfo displayInfo = mDisplayManager.getDisplayInfo(Display.DEFAULT_DISPLAY); switch (displayInfo.rotation) { case Surface.ROTATION_0: mSurface.setPosition(0, 0); mSurface.setMatrix(1, 0, 0, 1); break; case Surface.ROTATION_90: mSurface.setPosition(0, displayInfo.logicalHeight); mSurface.setMatrix(0, -1, 1, 0); break; case Surface.ROTATION_180: mSurface.setPosition(displayInfo.logicalWidth, displayInfo.logicalHeight); mSurface.setMatrix(-1, 0, 0, -1); break; case Surface.ROTATION_270: mSurface.setPosition(displayInfo.logicalWidth, 0); mSurface.setMatrix(0, 1, -1, 0); break; } } } } } Loading
core/java/android/view/DisplayInfo.java +10 −0 Original line number Diff line number Diff line Loading @@ -285,6 +285,16 @@ public final class DisplayInfo implements Parcelable { getMetricsWithSize(outMetrics, cih, logicalWidth, logicalHeight); } public int getNaturalWidth() { return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ? logicalWidth : logicalHeight; } public int getNaturalHeight() { return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ? logicalHeight : logicalWidth; } private void getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfoHolder cih, int width, int height) { outMetrics.densityDpi = outMetrics.noncompatDensityDpi = logicalDensityDpi; Loading
services/java/com/android/server/display/DisplayManagerService.java +40 −0 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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; Loading Loading @@ -260,6 +265,36 @@ public final class DisplayManagerService extends IDisplayManager.Stub { return mHeadless; } /** * 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 Loading Loading @@ -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(); } } /** Loading
services/java/com/android/server/display/DisplayTransactionListener.java 0 → 100644 +26 −0 Original line number Diff line number Diff line /* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.display; /** * Called within a Surface transaction whenever the size or orientation of a * display may have changed. Provides an opportunity for the client to * update the position of its surfaces as part of the same transaction. */ public interface DisplayTransactionListener { void onDisplayTransaction(); }
services/java/com/android/server/power/DisplayPowerController.java +5 −6 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.server.power; import com.android.server.LightsService; import com.android.server.TwilightService; import com.android.server.TwilightService.TwilightState; import com.android.server.display.DisplayManagerService; import android.animation.Animator; import android.animation.ObjectAnimator; Loading @@ -29,7 +30,6 @@ import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.hardware.SystemSensorManager; import android.hardware.display.DisplayManager; import android.os.Handler; import android.os.Looper; import android.os.Message; Loading @@ -40,7 +40,6 @@ import android.util.FloatMath; import android.util.Slog; import android.util.Spline; import android.util.TimeUtils; import android.view.Display; import java.io.PrintWriter; Loading Loading @@ -183,7 +182,7 @@ final class DisplayPowerController { private final TwilightService mTwilight; // The display manager. private final DisplayManager mDisplayManager; private final DisplayManagerService mDisplayManager; // The sensor manager. private final SensorManager mSensorManager; Loading Loading @@ -346,6 +345,7 @@ final class DisplayPowerController { */ public DisplayPowerController(Looper looper, Context context, Notifier notifier, LightsService lights, TwilightService twilight, DisplayManagerService displayManager, DisplayBlanker displayBlanker, Callbacks callbacks, Handler callbackHandler) { mHandler = new DisplayControllerHandler(looper); Loading @@ -357,7 +357,7 @@ final class DisplayPowerController { mLights = lights; mTwilight = twilight; mSensorManager = new SystemSensorManager(mHandler.getLooper()); mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE); mDisplayManager = displayManager; final Resources resources = context.getResources(); Loading Loading @@ -518,9 +518,8 @@ final class DisplayPowerController { } private void initialize() { Display display = mDisplayManager.getDisplay(Display.DEFAULT_DISPLAY); mPowerState = new DisplayPowerState( new ElectronBeam(display), mDisplayBlanker, new ElectronBeam(mDisplayManager), mDisplayBlanker, mLights.getLight(LightsService.LIGHT_ID_BACKLIGHT)); mElectronBeamOnAnimator = ObjectAnimator.ofFloat( Loading
services/java/com/android/server/power/ElectronBeam.java +71 −36 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.server.power; import com.android.server.display.DisplayManagerService; import com.android.server.display.DisplayTransactionListener; import android.graphics.Bitmap; import android.graphics.PixelFormat; import android.opengl.EGL14; Loading Loading @@ -72,14 +75,13 @@ final class ElectronBeam { private boolean mPrepared; private int mMode; private final Display mDisplay; private final DisplayInfo mDisplayInfo = new DisplayInfo(); private final DisplayManagerService mDisplayManager; private int mDisplayLayerStack; // layer stack associated with primary display private int mDisplayRotation; private int mDisplayWidth; // real width, not rotated private int mDisplayHeight; // real height, not rotated private SurfaceSession mSurfaceSession; private Surface mSurface; private NaturalSurfaceLayout mSurfaceLayout; private EGLDisplay mEglDisplay; private EGLConfig mEglConfig; private EGLContext mEglContext; Loading Loading @@ -111,8 +113,8 @@ final class ElectronBeam { */ public static final int MODE_FADE = 2; public ElectronBeam(Display display) { mDisplay = display; public ElectronBeam(DisplayManagerService displayManager) { mDisplayManager = displayManager; } /** Loading @@ -129,18 +131,12 @@ final class ElectronBeam { mMode = mode; // Get the display size and adjust it for rotation. mDisplay.getDisplayInfo(mDisplayInfo); mDisplayLayerStack = mDisplay.getLayerStack(); mDisplayRotation = mDisplayInfo.rotation; if (mDisplayRotation == Surface.ROTATION_90 || mDisplayRotation == Surface.ROTATION_270) { mDisplayWidth = mDisplayInfo.logicalHeight; mDisplayHeight = mDisplayInfo.logicalWidth; } else { mDisplayWidth = mDisplayInfo.logicalWidth; mDisplayHeight = mDisplayInfo.logicalHeight; } // Get the display size and layer stack. // This is not expected to change while the electron beam surface is showing. DisplayInfo displayInfo = mDisplayManager.getDisplayInfo(Display.DEFAULT_DISPLAY); mDisplayLayerStack = displayInfo.layerStack; mDisplayWidth = displayInfo.getNaturalWidth(); mDisplayHeight = displayInfo.getNaturalHeight(); // Prepare the surface for drawing. if (!tryPrepare()) { Loading Loading @@ -551,24 +547,8 @@ final class ElectronBeam { mSurface.setLayerStack(mDisplayLayerStack); mSurface.setSize(mDisplayWidth, mDisplayHeight); switch (mDisplayRotation) { case Surface.ROTATION_0: mSurface.setPosition(0, 0); mSurface.setMatrix(1, 0, 0, 1); break; case Surface.ROTATION_90: mSurface.setPosition(0, mDisplayWidth); mSurface.setMatrix(0, -1, 1, 0); break; case Surface.ROTATION_180: mSurface.setPosition(mDisplayWidth, mDisplayHeight); mSurface.setMatrix(-1, 0, 0, -1); break; case Surface.ROTATION_270: mSurface.setPosition(mDisplayHeight, 0); mSurface.setMatrix(0, 1, -1, 0); break; } mSurfaceLayout = new NaturalSurfaceLayout(mDisplayManager, mSurface); mSurfaceLayout.onDisplayTransaction(); } finally { Surface.closeTransaction(); } Loading Loading @@ -601,6 +581,8 @@ final class ElectronBeam { private void destroySurface() { if (mSurface != null) { mSurfaceLayout.dispose(); mSurfaceLayout = null; Surface.openTransaction(); try { mSurface.destroy(); Loading Loading @@ -711,10 +693,63 @@ final class ElectronBeam { pw.println(" mPrepared=" + mPrepared); pw.println(" mMode=" + mMode); pw.println(" mDisplayLayerStack=" + mDisplayLayerStack); pw.println(" mDisplayRotation=" + mDisplayRotation); pw.println(" mDisplayWidth=" + mDisplayWidth); pw.println(" mDisplayHeight=" + mDisplayHeight); pw.println(" mSurfaceVisible=" + mSurfaceVisible); pw.println(" mSurfaceAlpha=" + mSurfaceAlpha); } /** * Keeps a surface aligned with the natural orientation of the device. * Updates the position and transformation of the matrix whenever the display * is rotated. This is a little tricky because the display transaction * callback can be invoked on any thread, not necessarily the thread that * owns the electron beam. */ private static final class NaturalSurfaceLayout implements DisplayTransactionListener { private final DisplayManagerService mDisplayManager; private Surface mSurface; public NaturalSurfaceLayout(DisplayManagerService displayManager, Surface surface) { mDisplayManager = displayManager; mSurface = surface; mDisplayManager.registerDisplayTransactionListener(this); } public void dispose() { synchronized (this) { mSurface = null; } mDisplayManager.unregisterDisplayTransactionListener(this); } @Override public void onDisplayTransaction() { synchronized (this) { if (mSurface == null) { return; } DisplayInfo displayInfo = mDisplayManager.getDisplayInfo(Display.DEFAULT_DISPLAY); switch (displayInfo.rotation) { case Surface.ROTATION_0: mSurface.setPosition(0, 0); mSurface.setMatrix(1, 0, 0, 1); break; case Surface.ROTATION_90: mSurface.setPosition(0, displayInfo.logicalHeight); mSurface.setMatrix(0, -1, 1, 0); break; case Surface.ROTATION_180: mSurface.setPosition(displayInfo.logicalWidth, displayInfo.logicalHeight); mSurface.setMatrix(-1, 0, 0, -1); break; case Surface.ROTATION_270: mSurface.setPosition(displayInfo.logicalWidth, 0); mSurface.setMatrix(0, 1, -1, 0); break; } } } } }