diff options
30 files changed, 1393 insertions, 1338 deletions
diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java index 9b5857f..06ef472 100644 --- a/core/java/android/app/UiAutomationConnection.java +++ b/core/java/android/app/UiAutomationConnection.java @@ -27,7 +27,7 @@ import android.os.RemoteException; import android.os.ServiceManager; import android.view.IWindowManager; import android.view.InputEvent; -import android.view.Surface; +import android.view.SurfaceControl; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.IAccessibilityManager; @@ -135,7 +135,7 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub { } final long identity = Binder.clearCallingIdentity(); try { - return Surface.screenshot(width, height); + return SurfaceControl.screenshot(width, height); } finally { Binder.restoreCallingIdentity(identity); } diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java index b661748..f28e4b5 100644 --- a/core/java/android/view/Choreographer.java +++ b/core/java/android/view/Choreographer.java @@ -693,7 +693,7 @@ public final class Choreographer { // At this time Surface Flinger won't send us vsyncs for secondary displays // but that could change in the future so let's log a message to help us remember // that we need to fix this. - if (builtInDisplayId != Surface.BUILT_IN_DISPLAY_ID_MAIN) { + if (builtInDisplayId != SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) { Log.d(TAG, "Received vsync from secondary display, but we don't support " + "this case yet. Choreographer needs a way to explicitly request " + "vsync for a specific display to ensure it doesn't lose track " diff --git a/core/java/android/view/DisplayEventReceiver.java b/core/java/android/view/DisplayEventReceiver.java index a919ffc..4dade20 100644 --- a/core/java/android/view/DisplayEventReceiver.java +++ b/core/java/android/view/DisplayEventReceiver.java @@ -102,7 +102,7 @@ public abstract class DisplayEventReceiver { * @param timestampNanos The timestamp of the pulse, in the {@link System#nanoTime()} * timebase. * @param builtInDisplayId The surface flinger built-in display id such as - * {@link Surface#BUILT_IN_DISPLAY_ID_MAIN}. + * {@link SurfaceControl#BUILT_IN_DISPLAY_ID_MAIN}. * @param frame The frame number. Increases by one for each vertical sync interval. */ public void onVsync(long timestampNanos, int builtInDisplayId, int frame) { @@ -114,7 +114,7 @@ public abstract class DisplayEventReceiver { * @param timestampNanos The timestamp of the event, in the {@link System#nanoTime()} * timebase. * @param builtInDisplayId The surface flinger built-in display id such as - * {@link Surface#BUILT_IN_DISPLAY_ID_HDMI}. + * {@link SurfaceControl#BUILT_IN_DISPLAY_ID_HDMI}. * @param connected True if the display is connected, false if it disconnected. */ public void onHotplug(long timestampNanos, int builtInDisplayId, boolean connected) { diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index 48b7180..5e96dad 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -16,20 +16,15 @@ package android.view; -import dalvik.system.CloseGuard; - import android.content.res.CompatibilityInfo.Translator; -import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Rect; -import android.graphics.Region; import android.graphics.SurfaceTexture; -import android.os.IBinder; -import android.os.Parcelable; import android.os.Parcel; -import android.os.SystemProperties; +import android.os.Parcelable; import android.util.Log; +import dalvik.system.CloseGuard; /** * Handle onto a raw buffer that is being managed by the screen compositor. @@ -37,9 +32,6 @@ import android.util.Log; public class Surface implements Parcelable { private static final String TAG = "Surface"; - private static final boolean HEADLESS = "1".equals( - SystemProperties.get("ro.config.headless", "0")); - public static final Parcelable.Creator<Surface> CREATOR = new Parcelable.Creator<Surface>() { public Surface createFromParcel(Parcel source) { @@ -78,130 +70,6 @@ public class Surface implements Parcelable { */ public static final int ROTATION_270 = 3; - /* built-in physical display ids (keep in sync with ISurfaceComposer.h) - * these are different from the logical display ids used elsewhere in the framework */ - - /** - * Built-in physical display id: Main display. - * Use only with {@link #getBuiltInDisplay()}. - * @hide - */ - public static final int BUILT_IN_DISPLAY_ID_MAIN = 0; - - /** - * Built-in physical display id: Attached HDMI display. - * Use only with {@link #getBuiltInDisplay()}. - * @hide - */ - public static final int BUILT_IN_DISPLAY_ID_HDMI = 1; - - /* flags used in constructor (keep in sync with ISurfaceComposerClient.h) */ - - /** - * Surface creation flag: Surface is created hidden - * @hide */ - public static final int HIDDEN = 0x00000004; - - /** - * Surface creation flag: The surface contains secure content, special - * measures will be taken to disallow the surface's content to be copied - * from another process. In particular, screenshots and VNC servers will - * be disabled, but other measures can take place, for instance the - * surface might not be hardware accelerated. - * @hide - */ - public static final int SECURE = 0x00000080; - - /** - * Surface creation flag: Creates a surface where color components are interpreted - * as "non pre-multiplied" by their alpha channel. Of course this flag is - * meaningless for surfaces without an alpha channel. By default - * surfaces are pre-multiplied, which means that each color component is - * already multiplied by its alpha value. In this case the blending - * equation used is: - * - * DEST = SRC + DEST * (1-SRC_ALPHA) - * - * By contrast, non pre-multiplied surfaces use the following equation: - * - * DEST = SRC * SRC_ALPHA * DEST * (1-SRC_ALPHA) - * - * pre-multiplied surfaces must always be used if transparent pixels are - * composited on top of each-other into the surface. A pre-multiplied - * surface can never lower the value of the alpha component of a given - * pixel. - * - * In some rare situations, a non pre-multiplied surface is preferable. - * @hide - */ - public static final int NON_PREMULTIPLIED = 0x00000100; - - /** - * Surface creation flag: Indicates that the surface must be considered opaque, - * even if its pixel format is set to translucent. This can be useful if an - * application needs full RGBA 8888 support for instance but will - * still draw every pixel opaque. - * @hide - */ - public static final int OPAQUE = 0x00000400; - - /** - * Surface creation flag: Application requires a hardware-protected path to an - * external display sink. If a hardware-protected path is not available, - * then this surface will not be displayed on the external sink. - * @hide - */ - public static final int PROTECTED_APP = 0x00000800; - - // 0x1000 is reserved for an independent DRM protected flag in framework - - /** - * Surface creation flag: Creates a normal surface. - * This is the default. - * @hide - */ - public static final int FX_SURFACE_NORMAL = 0x00000000; - - /** - * Surface creation flag: Creates a Blur surface. - * Everything behind this surface is blurred by some amount. - * The quality and refresh speed of the blur effect is not settable or guaranteed. - * It is an error to lock a Blur surface, since it doesn't have a backing store. - * @hide - * @deprecated - */ - @Deprecated - public static final int FX_SURFACE_BLUR = 0x00010000; - - /** - * Surface creation flag: Creates a Dim surface. - * Everything behind this surface is dimmed by the amount specified - * in {@link #setAlpha}. It is an error to lock a Dim surface, since it - * doesn't have a backing store. - * @hide - */ - public static final int FX_SURFACE_DIM = 0x00020000; - - /** - * @hide - */ - public static final int FX_SURFACE_SCREENSHOT = 0x00030000; - - /** - * Mask used for FX values above. - * @hide - */ - public static final int FX_SURFACE_MASK = 0x000F0000; - - /* flags used with setFlags() (keep in sync with ISurfaceComposer.h) */ - - /** - * Surface flag: Hide the surface. - * Equivalent to calling hide(). - * @hide - */ - public static final int SURFACE_HIDDEN = 0x01; - private final CloseGuard mCloseGuard = CloseGuard.get(); private String mName; @@ -211,8 +79,8 @@ public class Surface implements Parcelable { // server or system processes. When this class is parceled we defer to the // mSurfaceControl to do the parceling. Otherwise we parcel the // mNativeSurface. - private int mNativeSurface; // Surface* - private int mNativeSurfaceControl; // SurfaceControl* + int mNativeObject; // package scope only for SurfaceControl access + private int mGenerationId; // incremented each time mNativeSurface changes private final Canvas mCanvas = new CompatibleCanvas(); private int mCanvasSaveCount; // Canvas save count at time of lockCanvas() @@ -225,112 +93,12 @@ public class Surface implements Parcelable { // non compatibility mode. private Matrix mCompatibleMatrix; - private native void nativeCreate(SurfaceSession session, String name, - int w, int h, int format, int flags) - throws OutOfResourcesException; - private native void nativeCreateFromSurfaceTexture(SurfaceTexture surfaceTexture) - throws OutOfResourcesException; - private native void nativeRelease(); - private native void nativeDestroy(); - - private native boolean nativeIsValid(); - private native boolean nativeIsConsumerRunningBehind(); - - private native Canvas nativeLockCanvas(Rect dirty); - private native void nativeUnlockCanvasAndPost(Canvas canvas); - - private static native Bitmap nativeScreenshot(IBinder displayToken, - int width, int height, int minLayer, int maxLayer, boolean allLayers); - - private static native void nativeOpenTransaction(); - private static native void nativeCloseTransaction(); - private static native void nativeSetAnimationTransaction(); - - private native void nativeSetLayer(int zorder); - private native void nativeSetPosition(float x, float y); - private native void nativeSetSize(int w, int h); - private native void nativeSetTransparentRegionHint(Region region); - private native void nativeSetAlpha(float alpha); - private native void nativeSetMatrix(float dsdx, float dtdx, float dsdy, float dtdy); - private native void nativeSetFlags(int flags, int mask); - private native void nativeSetWindowCrop(Rect crop); - private native void nativeSetLayerStack(int layerStack); - - private static native IBinder nativeGetBuiltInDisplay(int physicalDisplayId); - private static native IBinder nativeCreateDisplay(String name, boolean secure); - private static native void nativeSetDisplaySurface( - IBinder displayToken, Surface surface); - private static native void nativeSetDisplayLayerStack( - IBinder displayToken, int layerStack); - private static native void nativeSetDisplayProjection( - IBinder displayToken, int orientation, Rect layerStackRect, Rect displayRect); - private static native boolean nativeGetDisplayInfo( - IBinder displayToken, PhysicalDisplayInfo outInfo); - private static native void nativeBlankDisplay(IBinder displayToken); - private static native void nativeUnblankDisplay(IBinder displayToken); - - private native void nativeCopyFrom(Surface other); - private native void nativeTransferFrom(Surface other); - private native void nativeReadFromParcel(Parcel source); - private native void nativeWriteToParcel(Parcel dest); - /** * Create an empty surface, which will later be filled in by readFromParcel(). * @hide */ public Surface() { - checkHeadless(); - - mCloseGuard.open("release"); - } - - /** - * Create a surface with a name. - * - * The surface creation flags specify what kind of surface to create and - * certain options such as whether the surface can be assumed to be opaque - * and whether it should be initially hidden. Surfaces should always be - * created with the {@link #HIDDEN} flag set to ensure that they are not - * made visible prematurely before all of the surface's properties have been - * configured. - * - * Good practice is to first create the surface with the {@link #HIDDEN} flag - * specified, open a transaction, set the surface layer, layer stack, alpha, - * and position, call {@link #show} if appropriate, and close the transaction. - * - * @param session The surface session, must not be null. - * @param name The surface name, must not be null. - * @param w The surface initial width. - * @param h The surface initial height. - * @param flags The surface creation flags. Should always include {@link #HIDDEN} - * in the creation flags. - * @hide - */ - public Surface(SurfaceSession session, - String name, int w, int h, int format, int flags) - throws OutOfResourcesException { - if (session == null) { - throw new IllegalArgumentException("session must not be null"); - } - if (name == null) { - throw new IllegalArgumentException("name must not be null"); - } - - if ((flags & HIDDEN) == 0) { - Log.w(TAG, "Surfaces should always be created with the HIDDEN flag set " - + "to ensure that they are not made visible prematurely before " - + "all of the surface's properties have been configured. " - + "Set the other properties and make the surface visible within " - + "a transaction. New surface name: " + name, - new Throwable()); - } - - checkHeadless(); - - mName = name; - nativeCreate(session, name, w, h, format, flags); - mCloseGuard.open("release"); } @@ -349,11 +117,9 @@ public class Surface implements Parcelable { throw new IllegalArgumentException("surfaceTexture must not be null"); } - checkHeadless(); - mName = surfaceTexture.toString(); try { - nativeCreateFromSurfaceTexture(surfaceTexture); + mNativeObject = nativeCreateFromSurfaceTexture(surfaceTexture); } catch (OutOfResourcesException ex) { // We can't throw OutOfResourcesException because it would be an API change. throw new RuntimeException(ex); @@ -362,13 +128,20 @@ public class Surface implements Parcelable { mCloseGuard.open("release"); } + private Surface(int nativeObject) { + mNativeObject = nativeObject; + mCloseGuard.open("release"); + } + @Override protected void finalize() throws Throwable { try { if (mCloseGuard != null) { mCloseGuard.warnIfOpen(); } - nativeRelease(); + if (mNativeObject != 0) { + nativeRelease(mNativeObject); + } } finally { super.finalize(); } @@ -380,7 +153,10 @@ public class Surface implements Parcelable { * This will make the surface invalid. */ public void release() { - nativeRelease(); + if (mNativeObject != 0) { + nativeRelease(mNativeObject); + mNativeObject = 0; + } mCloseGuard.close(); } @@ -391,7 +167,10 @@ public class Surface implements Parcelable { * @hide */ public void destroy() { - nativeDestroy(); + if (mNativeObject != 0) { + nativeDestroy(mNativeObject); + mNativeObject = 0; + } mCloseGuard.close(); } @@ -402,7 +181,8 @@ public class Surface implements Parcelable { * Otherwise returns false. */ public boolean isValid() { - return nativeIsValid(); + if (mNativeObject == 0) return false; + return nativeIsValid(mNativeObject); } /** @@ -423,7 +203,8 @@ public class Surface implements Parcelable { * @hide */ public boolean isConsumerRunningBehind() { - return nativeIsConsumerRunningBehind(); + checkNotReleased(); + return nativeIsConsumerRunningBehind(mNativeObject); } /** @@ -441,9 +222,10 @@ public class Surface implements Parcelable { * entire surface should be redrawn. * @return A canvas for drawing into the surface. */ - public Canvas lockCanvas(Rect dirty) + public Canvas lockCanvas(Rect inOutDirty) throws OutOfResourcesException, IllegalArgumentException { - return nativeLockCanvas(dirty); + checkNotReleased(); + return nativeLockCanvas(mNativeObject, inOutDirty); } /** @@ -453,7 +235,8 @@ public class Surface implements Parcelable { * @param canvas The canvas previously obtained from {@link #lockCanvas}. */ public void unlockCanvasAndPost(Canvas canvas) { - nativeUnlockCanvasAndPost(canvas); + checkNotReleased(); + nativeUnlockCanvasAndPost(mNativeObject, canvas); } /** @@ -476,190 +259,6 @@ public class Surface implements Parcelable { } } - /** - * Like {@link #screenshot(int, int, int, int)} but includes all - * Surfaces in the screenshot. - * - * @hide - */ - public static Bitmap screenshot(int width, int height) { - // TODO: should take the display as a parameter - IBinder displayToken = getBuiltInDisplay(BUILT_IN_DISPLAY_ID_MAIN); - return nativeScreenshot(displayToken, width, height, 0, 0, true); - } - - /** - * Copy the current screen contents into a bitmap and return it. - * - * @param width The desired width of the returned bitmap; the raw - * screen will be scaled down to this size. - * @param height The desired height of the returned bitmap; the raw - * screen will be scaled down to this size. - * @param minLayer The lowest (bottom-most Z order) surface layer to - * include in the screenshot. - * @param maxLayer The highest (top-most Z order) surface layer to - * include in the screenshot. - * @return Returns a Bitmap containing the screen contents, or null - * if an error occurs. - * - * @hide - */ - public static Bitmap screenshot(int width, int height, int minLayer, int maxLayer) { - // TODO: should take the display as a parameter - IBinder displayToken = getBuiltInDisplay(BUILT_IN_DISPLAY_ID_MAIN); - return nativeScreenshot(displayToken, width, height, minLayer, maxLayer, false); - } - - /* - * set surface parameters. - * needs to be inside open/closeTransaction block - */ - - /** start a transaction @hide */ - public static void openTransaction() { - nativeOpenTransaction(); - } - - /** end a transaction @hide */ - public static void closeTransaction() { - nativeCloseTransaction(); - } - - /** flag the transaction as an animation @hide */ - public static void setAnimationTransaction() { - nativeSetAnimationTransaction(); - } - - /** @hide */ - public void setLayer(int zorder) { - nativeSetLayer(zorder); - } - - /** @hide */ - public void setPosition(int x, int y) { - nativeSetPosition((float)x, (float)y); - } - - /** @hide */ - public void setPosition(float x, float y) { - nativeSetPosition(x, y); - } - - /** @hide */ - public void setSize(int w, int h) { - nativeSetSize(w, h); - } - - /** @hide */ - public void hide() { - nativeSetFlags(SURFACE_HIDDEN, SURFACE_HIDDEN); - } - - /** @hide */ - public void show() { - nativeSetFlags(0, SURFACE_HIDDEN); - } - - /** @hide */ - public void setTransparentRegionHint(Region region) { - nativeSetTransparentRegionHint(region); - } - - /** @hide */ - public void setAlpha(float alpha) { - nativeSetAlpha(alpha); - } - - /** @hide */ - public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { - nativeSetMatrix(dsdx, dtdx, dsdy, dtdy); - } - - /** @hide */ - public void setFlags(int flags, int mask) { - nativeSetFlags(flags, mask); - } - - /** @hide */ - public void setWindowCrop(Rect crop) { - nativeSetWindowCrop(crop); - } - - /** @hide */ - public void setLayerStack(int layerStack) { - nativeSetLayerStack(layerStack); - } - - /** @hide */ - public static IBinder getBuiltInDisplay(int builtInDisplayId) { - return nativeGetBuiltInDisplay(builtInDisplayId); - } - - /** @hide */ - public static IBinder createDisplay(String name, boolean secure) { - if (name == null) { - throw new IllegalArgumentException("name must not be null"); - } - return nativeCreateDisplay(name, secure); - } - - /** @hide */ - public static void setDisplaySurface(IBinder displayToken, Surface surface) { - if (displayToken == null) { - throw new IllegalArgumentException("displayToken must not be null"); - } - nativeSetDisplaySurface(displayToken, surface); - } - - /** @hide */ - public static void setDisplayLayerStack(IBinder displayToken, int layerStack) { - if (displayToken == null) { - throw new IllegalArgumentException("displayToken must not be null"); - } - nativeSetDisplayLayerStack(displayToken, layerStack); - } - - /** @hide */ - public static void setDisplayProjection(IBinder displayToken, - int orientation, Rect layerStackRect, Rect displayRect) { - if (displayToken == null) { - throw new IllegalArgumentException("displayToken must not be null"); - } - if (layerStackRect == null) { - throw new IllegalArgumentException("layerStackRect must not be null"); - } - if (displayRect == null) { - throw new IllegalArgumentException("displayRect must not be null"); - } - nativeSetDisplayProjection(displayToken, orientation, layerStackRect, displayRect); - } - - /** @hide */ - public static boolean getDisplayInfo(IBinder displayToken, PhysicalDisplayInfo outInfo) { - if (displayToken == null) { - throw new IllegalArgumentException("displayToken must not be null"); - } - if (outInfo == null) { - throw new IllegalArgumentException("outInfo must not be null"); - } - return nativeGetDisplayInfo(displayToken, outInfo); - } - - /** @hide */ - public static void blankDisplay(IBinder displayToken) { - if (displayToken == null) { - throw new IllegalArgumentException("displayToken must not be null"); - } - nativeBlankDisplay(displayToken); - } - - /** @hide */ - public static void unblankDisplay(IBinder displayToken) { - if (displayToken == null) { - throw new IllegalArgumentException("displayToken must not be null"); - } - nativeUnblankDisplay(displayToken); - } /** * Copy another surface to this one. This surface now holds a reference @@ -670,13 +269,15 @@ public class Surface implements Parcelable { * in to it. * @hide */ - public void copyFrom(Surface other) { + public void copyFrom(SurfaceControl other) { if (other == null) { throw new IllegalArgumentException("other must not be null"); } - if (other != this) { - nativeCopyFrom(other); + if (other.mNativeObject == 0) { + throw new NullPointerException( + "SurfaceControl native object is null. Are you using a released SurfaceControl?"); } + mNativeObject = nativeCopyFrom(mNativeObject, other.mNativeObject); } /** @@ -692,7 +293,13 @@ public class Surface implements Parcelable { throw new IllegalArgumentException("other must not be null"); } if (other != this) { - nativeTransferFrom(other); + if (mNativeObject != 0) { + // release our reference to our native object + nativeRelease(mNativeObject); + } + // transfer the reference from other to us + mNativeObject = other.mNativeObject; + other.mNativeObject = 0; } } @@ -705,9 +312,8 @@ public class Surface implements Parcelable { if (source == null) { throw new IllegalArgumentException("source must not be null"); } - mName = source.readString(); - nativeReadFromParcel(source); + mNativeObject = nativeReadFromParcel(mNativeObject, source); } @Override @@ -715,9 +321,8 @@ public class Surface implements Parcelable { if (dest == null) { throw new IllegalArgumentException("dest must not be null"); } - dest.writeString(mName); - nativeWriteToParcel(dest); + nativeWriteToParcel(mNativeObject, dest); if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) { release(); } @@ -728,85 +333,18 @@ public class Surface implements Parcelable { return "Surface(name=" + mName + ")"; } - private static void checkHeadless() { - if (HEADLESS) { - throw new UnsupportedOperationException("Device is headless"); - } - } - /** * Exception thrown when a surface couldn't be created or resized. */ public static class OutOfResourcesException extends Exception { public OutOfResourcesException() { } - public OutOfResourcesException(String name) { super(name); } } /** - * Describes the properties of a physical display known to surface flinger. - * @hide - */ - public static final class PhysicalDisplayInfo { - public int width; - public int height; - public float refreshRate; - public float density; - public float xDpi; - public float yDpi; - public boolean secure; - - public PhysicalDisplayInfo() { - } - - public PhysicalDisplayInfo(PhysicalDisplayInfo other) { - copyFrom(other); - } - - @Override - public boolean equals(Object o) { - return o instanceof PhysicalDisplayInfo && equals((PhysicalDisplayInfo)o); - } - - public boolean equals(PhysicalDisplayInfo other) { - return other != null - && width == other.width - && height == other.height - && refreshRate == other.refreshRate - && density == other.density - && xDpi == other.xDpi - && yDpi == other.yDpi - && secure == other.secure; - } - - @Override - public int hashCode() { - return 0; // don't care - } - - public void copyFrom(PhysicalDisplayInfo other) { - width = other.width; - height = other.height; - refreshRate = other.refreshRate; - density = other.density; - xDpi = other.xDpi; - yDpi = other.yDpi; - secure = other.secure; - } - - // For debugging purposes - @Override - public String toString() { - return "PhysicalDisplayInfo{" + width + " x " + height + ", " + refreshRate + " fps, " - + "density " + density + ", " + xDpi + " x " + yDpi + " dpi, secure " + secure - + "}"; - } - } - - /** * Returns a human readable representation of a rotation. * * @param rotation The rotation. @@ -893,4 +431,25 @@ public class Surface implements Parcelable { mOrigMatrix.set(m); } } + + private void checkNotReleased() { + if (mNativeObject == 0) throw new NullPointerException( + "mNativeObject is null. Have you called release() already?"); + } + + private native int nativeCreateFromSurfaceTexture(SurfaceTexture surfaceTexture) + throws OutOfResourcesException; + + private native void nativeRelease(int nativeObject); + private native void nativeDestroy(int nativeObject); + private native boolean nativeIsValid(int nativeObject); + + private native boolean nativeIsConsumerRunningBehind(int nativeObject); + + private native Canvas nativeLockCanvas(int nativeObject, Rect dirty); + private native void nativeUnlockCanvasAndPost(int nativeObject, Canvas canvas); + + private native int nativeCopyFrom(int nativeObject, int surfaceControlNativeObject); + private native int nativeReadFromParcel(int nativeObject, Parcel source); + private native void nativeWriteToParcel(int nativeObject, Parcel dest); } diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java new file mode 100644 index 0000000..dd288b9 --- /dev/null +++ b/core/java/android/view/SurfaceControl.java @@ -0,0 +1,575 @@ +/* + * Copyright (C) 2013 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 android.view; + +import dalvik.system.CloseGuard; +import android.graphics.Bitmap; +import android.graphics.Rect; +import android.graphics.Region; +import android.os.IBinder; +import android.os.SystemProperties; +import android.util.Log; + +/** + * SurfaceControl + * @hide + */ +public class SurfaceControl { + private static final String TAG = "SurfaceControl"; + private final CloseGuard mCloseGuard = CloseGuard.get(); + private String mName; + int mNativeObject; // package visibility only for Surface.java access + + private static final boolean HEADLESS = "1".equals( + SystemProperties.get("ro.config.headless", "0")); + + /** + * Exception thrown when a surface couldn't be created or resized. + */ + public static class OutOfResourcesException extends Exception { + public OutOfResourcesException() { + } + public OutOfResourcesException(String name) { + super(name); + } + } + + /* flags used in constructor (keep in sync with ISurfaceComposerClient.h) */ + + /** + * Surface creation flag: Surface is created hidden + */ + public static final int HIDDEN = 0x00000004; + + /** + * Surface creation flag: The surface contains secure content, special + * measures will be taken to disallow the surface's content to be copied + * from another process. In particular, screenshots and VNC servers will + * be disabled, but other measures can take place, for instance the + * surface might not be hardware accelerated. + * + */ + public static final int SECURE = 0x00000080; + + /** + * Surface creation flag: Creates a surface where color components are interpreted + * as "non pre-multiplied" by their alpha channel. Of course this flag is + * meaningless for surfaces without an alpha channel. By default + * surfaces are pre-multiplied, which means that each color component is + * already multiplied by its alpha value. In this case the blending + * equation used is: + * + * DEST = SRC + DEST * (1-SRC_ALPHA) + * + * By contrast, non pre-multiplied surfaces use the following equation: + * + * DEST = SRC * SRC_ALPHA * DEST * (1-SRC_ALPHA) + * + * pre-multiplied surfaces must always be used if transparent pixels are + * composited on top of each-other into the surface. A pre-multiplied + * surface can never lower the value of the alpha component of a given + * pixel. + * + * In some rare situations, a non pre-multiplied surface is preferable. + * + */ + public static final int NON_PREMULTIPLIED = 0x00000100; + + /** + * Surface creation flag: Indicates that the surface must be considered opaque, + * even if its pixel format is set to translucent. This can be useful if an + * application needs full RGBA 8888 support for instance but will + * still draw every pixel opaque. + * + */ + public static final int OPAQUE = 0x00000400; + + /** + * Surface creation flag: Application requires a hardware-protected path to an + * external display sink. If a hardware-protected path is not available, + * then this surface will not be displayed on the external sink. + * + */ + public static final int PROTECTED_APP = 0x00000800; + + // 0x1000 is reserved for an independent DRM protected flag in framework + + /** + * Surface creation flag: Creates a normal surface. + * This is the default. + * + */ + public static final int FX_SURFACE_NORMAL = 0x00000000; + + /** + * Surface creation flag: Creates a Blur surface. + * Everything behind this surface is blurred by some amount. + * The quality and refresh speed of the blur effect is not settable or guaranteed. + * It is an error to lock a Blur surface, since it doesn't have a backing store. + * + * @deprecated + */ + @Deprecated + public static final int FX_SURFACE_BLUR = 0x00010000; + + /** + * Surface creation flag: Creates a Dim surface. + * Everything behind this surface is dimmed by the amount specified + * in {@link #setAlpha}. It is an error to lock a Dim surface, since it + * doesn't have a backing store. + * + */ + public static final int FX_SURFACE_DIM = 0x00020000; + + /** + * + */ + public static final int FX_SURFACE_SCREENSHOT = 0x00030000; + + /** + * Mask used for FX values above. + * + */ + public static final int FX_SURFACE_MASK = 0x000F0000; + + /* flags used with setFlags() (keep in sync with ISurfaceComposer.h) */ + + /** + * Surface flag: Hide the surface. + * Equivalent to calling hide(). + */ + public static final int SURFACE_HIDDEN = 0x01; + + + /* built-in physical display ids (keep in sync with ISurfaceComposer.h) + * these are different from the logical display ids used elsewhere in the framework */ + + /** + * Built-in physical display id: Main display. + * Use only with {@link SurfaceControl#getBuiltInDisplay()}. + */ + public static final int BUILT_IN_DISPLAY_ID_MAIN = 0; + + /** + * Built-in physical display id: Attached HDMI display. + * Use only with {@link SurfaceControl#getBuiltInDisplay()}. + */ + public static final int BUILT_IN_DISPLAY_ID_HDMI = 1; + + + + /** + * Create a surface with a name. + * + * The surface creation flags specify what kind of surface to create and + * certain options such as whether the surface can be assumed to be opaque + * and whether it should be initially hidden. Surfaces should always be + * created with the {@link #HIDDEN} flag set to ensure that they are not + * made visible prematurely before all of the surface's properties have been + * configured. + * + * Good practice is to first create the surface with the {@link #HIDDEN} flag + * specified, open a transaction, set the surface layer, layer stack, alpha, + * and position, call {@link #show} if appropriate, and close the transaction. + * + * @param session The surface session, must not be null. + * @param name The surface name, must not be null. + * @param w The surface initial width. + * @param h The surface initial height. + * @param flags The surface creation flags. Should always include {@link #HIDDEN} + * in the creation flags. + */ + public SurfaceControl(SurfaceSession session, + String name, int w, int h, int format, int flags) + throws OutOfResourcesException { + if (session == null) { + throw new IllegalArgumentException("session must not be null"); + } + if (name == null) { + throw new IllegalArgumentException("name must not be null"); + } + + if ((flags & SurfaceControl.HIDDEN) == 0) { + Log.w(TAG, "Surfaces should always be created with the HIDDEN flag set " + + "to ensure that they are not made visible prematurely before " + + "all of the surface's properties have been configured. " + + "Set the other properties and make the surface visible within " + + "a transaction. New surface name: " + name, + new Throwable()); + } + + checkHeadless(); + + mName = name; + mNativeObject = nativeCreate(session, name, w, h, format, flags); + if (mNativeObject == 0) { + throw new OutOfResourcesException( + "Couldn't allocate SurfaceControl native object"); + } + + mCloseGuard.open("release"); + } + + @Override + protected void finalize() throws Throwable { + try { + if (mCloseGuard != null) { + mCloseGuard.warnIfOpen(); + } + if (mNativeObject != 0) { + nativeRelease(mNativeObject); + } + } finally { + super.finalize(); + } + } + + @Override + public String toString() { + return "Surface(name=" + mName + ")"; + } + + /** + * Release the local reference to the server-side surface. + * Always call release() when you're done with a Surface. + * This will make the surface invalid. + */ + public void release() { + if (mNativeObject != 0) { + nativeRelease(mNativeObject); + mNativeObject = 0; + } + mCloseGuard.close(); + } + + /** + * Free all server-side state associated with this surface and + * release this object's reference. This method can only be + * called from the process that created the service. + */ + public void destroy() { + if (mNativeObject != 0) { + nativeDestroy(mNativeObject); + mNativeObject = 0; + } + mCloseGuard.close(); + } + + private void checkNotReleased() { + if (mNativeObject == 0) throw new NullPointerException( + "mNativeObject is null. Have you called release() already?"); + } + + /* + * set surface parameters. + * needs to be inside open/closeTransaction block + */ + + /** start a transaction */ + public static void openTransaction() { + nativeOpenTransaction(); + } + + /** end a transaction */ + public static void closeTransaction() { + nativeCloseTransaction(); + } + + /** flag the transaction as an animation */ + public static void setAnimationTransaction() { + nativeSetAnimationTransaction(); + } + + public void setLayer(int zorder) { + checkNotReleased(); + nativeSetLayer(mNativeObject, zorder); + } + + public void setPosition(int x, int y) { + checkNotReleased(); + nativeSetPosition(mNativeObject, (float)x, (float)y); + } + + public void setPosition(float x, float y) { + checkNotReleased(); + nativeSetPosition(mNativeObject, x, y); + } + + public void setSize(int w, int h) { + checkNotReleased(); + nativeSetSize(mNativeObject, w, h); + } + + public void hide() { + checkNotReleased(); + nativeSetFlags(mNativeObject, SURFACE_HIDDEN, SURFACE_HIDDEN); + } + + public void show() { + checkNotReleased(); + nativeSetFlags(mNativeObject, 0, SURFACE_HIDDEN); + } + + public void setTransparentRegionHint(Region region) { + checkNotReleased(); + nativeSetTransparentRegionHint(mNativeObject, region); + } + + public void setAlpha(float alpha) { + checkNotReleased(); + nativeSetAlpha(mNativeObject, alpha); + } + + public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) { + checkNotReleased(); + nativeSetMatrix(mNativeObject, dsdx, dtdx, dsdy, dtdy); + } + + public void setFlags(int flags, int mask) { + checkNotReleased(); + nativeSetFlags(mNativeObject, flags, mask); + } + + public void setWindowCrop(Rect crop) { + checkNotReleased(); + if (crop != null) { + nativeSetWindowCrop(mNativeObject, + crop.left, crop.top, crop.right, crop.bottom); + } else { + nativeSetWindowCrop(mNativeObject, 0, 0, 0, 0); + } + } + + public void setLayerStack(int layerStack) { + checkNotReleased(); + nativeSetLayerStack(mNativeObject, layerStack); + } + + /* + * set display parameters. + * needs to be inside open/closeTransaction block + */ + + /** + * Describes the properties of a physical display known to surface flinger. + */ + public static final class PhysicalDisplayInfo { + public int width; + public int height; + public float refreshRate; + public float density; + public float xDpi; + public float yDpi; + public boolean secure; + + public PhysicalDisplayInfo() { + } + + public PhysicalDisplayInfo(PhysicalDisplayInfo other) { + copyFrom(other); + } + + @Override + public boolean equals(Object o) { + return o instanceof PhysicalDisplayInfo && equals((PhysicalDisplayInfo)o); + } + + public boolean equals(PhysicalDisplayInfo other) { + return other != null + && width == other.width + && height == other.height + && refreshRate == other.refreshRate + && density == other.density + && xDpi == other.xDpi + && yDpi == other.yDpi + && secure == other.secure; + } + + @Override + public int hashCode() { + return 0; // don't care + } + + public void copyFrom(PhysicalDisplayInfo other) { + width = other.width; + height = other.height; + refreshRate = other.refreshRate; + density = other.density; + xDpi = other.xDpi; + yDpi = other.yDpi; + secure = other.secure; + } + + // For debugging purposes + @Override + public String toString() { + return "PhysicalDisplayInfo{" + width + " x " + height + ", " + refreshRate + " fps, " + + "density " + density + ", " + xDpi + " x " + yDpi + " dpi, secure " + secure + + "}"; + } + } + + public static void unblankDisplay(IBinder displayToken) { + if (displayToken == null) { + throw new IllegalArgumentException("displayToken must not be null"); + } + nativeUnblankDisplay(displayToken); + } + + public static void blankDisplay(IBinder displayToken) { + if (displayToken == null) { + throw new IllegalArgumentException("displayToken must not be null"); + } + nativeBlankDisplay(displayToken); + } + + public static boolean getDisplayInfo(IBinder displayToken, SurfaceControl.PhysicalDisplayInfo outInfo) { + if (displayToken == null) { + throw new IllegalArgumentException("displayToken must not be null"); + } + if (outInfo == null) { + throw new IllegalArgumentException("outInfo must not be null"); + } + return nativeGetDisplayInfo(displayToken, outInfo); + } + + public static void setDisplayProjection(IBinder displayToken, + int orientation, Rect layerStackRect, Rect displayRect) { + if (displayToken == null) { + throw new IllegalArgumentException("displayToken must not be null"); + } + if (layerStackRect == null) { + throw new IllegalArgumentException("layerStackRect must not be null"); + } + if (displayRect == null) { + throw new IllegalArgumentException("displayRect must not be null"); + } + nativeSetDisplayProjection(displayToken, orientation, + layerStackRect.left, layerStackRect.top, layerStackRect.right, layerStackRect.bottom, + displayRect.left, displayRect.top, displayRect.right, displayRect.bottom); + } + + public static void setDisplayLayerStack(IBinder displayToken, int layerStack) { + if (displayToken == null) { + throw new IllegalArgumentException("displayToken must not be null"); + } + nativeSetDisplayLayerStack(displayToken, layerStack); + } + + public static void setDisplaySurface(IBinder displayToken, Surface surface) { + if (displayToken == null) { + throw new IllegalArgumentException("displayToken must not be null"); + } + if (surface == null) { + throw new IllegalArgumentException("surface must not be null"); + } + if (surface.mNativeObject == 0) + throw new NullPointerException("Surface native object is null. Are you using a released surface?"); + + nativeSetDisplaySurface(displayToken, surface.mNativeObject); + } + + public static IBinder createDisplay(String name, boolean secure) { + if (name == null) { + throw new IllegalArgumentException("name must not be null"); + } + return nativeCreateDisplay(name, secure); + } + + public static IBinder getBuiltInDisplay(int builtInDisplayId) { + return nativeGetBuiltInDisplay(builtInDisplayId); + } + + + /** + * Copy the current screen contents into a bitmap and return it. + * + * @param width The desired width of the returned bitmap; the raw + * screen will be scaled down to this size. + * @param height The desired height of the returned bitmap; the raw + * screen will be scaled down to this size. + * @param minLayer The lowest (bottom-most Z order) surface layer to + * include in the screenshot. + * @param maxLayer The highest (top-most Z order) surface layer to + * include in the screenshot. + * @return Returns a Bitmap containing the screen contents, or null + * if an error occurs. + * + */ + public static Bitmap screenshot(int width, int height, int minLayer, int maxLayer) { + // TODO: should take the display as a parameter + IBinder displayToken = SurfaceControl.getBuiltInDisplay(SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); + return nativeScreenshot(displayToken, width, height, minLayer, maxLayer, false); + } + + /** + * Like {@link SurfaceControl#screenshot(int, int, int, int)} but includes all + * Surfaces in the screenshot. + * + */ + public static Bitmap screenshot(int width, int height) { + // TODO: should take the display as a parameter + IBinder displayToken = SurfaceControl.getBuiltInDisplay(SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); + return nativeScreenshot(displayToken, width, height, 0, 0, true); + } + + private static void checkHeadless() { + if (HEADLESS) { + throw new UnsupportedOperationException("Device is headless"); + } + } + + + + private native int nativeCreate(SurfaceSession session, String name, + int w, int h, int format, int flags) + throws OutOfResourcesException; + private native void nativeRelease(int nativeObject); + private native void nativeDestroy(int nativeObject); + + private static native Bitmap nativeScreenshot(IBinder displayToken, + int width, int height, int minLayer, int maxLayer, boolean allLayers); + + private static native void nativeOpenTransaction(); + private static native void nativeCloseTransaction(); + private static native void nativeSetAnimationTransaction(); + + private native void nativeSetLayer(int nativeObject, int zorder); + private native void nativeSetPosition(int nativeObject, float x, float y); + private native void nativeSetSize(int nativeObject, int w, int h); + private native void nativeSetTransparentRegionHint(int nativeObject, Region region); + private native void nativeSetAlpha(int nativeObject, float alpha); + private native void nativeSetMatrix(int nativeObject, float dsdx, float dtdx, float dsdy, float dtdy); + private native void nativeSetFlags(int nativeObject, int flags, int mask); + private native void nativeSetWindowCrop(int nativeObject, int l, int t, int r, int b); + private native void nativeSetLayerStack(int nativeObject, int layerStack); + + private static native IBinder nativeGetBuiltInDisplay(int physicalDisplayId); + private static native IBinder nativeCreateDisplay(String name, boolean secure); + private static native void nativeSetDisplaySurface( + IBinder displayToken, int nativeSurfaceObject); + private static native void nativeSetDisplayLayerStack( + IBinder displayToken, int layerStack); + private static native void nativeSetDisplayProjection( + IBinder displayToken, int orientation, + int l, int t, int r, int b, + int L, int T, int R, int B); + private static native boolean nativeGetDisplayInfo( + IBinder displayToken, SurfaceControl.PhysicalDisplayInfo outInfo); + private static native void nativeBlankDisplay(IBinder displayToken); + private static native void nativeUnblankDisplay(IBinder displayToken); +} diff --git a/core/jni/Android.mk b/core/jni/Android.mk index d705024..f47865e 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -42,6 +42,7 @@ LOCAL_SRC_FILES:= \ android_emoji_EmojiFactory.cpp \ android_view_DisplayEventReceiver.cpp \ android_view_Surface.cpp \ + android_view_SurfaceControl.cpp \ android_view_SurfaceSession.cpp \ android_view_TextureView.cpp \ android_view_InputChannel.cpp \ diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 94324f8..74fd391 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -47,8 +47,6 @@ using namespace android; -extern void register_BindTest(); - extern int register_android_os_Binder(JNIEnv* env); extern int register_android_os_Process(JNIEnv* env); extern int register_android_graphics_Bitmap(JNIEnv*); @@ -121,6 +119,7 @@ extern int register_android_view_GLES20DisplayList(JNIEnv* env); extern int register_android_view_GLES20Canvas(JNIEnv* env); extern int register_android_view_HardwareRenderer(JNIEnv* env); extern int register_android_view_Surface(JNIEnv* env); +extern int register_android_view_SurfaceControl(JNIEnv* env); extern int register_android_view_SurfaceSession(JNIEnv* env); extern int register_android_view_TextureView(JNIEnv* env); extern int register_android_database_CursorWindow(JNIEnv* env); @@ -1112,6 +1111,7 @@ static const RegJNIRec gRegJNI[] = { REG_JNI(register_android_view_GLES20Canvas), REG_JNI(register_android_view_HardwareRenderer), REG_JNI(register_android_view_Surface), + REG_JNI(register_android_view_SurfaceControl), REG_JNI(register_android_view_SurfaceSession), REG_JNI(register_android_view_TextureView), REG_JNI(register_com_google_android_gles_jni_EGLImpl), diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp index 0e0893b..7c65662 100644 --- a/core/jni/android_hardware_Camera.cpp +++ b/core/jni/android_hardware_Camera.cpp @@ -23,6 +23,7 @@ #include "JNIHelp.h" #include "android_runtime/AndroidRuntime.h" #include <android_runtime/android_graphics_SurfaceTexture.h> +#include <android_runtime/android_view_Surface.h> #include <cutils/properties.h> #include <utils/Vector.h> @@ -36,7 +37,6 @@ using namespace android; struct fields_t { jfieldID context; - jfieldID surface; jfieldID facing; jfieldID orientation; jfieldID canDisableShutterSound; @@ -537,10 +537,8 @@ static void android_hardware_Camera_setPreviewDisplay(JNIEnv *env, jobject thiz, sp<Camera> camera = get_native_camera(env, thiz, NULL); if (camera == 0) return; - sp<Surface> surface = NULL; - if (jSurface != NULL) { - surface = reinterpret_cast<Surface*>(env->GetIntField(jSurface, fields.surface)); - } + sp<Surface> surface = android_view_Surface_getSurface(env, jSurface); + if (camera->setPreviewDisplay(surface) != NO_ERROR) { jniThrowException(env, "java/io/IOException", "setPreviewDisplay failed"); } @@ -965,7 +963,6 @@ int register_android_hardware_Camera(JNIEnv *env) { field fields_to_find[] = { { "android/hardware/Camera", "mNativeContext", "I", &fields.context }, - { "android/view/Surface", ANDROID_VIEW_SURFACE_JNI_ID, "I", &fields.surface }, { "android/hardware/Camera$CameraInfo", "facing", "I", &fields.facing }, { "android/hardware/Camera$CameraInfo", "orientation", "I", &fields.orientation }, { "android/hardware/Camera$CameraInfo", "canDisableShutterSound", "Z", diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index 40b505c..6f71868 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -18,41 +18,30 @@ #include <stdio.h> +#include "jni.h" +#include "JNIHelp.h" #include "android_os_Parcel.h" -#include "android_util_Binder.h" #include "android/graphics/GraphicsJNI.h" -#include "android/graphics/Region.h" -#include <binder/IMemory.h> +#include <android_runtime/AndroidRuntime.h> +#include <android_runtime/android_view_Surface.h> +#include <android_runtime/android_graphics_SurfaceTexture.h> -#include <gui/ISurfaceComposer.h> #include <gui/Surface.h> -#include <gui/SurfaceComposerClient.h> #include <gui/GLConsumer.h> -#include <ui/DisplayInfo.h> #include <ui/Rect.h> #include <ui/Region.h> -#include <EGL/egl.h> - #include <SkCanvas.h> #include <SkBitmap.h> #include <SkRegion.h> -#include <SkPixelRef.h> -#include "jni.h" -#include "JNIHelp.h" -#include <android_runtime/AndroidRuntime.h> -#include <android_runtime/android_view_Surface.h> -#include <android_runtime/android_view_SurfaceSession.h> -#include <android_runtime/android_graphics_SurfaceTexture.h> #include <utils/misc.h> #include <utils/Log.h> #include <ScopedUtfChars.h> - // ---------------------------------------------------------------------------- namespace android { @@ -62,8 +51,7 @@ static const char* const OutOfResourcesException = static struct { jclass clazz; - jfieldID mNativeSurface; - jfieldID mNativeSurfaceControl; + jfieldID mNativeObject; jfieldID mGenerationId; jfieldID mCanvas; jfieldID mCanvasSaveCount; @@ -82,166 +70,19 @@ static struct { jfieldID mSurfaceFormat; } gCanvasClassInfo; -static struct { - jfieldID width; - jfieldID height; - jfieldID refreshRate; - jfieldID density; - jfieldID xDpi; - jfieldID yDpi; - jfieldID secure; -} gPhysicalDisplayInfoClassInfo; - - -class ScreenshotPixelRef : public SkPixelRef { -public: - ScreenshotPixelRef(SkColorTable* ctable) { - fCTable = ctable; - SkSafeRef(ctable); - setImmutable(); - } - - virtual ~ScreenshotPixelRef() { - SkSafeUnref(fCTable); - } - - status_t update(const sp<IBinder>& display, int width, int height, - int minLayer, int maxLayer, bool allLayers) { - status_t res = (width > 0 && height > 0) - ? (allLayers - ? mScreenshot.update(display, width, height) - : mScreenshot.update(display, width, height, minLayer, maxLayer)) - : mScreenshot.update(display); - if (res != NO_ERROR) { - return res; - } - - return NO_ERROR; - } - - uint32_t getWidth() const { - return mScreenshot.getWidth(); - } - - uint32_t getHeight() const { - return mScreenshot.getHeight(); - } - - uint32_t getStride() const { - return mScreenshot.getStride(); - } - - uint32_t getFormat() const { - return mScreenshot.getFormat(); - } - -protected: - // overrides from SkPixelRef - virtual void* onLockPixels(SkColorTable** ct) { - *ct = fCTable; - return (void*)mScreenshot.getPixels(); - } - - virtual void onUnlockPixels() { - } - -private: - ScreenshotClient mScreenshot; - SkColorTable* fCTable; - - typedef SkPixelRef INHERITED; -}; - - // ---------------------------------------------------------------------------- -static sp<SurfaceControl> getSurfaceControl(JNIEnv* env, jobject surfaceObj) { - return reinterpret_cast<SurfaceControl*>( - env->GetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurfaceControl)); -} - -static void setSurfaceControl(JNIEnv* env, jobject surfaceObj, - const sp<SurfaceControl>& surface) { - SurfaceControl* const p = reinterpret_cast<SurfaceControl*>( - env->GetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurfaceControl)); - if (surface.get()) { - surface->incStrong(surfaceObj); - } - if (p) { - p->decStrong(surfaceObj); - } - env->SetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurfaceControl, - reinterpret_cast<jint>(surface.get())); -} - -static sp<Surface> getSurface(JNIEnv* env, jobject surfaceObj) { - sp<Surface> result(android_view_Surface_getSurface(env, surfaceObj)); - if (result == NULL) { - /* - * if this method is called from the WindowManager's process, it means - * the client is is not remote, and therefore is allowed to have - * a Surface (data), so we create it here. - * If we don't have a SurfaceControl, it means we're in a different - * process. - */ - - SurfaceControl* const control = reinterpret_cast<SurfaceControl*>( - env->GetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurfaceControl)); - if (control) { - result = control->getSurface(); - if (result != NULL) { - result->incStrong(surfaceObj); - env->SetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurface, - reinterpret_cast<jint>(result.get())); - } - } - } - return result; -} - -sp<ANativeWindow> android_view_Surface_getNativeWindow(JNIEnv* env, jobject surfaceObj) { - return getSurface(env, surfaceObj); -} - bool android_view_Surface_isInstanceOf(JNIEnv* env, jobject obj) { return env->IsInstanceOf(obj, gSurfaceClassInfo.clazz); } -sp<Surface> android_view_Surface_getSurface(JNIEnv* env, jobject surfaceObj) { - return reinterpret_cast<Surface*>( - env->GetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurface)); -} - -static void setSurface(JNIEnv* env, jobject surfaceObj, const sp<Surface>& surface) { - Surface* const p = reinterpret_cast<Surface*>( - env->GetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurface)); - if (surface.get()) { - surface->incStrong(surfaceObj); - } - if (p) { - p->decStrong(surfaceObj); - } - env->SetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurface, - reinterpret_cast<jint>(surface.get())); - - // This test is conservative and it would be better to compare the ISurfaces - if (p && p != surface.get()) { - jint generationId = env->GetIntField(surfaceObj, - gSurfaceClassInfo.mGenerationId); - generationId++; - env->SetIntField(surfaceObj, - gSurfaceClassInfo.mGenerationId, generationId); - } +sp<ANativeWindow> android_view_Surface_getNativeWindow(JNIEnv* env, jobject surfaceObj) { + return android_view_Surface_getSurface(env, surfaceObj); } -static sp<IGraphicBufferProducer> getISurfaceTexture(JNIEnv* env, jobject surfaceObj) { - if (surfaceObj) { - sp<Surface> surface(getSurface(env, surfaceObj)); - if (surface != NULL) { - return surface->getSurfaceTexture(); - } - } - return NULL; +sp<Surface> android_view_Surface_getSurface(JNIEnv* env, jobject surfaceObj) { + return reinterpret_cast<Surface *>( + env->GetIntField(surfaceObj, gSurfaceClassInfo.mNativeObject)); } jobject android_view_Surface_createFromISurfaceTexture(JNIEnv* env, @@ -255,7 +96,7 @@ jobject android_view_Surface_createFromISurfaceTexture(JNIEnv* env, return NULL; } - jobject surfaceObj = env->NewObject(gSurfaceClassInfo.clazz, gSurfaceClassInfo.ctor); + jobject surfaceObj = env->NewObject(gSurfaceClassInfo.clazz, gSurfaceClassInfo.ctor, surface.get()); if (surfaceObj == NULL) { if (env->ExceptionCheck()) { ALOGE("Could not create instance of Surface from IGraphicBufferProducer."); @@ -264,82 +105,55 @@ jobject android_view_Surface_createFromISurfaceTexture(JNIEnv* env, } return NULL; } - - setSurface(env, surfaceObj, surface); + surface->incStrong(surfaceObj); return surfaceObj; } - // ---------------------------------------------------------------------------- -static void nativeCreate(JNIEnv* env, jobject surfaceObj, jobject sessionObj, - jstring nameStr, jint w, jint h, jint format, jint flags) { - ScopedUtfChars name(env, nameStr); - sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj)); - - sp<SurfaceControl> surface = client->createSurface( - String8(name.c_str()), w, h, format, flags); - if (surface == NULL) { - jniThrowException(env, OutOfResourcesException, NULL); - return; - } - - setSurfaceControl(env, surfaceObj, surface); -} - -static void nativeCreateFromSurfaceTexture(JNIEnv* env, jobject surfaceObj, +static jint nativeCreateFromSurfaceTexture(JNIEnv* env, jobject surfaceObj, jobject surfaceTextureObj) { sp<GLConsumer> st(SurfaceTexture_getSurfaceTexture(env, surfaceTextureObj)); if (st == NULL) { jniThrowException(env, "java/lang/IllegalArgumentException", "SurfaceTexture has already been released"); - return; + return 0; } sp<IGraphicBufferProducer> bq = st->getBufferQueue(); - sp<Surface> surface(new Surface(bq)); if (surface == NULL) { jniThrowException(env, OutOfResourcesException, NULL); - return; + return 0; } - setSurface(env, surfaceObj, surface); + surface->incStrong(surfaceObj); + return int(surface.get()); } -static void nativeRelease(JNIEnv* env, jobject surfaceObj) { - setSurfaceControl(env, surfaceObj, NULL); - setSurface(env, surfaceObj, NULL); +static void nativeRelease(JNIEnv* env, jobject surfaceObj, jint nativeObject) { + sp<Surface> sur(reinterpret_cast<Surface *>(nativeObject)); + sur->decStrong(surfaceObj); } -static void nativeDestroy(JNIEnv* env, jobject surfaceObj) { - sp<SurfaceControl> surfaceControl(getSurfaceControl(env, surfaceObj)); - if (SurfaceControl::isValid(surfaceControl)) { - surfaceControl->clear(); - } - setSurfaceControl(env, surfaceObj, NULL); - setSurface(env, surfaceObj, NULL); +static void nativeDestroy(JNIEnv* env, jobject surfaceObj, jint nativeObject) { + sp<Surface> sur(reinterpret_cast<Surface *>(nativeObject)); + sur->decStrong(surfaceObj); } -static jboolean nativeIsValid(JNIEnv* env, jobject surfaceObj) { - sp<SurfaceControl> surfaceControl(getSurfaceControl(env, surfaceObj)); - if (surfaceControl != NULL) { - return SurfaceControl::isValid(surfaceControl) ? JNI_TRUE : JNI_FALSE; - } - - sp<Surface> surface(getSurface(env, surfaceObj)); - return Surface::isValid(surface) ? JNI_TRUE : JNI_FALSE; +static jboolean nativeIsValid(JNIEnv* env, jobject surfaceObj, jint nativeObject) { + sp<Surface> sur(reinterpret_cast<Surface *>(nativeObject)); + return Surface::isValid(sur) ? JNI_TRUE : JNI_FALSE; } -static jboolean nativeIsConsumerRunningBehind(JNIEnv* env, jobject surfaceObj) { - sp<Surface> surface(getSurface(env, surfaceObj)); - if (!Surface::isValid(surface)) { +static jboolean nativeIsConsumerRunningBehind(JNIEnv* env, jobject surfaceObj, jint nativeObject) { + sp<Surface> sur(reinterpret_cast<Surface *>(nativeObject)); + if (!Surface::isValid(sur)) { doThrowIAE(env); return JNI_FALSE; } - int value = 0; - ANativeWindow* anw = static_cast<ANativeWindow*>(surface.get()); + ANativeWindow* anw = static_cast<ANativeWindow*>(sur.get()); anw->query(anw, NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &value); return value; } @@ -359,8 +173,9 @@ static inline SkBitmap::Config convertPixelFormat(PixelFormat format) { } } -static jobject nativeLockCanvas(JNIEnv* env, jobject surfaceObj, jobject dirtyRectObj) { - sp<Surface> surface(getSurface(env, surfaceObj)); +static jobject nativeLockCanvas(JNIEnv* env, jobject surfaceObj, jint nativeObject, jobject dirtyRectObj) { + sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject)); + if (!Surface::isValid(surface)) { doThrowIAE(env); return NULL; @@ -440,14 +255,14 @@ static jobject nativeLockCanvas(JNIEnv* env, jobject surfaceObj, jobject dirtyRe return canvasObj; } -static void nativeUnlockCanvasAndPost(JNIEnv* env, jobject surfaceObj, jobject canvasObj) { +static void nativeUnlockCanvasAndPost(JNIEnv* env, jobject surfaceObj, jint nativeObject, jobject canvasObj) { jobject ownCanvasObj = env->GetObjectField(surfaceObj, gSurfaceClassInfo.mCanvas); if (!env->IsSameObject(ownCanvasObj, canvasObj)) { doThrowIAE(env); return; } - sp<Surface> surface(getSurface(env, surfaceObj)); + sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject)); if (!Surface::isValid(surface)) { return; } @@ -467,393 +282,81 @@ static void nativeUnlockCanvasAndPost(JNIEnv* env, jobject surfaceObj, jobject c } } -static jobject nativeScreenshot(JNIEnv* env, jclass clazz, jobject displayTokenObj, - jint width, jint height, jint minLayer, jint maxLayer, bool allLayers) { - sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj); - if (displayToken == NULL) { - return NULL; - } - - ScreenshotPixelRef* pixels = new ScreenshotPixelRef(NULL); - if (pixels->update(displayToken, width, height, - minLayer, maxLayer, allLayers) != NO_ERROR) { - delete pixels; - return NULL; - } - - uint32_t w = pixels->getWidth(); - uint32_t h = pixels->getHeight(); - uint32_t s = pixels->getStride(); - uint32_t f = pixels->getFormat(); - ssize_t bpr = s * android::bytesPerPixel(f); - - SkBitmap* bitmap = new SkBitmap(); - bitmap->setConfig(convertPixelFormat(f), w, h, bpr); - if (f == PIXEL_FORMAT_RGBX_8888) { - bitmap->setIsOpaque(true); - } - - if (w > 0 && h > 0) { - bitmap->setPixelRef(pixels)->unref(); - bitmap->lockPixels(); - } else { - // be safe with an empty bitmap. - delete pixels; - bitmap->setPixels(NULL); - } - - return GraphicsJNI::createBitmap(env, bitmap, false, NULL); -} - -static void nativeOpenTransaction(JNIEnv* env, jclass clazz) { - SurfaceComposerClient::openGlobalTransaction(); -} - -static void nativeCloseTransaction(JNIEnv* env, jclass clazz) { - SurfaceComposerClient::closeGlobalTransaction(); -} - -static void nativeSetAnimationTransaction(JNIEnv* env, jclass clazz) { - SurfaceComposerClient::setAnimationTransaction(); -} - -static void nativeSetLayer(JNIEnv* env, jobject surfaceObj, jint zorder) { - sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj)); - if (surface == NULL) return; - - status_t err = surface->setLayer(zorder); - if (err < 0 && err != NO_INIT) { - doThrowIAE(env); - } -} - -static void nativeSetPosition(JNIEnv* env, jobject surfaceObj, jfloat x, jfloat y) { - sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj)); - if (surface == NULL) return; - - status_t err = surface->setPosition(x, y); - if (err < 0 && err != NO_INIT) { - doThrowIAE(env); - } -} - -static void nativeSetSize(JNIEnv* env, jobject surfaceObj, jint w, jint h) { - sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj)); - if (surface == NULL) return; - - status_t err = surface->setSize(w, h); - if (err < 0 && err != NO_INIT) { - doThrowIAE(env); - } -} - -static void nativeSetFlags(JNIEnv* env, jobject surfaceObj, jint flags, jint mask) { - sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj)); - if (surface == NULL) return; - - status_t err = surface->setFlags(flags, mask); - if (err < 0 && err != NO_INIT) { - doThrowIAE(env); - } -} - -static void nativeSetTransparentRegionHint(JNIEnv* env, jobject surfaceObj, jobject regionObj) { - sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj)); - if (surface == NULL) return; - - SkRegion* region = android_graphics_Region_getSkRegion(env, regionObj); - if (!region) { - doThrowIAE(env); - return; - } - - const SkIRect& b(region->getBounds()); - Region reg(Rect(b.fLeft, b.fTop, b.fRight, b.fBottom)); - if (region->isComplex()) { - SkRegion::Iterator it(*region); - while (!it.done()) { - const SkIRect& r(it.rect()); - reg.addRectUnchecked(r.fLeft, r.fTop, r.fRight, r.fBottom); - it.next(); - } - } - - status_t err = surface->setTransparentRegionHint(reg); - if (err < 0 && err != NO_INIT) { - doThrowIAE(env); - } -} - -static void nativeSetAlpha(JNIEnv* env, jobject surfaceObj, jfloat alpha) { - sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj)); - if (surface == NULL) return; - - status_t err = surface->setAlpha(alpha); - if (err < 0 && err != NO_INIT) { - doThrowIAE(env); - } -} - -static void nativeSetMatrix(JNIEnv* env, jobject surfaceObj, - jfloat dsdx, jfloat dtdx, jfloat dsdy, jfloat dtdy) { - sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj)); - if (surface == NULL) return; - - status_t err = surface->setMatrix(dsdx, dtdx, dsdy, dtdy); - if (err < 0 && err != NO_INIT) { - doThrowIAE(env); - } -} - -static void nativeSetWindowCrop(JNIEnv* env, jobject surfaceObj, jobject cropObj) { - const sp<SurfaceControl>& surface(getSurfaceControl(env, surfaceObj)); - if (surface == NULL) return; - - Rect crop; - if (cropObj) { - crop.left = env->GetIntField(cropObj, gRectClassInfo.left); - crop.top = env->GetIntField(cropObj, gRectClassInfo.top); - crop.right = env->GetIntField(cropObj, gRectClassInfo.right); - crop.bottom = env->GetIntField(cropObj, gRectClassInfo.bottom); - } else { - crop.left = crop.top = crop.right = crop.bottom = 0; - } - - status_t err = surface->setCrop(crop); - if (err < 0 && err != NO_INIT) { - doThrowIAE(env); - } -} - -static void nativeSetLayerStack(JNIEnv* env, jobject surfaceObj, jint layerStack) { - sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj)); - if (surface == NULL) return; - - status_t err = surface->setLayerStack(layerStack); - if (err < 0 && err != NO_INIT) { - doThrowIAE(env); - } -} - -static jobject nativeGetBuiltInDisplay(JNIEnv* env, jclass clazz, jint id) { - sp<IBinder> token(SurfaceComposerClient::getBuiltInDisplay(id)); - return javaObjectForIBinder(env, token); -} - -static jobject nativeCreateDisplay(JNIEnv* env, jclass clazz, jstring nameObj, - jboolean secure) { - ScopedUtfChars name(env, nameObj); - sp<IBinder> token(SurfaceComposerClient::createDisplay( - String8(name.c_str()), bool(secure))); - return javaObjectForIBinder(env, token); -} - -static void nativeSetDisplaySurface(JNIEnv* env, jclass clazz, - jobject tokenObj, jobject surfaceObj) { - sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); - if (token == NULL) return; - - sp<IGraphicBufferProducer> bufferProducer(getISurfaceTexture(env, surfaceObj)); - SurfaceComposerClient::setDisplaySurface(token, bufferProducer); -} - -static void nativeSetDisplayLayerStack(JNIEnv* env, jclass clazz, - jobject tokenObj, jint layerStack) { - sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); - if (token == NULL) return; - - SurfaceComposerClient::setDisplayLayerStack(token, layerStack); -} - -static void nativeSetDisplayProjection(JNIEnv* env, jclass clazz, - jobject tokenObj, jint orientation, jobject layerStackRectObj, jobject displayRectObj) { - sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); - if (token == NULL) return; - - Rect layerStackRect; - layerStackRect.left = env->GetIntField(layerStackRectObj, gRectClassInfo.left); - layerStackRect.top = env->GetIntField(layerStackRectObj, gRectClassInfo.top); - layerStackRect.right = env->GetIntField(layerStackRectObj, gRectClassInfo.right); - layerStackRect.bottom = env->GetIntField(layerStackRectObj, gRectClassInfo.bottom); - - Rect displayRect; - displayRect.left = env->GetIntField(displayRectObj, gRectClassInfo.left); - displayRect.top = env->GetIntField(displayRectObj, gRectClassInfo.top); - displayRect.right = env->GetIntField(displayRectObj, gRectClassInfo.right); - displayRect.bottom = env->GetIntField(displayRectObj, gRectClassInfo.bottom); - - SurfaceComposerClient::setDisplayProjection(token, orientation, layerStackRect, displayRect); -} - -static jboolean nativeGetDisplayInfo(JNIEnv* env, jclass clazz, - jobject tokenObj, jobject infoObj) { - sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); - if (token == NULL) return JNI_FALSE; - - DisplayInfo info; - if (SurfaceComposerClient::getDisplayInfo(token, &info)) { - return JNI_FALSE; - } - - env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.width, info.w); - env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.height, info.h); - env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.refreshRate, info.fps); - env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.density, info.density); - env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.xDpi, info.xdpi); - env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.yDpi, info.ydpi); - env->SetBooleanField(infoObj, gPhysicalDisplayInfoClassInfo.secure, info.secure); - return JNI_TRUE; -} - -static void nativeBlankDisplay(JNIEnv* env, jclass clazz, jobject tokenObj) { - sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); - if (token == NULL) return; - - ALOGD_IF_SLOW(100, "Excessive delay in blankDisplay() while turning screen off"); - SurfaceComposerClient::blankDisplay(token); -} - -static void nativeUnblankDisplay(JNIEnv* env, jclass clazz, jobject tokenObj) { - sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); - if (token == NULL) return; - - ALOGD_IF_SLOW(100, "Excessive delay in unblankDisplay() while turning screen on"); - SurfaceComposerClient::unblankDisplay(token); -} - // ---------------------------------------------------------------------------- -static void nativeCopyFrom(JNIEnv* env, jobject surfaceObj, jobject otherObj) { +static jint nativeCopyFrom(JNIEnv* env, jobject surfaceObj, + jint nativeObject, jint surfaceControlNativeObj) { /* * This is used by the WindowManagerService just after constructing * a Surface and is necessary for returning the Surface reference to * the caller. At this point, we should only have a SurfaceControl. */ - sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj)); - sp<SurfaceControl> other(getSurfaceControl(env, otherObj)); - if (!SurfaceControl::isSameSurface(surface, other)) { - // we reassign the surface only if it's a different one - // otherwise we would loose our client-side state. - setSurfaceControl(env, surfaceObj, other); + sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj)); + sp<Surface> other(ctrl->getSurface()); + if (other != NULL) { + other->incStrong(surfaceObj); + } + + sp<Surface> sur(reinterpret_cast<Surface *>(nativeObject)); + if (sur != NULL) { + sur->decStrong(surfaceObj); } -} -static void nativeTransferFrom(JNIEnv* env, jobject surfaceObj, jobject otherObj) { - sp<SurfaceControl> control(getSurfaceControl(env, otherObj)); - sp<Surface> surface(android_view_Surface_getSurface(env, otherObj)); - setSurfaceControl(env, surfaceObj, control); - setSurface(env, surfaceObj, surface); - setSurfaceControl(env, otherObj, NULL); - setSurface(env, otherObj, NULL); + return int(other.get()); } -static void nativeReadFromParcel(JNIEnv* env, jobject surfaceObj, jobject parcelObj) { +static jint nativeReadFromParcel(JNIEnv* env, jobject surfaceObj, + jint nativeObject, jobject parcelObj) { Parcel* parcel = parcelForJavaObject(env, parcelObj); if (parcel == NULL) { doThrowNPE(env); - return; + return 0; } - - sp<Surface> surface(Surface::readFromParcel(*parcel)); - setSurfaceControl(env, surfaceObj, NULL); - setSurface(env, surfaceObj, surface); + sp<Surface> self(reinterpret_cast<Surface *>(nativeObject)); + if (self != NULL) { + self->decStrong(surfaceObj); + } + sp<Surface> sur(Surface::readFromParcel(*parcel)); + if (sur != NULL) { + sur->incStrong(surfaceObj); + } + return int(sur.get()); } -static void nativeWriteToParcel(JNIEnv* env, jobject surfaceObj, jobject parcelObj) { +static void nativeWriteToParcel(JNIEnv* env, jobject surfaceObj, + jint nativeObject, jobject parcelObj) { Parcel* parcel = parcelForJavaObject(env, parcelObj); if (parcel == NULL) { doThrowNPE(env); return; } - - // The Java instance may have a SurfaceControl (in the case of the - // WindowManager or a system app). In that case, we defer to the - // SurfaceControl to send its ISurface. Otherwise, if the Surface is - // available we let it parcel itself. Finally, if the Surface is also - // NULL we fall back to using the SurfaceControl path which sends an - // empty surface; this matches legacy behavior. - sp<SurfaceControl> control(getSurfaceControl(env, surfaceObj)); - if (control != NULL) { - SurfaceControl::writeSurfaceToParcel(control, parcel); - } else { - sp<Surface> surface(android_view_Surface_getSurface(env, surfaceObj)); - if (surface != NULL) { - Surface::writeToParcel(surface, parcel); - } else { - SurfaceControl::writeSurfaceToParcel(NULL, parcel); - } - } + sp<Surface> self(reinterpret_cast<Surface *>(nativeObject)); + Surface::writeToParcel(self, parcel); } // ---------------------------------------------------------------------------- static JNINativeMethod gSurfaceMethods[] = { - {"nativeCreate", "(Landroid/view/SurfaceSession;Ljava/lang/String;IIII)V", - (void*)nativeCreate }, - {"nativeCreateFromSurfaceTexture", "(Landroid/graphics/SurfaceTexture;)V", + {"nativeCreateFromSurfaceTexture", "(Landroid/graphics/SurfaceTexture;)I", (void*)nativeCreateFromSurfaceTexture }, - {"nativeRelease", "()V", + {"nativeRelease", "(I)V", (void*)nativeRelease }, - {"nativeDestroy", "()V", + {"nativeDestroy", "(I)V", (void*)nativeDestroy }, - {"nativeIsValid", "()Z", + {"nativeIsValid", "(I)Z", (void*)nativeIsValid }, - {"nativeIsConsumerRunningBehind", "()Z", + {"nativeIsConsumerRunningBehind", "(I)Z", (void*)nativeIsConsumerRunningBehind }, - {"nativeLockCanvas", "(Landroid/graphics/Rect;)Landroid/graphics/Canvas;", + {"nativeLockCanvas", "(ILandroid/graphics/Rect;)Landroid/graphics/Canvas;", (void*)nativeLockCanvas }, - {"nativeUnlockCanvasAndPost", "(Landroid/graphics/Canvas;)V", + {"nativeUnlockCanvasAndPost", "(ILandroid/graphics/Canvas;)V", (void*)nativeUnlockCanvasAndPost }, - {"nativeScreenshot", "(Landroid/os/IBinder;IIIIZ)Landroid/graphics/Bitmap;", - (void*)nativeScreenshot }, - {"nativeOpenTransaction", "()V", - (void*)nativeOpenTransaction }, - {"nativeCloseTransaction", "()V", - (void*)nativeCloseTransaction }, - {"nativeSetAnimationTransaction", "()V", - (void*)nativeSetAnimationTransaction }, - {"nativeSetLayer", "(I)V", - (void*)nativeSetLayer }, - {"nativeSetPosition", "(FF)V", - (void*)nativeSetPosition }, - {"nativeSetSize", "(II)V", - (void*)nativeSetSize }, - {"nativeSetTransparentRegionHint", "(Landroid/graphics/Region;)V", - (void*)nativeSetTransparentRegionHint }, - {"nativeSetAlpha", "(F)V", - (void*)nativeSetAlpha }, - {"nativeSetMatrix", "(FFFF)V", - (void*)nativeSetMatrix }, - {"nativeSetFlags", "(II)V", - (void*)nativeSetFlags }, - {"nativeSetWindowCrop", "(Landroid/graphics/Rect;)V", - (void*)nativeSetWindowCrop }, - {"nativeSetLayerStack", "(I)V", - (void*)nativeSetLayerStack }, - {"nativeGetBuiltInDisplay", "(I)Landroid/os/IBinder;", - (void*)nativeGetBuiltInDisplay }, - {"nativeCreateDisplay", "(Ljava/lang/String;Z)Landroid/os/IBinder;", - (void*)nativeCreateDisplay }, - {"nativeSetDisplaySurface", "(Landroid/os/IBinder;Landroid/view/Surface;)V", - (void*)nativeSetDisplaySurface }, - {"nativeSetDisplayLayerStack", "(Landroid/os/IBinder;I)V", - (void*)nativeSetDisplayLayerStack }, - {"nativeSetDisplayProjection", "(Landroid/os/IBinder;ILandroid/graphics/Rect;Landroid/graphics/Rect;)V", - (void*)nativeSetDisplayProjection }, - {"nativeGetDisplayInfo", "(Landroid/os/IBinder;Landroid/view/Surface$PhysicalDisplayInfo;)Z", - (void*)nativeGetDisplayInfo }, - {"nativeBlankDisplay", "(Landroid/os/IBinder;)V", - (void*)nativeBlankDisplay }, - {"nativeUnblankDisplay", "(Landroid/os/IBinder;)V", - (void*)nativeUnblankDisplay }, - {"nativeCopyFrom", "(Landroid/view/Surface;)V", + {"nativeCopyFrom", "(II)I", (void*)nativeCopyFrom }, - {"nativeTransferFrom", "(Landroid/view/Surface;)V", - (void*)nativeTransferFrom }, - {"nativeReadFromParcel", "(Landroid/os/Parcel;)V", + {"nativeReadFromParcel", "(ILandroid/os/Parcel;)I", (void*)nativeReadFromParcel }, - {"nativeWriteToParcel", "(Landroid/os/Parcel;)V", + {"nativeWriteToParcel", "(ILandroid/os/Parcel;)V", (void*)nativeWriteToParcel }, }; @@ -864,17 +367,15 @@ int register_android_view_Surface(JNIEnv* env) jclass clazz = env->FindClass("android/view/Surface"); gSurfaceClassInfo.clazz = jclass(env->NewGlobalRef(clazz)); - gSurfaceClassInfo.mNativeSurface = - env->GetFieldID(gSurfaceClassInfo.clazz, ANDROID_VIEW_SURFACE_JNI_ID, "I"); - gSurfaceClassInfo.mNativeSurfaceControl = - env->GetFieldID(gSurfaceClassInfo.clazz, "mNativeSurfaceControl", "I"); + gSurfaceClassInfo.mNativeObject = + env->GetFieldID(gSurfaceClassInfo.clazz, "mNativeObject", "I"); gSurfaceClassInfo.mGenerationId = env->GetFieldID(gSurfaceClassInfo.clazz, "mGenerationId", "I"); gSurfaceClassInfo.mCanvas = env->GetFieldID(gSurfaceClassInfo.clazz, "mCanvas", "Landroid/graphics/Canvas;"); gSurfaceClassInfo.mCanvasSaveCount = env->GetFieldID(gSurfaceClassInfo.clazz, "mCanvasSaveCount", "I"); - gSurfaceClassInfo.ctor = env->GetMethodID(gSurfaceClassInfo.clazz, "<init>", "()V"); + gSurfaceClassInfo.ctor = env->GetMethodID(gSurfaceClassInfo.clazz, "<init>", "(I)V"); clazz = env->FindClass("android/graphics/Canvas"); gCanvasClassInfo.mNativeCanvas = env->GetFieldID(clazz, "mNativeCanvas", "I"); @@ -886,14 +387,6 @@ int register_android_view_Surface(JNIEnv* env) gRectClassInfo.right = env->GetFieldID(clazz, "right", "I"); gRectClassInfo.bottom = env->GetFieldID(clazz, "bottom", "I"); - clazz = env->FindClass("android/view/Surface$PhysicalDisplayInfo"); - gPhysicalDisplayInfoClassInfo.width = env->GetFieldID(clazz, "width", "I"); - gPhysicalDisplayInfoClassInfo.height = env->GetFieldID(clazz, "height", "I"); - gPhysicalDisplayInfoClassInfo.refreshRate = env->GetFieldID(clazz, "refreshRate", "F"); - gPhysicalDisplayInfoClassInfo.density = env->GetFieldID(clazz, "density", "F"); - gPhysicalDisplayInfoClassInfo.xDpi = env->GetFieldID(clazz, "xDpi", "F"); - gPhysicalDisplayInfoClassInfo.yDpi = env->GetFieldID(clazz, "yDpi", "F"); - gPhysicalDisplayInfoClassInfo.secure = env->GetFieldID(clazz, "secure", "Z"); return err; } diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp new file mode 100644 index 0000000..7398895 --- /dev/null +++ b/core/jni/android_view_SurfaceControl.cpp @@ -0,0 +1,451 @@ +/* + * Copyright (C) 2013 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. + */ + +#define LOG_TAG "SurfaceControl" + +#include <stdio.h> + +#include "jni.h" +#include "JNIHelp.h" + +#include "android_os_Parcel.h" +#include "android_util_Binder.h" +#include "android/graphics/GraphicsJNI.h" +#include "android/graphics/Region.h" + +#include <android_runtime/AndroidRuntime.h> +#include <android_runtime/android_view_SurfaceSession.h> + +#include <gui/Surface.h> +#include <gui/SurfaceComposerClient.h> + +#include <ui/DisplayInfo.h> +#include <ui/Rect.h> +#include <ui/Region.h> + +#include <utils/Log.h> + +#include <ScopedUtfChars.h> + +// ---------------------------------------------------------------------------- + +namespace android { + +static const char* const OutOfResourcesException = + "android/view/Surface$OutOfResourcesException"; + +static struct { + jfieldID width; + jfieldID height; + jfieldID refreshRate; + jfieldID density; + jfieldID xDpi; + jfieldID yDpi; + jfieldID secure; +} gPhysicalDisplayInfoClassInfo; + + +class ScreenshotPixelRef : public SkPixelRef { +public: + ScreenshotPixelRef(SkColorTable* ctable) { + fCTable = ctable; + SkSafeRef(ctable); + setImmutable(); + } + + virtual ~ScreenshotPixelRef() { + SkSafeUnref(fCTable); + } + + status_t update(const sp<IBinder>& display, int width, int height, + int minLayer, int maxLayer, bool allLayers) { + status_t res = (width > 0 && height > 0) + ? (allLayers + ? mScreenshot.update(display, width, height) + : mScreenshot.update(display, width, height, minLayer, maxLayer)) + : mScreenshot.update(display); + if (res != NO_ERROR) { + return res; + } + + return NO_ERROR; + } + + uint32_t getWidth() const { + return mScreenshot.getWidth(); + } + + uint32_t getHeight() const { + return mScreenshot.getHeight(); + } + + uint32_t getStride() const { + return mScreenshot.getStride(); + } + + uint32_t getFormat() const { + return mScreenshot.getFormat(); + } + +protected: + // overrides from SkPixelRef + virtual void* onLockPixels(SkColorTable** ct) { + *ct = fCTable; + return (void*)mScreenshot.getPixels(); + } + + virtual void onUnlockPixels() { + } + +private: + ScreenshotClient mScreenshot; + SkColorTable* fCTable; + + typedef SkPixelRef INHERITED; +}; + + +// ---------------------------------------------------------------------------- + +static jint nativeCreate(JNIEnv* env, jobject surfaceObj, jobject sessionObj, + jstring nameStr, jint w, jint h, jint format, jint flags) { + ScopedUtfChars name(env, nameStr); + sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj)); + sp<SurfaceControl> surface = client->createSurface( + String8(name.c_str()), w, h, format, flags); + if (surface == NULL) { + jniThrowException(env, OutOfResourcesException, NULL); + return 0; + } + surface->incStrong(surfaceObj); + return int(surface.get()); +} + +static void nativeRelease(JNIEnv* env, jobject surfaceObj, jint nativeObject) { + sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(nativeObject)); + ctrl->decStrong(surfaceObj); +} + +static void nativeDestroy(JNIEnv* env, jobject surfaceObj, jint nativeObject) { + sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(nativeObject)); + ctrl->clear(); + ctrl->decStrong(surfaceObj); +} + +static inline SkBitmap::Config convertPixelFormat(PixelFormat format) { + /* note: if PIXEL_FORMAT_RGBX_8888 means that all alpha bytes are 0xFF, then + we can map to SkBitmap::kARGB_8888_Config, and optionally call + bitmap.setIsOpaque(true) on the resulting SkBitmap (as an accelerator) + */ + switch (format) { + case PIXEL_FORMAT_RGBX_8888: return SkBitmap::kARGB_8888_Config; + case PIXEL_FORMAT_RGBA_8888: return SkBitmap::kARGB_8888_Config; + case PIXEL_FORMAT_RGBA_4444: return SkBitmap::kARGB_4444_Config; + case PIXEL_FORMAT_RGB_565: return SkBitmap::kRGB_565_Config; + case PIXEL_FORMAT_A_8: return SkBitmap::kA8_Config; + default: return SkBitmap::kNo_Config; + } +} + +static jobject nativeScreenshot(JNIEnv* env, jclass clazz, jobject displayTokenObj, + jint width, jint height, jint minLayer, jint maxLayer, bool allLayers) { + sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj); + if (displayToken == NULL) { + return NULL; + } + + ScreenshotPixelRef* pixels = new ScreenshotPixelRef(NULL); + if (pixels->update(displayToken, width, height, + minLayer, maxLayer, allLayers) != NO_ERROR) { + delete pixels; + return NULL; + } + + uint32_t w = pixels->getWidth(); + uint32_t h = pixels->getHeight(); + uint32_t s = pixels->getStride(); + uint32_t f = pixels->getFormat(); + ssize_t bpr = s * android::bytesPerPixel(f); + + SkBitmap* bitmap = new SkBitmap(); + bitmap->setConfig(convertPixelFormat(f), w, h, bpr); + if (f == PIXEL_FORMAT_RGBX_8888) { + bitmap->setIsOpaque(true); + } + + if (w > 0 && h > 0) { + bitmap->setPixelRef(pixels)->unref(); + bitmap->lockPixels(); + } else { + // be safe with an empty bitmap. + delete pixels; + bitmap->setPixels(NULL); + } + + return GraphicsJNI::createBitmap(env, bitmap, false, NULL); +} + +static void nativeOpenTransaction(JNIEnv* env, jclass clazz) { + SurfaceComposerClient::openGlobalTransaction(); +} + +static void nativeCloseTransaction(JNIEnv* env, jclass clazz) { + SurfaceComposerClient::closeGlobalTransaction(); +} + +static void nativeSetAnimationTransaction(JNIEnv* env, jclass clazz) { + SurfaceComposerClient::setAnimationTransaction(); +} + +static void nativeSetLayer(JNIEnv* env, jobject surfaceObj, jint nativeObject, jint zorder) { + SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); + status_t err = ctrl->setLayer(zorder); + if (err < 0 && err != NO_INIT) { + doThrowIAE(env); + } +} + +static void nativeSetPosition(JNIEnv* env, jobject surfaceObj, jint nativeObject, jfloat x, jfloat y) { + SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); + status_t err = ctrl->setPosition(x, y); + if (err < 0 && err != NO_INIT) { + doThrowIAE(env); + } +} + +static void nativeSetSize(JNIEnv* env, jobject surfaceObj, jint nativeObject, jint w, jint h) { + SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); + status_t err = ctrl->setSize(w, h); + if (err < 0 && err != NO_INIT) { + doThrowIAE(env); + } +} + +static void nativeSetFlags(JNIEnv* env, jobject surfaceObj, jint nativeObject, jint flags, jint mask) { + SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); + status_t err = ctrl->setFlags(flags, mask); + if (err < 0 && err != NO_INIT) { + doThrowIAE(env); + } +} + +static void nativeSetTransparentRegionHint(JNIEnv* env, jobject surfaceObj, jint nativeObject, jobject regionObj) { + SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); + SkRegion* region = android_graphics_Region_getSkRegion(env, regionObj); + if (!region) { + doThrowIAE(env); + return; + } + + const SkIRect& b(region->getBounds()); + Region reg(Rect(b.fLeft, b.fTop, b.fRight, b.fBottom)); + if (region->isComplex()) { + SkRegion::Iterator it(*region); + while (!it.done()) { + const SkIRect& r(it.rect()); + reg.addRectUnchecked(r.fLeft, r.fTop, r.fRight, r.fBottom); + it.next(); + } + } + + status_t err = ctrl->setTransparentRegionHint(reg); + if (err < 0 && err != NO_INIT) { + doThrowIAE(env); + } +} + +static void nativeSetAlpha(JNIEnv* env, jobject surfaceObj, jint nativeObject, jfloat alpha) { + SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); + status_t err = ctrl->setAlpha(alpha); + if (err < 0 && err != NO_INIT) { + doThrowIAE(env); + } +} + +static void nativeSetMatrix(JNIEnv* env, jobject surfaceObj, jint nativeObject, + jfloat dsdx, jfloat dtdx, jfloat dsdy, jfloat dtdy) { + SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); + status_t err = ctrl->setMatrix(dsdx, dtdx, dsdy, dtdy); + if (err < 0 && err != NO_INIT) { + doThrowIAE(env); + } +} + +static void nativeSetWindowCrop(JNIEnv* env, jobject surfaceObj, jint nativeObject, + jint l, jint t, jint r, jint b) { + SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); + Rect crop(l, t, r, b); + status_t err = ctrl->setCrop(crop); + if (err < 0 && err != NO_INIT) { + doThrowIAE(env); + } +} + +static void nativeSetLayerStack(JNIEnv* env, jobject surfaceObj, jint nativeObject, jint layerStack) { + SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject); + status_t err = ctrl->setLayerStack(layerStack); + if (err < 0 && err != NO_INIT) { + doThrowIAE(env); + } +} + +static jobject nativeGetBuiltInDisplay(JNIEnv* env, jclass clazz, jint id) { + sp<IBinder> token(SurfaceComposerClient::getBuiltInDisplay(id)); + return javaObjectForIBinder(env, token); +} + +static jobject nativeCreateDisplay(JNIEnv* env, jclass clazz, jstring nameObj, + jboolean secure) { + ScopedUtfChars name(env, nameObj); + sp<IBinder> token(SurfaceComposerClient::createDisplay( + String8(name.c_str()), bool(secure))); + return javaObjectForIBinder(env, token); +} + +static void nativeSetDisplaySurface(JNIEnv* env, jclass clazz, + jobject tokenObj, jint nativeSurfaceObject) { + sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); + if (token == NULL) return; + sp<Surface> sur(reinterpret_cast<Surface *>(nativeSurfaceObject)); + sp<IGraphicBufferProducer> bufferProducer(sur->getSurfaceTexture()); + SurfaceComposerClient::setDisplaySurface(token, bufferProducer); +} + +static void nativeSetDisplayLayerStack(JNIEnv* env, jclass clazz, + jobject tokenObj, jint layerStack) { + sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); + if (token == NULL) return; + + SurfaceComposerClient::setDisplayLayerStack(token, layerStack); +} + +static void nativeSetDisplayProjection(JNIEnv* env, jclass clazz, + jobject tokenObj, jint orientation, + jint layerStackRect_left, jint layerStackRect_top, jint layerStackRect_right, jint layerStackRect_bottom, + jint displayRect_left, jint displayRect_top, jint displayRect_right, jint displayRect_bottom) { + sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); + if (token == NULL) return; + Rect layerStackRect(layerStackRect_left, layerStackRect_top, layerStackRect_right, layerStackRect_bottom); + Rect displayRect(displayRect_left, displayRect_top, displayRect_right, displayRect_bottom); + SurfaceComposerClient::setDisplayProjection(token, orientation, layerStackRect, displayRect); +} + +static jboolean nativeGetDisplayInfo(JNIEnv* env, jclass clazz, + jobject tokenObj, jobject infoObj) { + sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); + if (token == NULL) return JNI_FALSE; + + DisplayInfo info; + if (SurfaceComposerClient::getDisplayInfo(token, &info)) { + return JNI_FALSE; + } + + env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.width, info.w); + env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.height, info.h); + env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.refreshRate, info.fps); + env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.density, info.density); + env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.xDpi, info.xdpi); + env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.yDpi, info.ydpi); + env->SetBooleanField(infoObj, gPhysicalDisplayInfoClassInfo.secure, info.secure); + return JNI_TRUE; +} + +static void nativeBlankDisplay(JNIEnv* env, jclass clazz, jobject tokenObj) { + sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); + if (token == NULL) return; + + ALOGD_IF_SLOW(100, "Excessive delay in blankDisplay() while turning screen off"); + SurfaceComposerClient::blankDisplay(token); +} + +static void nativeUnblankDisplay(JNIEnv* env, jclass clazz, jobject tokenObj) { + sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); + if (token == NULL) return; + + ALOGD_IF_SLOW(100, "Excessive delay in unblankDisplay() while turning screen on"); + SurfaceComposerClient::unblankDisplay(token); +} + +// ---------------------------------------------------------------------------- + +static JNINativeMethod sSurfaceControlMethods[] = { + {"nativeCreate", "(Landroid/view/SurfaceSession;Ljava/lang/String;IIII)I", + (void*)nativeCreate }, + {"nativeRelease", "(I)V", + (void*)nativeRelease }, + {"nativeDestroy", "(I)V", + (void*)nativeDestroy }, + {"nativeScreenshot", "(Landroid/os/IBinder;IIIIZ)Landroid/graphics/Bitmap;", + (void*)nativeScreenshot }, + {"nativeOpenTransaction", "()V", + (void*)nativeOpenTransaction }, + {"nativeCloseTransaction", "()V", + (void*)nativeCloseTransaction }, + {"nativeSetAnimationTransaction", "()V", + (void*)nativeSetAnimationTransaction }, + {"nativeSetLayer", "(II)V", + (void*)nativeSetLayer }, + {"nativeSetPosition", "(IFF)V", + (void*)nativeSetPosition }, + {"nativeSetSize", "(III)V", + (void*)nativeSetSize }, + {"nativeSetTransparentRegionHint", "(ILandroid/graphics/Region;)V", + (void*)nativeSetTransparentRegionHint }, + {"nativeSetAlpha", "(IF)V", + (void*)nativeSetAlpha }, + {"nativeSetMatrix", "(IFFFF)V", + (void*)nativeSetMatrix }, + {"nativeSetFlags", "(III)V", + (void*)nativeSetFlags }, + {"nativeSetWindowCrop", "(IIIII)V", + (void*)nativeSetWindowCrop }, + {"nativeSetLayerStack", "(II)V", + (void*)nativeSetLayerStack }, + {"nativeGetBuiltInDisplay", "(I)Landroid/os/IBinder;", + (void*)nativeGetBuiltInDisplay }, + {"nativeCreateDisplay", "(Ljava/lang/String;Z)Landroid/os/IBinder;", + (void*)nativeCreateDisplay }, + {"nativeSetDisplaySurface", "(Landroid/os/IBinder;I)V", + (void*)nativeSetDisplaySurface }, + {"nativeSetDisplayLayerStack", "(Landroid/os/IBinder;I)V", + (void*)nativeSetDisplayLayerStack }, + {"nativeSetDisplayProjection", "(Landroid/os/IBinder;IIIIIIIII)V", + (void*)nativeSetDisplayProjection }, + {"nativeGetDisplayInfo", "(Landroid/os/IBinder;Landroid/view/SurfaceControl$PhysicalDisplayInfo;)Z", + (void*)nativeGetDisplayInfo }, + {"nativeBlankDisplay", "(Landroid/os/IBinder;)V", + (void*)nativeBlankDisplay }, + {"nativeUnblankDisplay", "(Landroid/os/IBinder;)V", + (void*)nativeUnblankDisplay }, +}; + +int register_android_view_SurfaceControl(JNIEnv* env) +{ + int err = AndroidRuntime::registerNativeMethods(env, "android/view/SurfaceControl", + sSurfaceControlMethods, NELEM(sSurfaceControlMethods)); + + jclass clazz = env->FindClass("android/view/SurfaceControl$PhysicalDisplayInfo"); + gPhysicalDisplayInfoClassInfo.width = env->GetFieldID(clazz, "width", "I"); + gPhysicalDisplayInfoClassInfo.height = env->GetFieldID(clazz, "height", "I"); + gPhysicalDisplayInfoClassInfo.refreshRate = env->GetFieldID(clazz, "refreshRate", "F"); + gPhysicalDisplayInfoClassInfo.density = env->GetFieldID(clazz, "density", "F"); + gPhysicalDisplayInfoClassInfo.xDpi = env->GetFieldID(clazz, "xDpi", "F"); + gPhysicalDisplayInfoClassInfo.yDpi = env->GetFieldID(clazz, "yDpi", "F"); + gPhysicalDisplayInfoClassInfo.secure = env->GetFieldID(clazz, "secure", "Z"); + return err; +} + +}; diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp index b6e6ceb..ac10cd4 100644 --- a/media/jni/android_media_MediaRecorder.cpp +++ b/media/jni/android_media_MediaRecorder.cpp @@ -34,6 +34,7 @@ #include "android_runtime/AndroidRuntime.h" #include <system/audio.h> +#include <android_runtime/android_view_Surface.h> // ---------------------------------------------------------------------------- @@ -47,8 +48,6 @@ extern sp<Camera> get_native_camera(JNIEnv *env, jobject thiz, struct JNICameraC struct fields_t { jfieldID context; jfieldID surface; - /* actually in android.view.Surface XXX */ - jfieldID surface_native; jmethodID post_event; }; @@ -109,8 +108,7 @@ void JNIMediaRecorderListener::notify(int msg, int ext1, int ext2) static sp<Surface> get_surface(JNIEnv* env, jobject clazz) { ALOGV("get_surface"); - Surface* const p = (Surface*)env->GetIntField(clazz, fields.surface_native); - return sp<Surface>(p); + return android_view_Surface_getSurface(env, clazz); } // Returns true if it throws an exception. @@ -409,11 +407,6 @@ android_media_MediaRecorder_native_init(JNIEnv *env) return; } - fields.surface_native = env->GetFieldID(surface, ANDROID_VIEW_SURFACE_JNI_ID, "I"); - if (fields.surface_native == NULL) { - return; - } - fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative", "(Ljava/lang/Object;IIILjava/lang/Object;)V"); if (fields.post_event == NULL) { diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp index 41c28c0..c1ad516 100644 --- a/media/jni/mediaeditor/VideoEditorMain.cpp +++ b/media/jni/mediaeditor/VideoEditorMain.cpp @@ -34,6 +34,8 @@ #include "VideoEditorMain.h" +#include <android_runtime/android_view_Surface.h> + extern "C" { #include <M4OSA_Clock.h> #include <M4OSA_CharStar.h> @@ -628,19 +630,8 @@ static void videoEditor_clearSurface(JNIEnv* pEnv, (NULL == surface), "surface is null"); - jclass surfaceClass = pEnv->FindClass("android/view/Surface"); - videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, - (M4OSA_NULL == surfaceClass), - "not initialized"); - - jfieldID surface_native = - pEnv->GetFieldID(surfaceClass, ANDROID_VIEW_SURFACE_JNI_ID, "I"); - videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, - (M4OSA_NULL == surface_native), - "not initialized"); + sp<Surface> previewSurface = android_view_Surface_getSurface(pEnv, surface); - Surface* const p = (Surface*)pEnv->GetIntField(surface, surface_native); - sp<Surface> previewSurface = sp<Surface>(p); // Validate the mSurface's mNativeSurface field videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, (NULL == previewSurface.get()), @@ -709,19 +700,9 @@ static int videoEditor_renderPreviewFrame(JNIEnv* pEnv, videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv, (NULL == mSurface), "mSurface is null"); - jclass surfaceClass = pEnv->FindClass("android/view/Surface"); - videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, - (M4OSA_NULL == surfaceClass), - "not initialized"); - jfieldID surface_native = - pEnv->GetFieldID(surfaceClass, ANDROID_VIEW_SURFACE_JNI_ID, "I"); - videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, - (M4OSA_NULL == surface_native), - "not initialized"); + sp<Surface> previewSurface = android_view_Surface_getSurface(pEnv, mSurface); - Surface* const p = (Surface*)pEnv->GetIntField(mSurface, surface_native); - sp<Surface> previewSurface = sp<Surface>(p); // Validate the mSurface's mNativeSurface field videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, (NULL == previewSurface.get()), @@ -1038,20 +1019,8 @@ static int videoEditor_renderMediaItemPreviewFrame(JNIEnv* pEnv, videoEditJava_checkAndThrowIllegalArgumentException(&needToBeLoaded, pEnv, (NULL == mSurface), "mSurface is null"); - jclass surfaceClass = pEnv->FindClass("android/view/Surface"); - videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, - (M4OSA_NULL == surfaceClass), - "not initialized"); - - jfieldID surface_native = - pEnv->GetFieldID(surfaceClass, ANDROID_VIEW_SURFACE_JNI_ID, "I"); - videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, - (M4OSA_NULL == surface_native), - "not initialized"); - - Surface* const p = (Surface*)pEnv->GetIntField(mSurface, surface_native); - sp<Surface> previewSurface = sp<Surface>(p); + sp<Surface> previewSurface = android_view_Surface_getSurface(pEnv, mSurface); const char *pString = pEnv->GetStringUTFChars(filePath, NULL); if (pString == M4OSA_NULL) { @@ -2144,21 +2113,8 @@ videoEditor_startPreview( (NULL == mSurface), "mSurface is null"); - jclass surfaceClass = pEnv->FindClass("android/view/Surface"); - videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, - (M4OSA_NULL == surfaceClass), - "not initialized"); - //jfieldID surface_native = pEnv->GetFieldID(surfaceClass, "mSurface", "I"); - jfieldID surface_native - = pEnv->GetFieldID(surfaceClass, ANDROID_VIEW_SURFACE_JNI_ID, "I"); - - videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, - (M4OSA_NULL == surface_native), - "not initialized"); - - Surface* const p = (Surface*)pEnv->GetIntField(mSurface, surface_native); + sp<Surface> previewSurface = android_view_Surface_getSurface(pEnv, mSurface); - sp<Surface> previewSurface = sp<Surface>(p); // Validate the mSurface's mNativeSurface field videoEditJava_checkAndThrowIllegalStateException(&needToBeLoaded, pEnv, (NULL == previewSurface.get()), diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java index ddfaad5..b498368 100644 --- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java +++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java @@ -50,6 +50,7 @@ import android.view.Display; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.Surface; +import android.view.SurfaceControl; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; @@ -455,7 +456,7 @@ class GlobalScreenshot { } // Take the screenshot - mScreenBitmap = Surface.screenshot((int) dims[0], (int) dims[1]); + mScreenBitmap = SurfaceControl.screenshot((int) dims[0], (int) dims[1]); if (mScreenBitmap == null) { notifyScreenshotError(mContext, mNotificationManager); finisher.run(); diff --git a/services/java/com/android/server/display/DisplayDevice.java b/services/java/com/android/server/display/DisplayDevice.java index a3ab3c1..4161147 100644 --- a/services/java/com/android/server/display/DisplayDevice.java +++ b/services/java/com/android/server/display/DisplayDevice.java @@ -19,6 +19,7 @@ package com.android.server.display; import android.graphics.Rect; import android.os.IBinder; import android.view.Surface; +import android.view.SurfaceControl; import java.io.PrintWriter; @@ -122,7 +123,7 @@ abstract class DisplayDevice { public final void setLayerStackInTransactionLocked(int layerStack) { if (mCurrentLayerStack != layerStack) { mCurrentLayerStack = layerStack; - Surface.setDisplayLayerStack(mDisplayToken, layerStack); + SurfaceControl.setDisplayLayerStack(mDisplayToken, layerStack); } } @@ -155,7 +156,7 @@ abstract class DisplayDevice { } mCurrentDisplayRect.set(displayRect); - Surface.setDisplayProjection(mDisplayToken, + SurfaceControl.setDisplayProjection(mDisplayToken, orientation, layerStackRect, displayRect); } } @@ -166,7 +167,7 @@ abstract class DisplayDevice { public final void setSurfaceInTransactionLocked(Surface surface) { if (mCurrentSurface != surface) { mCurrentSurface = surface; - Surface.setDisplaySurface(mDisplayToken, surface); + SurfaceControl.setDisplaySurface(mDisplayToken, surface); } } diff --git a/services/java/com/android/server/display/LocalDisplayAdapter.java b/services/java/com/android/server/display/LocalDisplayAdapter.java index ee2d617..475f27b 100644 --- a/services/java/com/android/server/display/LocalDisplayAdapter.java +++ b/services/java/com/android/server/display/LocalDisplayAdapter.java @@ -25,7 +25,8 @@ import android.util.SparseArray; import android.view.Display; import android.view.DisplayEventReceiver; import android.view.Surface; -import android.view.Surface.PhysicalDisplayInfo; +import android.view.SurfaceControl; +import android.view.SurfaceControl.PhysicalDisplayInfo; import java.io.PrintWriter; @@ -39,15 +40,15 @@ final class LocalDisplayAdapter extends DisplayAdapter { private static final String TAG = "LocalDisplayAdapter"; private static final int[] BUILT_IN_DISPLAY_IDS_TO_SCAN = new int[] { - Surface.BUILT_IN_DISPLAY_ID_MAIN, - Surface.BUILT_IN_DISPLAY_ID_HDMI, + SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN, + SurfaceControl.BUILT_IN_DISPLAY_ID_HDMI, }; private final SparseArray<LocalDisplayDevice> mDevices = new SparseArray<LocalDisplayDevice>(); private HotplugDisplayEventReceiver mHotplugReceiver; - private final PhysicalDisplayInfo mTempPhys = new PhysicalDisplayInfo(); + private final SurfaceControl.PhysicalDisplayInfo mTempPhys = new SurfaceControl.PhysicalDisplayInfo(); // Called with SyncRoot lock held. public LocalDisplayAdapter(DisplayManagerService.SyncRoot syncRoot, @@ -67,8 +68,8 @@ final class LocalDisplayAdapter extends DisplayAdapter { } private void tryConnectDisplayLocked(int builtInDisplayId) { - IBinder displayToken = Surface.getBuiltInDisplay(builtInDisplayId); - if (displayToken != null && Surface.getDisplayInfo(displayToken, mTempPhys)) { + IBinder displayToken = SurfaceControl.getBuiltInDisplay(builtInDisplayId); + if (displayToken != null && SurfaceControl.getDisplayInfo(displayToken, mTempPhys)) { LocalDisplayDevice device = mDevices.get(builtInDisplayId); if (device == null) { // Display was added. @@ -97,20 +98,20 @@ final class LocalDisplayAdapter extends DisplayAdapter { private final class LocalDisplayDevice extends DisplayDevice { private final int mBuiltInDisplayId; - private final PhysicalDisplayInfo mPhys; + private final SurfaceControl.PhysicalDisplayInfo mPhys; private DisplayDeviceInfo mInfo; private boolean mHavePendingChanges; private boolean mBlanked; public LocalDisplayDevice(IBinder displayToken, int builtInDisplayId, - PhysicalDisplayInfo phys) { + SurfaceControl.PhysicalDisplayInfo phys) { super(LocalDisplayAdapter.this, displayToken); mBuiltInDisplayId = builtInDisplayId; - mPhys = new PhysicalDisplayInfo(phys); + mPhys = new SurfaceControl.PhysicalDisplayInfo(phys); } - public boolean updatePhysicalDisplayInfoLocked(PhysicalDisplayInfo phys) { + public boolean updatePhysicalDisplayInfoLocked(SurfaceControl.PhysicalDisplayInfo phys) { if (!mPhys.equals(phys)) { mPhys.copyFrom(phys); mHavePendingChanges = true; @@ -142,7 +143,7 @@ final class LocalDisplayAdapter extends DisplayAdapter { | DisplayDeviceInfo.FLAG_SUPPORTS_PROTECTED_BUFFERS; } - if (mBuiltInDisplayId == Surface.BUILT_IN_DISPLAY_ID_MAIN) { + if (mBuiltInDisplayId == SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) { mInfo.name = getContext().getResources().getString( com.android.internal.R.string.display_manager_built_in_display_name); mInfo.flags |= DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY @@ -172,13 +173,13 @@ final class LocalDisplayAdapter extends DisplayAdapter { @Override public void blankLocked() { mBlanked = true; - Surface.blankDisplay(getDisplayTokenLocked()); + SurfaceControl.blankDisplay(getDisplayTokenLocked()); } @Override public void unblankLocked() { mBlanked = false; - Surface.unblankDisplay(getDisplayTokenLocked()); + SurfaceControl.unblankDisplay(getDisplayTokenLocked()); } @Override diff --git a/services/java/com/android/server/display/OverlayDisplayAdapter.java b/services/java/com/android/server/display/OverlayDisplayAdapter.java index 36e9f74..a18352c 100644 --- a/services/java/com/android/server/display/OverlayDisplayAdapter.java +++ b/services/java/com/android/server/display/OverlayDisplayAdapter.java @@ -30,6 +30,7 @@ import android.util.Slog; import android.view.Display; import android.view.Gravity; import android.view.Surface; +import android.view.SurfaceControl; import java.io.PrintWriter; import java.util.ArrayList; @@ -284,7 +285,7 @@ final class OverlayDisplayAdapter extends DisplayAdapter { @Override public void onWindowCreated(SurfaceTexture surfaceTexture, float refreshRate) { synchronized (getSyncRoot()) { - IBinder displayToken = Surface.createDisplay(mName, false); + IBinder displayToken = SurfaceControl.createDisplay(mName, false); mDevice = new OverlayDisplayDevice(displayToken, mName, mWidth, mHeight, refreshRate, mDensityDpi, surfaceTexture); diff --git a/services/java/com/android/server/display/WifiDisplayAdapter.java b/services/java/com/android/server/display/WifiDisplayAdapter.java index c8a44d2..b655b3a 100644 --- a/services/java/com/android/server/display/WifiDisplayAdapter.java +++ b/services/java/com/android/server/display/WifiDisplayAdapter.java @@ -41,6 +41,7 @@ import android.provider.Settings; import android.util.Slog; import android.view.Display; import android.view.Surface; +import android.view.SurfaceControl; import java.io.PrintWriter; import java.util.Arrays; @@ -332,7 +333,7 @@ final class WifiDisplayAdapter extends DisplayAdapter { String name = display.getFriendlyDisplayName(); String address = display.getDeviceAddress(); - IBinder displayToken = Surface.createDisplay(name, secure); + IBinder displayToken = SurfaceControl.createDisplay(name, secure); mDisplayDevice = new WifiDisplayDevice(displayToken, name, width, height, refreshRate, deviceFlags, address, surface); sendDisplayDeviceEventLocked(mDisplayDevice, DISPLAY_DEVICE_EVENT_ADDED); diff --git a/services/java/com/android/server/power/ElectronBeam.java b/services/java/com/android/server/power/ElectronBeam.java index 8e19e11..2828e5e 100644 --- a/services/java/com/android/server/power/ElectronBeam.java +++ b/services/java/com/android/server/power/ElectronBeam.java @@ -34,6 +34,7 @@ import android.util.Slog; import android.view.Display; import android.view.DisplayInfo; import android.view.Surface; +import android.view.SurfaceControl; import android.view.SurfaceSession; import java.io.PrintWriter; @@ -80,7 +81,8 @@ final class ElectronBeam { private int mDisplayWidth; // real width, not rotated private int mDisplayHeight; // real height, not rotated private SurfaceSession mSurfaceSession; - private Surface mSurface; + private SurfaceControl mSurfaceControl; + private final Surface mSurface = new Surface(); private NaturalSurfaceLayout mSurfaceLayout; private EGLDisplay mEglDisplay; private EGLConfig mEglConfig; @@ -370,7 +372,7 @@ final class ElectronBeam { private boolean captureScreenshotTextureAndSetViewport() { // TODO: Use a SurfaceTexture to avoid the extra texture upload. - Bitmap bitmap = Surface.screenshot(mDisplayWidth, mDisplayHeight, + Bitmap bitmap = SurfaceControl.screenshot(mDisplayWidth, mDisplayHeight, 0, ELECTRON_BEAM_LAYER - 1); if (bitmap == null) { Slog.e(TAG, "Could not take a screenshot!"); @@ -525,32 +527,33 @@ final class ElectronBeam { mSurfaceSession = new SurfaceSession(); } - Surface.openTransaction(); + SurfaceControl.openTransaction(); try { - if (mSurface == null) { + if (mSurfaceControl == null) { try { int flags; if (mMode == MODE_FADE) { - flags = Surface.FX_SURFACE_DIM | Surface.HIDDEN; + flags = SurfaceControl.FX_SURFACE_DIM | SurfaceControl.HIDDEN; } else { - flags = Surface.OPAQUE | Surface.HIDDEN; + flags = SurfaceControl.OPAQUE | SurfaceControl.HIDDEN; } - mSurface = new Surface(mSurfaceSession, + mSurfaceControl = new SurfaceControl(mSurfaceSession, "ElectronBeam", mDisplayWidth, mDisplayHeight, PixelFormat.OPAQUE, flags); - } catch (Surface.OutOfResourcesException ex) { + } catch (SurfaceControl.OutOfResourcesException ex) { Slog.e(TAG, "Unable to create surface.", ex); return false; } } - mSurface.setLayerStack(mDisplayLayerStack); - mSurface.setSize(mDisplayWidth, mDisplayHeight); - - mSurfaceLayout = new NaturalSurfaceLayout(mDisplayManager, mSurface); + mSurfaceControl.setLayerStack(mDisplayLayerStack); + mSurfaceControl.setSize(mDisplayWidth, mDisplayHeight); + mSurface.copyFrom(mSurfaceControl); + + mSurfaceLayout = new NaturalSurfaceLayout(mDisplayManager, mSurfaceControl); mSurfaceLayout.onDisplayTransaction(); } finally { - Surface.closeTransaction(); + SurfaceControl.closeTransaction(); } return true; } @@ -560,6 +563,7 @@ final class ElectronBeam { int[] eglSurfaceAttribList = new int[] { EGL14.EGL_NONE }; + // turn our SurfaceControl into a Surface mEglSurface = EGL14.eglCreateWindowSurface(mEglDisplay, mEglConfig, mSurface, eglSurfaceAttribList, 0); if (mEglSurface == null) { @@ -580,16 +584,17 @@ final class ElectronBeam { } private void destroySurface() { - if (mSurface != null) { + if (mSurfaceControl != null) { mSurfaceLayout.dispose(); mSurfaceLayout = null; - Surface.openTransaction(); + SurfaceControl.openTransaction(); try { - mSurface.destroy(); + mSurfaceControl.destroy(); + mSurface.release(); } finally { - Surface.closeTransaction(); + SurfaceControl.closeTransaction(); } - mSurface = null; + mSurfaceControl = null; mSurfaceVisible = false; mSurfaceAlpha = 0f; } @@ -597,13 +602,13 @@ final class ElectronBeam { private boolean showSurface(float alpha) { if (!mSurfaceVisible || mSurfaceAlpha != alpha) { - Surface.openTransaction(); + SurfaceControl.openTransaction(); try { - mSurface.setLayer(ELECTRON_BEAM_LAYER); - mSurface.setAlpha(alpha); - mSurface.show(); + mSurfaceControl.setLayer(ELECTRON_BEAM_LAYER); + mSurfaceControl.setAlpha(alpha); + mSurfaceControl.show(); } finally { - Surface.closeTransaction(); + SurfaceControl.closeTransaction(); } mSurfaceVisible = true; mSurfaceAlpha = alpha; @@ -708,9 +713,9 @@ final class ElectronBeam { */ private static final class NaturalSurfaceLayout implements DisplayTransactionListener { private final DisplayManagerService mDisplayManager; - private Surface mSurface; + private SurfaceControl mSurface; - public NaturalSurfaceLayout(DisplayManagerService displayManager, Surface surface) { + public NaturalSurfaceLayout(DisplayManagerService displayManager, SurfaceControl surface) { mDisplayManager = displayManager; mSurface = surface; mDisplayManager.registerDisplayTransactionListener(this); diff --git a/services/java/com/android/server/wm/AppWindowAnimator.java b/services/java/com/android/server/wm/AppWindowAnimator.java index ad68307..297324b 100644 --- a/services/java/com/android/server/wm/AppWindowAnimator.java +++ b/services/java/com/android/server/wm/AppWindowAnimator.java @@ -6,6 +6,7 @@ import android.graphics.Matrix; import android.util.Slog; import android.view.Display; import android.view.Surface; +import android.view.SurfaceControl; import android.view.WindowManagerPolicy; import android.view.animation.Animation; import android.view.animation.Transformation; @@ -38,7 +39,7 @@ public class AppWindowAnimator { boolean allDrawn; // Special surface for thumbnail animation. - Surface thumbnail; + SurfaceControl thumbnail; int thumbnailTransactionSeq; int thumbnailX; int thumbnailY; diff --git a/services/java/com/android/server/wm/BlackFrame.java b/services/java/com/android/server/wm/BlackFrame.java index 5b77b20..a197840 100644 --- a/services/java/com/android/server/wm/BlackFrame.java +++ b/services/java/com/android/server/wm/BlackFrame.java @@ -23,6 +23,7 @@ import android.graphics.PixelFormat; import android.graphics.Rect; import android.util.Slog; import android.view.Surface; +import android.view.SurfaceControl; import android.view.SurfaceSession; /** @@ -33,7 +34,7 @@ public class BlackFrame { final int left; final int top; final int layer; - final Surface surface; + final SurfaceControl surface; BlackSurface(SurfaceSession session, int layer, int l, int t, int r, int b, int layerStack) throws Surface.OutOfResourcesException { @@ -42,13 +43,17 @@ public class BlackFrame { this.layer = layer; int w = r-l; int h = b-t; - if (WindowManagerService.DEBUG_SURFACE_TRACE) { - surface = new WindowStateAnimator.SurfaceTrace(session, "BlackSurface(" - + l + ", " + t + ")", - w, h, PixelFormat.OPAQUE, Surface.FX_SURFACE_DIM | Surface.HIDDEN); - } else { - surface = new Surface(session, "BlackSurface", - w, h, PixelFormat.OPAQUE, Surface.FX_SURFACE_DIM | Surface.HIDDEN); + try { + if (WindowManagerService.DEBUG_SURFACE_TRACE) { + surface = new WindowStateAnimator.SurfaceTrace(session, "BlackSurface(" + + l + ", " + t + ")", + w, h, PixelFormat.OPAQUE, SurfaceControl.FX_SURFACE_DIM | SurfaceControl.HIDDEN); + } else { + surface = new SurfaceControl(session, "BlackSurface", + w, h, PixelFormat.OPAQUE, SurfaceControl.FX_SURFACE_DIM | SurfaceControl.HIDDEN); + } + } catch (SurfaceControl.OutOfResourcesException e) { + throw new Surface.OutOfResourcesException(e.getMessage()); } surface.setAlpha(1); surface.setLayerStack(layerStack); diff --git a/services/java/com/android/server/wm/DimLayer.java b/services/java/com/android/server/wm/DimLayer.java index 88efe2e..9bd36ba 100644 --- a/services/java/com/android/server/wm/DimLayer.java +++ b/services/java/com/android/server/wm/DimLayer.java @@ -7,6 +7,7 @@ import android.os.SystemClock; import android.util.Slog; import android.view.DisplayInfo; import android.view.Surface; +import android.view.SurfaceControl; import java.io.PrintWriter; @@ -18,7 +19,7 @@ public class DimLayer { final DisplayContent mDisplayContent; /** Actual surface that dims */ - Surface mDimSurface; + SurfaceControl mDimSurface; /** Last value passed to mDimSurface.setAlpha() */ float mAlpha = 0; @@ -47,17 +48,17 @@ public class DimLayer { DimLayer(WindowManagerService service, int displayId) { if (DEBUG) Slog.v(TAG, "Ctor: displayId=" + displayId); mDisplayContent = service.getDisplayContentLocked(displayId); - Surface.openTransaction(); + SurfaceControl.openTransaction(); try { if (WindowManagerService.DEBUG_SURFACE_TRACE) { mDimSurface = new WindowStateAnimator.SurfaceTrace(service.mFxSession, "DimSurface", 16, 16, PixelFormat.OPAQUE, - Surface.FX_SURFACE_DIM | Surface.HIDDEN); + SurfaceControl.FX_SURFACE_DIM | SurfaceControl.HIDDEN); } else { - mDimSurface = new Surface(service.mFxSession, TAG, + mDimSurface = new SurfaceControl(service.mFxSession, TAG, 16, 16, PixelFormat.OPAQUE, - Surface.FX_SURFACE_DIM | Surface.HIDDEN); + SurfaceControl.FX_SURFACE_DIM | SurfaceControl.HIDDEN); } if (WindowManagerService.SHOW_TRANSACTIONS || WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(TAG, @@ -66,7 +67,7 @@ public class DimLayer { } catch (Exception e) { Slog.e(WindowManagerService.TAG, "Exception creating Dim surface", e); } finally { - Surface.closeTransaction(); + SurfaceControl.closeTransaction(); } } diff --git a/services/java/com/android/server/wm/DisplayMagnifier.java b/services/java/com/android/server/wm/DisplayMagnifier.java index 61093ad..55c6fa6 100644 --- a/services/java/com/android/server/wm/DisplayMagnifier.java +++ b/services/java/com/android/server/wm/DisplayMagnifier.java @@ -43,6 +43,7 @@ import android.view.IMagnificationCallbacks; import android.view.MagnificationSpec; import android.view.Surface; import android.view.Surface.OutOfResourcesException; +import android.view.SurfaceControl; import android.view.WindowManager; import android.view.WindowManagerPolicy; import android.view.animation.DecelerateInterpolator; @@ -481,7 +482,8 @@ final class DisplayMagnifier { private final Paint mPaint = new Paint(); private final ValueAnimator mShowHideFrameAnimator; - private final Surface mSurface; + private final SurfaceControl mSurfaceControl; + private final Surface mSurface = new Surface(); private boolean mShown; private int mAlpha; @@ -489,20 +491,21 @@ final class DisplayMagnifier { private boolean mInvalidated; public ViewportWindow(Context context) { - Surface surface = null; + SurfaceControl surface = null; try { mWindowManager.getDefaultDisplay().getRealSize(mTempPoint); - surface = new Surface(mWindowManagerService.mFxSession, SURFACE_TITLE, - mTempPoint.x, mTempPoint.y, PixelFormat.TRANSLUCENT, Surface.HIDDEN); - } catch (OutOfResourcesException oore) { + surface = new SurfaceControl(mWindowManagerService.mFxSession, SURFACE_TITLE, + mTempPoint.x, mTempPoint.y, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN); + } catch (SurfaceControl.OutOfResourcesException oore) { /* ignore */ } - mSurface = surface; - mSurface.setLayerStack(mWindowManager.getDefaultDisplay().getLayerStack()); - mSurface.setLayer(mWindowManagerService.mPolicy.windowTypeToLayerLw( + mSurfaceControl = surface; + mSurfaceControl.setLayerStack(mWindowManager.getDefaultDisplay().getLayerStack()); + mSurfaceControl.setLayer(mWindowManagerService.mPolicy.windowTypeToLayerLw( WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY) * WindowManagerService.TYPE_LAYER_MULTIPLIER); - mSurface.setPosition(0, 0); + mSurfaceControl.setPosition(0, 0); + mSurface.copyFrom(mSurfaceControl); TypedValue typedValue = new TypedValue(); context.getTheme().resolveAttribute(R.attr.colorActivatedHighlight, @@ -591,7 +594,7 @@ final class DisplayMagnifier { public void updateSize() { synchronized (mWindowManagerService.mWindowMap) { mWindowManager.getDefaultDisplay().getRealSize(mTempPoint); - mSurface.setSize(mTempPoint.x, mTempPoint.y); + mSurfaceControl.setSize(mTempPoint.x, mTempPoint.y); invalidate(mDirtyRect); } } @@ -641,16 +644,17 @@ final class DisplayMagnifier { canvas.drawPath(path, mPaint); mSurface.unlockCanvasAndPost(canvas); - + if (mAlpha > 0) { - mSurface.show(); + mSurfaceControl.show(); } else { - mSurface.hide(); + mSurfaceControl.hide(); } } } public void releaseSurface() { + mSurfaceControl.release(); mSurface.release(); } } diff --git a/services/java/com/android/server/wm/DragState.java b/services/java/com/android/server/wm/DragState.java index 72fc180..63f306f 100644 --- a/services/java/com/android/server/wm/DragState.java +++ b/services/java/com/android/server/wm/DragState.java @@ -34,6 +34,7 @@ import android.view.Display; import android.view.DragEvent; import android.view.InputChannel; import android.view.Surface; +import android.view.SurfaceControl; import android.view.View; import android.view.WindowManager; @@ -45,7 +46,7 @@ import java.util.ArrayList; class DragState { final WindowManagerService mService; IBinder mToken; - Surface mSurface; + SurfaceControl mSurface; int mFlags; IBinder mLocalWin; ClipData mData; @@ -64,7 +65,7 @@ class DragState { private final Region mTmpRegion = new Region(); - DragState(WindowManagerService service, IBinder token, Surface surface, + DragState(WindowManagerService service, IBinder token, SurfaceControl surface, int flags, IBinder localWin) { mService = service; mToken = token; @@ -293,14 +294,14 @@ class DragState { // Move the surface to the given touch if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i( WindowManagerService.TAG, ">>> OPEN TRANSACTION notifyMoveLw"); - Surface.openTransaction(); + SurfaceControl.openTransaction(); try { mSurface.setPosition(x - mThumbOffsetX, y - mThumbOffsetY); if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " DRAG " + mSurface + ": pos=(" + (int)(x - mThumbOffsetX) + "," + (int)(y - mThumbOffsetY) + ")"); } finally { - Surface.closeTransaction(); + SurfaceControl.closeTransaction(); if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i( WindowManagerService.TAG, "<<< CLOSE TRANSACTION notifyMoveLw"); } diff --git a/services/java/com/android/server/wm/ScreenRotationAnimation.java b/services/java/com/android/server/wm/ScreenRotationAnimation.java index 71a61c6..05397ac 100644 --- a/services/java/com/android/server/wm/ScreenRotationAnimation.java +++ b/services/java/com/android/server/wm/ScreenRotationAnimation.java @@ -27,6 +27,7 @@ import android.graphics.Rect; import android.util.Slog; import android.view.Display; import android.view.Surface; +import android.view.SurfaceControl; import android.view.SurfaceSession; import android.view.animation.Animation; import android.view.animation.AnimationUtils; @@ -43,7 +44,7 @@ class ScreenRotationAnimation { final Context mContext; final Display mDisplay; - Surface mSurface; + SurfaceControl mSurface; BlackFrame mCustomBlackFrame; BlackFrame mExitingBlackFrame; BlackFrame mEnteringBlackFrame; @@ -213,7 +214,7 @@ class ScreenRotationAnimation { if (!inTransaction) { if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG, ">>> OPEN TRANSACTION ScreenRotationAnimation"); - Surface.openTransaction(); + SurfaceControl.openTransaction(); } try { @@ -221,22 +222,17 @@ class ScreenRotationAnimation { if (WindowManagerService.DEBUG_SURFACE_TRACE) { mSurface = new SurfaceTrace(session, "FreezeSurface", mWidth, mHeight, - PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT | Surface.HIDDEN); + PixelFormat.OPAQUE, SurfaceControl.FX_SURFACE_SCREENSHOT | SurfaceControl.HIDDEN); } else { - mSurface = new Surface(session, "FreezeSurface", + mSurface = new SurfaceControl(session, "FreezeSurface", mWidth, mHeight, - PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT | Surface.HIDDEN); - } - if (!mSurface.isValid()) { - // Screenshot failed, punt. - mSurface = null; - return; + PixelFormat.OPAQUE, SurfaceControl.FX_SURFACE_SCREENSHOT | SurfaceControl.HIDDEN); } mSurface.setLayerStack(mDisplay.getLayerStack()); mSurface.setLayer(FREEZE_LAYER + 1); mSurface.setAlpha(0); mSurface.show(); - } catch (Surface.OutOfResourcesException e) { + } catch (SurfaceControl.OutOfResourcesException e) { Slog.w(TAG, "Unable to allocate freeze surface", e); } @@ -247,7 +243,7 @@ class ScreenRotationAnimation { setRotationInTransaction(originalRotation); } finally { if (!inTransaction) { - Surface.closeTransaction(); + SurfaceControl.closeTransaction(); if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i(WindowManagerService.TAG, "<<< CLOSE TRANSACTION ScreenRotationAnimation"); } @@ -496,7 +492,7 @@ class ScreenRotationAnimation { if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i( WindowManagerService.TAG, ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation"); - Surface.openTransaction(); + SurfaceControl.openTransaction(); // Compute the transformation matrix that must be applied // the the black frame to make it stay in the initial position @@ -516,7 +512,7 @@ class ScreenRotationAnimation { } catch (Surface.OutOfResourcesException e) { Slog.w(TAG, "Unable to allocate black surface", e); } finally { - Surface.closeTransaction(); + SurfaceControl.closeTransaction(); if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i( WindowManagerService.TAG, "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation"); @@ -527,7 +523,7 @@ class ScreenRotationAnimation { if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i( WindowManagerService.TAG, ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation"); - Surface.openTransaction(); + SurfaceControl.openTransaction(); try { // Compute the transformation matrix that must be applied // the the black frame to make it stay in the initial position @@ -546,7 +542,7 @@ class ScreenRotationAnimation { } catch (Surface.OutOfResourcesException e) { Slog.w(TAG, "Unable to allocate black surface", e); } finally { - Surface.closeTransaction(); + SurfaceControl.closeTransaction(); if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i( WindowManagerService.TAG, "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation"); @@ -557,7 +553,7 @@ class ScreenRotationAnimation { if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i( WindowManagerService.TAG, ">>> OPEN TRANSACTION ScreenRotationAnimation.startAnimation"); - Surface.openTransaction(); + SurfaceControl.openTransaction(); try { Rect outer = new Rect(-finalWidth*1, -finalHeight*1, @@ -568,7 +564,7 @@ class ScreenRotationAnimation { } catch (Surface.OutOfResourcesException e) { Slog.w(TAG, "Unable to allocate black surface", e); } finally { - Surface.closeTransaction(); + SurfaceControl.closeTransaction(); if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS || DEBUG_STATE) Slog.i( WindowManagerService.TAG, "<<< CLOSE TRANSACTION ScreenRotationAnimation.startAnimation"); diff --git a/services/java/com/android/server/wm/Session.java b/services/java/com/android/server/wm/Session.java index 3b4c1ab..7a0fa16 100644 --- a/services/java/com/android/server/wm/Session.java +++ b/services/java/com/android/server/wm/Session.java @@ -40,6 +40,7 @@ import android.view.IWindow; import android.view.IWindowSession; import android.view.InputChannel; import android.view.Surface; +import android.view.SurfaceControl; import android.view.SurfaceSession; import android.view.WindowManager; @@ -313,10 +314,10 @@ final class Session extends IWindowSession.Stub mService.mDragState.mThumbOffsetY = thumbCenterY; // Make the surface visible at the proper location - final Surface surface = mService.mDragState.mSurface; + final SurfaceControl surface = mService.mDragState.mSurface; if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i( WindowManagerService.TAG, ">>> OPEN TRANSACTION performDrag"); - Surface.openTransaction(); + SurfaceControl.openTransaction(); try { surface.setPosition(touchX - thumbCenterX, touchY - thumbCenterY); @@ -325,7 +326,7 @@ final class Session extends IWindowSession.Stub surface.setLayerStack(display.getLayerStack()); surface.show(); } finally { - Surface.closeTransaction(); + SurfaceControl.closeTransaction(); if (WindowManagerService.SHOW_LIGHT_TRANSACTIONS) Slog.i( WindowManagerService.TAG, "<<< CLOSE TRANSACTION performDrag"); } diff --git a/services/java/com/android/server/wm/StrictModeFlash.java b/services/java/com/android/server/wm/StrictModeFlash.java index 90bbd08..31628e3 100644 --- a/services/java/com/android/server/wm/StrictModeFlash.java +++ b/services/java/com/android/server/wm/StrictModeFlash.java @@ -24,29 +24,32 @@ import android.graphics.Rect; import android.graphics.Region; import android.view.Display; import android.view.Surface; +import android.view.SurfaceControl; import android.view.SurfaceSession; class StrictModeFlash { private static final String TAG = "StrictModeFlash"; - Surface mSurface; - int mLastDW; - int mLastDH; - boolean mDrawNeeded; - final int mThickness = 20; + private final SurfaceControl mSurfaceControl; + private final Surface mSurface = new Surface(); + private int mLastDW; + private int mLastDH; + private boolean mDrawNeeded; + private final int mThickness = 20; public StrictModeFlash(Display display, SurfaceSession session) { + SurfaceControl ctrl = null; try { - mSurface = new Surface(session, "StrictModeFlash", - 1, 1, PixelFormat.TRANSLUCENT, Surface.HIDDEN); - } catch (Surface.OutOfResourcesException e) { - return; + ctrl = new SurfaceControl(session, "StrictModeFlash", + 1, 1, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN); + ctrl.setLayerStack(display.getLayerStack()); + ctrl.setLayer(WindowManagerService.TYPE_LAYER_MULTIPLIER * 101); // one more than Watermark? arbitrary. + ctrl.setPosition(0, 0); + ctrl.show(); + mSurface.copyFrom(ctrl); + } catch (SurfaceControl.OutOfResourcesException e) { } - - mSurface.setLayerStack(display.getLayerStack()); - mSurface.setLayer(WindowManagerService.TYPE_LAYER_MULTIPLIER * 101); // one more than Watermark? arbitrary. - mSurface.setPosition(0, 0); - mSurface.show(); + mSurfaceControl = ctrl; mDrawNeeded = true; } @@ -88,14 +91,14 @@ class StrictModeFlash { // Note: caller responsible for being inside // Surface.openTransaction() / closeTransaction() public void setVisibility(boolean on) { - if (mSurface == null) { + if (mSurfaceControl == null) { return; } drawIfNeeded(); if (on) { - mSurface.show(); + mSurfaceControl.show(); } else { - mSurface.hide(); + mSurfaceControl.hide(); } } @@ -105,7 +108,7 @@ class StrictModeFlash { } mLastDW = dw; mLastDH = dh; - mSurface.setSize(dw, dh); + mSurfaceControl.setSize(dw, dh); mDrawNeeded = true; } diff --git a/services/java/com/android/server/wm/Watermark.java b/services/java/com/android/server/wm/Watermark.java index ac152c9..fedd314 100644 --- a/services/java/com/android/server/wm/Watermark.java +++ b/services/java/com/android/server/wm/Watermark.java @@ -28,6 +28,7 @@ import android.util.Log; import android.util.TypedValue; import android.view.Display; import android.view.Surface; +import android.view.SurfaceControl; import android.view.SurfaceSession; import android.view.Surface.OutOfResourcesException; @@ -35,21 +36,20 @@ import android.view.Surface.OutOfResourcesException; * Displays a watermark on top of the window manager's windows. */ class Watermark { - final Display mDisplay; - final String[] mTokens; - final String mText; - final Paint mTextPaint; - final int mTextWidth; - final int mTextHeight; - final int mTextAscent; - final int mTextDescent; - final int mDeltaX; - final int mDeltaY; - - Surface mSurface; - int mLastDW; - int mLastDH; - boolean mDrawNeeded; + private final Display mDisplay; + private final String[] mTokens; + private final String mText; + private final Paint mTextPaint; + private final int mTextWidth; + private final int mTextHeight; + private final int mDeltaX; + private final int mDeltaY; + + private final SurfaceControl mSurfaceControl; + private final Surface mSurface = new Surface(); + private int mLastDW; + private int mLastDH; + private boolean mDrawNeeded; Watermark(Display display, DisplayMetrics dm, SurfaceSession session, String[] tokens) { if (false) { @@ -90,8 +90,6 @@ class Watermark { FontMetricsInt fm = mTextPaint.getFontMetricsInt(); mTextWidth = (int)mTextPaint.measureText(mText); - mTextAscent = fm.ascent; - mTextDescent = fm.descent; mTextHeight = fm.descent - fm.ascent; mDeltaX = WindowManagerService.getPropertyInt(tokens, 2, @@ -112,22 +110,25 @@ class Watermark { mTextPaint.setColor(color); mTextPaint.setShadowLayer(shadowRadius, shadowDx, shadowDy, shadowColor); + SurfaceControl ctrl = null; try { - mSurface = new Surface(session, "WatermarkSurface", - 1, 1, PixelFormat.TRANSLUCENT, Surface.HIDDEN); - mSurface.setLayerStack(mDisplay.getLayerStack()); - mSurface.setLayer(WindowManagerService.TYPE_LAYER_MULTIPLIER*100); - mSurface.setPosition(0, 0); - mSurface.show(); - } catch (OutOfResourcesException e) { + ctrl = new SurfaceControl(session, "WatermarkSurface", + 1, 1, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN); + ctrl.setLayerStack(mDisplay.getLayerStack()); + ctrl.setLayer(WindowManagerService.TYPE_LAYER_MULTIPLIER*100); + ctrl.setPosition(0, 0); + ctrl.show(); + mSurface.copyFrom(ctrl); + } catch (SurfaceControl.OutOfResourcesException e) { } + mSurfaceControl = ctrl; } void positionSurface(int dw, int dh) { if (mLastDW != dw || mLastDH != dh) { mLastDW = dw; mLastDH = dh; - mSurface.setSize(dw, dh); + mSurfaceControl.setSize(dw, dh); mDrawNeeded = true; } } diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java index 546bf2f..1821b6b 100644 --- a/services/java/com/android/server/wm/WindowAnimator.java +++ b/services/java/com/android/server/wm/WindowAnimator.java @@ -22,6 +22,7 @@ import android.util.TimeUtils; import android.util.TypedValue; import android.view.Display; import android.view.Surface; +import android.view.SurfaceControl; import android.view.WindowManagerPolicy; import android.view.animation.Animation; @@ -529,8 +530,8 @@ public class WindowAnimator { if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i( TAG, ">>> OPEN TRANSACTION animateLocked"); - Surface.openTransaction(); - Surface.setAnimationTransaction(); + SurfaceControl.openTransaction(); + SurfaceControl.setAnimationTransaction(); try { final int numDisplays = mDisplayContentsAnimators.size(); for (int i = 0; i < numDisplays; i++) { @@ -622,7 +623,7 @@ public class WindowAnimator { } catch (RuntimeException e) { Log.wtf(TAG, "Unhandled exception in Window Manager", e); } finally { - Surface.closeTransaction(); + SurfaceControl.closeTransaction(); if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i( TAG, "<<< CLOSE TRANSACTION animateLocked"); } diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index a4b5a56..a923604 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -132,6 +132,7 @@ import android.view.KeyEvent; import android.view.MagnificationSpec; import android.view.MotionEvent; import android.view.Surface; +import android.view.SurfaceControl; import android.view.SurfaceSession; import android.view.View; import android.view.ViewTreeObserver; @@ -781,11 +782,11 @@ public class WindowManagerService extends IWindowManager.Stub // Add ourself to the Watchdog monitors. Watchdog.getInstance().addMonitor(this); - Surface.openTransaction(); + SurfaceControl.openTransaction(); try { createWatermarkInTransaction(); } finally { - Surface.closeTransaction(); + SurfaceControl.closeTransaction(); } } @@ -2480,7 +2481,7 @@ public class WindowManagerService extends IWindowManager.Stub } } - static void logSurface(Surface s, String title, String msg, RuntimeException where) { + static void logSurface(SurfaceControl s, String title, String msg, RuntimeException where) { String str = " SURFACE " + s + ": " + msg + " / " + title; if (where != null) { Slog.i(TAG, str, where); @@ -2777,7 +2778,7 @@ public class WindowManagerService extends IWindowManager.Stub if (!win.mHasSurface) { surfaceChanged = true; } - Surface surface = winAnimator.createSurfaceLocked(); + SurfaceControl surface = winAnimator.createSurfaceLocked(); if (surface != null) { outSurface.copyFrom(surface); if (SHOW_TRANSACTIONS) Slog.i(TAG, @@ -5411,7 +5412,7 @@ public class WindowManagerService extends IWindowManager.Stub if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION showStrictModeViolation"); - Surface.openTransaction(); + SurfaceControl.openTransaction(); try { // TODO(multi-display): support multiple displays if (mStrictModeFlash == null) { @@ -5420,7 +5421,7 @@ public class WindowManagerService extends IWindowManager.Stub } mStrictModeFlash.setVisibility(on); } finally { - Surface.closeTransaction(); + SurfaceControl.closeTransaction(); if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION showStrictModeViolation"); } @@ -5575,7 +5576,7 @@ public class WindowManagerService extends IWindowManager.Stub + " surfaceLayer=" + win.mWinAnimator.mSurfaceLayer); } } - rawss = Surface.screenshot(dw, dh, 0, maxLayer); + rawss = SurfaceControl.screenshot(dw, dh, 0, maxLayer); } if (rawss == null) { @@ -5785,7 +5786,7 @@ public class WindowManagerService extends IWindowManager.Stub if (SHOW_TRANSACTIONS) { Slog.i(TAG, ">>> OPEN TRANSACTION setRotationUnchecked"); } - Surface.openTransaction(); + SurfaceControl.openTransaction(); } try { // NOTE: We disable the rotation in the emulator because @@ -5803,7 +5804,7 @@ public class WindowManagerService extends IWindowManager.Stub mDisplayManagerService.performTraversalInTransactionFromWindowManager(); } finally { if (!inTransaction) { - Surface.closeTransaction(); + SurfaceControl.closeTransaction(); if (SHOW_LIGHT_TRANSACTIONS) { Slog.i(TAG, "<<< CLOSE TRANSACTION setRotationUnchecked"); } @@ -6625,8 +6626,8 @@ public class WindowManagerService extends IWindowManager.Stub // TODO(multi-display): support other displays final DisplayContent displayContent = getDefaultDisplayContentLocked(); final Display display = displayContent.getDisplay(); - Surface surface = new Surface(session, "drag surface", - width, height, PixelFormat.TRANSLUCENT, Surface.HIDDEN); + SurfaceControl surface = new SurfaceControl(session, "drag surface", + width, height, PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN); surface.setLayerStack(display.getLayerStack()); if (SHOW_TRANSACTIONS) Slog.i(TAG, " DRAG " + surface + ": CREATE"); @@ -6643,7 +6644,7 @@ public class WindowManagerService extends IWindowManager.Stub } else { Slog.w(TAG, "Drag already in progress"); } - } catch (Surface.OutOfResourcesException e) { + } catch (SurfaceControl.OutOfResourcesException e) { Slog.e(TAG, "Can't allocate drag surface w=" + width + " h=" + height, e); if (mDragState != null) { mDragState.reset(); @@ -8238,10 +8239,10 @@ public class WindowManagerService extends IWindowManager.Stub // TODO(multi-display): support other displays final DisplayContent displayContent = getDefaultDisplayContentLocked(); final Display display = displayContent.getDisplay(); - Surface surface = new Surface(mFxSession, + SurfaceControl surface = new SurfaceControl(mFxSession, "thumbnail anim", dirty.width(), dirty.height(), - PixelFormat.TRANSLUCENT, Surface.HIDDEN); + PixelFormat.TRANSLUCENT, SurfaceControl.HIDDEN); surface.setLayerStack(display.getLayerStack()); appAnimator.thumbnail = surface; if (SHOW_TRANSACTIONS) Slog.i(TAG, " THUMBNAIL " + surface + ": CREATE"); @@ -8262,10 +8263,14 @@ public class WindowManagerService extends IWindowManager.Stub mAppTransition.getStartingPoint(p); appAnimator.thumbnailX = p.x; appAnimator.thumbnailY = p.y; - } catch (Surface.OutOfResourcesException e) { + } catch (SurfaceControl.OutOfResourcesException e) { Slog.e(TAG, "Can't allocate thumbnail surface w=" + dirty.width() + " h=" + dirty.height(), e); appAnimator.clearThumbnail(); + } catch (Surface.OutOfResourcesException e) { + Slog.e(TAG, "Can't allocate Canvas surface w=" + dirty.width() + + " h=" + dirty.height(), e); + appAnimator.clearThumbnail(); } } @@ -8527,7 +8532,7 @@ public class WindowManagerService extends IWindowManager.Stub if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces"); - Surface.openTransaction(); + SurfaceControl.openTransaction(); try { if (mWatermark != null) { @@ -8802,7 +8807,7 @@ public class WindowManagerService extends IWindowManager.Stub } catch (RuntimeException e) { Log.wtf(TAG, "Unhandled exception in Window Manager", e); } finally { - Surface.closeTransaction(); + SurfaceControl.closeTransaction(); if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces"); } @@ -9215,7 +9220,7 @@ public class WindowManagerService extends IWindowManager.Stub boolean reclaimSomeSurfaceMemoryLocked(WindowStateAnimator winAnimator, String operation, boolean secure) { - final Surface surface = winAnimator.mSurface; + final SurfaceControl surface = winAnimator.mSurface; boolean leakedSurface = false; boolean killedApps = false; diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java index a4c6a9e..82e59a8 100644 --- a/services/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/java/com/android/server/wm/WindowStateAnimator.java @@ -20,6 +20,7 @@ import android.view.Display; import android.view.DisplayInfo; import android.view.MagnificationSpec; import android.view.Surface; +import android.view.SurfaceControl; import android.view.SurfaceSession; import android.view.WindowManager; import android.view.WindowManagerPolicy; @@ -87,8 +88,8 @@ class WindowStateAnimator { int mAnimLayer; int mLastLayer; - Surface mSurface; - Surface mPendingDestroySurface; + SurfaceControl mSurface; + SurfaceControl mPendingDestroySurface; /** * Set when we have changed the size of the surface, to know that @@ -477,7 +478,7 @@ class WindowStateAnimator { return true; } - static class SurfaceTrace extends Surface { + static class SurfaceTrace extends SurfaceControl { private final static String SURFACE_TAG = "SurfaceTrace"; final static ArrayList<SurfaceTrace> sSurfaces = new ArrayList<SurfaceTrace>(); @@ -623,7 +624,7 @@ class WindowStateAnimator { } } - Surface createSurfaceLocked() { + SurfaceControl createSurfaceLocked() { if (mSurface == null) { if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG, "createSurface " + this + ": mDrawState=DRAW_PENDING"); @@ -641,11 +642,11 @@ class WindowStateAnimator { mService.makeWindowFreezingScreenIfNeededLocked(mWin); - int flags = Surface.HIDDEN; + int flags = SurfaceControl.HIDDEN; final WindowManager.LayoutParams attrs = mWin.mAttrs; if ((attrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) { - flags |= Surface.SECURE; + flags |= SurfaceControl.SECURE; } if (WindowState.DEBUG_VISIBILITY) Slog.v( TAG, "Creating surface in session " @@ -681,7 +682,7 @@ class WindowStateAnimator { WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0; final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format; if (!PixelFormat.formatHasAlpha(attrs.format)) { - flags |= Surface.OPAQUE; + flags |= SurfaceControl.OPAQUE; } if (DEBUG_SURFACE_TRACE) { mSurface = new SurfaceTrace( @@ -689,7 +690,7 @@ class WindowStateAnimator { attrs.getTitle().toString(), w, h, format, flags); } else { - mSurface = new Surface( + mSurface = new SurfaceControl( mSession.mSurfaceSession, attrs.getTitle().toString(), w, h, format, flags); @@ -703,7 +704,7 @@ class WindowStateAnimator { + attrs.format + " flags=0x" + Integer.toHexString(flags) + " / " + this); - } catch (Surface.OutOfResourcesException e) { + } catch (SurfaceControl.OutOfResourcesException e) { mWin.mHasSurface = false; Slog.w(TAG, "OutOfResourcesException creating surface"); mService.reclaimSomeSurfaceMemoryLocked(this, "create", true); @@ -727,7 +728,7 @@ class WindowStateAnimator { + mWin.mCompatFrame.width() + "x" + mWin.mCompatFrame.height() + "), layer=" + mAnimLayer + " HIDE", null); } - Surface.openTransaction(); + SurfaceControl.openTransaction(); try { try { mSurfaceX = mWin.mFrame.left + mWin.mXOffset; @@ -744,7 +745,7 @@ class WindowStateAnimator { } mLastHidden = true; } finally { - Surface.closeTransaction(); + SurfaceControl.closeTransaction(); if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION createSurfaceLocked"); } @@ -1324,13 +1325,13 @@ class WindowStateAnimator { } if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setTransparentRegion"); - Surface.openTransaction(); + SurfaceControl.openTransaction(); try { if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, "transparentRegionHint=" + region, null); mSurface.setTransparentRegionHint(region); } finally { - Surface.closeTransaction(); + SurfaceControl.closeTransaction(); if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setTransparentRegion"); } @@ -1351,7 +1352,7 @@ class WindowStateAnimator { } if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setWallpaperOffset"); - Surface.openTransaction(); + SurfaceControl.openTransaction(); try { if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, "POS " + left + ", " + top, null); @@ -1361,7 +1362,7 @@ class WindowStateAnimator { Slog.w(TAG, "Error positioning surface of " + mWin + " pos=(" + left + "," + top + ")", e); } finally { - Surface.closeTransaction(); + SurfaceControl.closeTransaction(); if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setWallpaperOffset"); } |