diff options
author | Jeff Brown <jeffbrown@google.com> | 2012-08-26 02:47:39 -0700 |
---|---|---|
committer | Jeff Brown <jeffbrown@google.com> | 2012-08-27 14:34:54 -0700 |
commit | 64a55af0ac700baecb0877235eb42caac59a3560 (patch) | |
tree | 0f3c36ce8204e6cf8eedf04ce9ae24373239ddd8 | |
parent | 0b722fe9ce98d97dbcb6fefd170b85ab7037e528 (diff) | |
download | frameworks_base-64a55af0ac700baecb0877235eb42caac59a3560.zip frameworks_base-64a55af0ac700baecb0877235eb42caac59a3560.tar.gz frameworks_base-64a55af0ac700baecb0877235eb42caac59a3560.tar.bz2 |
Add plumbing for new surface flinger display API.
Cleaned up the implementation of Surface and SurfaceSession
to use more consistent naming and structure.
Added JNI for all of the new surface flinger display API calls.
Enforced the requirement that all Surfaces created by
the window manager be named.
Updated the display manager service to use the new methods.
Change-Id: I2a658f1bfd0437e1c6f9d22df8d4ffcce7284ca2
34 files changed, 1427 insertions, 1072 deletions
diff --git a/api/current.txt b/api/current.txt index bcb6fab..22509e5 100644 --- a/api/current.txt +++ b/api/current.txt @@ -6475,6 +6475,7 @@ package android.content.pm { method public abstract int checkSignatures(int, int); method public abstract void clearPackagePreferredActivities(java.lang.String); method public abstract java.lang.String[] currentToCanonicalPackageNames(java.lang.String[]); + method public abstract void extendVerificationTimeout(int, int, long); method public abstract android.graphics.drawable.Drawable getActivityIcon(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException; method public abstract android.graphics.drawable.Drawable getActivityIcon(android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException; method public abstract android.content.pm.ActivityInfo getActivityInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException; @@ -6533,7 +6534,6 @@ package android.content.pm { method public abstract void setComponentEnabledSetting(android.content.ComponentName, int, int); method public abstract void setInstallerPackageName(java.lang.String, java.lang.String); method public abstract void verifyPendingInstall(int, int); - method public abstract void extendVerificationTimeout(int, int, long); field public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0; // 0x0 field public static final int COMPONENT_ENABLED_STATE_DISABLED = 2; // 0x2 field public static final int COMPONENT_ENABLED_STATE_DISABLED_USER = 3; // 0x3 @@ -6594,6 +6594,7 @@ package android.content.pm { field public static final int GET_UNINSTALLED_PACKAGES = 8192; // 0x2000 field public static final int GET_URI_PERMISSION_PATTERNS = 2048; // 0x800 field public static final int MATCH_DEFAULT_ONLY = 65536; // 0x10000 + field public static final long MAXIMUM_VERIFICATION_TIMEOUT = 3600000L; // 0x36ee80L field public static final int PERMISSION_DENIED = -1; // 0xffffffff field public static final int PERMISSION_GRANTED = 0; // 0x0 field public static final int SIGNATURE_FIRST_NOT_SIGNED = -1; // 0xffffffff @@ -6604,7 +6605,6 @@ package android.content.pm { field public static final int SIGNATURE_UNKNOWN_PACKAGE = -4; // 0xfffffffc field public static final int VERIFICATION_ALLOW = 1; // 0x1 field public static final int VERIFICATION_REJECT = -1; // 0xffffffff - field public static final long MAXIMUM_VERIFICATION_TIMEOUT = 3600000L; // 0x36ee80 } public static class PackageManager.NameNotFoundException extends android.util.AndroidException { @@ -20069,8 +20069,8 @@ package android.service.dreams { method public void setContentView(android.view.View); method public void setContentView(android.view.View, android.view.ViewGroup.LayoutParams); method public void setInteractive(boolean); - field public static final java.lang.String SERVICE_INTERFACE = "android.service.dreams.Dream"; field public static final java.lang.String METADATA_NAME_CONFIG_ACTIVITY = "android.service.dreams.config_activity"; + field public static final java.lang.String SERVICE_INTERFACE = "android.service.dreams.Dream"; } } @@ -21328,6 +21328,7 @@ package android.test.mock { method public int checkSignatures(int, int); method public void clearPackagePreferredActivities(java.lang.String); method public java.lang.String[] currentToCanonicalPackageNames(java.lang.String[]); + method public void extendVerificationTimeout(int, int, long); method public android.graphics.drawable.Drawable getActivityIcon(android.content.ComponentName) throws android.content.pm.PackageManager.NameNotFoundException; method public android.graphics.drawable.Drawable getActivityIcon(android.content.Intent) throws android.content.pm.PackageManager.NameNotFoundException; method public android.content.pm.ActivityInfo getActivityInfo(android.content.ComponentName, int) throws android.content.pm.PackageManager.NameNotFoundException; @@ -21385,7 +21386,6 @@ package android.test.mock { method public void setComponentEnabledSetting(android.content.ComponentName, int, int); method public void setInstallerPackageName(java.lang.String, java.lang.String); method public void verifyPendingInstall(int, int); - method public void extendVerificationTimeout(int, int, long); } public class MockResources extends android.content.res.Resources { @@ -24422,7 +24422,7 @@ package android.view { method public android.graphics.Canvas lockCanvas(android.graphics.Rect) throws java.lang.IllegalArgumentException, android.view.Surface.OutOfResourcesException; method public void readFromParcel(android.os.Parcel); method public void release(); - method public void unlockCanvas(android.graphics.Canvas); + method public deprecated void unlockCanvas(android.graphics.Canvas); method public void unlockCanvasAndPost(android.graphics.Canvas); method public void writeToParcel(android.os.Parcel, int); field public static final android.os.Parcelable.Creator CREATOR; diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java index 84b3d64..cf1767d 100644 --- a/core/java/android/view/Surface.java +++ b/core/java/android/view/Surface.java @@ -16,6 +16,8 @@ package android.view; +import dalvik.system.CloseGuard; + import android.content.res.CompatibilityInfo.Translator; import android.graphics.Bitmap; import android.graphics.Canvas; @@ -23,9 +25,9 @@ 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.Process; import android.os.SystemProperties; import android.util.Log; @@ -33,206 +35,187 @@ import android.util.Log; * Handle onto a raw buffer that is being managed by the screen compositor. */ public class Surface implements Parcelable { - private static final String LOG_TAG = "Surface"; - private static final boolean DEBUG_RELEASE = false; - - /* orientations for setOrientation() */ - public static final int ROTATION_0 = 0; - public static final int ROTATION_90 = 1; - public static final int ROTATION_180 = 2; - public static final int ROTATION_270 = 3; + private static final String TAG = "Surface"; - private static final boolean headless = "1".equals( + private static final boolean HEADLESS = "1".equals( SystemProperties.get("ro.config.headless", "0")); - private static void checkHeadless() { - if(headless) { - throw new UnsupportedOperationException("Device is headless"); + public static final Parcelable.Creator<Surface> CREATOR = + new Parcelable.Creator<Surface>() { + public Surface createFromParcel(Parcel source) { + try { + Surface s = new Surface(); + s.readFromParcel(source); + return s; + } catch (Exception e) { + Log.e(TAG, "Exception creating surface from parcel", e); + return null; + } } - } - /** - * Create Surface from a {@link SurfaceTexture}. - * - * Images drawn to the Surface will be made available to the {@link - * SurfaceTexture}, which can attach them an OpenGL ES texture via {@link - * SurfaceTexture#updateTexImage}. - * - * @param surfaceTexture The {@link SurfaceTexture} that is updated by this - * Surface. - */ - public Surface(SurfaceTexture surfaceTexture) { - checkHeadless(); - - if (DEBUG_RELEASE) { - mCreationStack = new Exception(); + public Surface[] newArray(int size) { + return new Surface[size]; } - mCanvas = new CompatibleCanvas(); - initFromSurfaceTexture(surfaceTexture); - } + }; /** - * Does this object hold a valid surface? Returns true if it holds - * a physical surface, so lockCanvas() will succeed. Otherwise - * returns false. + * Rotation constant: 0 degree rotation (natural orientation) */ - public native boolean isValid(); + public static final int ROTATION_0 = 0; - /** 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. + /** + * Rotation constant: 90 degree rotation. */ - public native void release(); + public static final int ROTATION_90 = 1; - /** draw into a surface */ - public Canvas lockCanvas(Rect dirty) throws OutOfResourcesException, IllegalArgumentException { - /* - * the dirty rectangle may be expanded to the surface's size, if for - * instance it has been resized or if the bits were lost, since the last - * call. - */ - return lockCanvasNative(dirty); - } - - /** unlock the surface and asks a page flip */ - public native void unlockCanvasAndPost(Canvas canvas); - - /** - * unlock the surface. the screen won't be updated until - * post() or postAll() is called + /** + * Rotation constant: 180 degree rotation. */ - public native void unlockCanvas(Canvas canvas); + public static final int ROTATION_180 = 2; - @Override - public String toString() { - return "Surface(name=" + mName + ", identity=" + getIdentity() + ")"; - } - - public int describeContents() { - return 0; - } + /** + * Rotation constant: 270 degree rotation. + */ + public static final int ROTATION_270 = 3; - public native void readFromParcel(Parcel source); - public native void writeToParcel(Parcel dest, int flags); + /* built-in physical display ids (keep in sync with ISurfaceComposer.h) + * these are different from the logical display ids used elsewhere in the framework */ /** - * Exception thrown when a surface couldn't be created or resized + * Built-in physical display id: Main display. + * Use only with {@link #getBuiltInDisplay()}. + * @hide */ - public static class OutOfResourcesException extends Exception { - public OutOfResourcesException() { - } - public OutOfResourcesException(String name) { - super(name); - } - } - - /* - * ----------------------------------------------------------------------- - * No user serviceable parts beyond this point - * ----------------------------------------------------------------------- + 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 ISurfaceComposer.h) */ + /* flags used in constructor (keep in sync with ISurfaceComposerClient.h) */ - /** Surface is created hidden @hide */ - public static final int HIDDEN = 0x00000004; + /** + * Surface creation flag: Surface is created hidden + * @hide */ + public static final int HIDDEN = 0x00000004; - /** 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 + /** + * 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; - - /** 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: - * + * @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: - * + * + * 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; - + * + * 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; + /** - * Indicates that the surface must be considered opaque, even if its - * pixel format is set to translucent. This can be useful if an + * 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; - + public static final int OPAQUE = 0x00000400; + /** - * Application requires a hardware-protected path to an + * 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; + public static final int PROTECTED_APP = 0x00000800; // 0x1000 is reserved for an independent DRM protected flag in framework - /** Creates a normal surface. This is the default. @hide */ + /** + * Surface creation flag: Creates a normal surface. + * This is the default. + * @hide + */ public static final int FX_SURFACE_NORMAL = 0x00000000; - - /** 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. + + /** + * 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; - - /** 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_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; + public static final int FX_SURFACE_DIM = 0x00020000; - /** @hide */ - public static final int FX_SURFACE_SCREENSHOT = 0x00030000; + /** + * @hide + */ + public static final int FX_SURFACE_SCREENSHOT = 0x00030000; - /** Mask used for FX values above @hide */ - public static final int FX_SURFACE_MASK = 0x000F0000; + /** + * 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) */ - /** Hide the surface. Equivalent to calling hide(). @hide */ - public static final int SURFACE_HIDDEN = 0x01; + /** + * 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; + // Note: These fields are accessed by native code. // The mSurfaceControl will only be present for Surfaces used by the window // 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 mSurfaceControl; - private int mSaveCount; - private Canvas mCanvas; - private int mNativeSurface; - private int mSurfaceGenerationId; - private String mName; + private int mNativeSurface; // Surface* + private int mNativeSurfaceControl; // SurfaceControl* + private int mGenerationId; // incremented each time mNativeSurface changes + private final Canvas mCanvas = new CompatibleCanvas(); + private int mCanvasSaveCount; // Canvas save count at time of lockCanvas() // The Translator for density compatibility mode. This is used for scaling // the canvas to perform the appropriate density transformation. @@ -242,148 +225,245 @@ public class Surface implements Parcelable { // non compatibility mode. private Matrix mCompatibleMatrix; - private Exception mCreationStack; + 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 int nativeGetIdentity(); + 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 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); + private static native void nativeSetDisplaySurface( + IBinder displayToken, SurfaceTexture surfaceTexture); + private static native void nativeSetDisplayLayerStack( + IBinder displayToken, int layerStack); + private static native void nativeSetDisplayOrientation( + IBinder displayToken, int orientation); + private static native void nativeSetDisplayViewport( + IBinder displayToken, Rect viewport); + private static native void nativeSetDisplayFrame( + IBinder displayToken, Rect frame); + private static native boolean nativeGetDisplayInfo( + IBinder displayToken, PhysicalDisplayInfo outInfo); + + private native void nativeCopyFrom(Surface other); + private native void nativeTransferFrom(Surface other); + private native void nativeReadFromParcel(Parcel source); + private native void nativeWriteToParcel(Parcel dest); - /* - * We use a class initializer to allow the native code to cache some - * field offsets. + /** + * Create an empty surface, which will later be filled in by readFromParcel(). + * @hide */ - native private static void nativeClassInit(); - static { nativeClassInit(); } - - /** create a surface with a name @hide */ - public Surface(SurfaceSession s, - int pid, String name, int layerStack, int w, int h, int format, int flags) - throws OutOfResourcesException { - // FIXME: remove pid and layerstack arguments + public Surface() { checkHeadless(); - if (DEBUG_RELEASE) { - mCreationStack = new Exception(); - } + 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) { - name = "<pid " + Process.myPid() + ">"; + 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()); } - mCanvas = new CompatibleCanvas(); - init(s, name, w, h, format, flags); - setLayerStack(layerStack); + checkHeadless(); + mName = name; + nativeCreate(session, name, w, h, format, flags); + + mCloseGuard.open("release"); } /** - * Create an empty surface, which will later be filled in by - * readFromParcel(). - * @hide + * Create Surface from a {@link SurfaceTexture}. + * + * Images drawn to the Surface will be made available to the {@link + * SurfaceTexture}, which can attach them to an OpenGL ES texture via {@link + * SurfaceTexture#updateTexImage}. + * + * @param surfaceTexture The {@link SurfaceTexture} that is updated by this + * Surface. */ - public Surface() { + public Surface(SurfaceTexture surfaceTexture) { + if (surfaceTexture == null) { + throw new IllegalArgumentException("surfaceTexture must not be null"); + } + checkHeadless(); - if (DEBUG_RELEASE) { - mCreationStack = new Exception(); + mName = surfaceTexture.toString(); + try { + nativeCreateFromSurfaceTexture(surfaceTexture); + } catch (OutOfResourcesException ex) { + // We can't throw OutOfResourcesException because it would be an API change. + throw new RuntimeException(ex); } - mCanvas = new CompatibleCanvas(); + + mCloseGuard.open("release"); } - private Surface(Parcel source) throws OutOfResourcesException { - init(source); + @Override + protected void finalize() throws Throwable { + try { + if (mCloseGuard != null) { + mCloseGuard.warnIfOpen(); + } + nativeRelease(); + } finally { + super.finalize(); + } } /** - * Copy another surface to this one. This surface now holds a reference - * to the same data as the original surface, and is -not- the owner. - * This is for use by the window manager when returning a window surface - * back from a client, converting it from the representation being managed - * by the window manager to the representation the client uses to draw - * in to it. + * 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() { + nativeRelease(); + 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. * @hide */ - public native void copyFrom(Surface o); + public void destroy() { + nativeDestroy(); + mCloseGuard.close(); + } /** - * Transfer the native state from 'o' to this surface, releasing it - * from 'o'. This is for use in the client side for drawing into a - * surface; not guaranteed to work on the window manager side. - * This is for use by the client to move the underlying surface from - * one Surface object to another, in particular in SurfaceFlinger. - * @hide. + * Returns true if this object holds a valid surface. + * + * @return True if it holds a physical surface, so lockCanvas() will succeed. + * Otherwise returns false. */ - public native void transferFrom(Surface o); + public boolean isValid() { + return nativeIsValid(); + } - /** @hide */ + /** + * Gets the generation number of this surface, incremented each time + * the native surface contained within this object changes. + * + * @return The current generation number. + * @hide + */ public int getGenerationId() { - return mSurfaceGenerationId; + return mGenerationId; } - /** - * Whether the consumer of this Surface is running behind the producer; - * that is, isConsumerRunningBehind() returns true if the consumer is more - * than one buffer ahead of the producer. + * Returns true if the consumer of this Surface is running behind the producer. + * + * @return True if the consumer is more than one buffer ahead of the producer. * @hide */ - public native boolean isConsumerRunningBehind(); + public boolean isConsumerRunningBehind() { + return nativeIsConsumerRunningBehind(); + } /** - * A Canvas class that can handle the compatibility mode. This does two - * things differently. - * <ul> - * <li>Returns the width and height of the target metrics, rather than - * native. For example, the canvas returns 320x480 even if an app is running - * in WVGA high density. - * <li>Scales the matrix in setMatrix by the application scale, except if - * the matrix looks like obtained from getMatrix. This is a hack to handle - * the case that an application uses getMatrix to keep the original matrix, - * set matrix of its own, then set the original matrix back. There is no - * perfect solution that works for all cases, and there are a lot of cases - * that this model does not work, but we hope this works for many apps. - * </ul> + * Gets a {@link Canvas} for drawing into this surface. + * + * After drawing into the provided {@link Canvas}, the caller should + * invoke {@link #unlockCanvasAndPost} to post the new contents to the surface. + * + * @param dirty A rectangle that represents the dirty region that the caller wants + * to redraw. This function may choose to expand the dirty rectangle if for example + * the surface has been resized or if the previous contents of the surface were + * not available. The caller should redraw the entire dirty region as represented + * by the contents of the dirty rect upon return from this function. + * The caller may also pass <code>null</code> instead, in the case where the + * entire surface should be redrawn. + * @return A canvas for drawing into the surface. */ - private class CompatibleCanvas extends Canvas { - // A temp matrix to remember what an application obtained via {@link getMatrix} - private Matrix mOrigMatrix = null; - - @Override - public int getWidth() { - int w = super.getWidth(); - if (mCompatibilityTranslator != null) { - w = (int)(w * mCompatibilityTranslator.applicationInvertedScale + .5f); - } - return w; - } - - @Override - public int getHeight() { - int h = super.getHeight(); - if (mCompatibilityTranslator != null) { - h = (int)(h * mCompatibilityTranslator.applicationInvertedScale + .5f); - } - return h; - } + public Canvas lockCanvas(Rect dirty) + throws OutOfResourcesException, IllegalArgumentException { + return nativeLockCanvas(dirty); + } - @Override - public void setMatrix(Matrix matrix) { - if (mCompatibleMatrix == null || mOrigMatrix == null || mOrigMatrix.equals(matrix)) { - // don't scale the matrix if it's not compatibility mode, or - // the matrix was obtained from getMatrix. - super.setMatrix(matrix); - } else { - Matrix m = new Matrix(mCompatibleMatrix); - m.preConcat(matrix); - super.setMatrix(m); - } - } + /** + * Posts the new contents of the {@link Canvas} to the surface and + * releases the {@link Canvas}. + * + * @param canvas The canvas previously obtained from {@link #lockCanvas}. + */ + public void unlockCanvasAndPost(Canvas canvas) { + nativeUnlockCanvasAndPost(canvas); + } - @Override - public void getMatrix(Matrix m) { - super.getMatrix(m); - if (mOrigMatrix == null) { - mOrigMatrix = new Matrix(); - } - mOrigMatrix.set(m); - } + /** + * @deprecated This API has been removed and is not supported. Do not use. + */ + @Deprecated + public void unlockCanvas(Canvas canvas) { + throw new UnsupportedOperationException(); } /** @@ -397,20 +477,6 @@ public class Surface implements Parcelable { mCompatibleMatrix.setScale(appScale, appScale); } } - - /** Free all server-side state associated with this surface and - * release this object's reference. @hide */ - public native void destroy(); - - private native Canvas lockCanvasNative(Rect dirty) throws OutOfResourcesException; - - /** - * set the orientation of the given display. - * @param display - * @param orientation - * @hide - */ - public static native void setOrientation(int display, int orientation); /** * Like {@link #screenshot(int, int, int, int)} but includes all @@ -418,8 +484,12 @@ public class Surface implements Parcelable { * * @hide */ - public static native Bitmap screenshot(int width, int height); - + 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. * @@ -431,91 +501,318 @@ public class Surface implements Parcelable { * 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. + * @return Returns a Bitmap containing the screen contents, or null + * if an error occurs. * * @hide */ - public static native Bitmap screenshot(int width, int height, int minLayer, int maxLayer); + 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 native void openTransaction(); + public static void openTransaction() { + nativeOpenTransaction(); + } + /** end a transaction @hide */ - public static native void closeTransaction(); + public static void closeTransaction() { + nativeCloseTransaction(); + } + + /** @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 native void setLayer(int zorder); + public void hide() { + nativeSetFlags(SURFACE_HIDDEN, SURFACE_HIDDEN); + } + /** @hide */ - public void setPosition(int x, int y) { setPosition((float)x, (float)y); } + public void show() { + nativeSetFlags(0, SURFACE_HIDDEN); + } + /** @hide */ - public native void setPosition(float x, float y); + 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 native void setSize(int w, int h); + public void setFlags(int flags, int mask) { + nativeSetFlags(flags, mask); + } + /** @hide */ - public native void hide(); + public void setWindowCrop(Rect crop) { + nativeSetWindowCrop(crop); + } + /** @hide */ - public native void show(); + public void setLayerStack(int layerStack) { + nativeSetLayerStack(layerStack); + } + /** @hide */ - public native void setTransparentRegionHint(Region region); + public static IBinder getBuiltInDisplay(int builtInDisplayId) { + return nativeGetBuiltInDisplay(builtInDisplayId); + } + /** @hide */ - public native void setAlpha(float alpha); + public static IBinder createDisplay(String name) { + if (name == null) { + throw new IllegalArgumentException("name must not be null"); + } + return nativeCreateDisplay(name); + } + /** @hide */ - public native void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy); + public static void setDisplaySurface(IBinder displayToken, SurfaceTexture surfaceTexture) { + if (displayToken == null) { + throw new IllegalArgumentException("displayToken must not be null"); + } + nativeSetDisplaySurface(displayToken, surfaceTexture); + } + /** @hide */ - public native void setFlags(int flags, int mask); + public static void setDisplayLayerStack(IBinder displayToken, int layerStack) { + if (displayToken == null) { + throw new IllegalArgumentException("displayToken must not be null"); + } + nativeSetDisplayLayerStack(displayToken, layerStack); + } + /** @hide */ - public native void setWindowCrop(Rect crop); + public static void setDisplayOrientation(IBinder displayToken, int orientation) { + if (displayToken == null) { + throw new IllegalArgumentException("displayToken must not be null"); + } + nativeSetDisplayOrientation(displayToken, orientation); + } + /** @hide */ - public native void setLayerStack(int layerStack); + public static void setDisplayViewport(IBinder displayToken, Rect viewport) { + if (displayToken == null) { + throw new IllegalArgumentException("displayToken must not be null"); + } + if (viewport == null) { + throw new IllegalArgumentException("viewport must not be null"); + } + nativeSetDisplayViewport(displayToken, viewport); + } + /** @hide */ + public static void setDisplayFrame(IBinder displayToken, Rect frame) { + if (displayToken == null) { + throw new IllegalArgumentException("displayToken must not be null"); + } + if (frame == null) { + throw new IllegalArgumentException("frame must not be null"); + } + nativeSetDisplayFrame(displayToken, frame); + } - - public static final Parcelable.Creator<Surface> CREATOR - = new Parcelable.Creator<Surface>() - { - public Surface createFromParcel(Parcel source) { - try { - return new Surface(source); - } catch (Exception e) { - Log.e(LOG_TAG, "Exception creating surface from parcel", e); - } - return null; + /** @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); + } - public Surface[] newArray(int size) { - return new Surface[size]; + /** + * Copy another surface to this one. This surface now holds a reference + * to the same data as the original surface, and is -not- the owner. + * This is for use by the window manager when returning a window surface + * back from a client, converting it from the representation being managed + * by the window manager to the representation the client uses to draw + * in to it. + * @hide + */ + public void copyFrom(Surface other) { + if (other == null) { + throw new IllegalArgumentException("other must not be null"); } - }; + if (other != this) { + nativeCopyFrom(other); + } + } + + /** + * Transfer the native state from 'other' to this surface, releasing it + * from 'other'. This is for use in the client side for drawing into a + * surface; not guaranteed to work on the window manager side. + * This is for use by the client to move the underlying surface from + * one Surface object to another, in particular in SurfaceFlinger. + * @hide. + */ + public void transferFrom(Surface other) { + if (other == null) { + throw new IllegalArgumentException("other must not be null"); + } + if (other != this) { + nativeTransferFrom(other); + } + } @Override - protected void finalize() throws Throwable { - try { - super.finalize(); - } finally { - if (mNativeSurface != 0 || mSurfaceControl != 0) { - if (DEBUG_RELEASE) { - Log.w(LOG_TAG, "Surface.finalize() has work. You should have called release() (" - + mNativeSurface + ", " + mSurfaceControl + ")", mCreationStack); - } else { - Log.w(LOG_TAG, "Surface.finalize() has work. You should have called release() (" - + mNativeSurface + ", " + mSurfaceControl + ")"); - } - } - release(); + public int describeContents() { + return 0; + } + + public void readFromParcel(Parcel source) { + if (source == null) { + throw new IllegalArgumentException("source must not be null"); } + + mName = source.readString(); + nativeReadFromParcel(source); } - - private native void init(SurfaceSession s, String name, - int w, int h, int format, int flags) - throws OutOfResourcesException; - private native void init(Parcel source) throws OutOfResourcesException; + @Override + public void writeToParcel(Parcel dest, int flags) { + if (dest == null) { + throw new IllegalArgumentException("dest must not be null"); + } - private native void initFromSurfaceTexture(SurfaceTexture surfaceTexture); + dest.writeString(mName); + nativeWriteToParcel(dest); + if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) { + release(); + } + } - private native int getIdentity(); + @Override + public String toString() { + return "Surface(name=" + mName + ", identity=" + nativeGetIdentity() + ")"; + } + + 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. + * @hide + */ + public static final class PhysicalDisplayInfo { + // TODO: redesign this + public int width; + public int height; + public float refreshRate; + public float density; + public float xDpi; + public float yDpi; + } + + /** + * A Canvas class that can handle the compatibility mode. + * This does two things differently. + * <ul> + * <li>Returns the width and height of the target metrics, rather than + * native. For example, the canvas returns 320x480 even if an app is running + * in WVGA high density. + * <li>Scales the matrix in setMatrix by the application scale, except if + * the matrix looks like obtained from getMatrix. This is a hack to handle + * the case that an application uses getMatrix to keep the original matrix, + * set matrix of its own, then set the original matrix back. There is no + * perfect solution that works for all cases, and there are a lot of cases + * that this model does not work, but we hope this works for many apps. + * </ul> + */ + private final class CompatibleCanvas extends Canvas { + // A temp matrix to remember what an application obtained via {@link getMatrix} + private Matrix mOrigMatrix = null; + + @Override + public int getWidth() { + int w = super.getWidth(); + if (mCompatibilityTranslator != null) { + w = (int)(w * mCompatibilityTranslator.applicationInvertedScale + .5f); + } + return w; + } + + @Override + public int getHeight() { + int h = super.getHeight(); + if (mCompatibilityTranslator != null) { + h = (int)(h * mCompatibilityTranslator.applicationInvertedScale + .5f); + } + return h; + } + + @Override + public void setMatrix(Matrix matrix) { + if (mCompatibleMatrix == null || mOrigMatrix == null || mOrigMatrix.equals(matrix)) { + // don't scale the matrix if it's not compatibility mode, or + // the matrix was obtained from getMatrix. + super.setMatrix(matrix); + } else { + Matrix m = new Matrix(mCompatibleMatrix); + m.preConcat(matrix); + super.setMatrix(m); + } + } + + @Override + public void getMatrix(Matrix m) { + super.getMatrix(m); + if (mOrigMatrix == null) { + mOrigMatrix = new Matrix(); + } + mOrigMatrix.set(m); + } + } } diff --git a/core/java/android/view/SurfaceSession.java b/core/java/android/view/SurfaceSession.java index 2491abe..0dfd94a 100644 --- a/core/java/android/view/SurfaceSession.java +++ b/core/java/android/view/SurfaceSession.java @@ -16,30 +16,32 @@ package android.view; - /** * An instance of this class represents a connection to the surface - * flinger, in which you can create one or more Surface instances that will + * flinger, from which you can create one or more Surface instances that will * be composited to the screen. * {@hide} */ -public class SurfaceSession { - private int mClient; +public final class SurfaceSession { + // Note: This field is accessed by native code. + private int mNativeClient; // SurfaceComposerClient* - private native void nativeInit(); - private native void nativeDestroy(); - private native void nativeKill(); + private static native int nativeCreate(); + private static native void nativeDestroy(int ptr); + private static native void nativeKill(int ptr); /** Create a new connection with the surface flinger. */ public SurfaceSession() { - nativeInit(); + mNativeClient = nativeCreate(); } /* no user serviceable parts here ... */ @Override protected void finalize() throws Throwable { try { - nativeDestroy(); + if (mNativeClient != 0) { + nativeDestroy(mNativeClient); + } } finally { super.finalize(); } @@ -48,10 +50,10 @@ public class SurfaceSession { /** * Forcibly detach native resources associated with this object. * Unlike destroy(), after this call any surfaces that were created - * from the session will no longer work. The session itself is destroyed. + * from the session will no longer work. */ public void kill() { - nativeKill(); + nativeKill(mNativeClient); } } diff --git a/core/jni/Android.mk b/core/jni/Android.mk index f950d3d..9d45479 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -46,6 +46,7 @@ LOCAL_SRC_FILES:= \ android_emoji_EmojiFactory.cpp \ android_view_DisplayEventReceiver.cpp \ android_view_Surface.cpp \ + android_view_SurfaceSession.cpp \ android_view_TextureView.cpp \ android_view_InputChannel.cpp \ android_view_InputDevice.cpp \ diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index 0c88297..55563a8 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -121,6 +121,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_SurfaceSession(JNIEnv* env); extern int register_android_view_TextureView(JNIEnv* env); extern int register_android_database_CursorWindow(JNIEnv* env); extern int register_android_database_SQLiteConnection(JNIEnv* env); @@ -1094,6 +1095,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_SurfaceSession), REG_JNI(register_android_view_TextureView), REG_JNI(register_com_google_android_gles_jni_EGLImpl), REG_JNI(register_com_google_android_gles_jni_GLImpl), diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp index 074afa3..21162f4 100644 --- a/core/jni/android_app_NativeActivity.cpp +++ b/core/jni/android_app_NativeActivity.cpp @@ -436,7 +436,7 @@ struct NativeCode : public ANativeActivity { void setSurface(jobject _surface) { if (_surface != NULL) { - nativeWindow = android_Surface_getNativeWindow(env, _surface); + nativeWindow = android_view_Surface_getNativeWindow(env, _surface); } else { nativeWindow = NULL; } diff --git a/core/jni/android_opengl_EGL14.cpp b/core/jni/android_opengl_EGL14.cpp index c271aeb..b1664c6 100644 --- a/core/jni/android_opengl_EGL14.cpp +++ b/core/jni/android_opengl_EGL14.cpp @@ -549,7 +549,7 @@ not_valid_surface: goto exit; } - window = android::android_Surface_getNativeWindow(_env, win); + window = android::android_view_Surface_getNativeWindow(_env, win); if (window == NULL) goto not_valid_surface; diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp index c302b23..4d5e680 100644 --- a/core/jni/android_view_Surface.cpp +++ b/core/jni/android_view_Surface.cpp @@ -18,8 +18,10 @@ #include <stdio.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> @@ -28,6 +30,7 @@ #include <gui/SurfaceComposerClient.h> #include <gui/SurfaceTexture.h> +#include <ui/DisplayInfo.h> #include <ui/Rect.h> #include <ui/Region.h> @@ -42,127 +45,135 @@ #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 <ScopedUtfChars.h> + // ---------------------------------------------------------------------------- namespace android { -enum { - // should match Parcelable.java - PARCELABLE_WRITE_RETURN_VALUE = 0x0001 -}; - -// ---------------------------------------------------------------------------- - static const char* const OutOfResourcesException = "android/view/Surface$OutOfResourcesException"; -const char* const kSurfaceSessionClassPathName = "android/view/SurfaceSession"; -const char* const kSurfaceClassPathName = "android/view/Surface"; +static struct { + jclass clazz; + jfieldID mNativeSurface; + jfieldID mNativeSurfaceControl; + jfieldID mGenerationId; + jfieldID mCanvas; + jfieldID mCanvasSaveCount; +} gSurfaceClassInfo; + +static struct { + jfieldID left; + jfieldID top; + jfieldID right; + jfieldID bottom; +} gRectClassInfo; + +static struct { + jfieldID mNativeCanvas; + jfieldID mSurfaceFormat; +} gCanvasClassInfo; + +static struct { + jfieldID width; + jfieldID height; + jfieldID refreshRate; + jfieldID density; + jfieldID xDpi; + jfieldID yDpi; +} gPhysicalDisplayInfoClassInfo; -struct sso_t { - jfieldID client; -}; -static sso_t sso; - -struct so_t { - jfieldID surfaceControl; - jfieldID surfaceGenerationId; - jfieldID surface; - jfieldID saveCount; - jfieldID canvas; -}; -static so_t so; -struct ro_t { - jfieldID l; - jfieldID t; - jfieldID r; - jfieldID b; -}; -static ro_t ro; +class ScreenshotPixelRef : public SkPixelRef { +public: + ScreenshotPixelRef(SkColorTable* ctable) { + fCTable = ctable; + SkSafeRef(ctable); + setImmutable(); + } -struct po_t { - jfieldID x; - jfieldID y; -}; -static po_t po; + virtual ~ScreenshotPixelRef() { + SkSafeUnref(fCTable); + } -struct co_t { - jfieldID surfaceFormat; -}; -static co_t co; + 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; + } -struct no_t { - jfieldID native_canvas; - jfieldID native_region; - jfieldID native_parcel; -}; -static no_t no; + return NO_ERROR; + } + + uint32_t getWidth() const { + return mScreenshot.getWidth(); + } + uint32_t getHeight() const { + return mScreenshot.getHeight(); + } -// ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- + uint32_t getStride() const { + return mScreenshot.getStride(); + } -static void SurfaceSession_nativeInit(JNIEnv* env, jobject clazz) -{ - sp<SurfaceComposerClient> client = new SurfaceComposerClient; - client->incStrong(clazz); - env->SetIntField(clazz, sso.client, (int)client.get()); -} + uint32_t getFormat() const { + return mScreenshot.getFormat(); + } -static void SurfaceSession_nativeDestroy(JNIEnv* env, jobject clazz) -{ - SurfaceComposerClient* client = - (SurfaceComposerClient*)env->GetIntField(clazz, sso.client); - if (client != 0) { - client->decStrong(clazz); - env->SetIntField(clazz, sso.client, 0); +protected: + // overrides from SkPixelRef + virtual void* onLockPixels(SkColorTable** ct) { + *ct = fCTable; + return (void*)mScreenshot.getPixels(); } -} -static void SurfaceSession_nativeKill(JNIEnv* env, jobject clazz) -{ - SurfaceComposerClient* client = - (SurfaceComposerClient*)env->GetIntField(clazz, sso.client); - if (client != 0) { - client->dispose(); - client->decStrong(clazz); - env->SetIntField(clazz, sso.client, 0); + virtual void onUnlockPixels() { } -} + +private: + ScreenshotClient mScreenshot; + SkColorTable* fCTable; + + typedef SkPixelRef INHERITED; +}; + // ---------------------------------------------------------------------------- -static sp<SurfaceControl> getSurfaceControl(JNIEnv* env, jobject clazz) -{ - SurfaceControl* const p = - (SurfaceControl*)env->GetIntField(clazz, so.surfaceControl); - return sp<SurfaceControl>(p); +static sp<SurfaceControl> getSurfaceControl(JNIEnv* env, jobject surfaceObj) { + return reinterpret_cast<SurfaceControl*>( + env->GetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurfaceControl)); } -static void setSurfaceControl(JNIEnv* env, jobject clazz, - const sp<SurfaceControl>& surface) -{ - SurfaceControl* const p = - (SurfaceControl*)env->GetIntField(clazz, so.surfaceControl); +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(clazz); + surface->incStrong(surfaceObj); } if (p) { - p->decStrong(clazz); + p->decStrong(surfaceObj); } - env->SetIntField(clazz, so.surfaceControl, (int)surface.get()); + env->SetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurfaceControl, + reinterpret_cast<jint>(surface.get())); } -static sp<Surface> getSurface(JNIEnv* env, jobject clazz) -{ - sp<Surface> result(Surface_getSurface(env, clazz)); - if (result == 0) { +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 @@ -171,89 +182,81 @@ static sp<Surface> getSurface(JNIEnv* env, jobject clazz) * process. */ - SurfaceControl* const control = - (SurfaceControl*)env->GetIntField(clazz, so.surfaceControl); + SurfaceControl* const control = reinterpret_cast<SurfaceControl*>( + env->GetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurfaceControl)); if (control) { result = control->getSurface(); - if (result != 0) { - result->incStrong(clazz); - env->SetIntField(clazz, so.surface, (int)result.get()); + if (result != NULL) { + result->incStrong(surfaceObj); + env->SetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurface, + reinterpret_cast<jint>(result.get())); } } } return result; } -sp<ANativeWindow> android_Surface_getNativeWindow( - JNIEnv* env, jobject clazz) { - return getSurface(env, clazz); +sp<ANativeWindow> android_view_Surface_getNativeWindow(JNIEnv* env, jobject surfaceObj) { + return getSurface(env, surfaceObj); } -bool android_Surface_isInstanceOf(JNIEnv* env, jobject obj) { - jclass surfaceClass = env->FindClass(kSurfaceClassPathName); - return env->IsInstanceOf(obj, surfaceClass); +bool android_view_Surface_isInstanceOf(JNIEnv* env, jobject obj) { + return env->IsInstanceOf(obj, gSurfaceClassInfo.clazz); } -sp<Surface> Surface_getSurface(JNIEnv* env, jobject clazz) { - sp<Surface> surface((Surface*)env->GetIntField(clazz, so.surface)); - return surface; +sp<Surface> android_view_Surface_getSurface(JNIEnv* env, jobject surfaceObj) { + return reinterpret_cast<Surface*>( + env->GetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurface)); } -void setSurface(JNIEnv* env, jobject clazz, const sp<Surface>& surface) -{ - Surface* const p = (Surface*)env->GetIntField(clazz, so.surface); +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(clazz); + surface->incStrong(surfaceObj); } if (p) { - p->decStrong(clazz); + p->decStrong(surfaceObj); } - env->SetIntField(clazz, so.surface, (int)surface.get()); + 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(clazz, so.surfaceGenerationId); + jint generationId = env->GetIntField(surfaceObj, + gSurfaceClassInfo.mGenerationId); generationId++; - env->SetIntField(clazz, so.surfaceGenerationId, generationId); + env->SetIntField(surfaceObj, + gSurfaceClassInfo.mGenerationId, generationId); } } // ---------------------------------------------------------------------------- -static void Surface_init( - JNIEnv* env, jobject clazz, - jobject session, - jstring jname, jint w, jint h, jint format, jint flags) -{ - if (session == NULL) { - doThrowNPE(env); - return; - } - - SurfaceComposerClient* client = - (SurfaceComposerClient*)env->GetIntField(session, sso.client); +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)); - const jchar* str = env->GetStringCritical(jname, 0); - const String8 name(str, env->GetStringLength(jname)); - env->ReleaseStringCritical(jname, str); - sp<SurfaceControl> surface = client->createSurface(name, w, h, format, flags); - - if (surface == 0) { + sp<SurfaceControl> surface = client->createSurface( + String8(name.c_str()), w, h, format, flags); + if (surface == NULL) { jniThrowException(env, OutOfResourcesException, NULL); return; } - setSurfaceControl(env, clazz, surface); -} -static void Surface_initFromSurfaceTexture( - JNIEnv* env, jobject clazz, jobject jst) -{ - sp<SurfaceTexture> st(SurfaceTexture_getSurfaceTexture(env, jst)); + setSurfaceControl(env, surfaceObj, surface); +} +static void nativeCreateFromSurfaceTexture(JNIEnv* env, jobject surfaceObj, + jobject surfaceTextureObj) { + sp<SurfaceTexture> st(SurfaceTexture_getSurfaceTexture(env, surfaceTextureObj)); if (st == NULL) { jniThrowException(env, "java/lang/IllegalArgumentException", "SurfaceTexture has already been released"); return; } + sp<ISurfaceTexture> bq = st->getBufferQueue(); sp<Surface> surface(new Surface(bq)); @@ -261,72 +264,62 @@ static void Surface_initFromSurfaceTexture( jniThrowException(env, OutOfResourcesException, NULL); return; } - setSurfaceControl(env, clazz, NULL); - setSurface(env, clazz, surface); -} -static void Surface_initParcel(JNIEnv* env, jobject clazz, jobject argParcel) -{ - Parcel* parcel = (Parcel*)env->GetIntField(argParcel, no.native_parcel); - if (parcel == NULL) { - doThrowNPE(env); - return; - } - - sp<Surface> sur(Surface::readFromParcel(*parcel)); - setSurface(env, clazz, sur); + setSurface(env, surfaceObj, surface); } -static jint Surface_getIdentity(JNIEnv* env, jobject clazz) -{ - const sp<SurfaceControl>& control(getSurfaceControl(env, clazz)); - if (control != 0) return (jint) control->getIdentity(); - const sp<Surface>& surface(getSurface(env, clazz)); - if (surface != 0) return (jint) surface->getIdentity(); - return -1; +static void nativeRelease(JNIEnv* env, jobject surfaceObj) { + setSurfaceControl(env, surfaceObj, NULL); + setSurface(env, surfaceObj, NULL); } -static void Surface_destroy(JNIEnv* env, jobject clazz, uintptr_t *ostack) -{ - const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); - if (SurfaceControl::isValid(surface)) { - surface->clear(); +static void nativeDestroy(JNIEnv* env, jobject surfaceObj) { + sp<SurfaceControl> surfaceControl(getSurfaceControl(env, surfaceObj)); + if (SurfaceControl::isValid(surfaceControl)) { + surfaceControl->clear(); } - setSurfaceControl(env, clazz, 0); - setSurface(env, clazz, 0); + setSurfaceControl(env, surfaceObj, NULL); + setSurface(env, surfaceObj, NULL); } -static void Surface_release(JNIEnv* env, jobject clazz, uintptr_t *ostack) -{ - setSurfaceControl(env, clazz, 0); - setSurface(env, clazz, 0); -} - -static jboolean Surface_isValid(JNIEnv* env, jobject clazz) -{ - const sp<SurfaceControl>& surfaceControl(getSurfaceControl(env, clazz)); - if (surfaceControl != 0) { +static jboolean nativeIsValid(JNIEnv* env, jobject surfaceObj) { + sp<SurfaceControl> surfaceControl(getSurfaceControl(env, surfaceObj)); + if (surfaceControl != NULL) { return SurfaceControl::isValid(surfaceControl) ? JNI_TRUE : JNI_FALSE; } - const sp<Surface>& surface(getSurface(env, clazz)); + + sp<Surface> surface(getSurface(env, surfaceObj)); return Surface::isValid(surface) ? JNI_TRUE : JNI_FALSE; } -static jboolean Surface_isConsumerRunningBehind(JNIEnv* env, jobject clazz) -{ - int value = 0; - const sp<Surface>& surface(getSurface(env, clazz)); +static jint nativeGetIdentity(JNIEnv* env, jobject surfaceObj) { + sp<SurfaceControl> control(getSurfaceControl(env, surfaceObj)); + if (control != NULL) { + return jint(control->getIdentity()); + } + + sp<Surface> surface(getSurface(env, surfaceObj)); + if (surface != NULL) { + return jint(surface->getIdentity()); + } + + return -1; +} + +static jboolean nativeIsConsumerRunningBehind(JNIEnv* env, jobject surfaceObj) { + sp<Surface> surface(getSurface(env, surfaceObj)); if (!Surface::isValid(surface)) { doThrowIAE(env); - return 0; + return JNI_FALSE; } - ANativeWindow* anw = static_cast<ANativeWindow *>(surface.get()); + + int value = 0; + ANativeWindow* anw = static_cast<ANativeWindow*>(surface.get()); anw->query(anw, NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &value); - return (jboolean)value; + return value; } -static inline SkBitmap::Config convertPixelFormat(PixelFormat format) -{ +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) @@ -341,44 +334,44 @@ static inline SkBitmap::Config convertPixelFormat(PixelFormat format) } } -static jobject Surface_lockCanvas(JNIEnv* env, jobject clazz, jobject dirtyRect) -{ - const sp<Surface>& surface(getSurface(env, clazz)); +static jobject nativeLockCanvas(JNIEnv* env, jobject surfaceObj, jobject dirtyRectObj) { + sp<Surface> surface(getSurface(env, surfaceObj)); if (!Surface::isValid(surface)) { doThrowIAE(env); - return 0; + return NULL; } // get dirty region Region dirtyRegion; - if (dirtyRect) { + if (dirtyRectObj) { Rect dirty; - dirty.left = env->GetIntField(dirtyRect, ro.l); - dirty.top = env->GetIntField(dirtyRect, ro.t); - dirty.right = env->GetIntField(dirtyRect, ro.r); - dirty.bottom= env->GetIntField(dirtyRect, ro.b); + dirty.left = env->GetIntField(dirtyRectObj, gRectClassInfo.left); + dirty.top = env->GetIntField(dirtyRectObj, gRectClassInfo.top); + dirty.right = env->GetIntField(dirtyRectObj, gRectClassInfo.right); + dirty.bottom = env->GetIntField(dirtyRectObj, gRectClassInfo.bottom); if (!dirty.isEmpty()) { dirtyRegion.set(dirty); } } else { - dirtyRegion.set(Rect(0x3FFF,0x3FFF)); + dirtyRegion.set(Rect(0x3FFF, 0x3FFF)); } Surface::SurfaceInfo info; status_t err = surface->lock(&info, &dirtyRegion); if (err < 0) { const char* const exception = (err == NO_MEMORY) ? - OutOfResourcesException : - "java/lang/IllegalArgumentException"; + OutOfResourcesException : + "java/lang/IllegalArgumentException"; jniThrowException(env, exception, NULL); - return 0; + return NULL; } // Associate a SkCanvas object to this surface - jobject canvas = env->GetObjectField(clazz, so.canvas); - env->SetIntField(canvas, co.surfaceFormat, info.format); + jobject canvasObj = env->GetObjectField(surfaceObj, gSurfaceClassInfo.mCanvas); + env->SetIntField(canvasObj, gCanvasClassInfo.mSurfaceFormat, info.format); - SkCanvas* nativeCanvas = (SkCanvas*)env->GetIntField(canvas, no.native_canvas); + SkCanvas* nativeCanvas = reinterpret_cast<SkCanvas*>( + env->GetIntField(canvasObj, gCanvasClassInfo.mNativeCanvas)); SkBitmap bitmap; ssize_t bpr = info.s * bytesPerPixel(info.format); bitmap.setConfig(convertPixelFormat(info.format), info.w, info.h, bpr); @@ -409,38 +402,38 @@ static jobject Surface_lockCanvas(JNIEnv* env, jobject clazz, jobject dirtyRect) nativeCanvas->clipRegion(clipReg); int saveCount = nativeCanvas->save(); - env->SetIntField(clazz, so.saveCount, saveCount); + env->SetIntField(surfaceObj, gSurfaceClassInfo.mCanvasSaveCount, saveCount); - if (dirtyRect) { + if (dirtyRectObj) { const Rect& bounds(dirtyRegion.getBounds()); - env->SetIntField(dirtyRect, ro.l, bounds.left); - env->SetIntField(dirtyRect, ro.t, bounds.top); - env->SetIntField(dirtyRect, ro.r, bounds.right); - env->SetIntField(dirtyRect, ro.b, bounds.bottom); + env->SetIntField(dirtyRectObj, gRectClassInfo.left, bounds.left); + env->SetIntField(dirtyRectObj, gRectClassInfo.top, bounds.top); + env->SetIntField(dirtyRectObj, gRectClassInfo.right, bounds.right); + env->SetIntField(dirtyRectObj, gRectClassInfo.bottom, bounds.bottom); } - return canvas; + return canvasObj; } -static void Surface_unlockCanvasAndPost( - JNIEnv* env, jobject clazz, jobject argCanvas) -{ - jobject canvas = env->GetObjectField(clazz, so.canvas); - if (env->IsSameObject(canvas, argCanvas) == JNI_FALSE) { +static void nativeUnlockCanvasAndPost(JNIEnv* env, jobject surfaceObj, jobject canvasObj) { + jobject ownCanvasObj = env->GetObjectField(surfaceObj, gSurfaceClassInfo.mCanvas); + if (!env->IsSameObject(ownCanvasObj, canvasObj)) { doThrowIAE(env); return; } - const sp<Surface>& surface(getSurface(env, clazz)); - if (!Surface::isValid(surface)) + sp<Surface> surface(getSurface(env, surfaceObj)); + if (!Surface::isValid(surface)) { return; + } // detach the canvas from the surface - SkCanvas* nativeCanvas = (SkCanvas*)env->GetIntField(canvas, no.native_canvas); - int saveCount = env->GetIntField(clazz, so.saveCount); + SkCanvas* nativeCanvas = reinterpret_cast<SkCanvas*>( + env->GetIntField(canvasObj, gCanvasClassInfo.mNativeCanvas)); + int saveCount = env->GetIntField(surfaceObj, gSurfaceClassInfo.mCanvasSaveCount); nativeCanvas->restoreToCount(saveCount); nativeCanvas->setBitmapDevice(SkBitmap()); - env->SetIntField(clazz, so.saveCount, 0); + env->SetIntField(surfaceObj, gSurfaceClassInfo.mCanvasSaveCount, 0); // unlock surface status_t err = surface->unlockAndPost(); @@ -449,102 +442,18 @@ static void Surface_unlockCanvasAndPost( } } -static void Surface_unlockCanvas( - JNIEnv* env, jobject clazz, jobject argCanvas) -{ - // XXX: this API has been removed - doThrowIAE(env); -} - -static void Surface_openTransaction( - JNIEnv* env, jobject clazz) -{ - SurfaceComposerClient::openGlobalTransaction(); -} - -static void Surface_closeTransaction( - JNIEnv* env, jobject clazz) -{ - SurfaceComposerClient::closeGlobalTransaction(); -} - -static void Surface_setOrientation( - JNIEnv* env, jobject clazz, jint, jint orientation) -{ - sp<IBinder> display = SurfaceComposerClient::getBuiltInDisplay( - ISurfaceComposer::eDisplayIdMain); - SurfaceComposerClient::setDisplayOrientation(display, orientation); -} - -class ScreenshotPixelRef : public SkPixelRef { -public: - ScreenshotPixelRef(SkColorTable* ctable) { - fCTable = ctable; - SkSafeRef(ctable); - setImmutable(); - } - virtual ~ScreenshotPixelRef() { - SkSafeUnref(fCTable); +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; } - 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 jobject doScreenshot(JNIEnv* env, jobject clazz, - jint width, jint height, - jint minLayer, jint maxLayer, bool allLayers) -{ - sp<IBinder> display = SurfaceComposerClient::getBuiltInDisplay( - ISurfaceComposer::eDisplayIdMain); ScreenshotPixelRef* pixels = new ScreenshotPixelRef(NULL); - if (pixels->update(display, width, height, + if (pixels->update(displayToken, width, height, minLayer, maxLayer, allLayers) != NO_ERROR) { delete pixels; - return 0; + return NULL; } uint32_t w = pixels->getWidth(); @@ -571,94 +480,68 @@ static jobject doScreenshot(JNIEnv* env, jobject clazz, return GraphicsJNI::createBitmap(env, bitmap, false, NULL); } -static jobject Surface_screenshotAll(JNIEnv* env, jobject clazz, jint width, jint height) -{ - return doScreenshot(env, clazz, width, height, 0, 0, true); +static void nativeOpenTransaction(JNIEnv* env, jclass clazz) { + SurfaceComposerClient::openGlobalTransaction(); } -static jobject Surface_screenshot(JNIEnv* env, jobject clazz, jint width, jint height, - jint minLayer, jint maxLayer) -{ - return doScreenshot(env, clazz, width, height, minLayer, maxLayer, false); +static void nativeCloseTransaction(JNIEnv* env, jclass clazz) { + SurfaceComposerClient::closeGlobalTransaction(); } -static void Surface_setLayer( - JNIEnv* env, jobject clazz, jint zorder) -{ - const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); - if (surface == 0) return; +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) { + if (err < 0 && err != NO_INIT) { doThrowIAE(env); } } -static void Surface_setPosition( - JNIEnv* env, jobject clazz, jfloat x, jfloat y) -{ - const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); - if (surface == 0) return; +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) { + if (err < 0 && err != NO_INIT) { doThrowIAE(env); } } -static void Surface_setSize( - JNIEnv* env, jobject clazz, jint w, jint h) -{ - const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); - if (surface == 0) return; +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) { + if (err < 0 && err != NO_INIT) { doThrowIAE(env); } } -static void Surface_hide( - JNIEnv* env, jobject clazz) -{ - const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); - if (surface == 0) return; - status_t err = surface->hide(); - 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; -static void Surface_show( - JNIEnv* env, jobject clazz) -{ - const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); - if (surface == 0) return; - status_t err = surface->show(); - if (err<0 && err!=NO_INIT) { + status_t err = surface->setFlags(flags, mask); + if (err < 0 && err != NO_INIT) { doThrowIAE(env); } } -static void Surface_setFlags( - JNIEnv* env, jobject clazz, jint flags, jint mask) -{ - const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); - if (surface == 0) return; - status_t err = surface->setFlags(flags, mask); - if (err<0 && err!=NO_INIT) { +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; } -} -static void Surface_setTransparentRegion( - JNIEnv* env, jobject clazz, jobject argRegion) -{ - const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); - if (surface == 0) return; - SkRegion* nativeRegion = (SkRegion*)env->GetIntField(argRegion, no.native_region); - - const SkIRect& b(nativeRegion->getBounds()); + const SkIRect& b(region->getBounds()); Region reg(Rect(b.fLeft, b.fTop, b.fRight, b.fBottom)); - if (nativeRegion->isComplex()) { - SkRegion::Iterator it(*nativeRegion); + 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); @@ -667,132 +550,197 @@ static void Surface_setTransparentRegion( } status_t err = surface->setTransparentRegionHint(reg); - if (err<0 && err!=NO_INIT) { + if (err < 0 && err != NO_INIT) { doThrowIAE(env); } } -static void Surface_setAlpha( - JNIEnv* env, jobject clazz, jfloat alpha) -{ - const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); - if (surface == 0) return; +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) { + if (err < 0 && err != NO_INIT) { doThrowIAE(env); } } -static void Surface_setMatrix( - JNIEnv* env, jobject clazz, - jfloat dsdx, jfloat dtdx, jfloat dsdy, jfloat dtdy) -{ - const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz)); - if (surface == 0) return; +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) { + if (err < 0 && err != NO_INIT) { doThrowIAE(env); } } -static void Surface_setWindowCrop(JNIEnv* env, jobject thiz, jobject crop) -{ - const sp<SurfaceControl>& surface(getSurfaceControl(env, thiz)); - if (surface == 0) return; - - Rect nativeCrop; - if (crop) { - nativeCrop.left = env->GetIntField(crop, ro.l); - nativeCrop.top = env->GetIntField(crop, ro.t); - nativeCrop.right = env->GetIntField(crop, ro.r); - nativeCrop.bottom= env->GetIntField(crop, ro.b); +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 { - nativeCrop.left = nativeCrop.top = nativeCrop.right = - nativeCrop.bottom = 0; + crop.left = crop.top = crop.right = crop.bottom = 0; } - status_t err = surface->setCrop(nativeCrop); - if (err<0 && err!=NO_INIT) { + status_t err = surface->setCrop(crop); + if (err < 0 && err != NO_INIT) { doThrowIAE(env); } } -static void Surface_setLayerStack(JNIEnv* env, jobject thiz, jint layerStack) -{ - const sp<SurfaceControl>& surface(getSurfaceControl(env, thiz)); - if (surface == 0) return; +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) { + 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 void Surface_copyFrom( - JNIEnv* env, jobject clazz, jobject other) -{ - if (clazz == other) +static jobject nativeCreateDisplay(JNIEnv* env, jclass clazz, jstring nameObj) { + ScopedUtfChars name(env, nameObj); + // TODO: pass the name to SF. + sp<IBinder> token(SurfaceComposerClient::createDisplay()); + return javaObjectForIBinder(env, token); +} + +static void nativeSetDisplaySurface(JNIEnv* env, jclass clazz, + jobject tokenObj, jobject surfaceTextureObj) { + sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); + if (token == NULL) return; + + if (!surfaceTextureObj) { + SurfaceComposerClient::setDisplaySurface(token, NULL); return; + } - if (other == NULL) { - doThrowNPE(env); + sp<SurfaceTexture> st(SurfaceTexture_getSurfaceTexture(env, surfaceTextureObj)); + if (st == NULL) { + jniThrowException(env, "java/lang/IllegalArgumentException", + "SurfaceTexture has already been released"); return; } + sp<ISurfaceTexture> bq = st->getBufferQueue(); + SurfaceComposerClient::setDisplaySurface(token, bq); +} + +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 nativeSetDisplayOrientation(JNIEnv* env, jclass clazz, + jobject tokenObj, jint orientation) { + sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); + if (token == NULL) return; + + SurfaceComposerClient::setDisplayOrientation(token, orientation); +} + +static void nativeSetDisplayViewport(JNIEnv* env, jclass clazz, + jobject tokenObj, jobject rectObj) { + sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); + if (token == NULL) return; + + Rect rect; + rect.left = env->GetIntField(rectObj, gRectClassInfo.left); + rect.top = env->GetIntField(rectObj, gRectClassInfo.top); + rect.right = env->GetIntField(rectObj, gRectClassInfo.right); + rect.bottom = env->GetIntField(rectObj, gRectClassInfo.bottom); + SurfaceComposerClient::setDisplayViewport(token, rect); +} + +static void nativeSetDisplayFrame(JNIEnv* env, jclass clazz, + jobject tokenObj, jobject rectObj) { + sp<IBinder> token(ibinderForJavaObject(env, tokenObj)); + if (token == NULL) return; + + Rect rect; + rect.left = env->GetIntField(rectObj, gRectClassInfo.left); + rect.top = env->GetIntField(rectObj, gRectClassInfo.top); + rect.right = env->GetIntField(rectObj, gRectClassInfo.right); + rect.bottom = env->GetIntField(rectObj, gRectClassInfo.bottom); + SurfaceComposerClient::setDisplayFrame(token, rect); +} + +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); + return JNI_TRUE; +} + +// ---------------------------------------------------------------------------- + +static void nativeCopyFrom(JNIEnv* env, jobject surfaceObj, jobject otherObj) { /* * 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. */ - const sp<SurfaceControl>& surface = getSurfaceControl(env, clazz); - const sp<SurfaceControl>& rhs = getSurfaceControl(env, other); - if (!SurfaceControl::isSameSurface(surface, rhs)) { + 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, clazz, rhs); + setSurfaceControl(env, surfaceObj, other); } } -static void Surface_transferFrom( - JNIEnv* env, jobject clazz, jobject other) -{ - if (clazz == other) - return; - - if (other == NULL) { - doThrowNPE(env); - return; - } - - sp<SurfaceControl> control(getSurfaceControl(env, other)); - sp<Surface> surface(Surface_getSurface(env, other)); - setSurfaceControl(env, clazz, control); - setSurface(env, clazz, surface); - setSurfaceControl(env, other, 0); - setSurface(env, other, 0); +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); } -static void Surface_readFromParcel( - JNIEnv* env, jobject clazz, jobject argParcel) -{ - Parcel* parcel = (Parcel*)env->GetIntField( argParcel, no.native_parcel); +static void nativeReadFromParcel(JNIEnv* env, jobject surfaceObj, jobject parcelObj) { + Parcel* parcel = parcelForJavaObject(env, parcelObj); if (parcel == NULL) { doThrowNPE(env); return; } - sp<Surface> sur(Surface::readFromParcel(*parcel)); - setSurface(env, clazz, sur); + sp<Surface> surface(Surface::readFromParcel(*parcel)); + setSurfaceControl(env, surfaceObj, NULL); + setSurface(env, surfaceObj, surface); } -static void Surface_writeToParcel( - JNIEnv* env, jobject clazz, jobject argParcel, jint flags) -{ - Parcel* parcel = (Parcel*)env->GetIntField( - argParcel, no.native_parcel); - +static void nativeWriteToParcel(JNIEnv* env, jobject surfaceObj, jobject parcelObj) { + Parcel* parcel = parcelForJavaObject(env, parcelObj); if (parcel == NULL) { doThrowNPE(env); return; @@ -804,110 +752,125 @@ static void Surface_writeToParcel( // 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. - const sp<SurfaceControl>& control(getSurfaceControl(env, clazz)); + sp<SurfaceControl> control(getSurfaceControl(env, surfaceObj)); if (control != NULL) { SurfaceControl::writeSurfaceToParcel(control, parcel); } else { - sp<Surface> surface(Surface_getSurface(env, clazz)); + sp<Surface> surface(android_view_Surface_getSurface(env, surfaceObj)); if (surface != NULL) { Surface::writeToParcel(surface, parcel); } else { SurfaceControl::writeSurfaceToParcel(NULL, parcel); } } - if (flags & PARCELABLE_WRITE_RETURN_VALUE) { - setSurfaceControl(env, clazz, NULL); - setSurface(env, clazz, NULL); - } } // ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- -// ---------------------------------------------------------------------------- - -static void nativeClassInit(JNIEnv* env, jclass clazz); - -static JNINativeMethod gSurfaceSessionMethods[] = { - {"nativeInit", "()V", (void*)SurfaceSession_nativeInit }, - {"nativeDestroy", "()V", (void*)SurfaceSession_nativeDestroy }, - {"nativeKill", "()V", (void*)SurfaceSession_nativeKill }, -}; static JNINativeMethod gSurfaceMethods[] = { - {"nativeClassInit", "()V", (void*)nativeClassInit }, - {"init", "(Landroid/view/SurfaceSession;Ljava/lang/String;IIII)V", (void*)Surface_init }, - {"init", "(Landroid/os/Parcel;)V", (void*)Surface_initParcel }, - {"initFromSurfaceTexture", "(Landroid/graphics/SurfaceTexture;)V", (void*)Surface_initFromSurfaceTexture }, - {"getIdentity", "()I", (void*)Surface_getIdentity }, - {"destroy", "()V", (void*)Surface_destroy }, - {"release", "()V", (void*)Surface_release }, - {"copyFrom", "(Landroid/view/Surface;)V", (void*)Surface_copyFrom }, - {"transferFrom", "(Landroid/view/Surface;)V", (void*)Surface_transferFrom }, - {"isValid", "()Z", (void*)Surface_isValid }, - {"lockCanvasNative", "(Landroid/graphics/Rect;)Landroid/graphics/Canvas;", (void*)Surface_lockCanvas }, - {"unlockCanvasAndPost", "(Landroid/graphics/Canvas;)V", (void*)Surface_unlockCanvasAndPost }, - {"unlockCanvas", "(Landroid/graphics/Canvas;)V", (void*)Surface_unlockCanvas }, - {"openTransaction", "()V", (void*)Surface_openTransaction }, - {"closeTransaction", "()V", (void*)Surface_closeTransaction }, - {"setOrientation", "(II)V", (void*)Surface_setOrientation }, - {"screenshot", "(II)Landroid/graphics/Bitmap;", (void*)Surface_screenshotAll }, - {"screenshot", "(IIII)Landroid/graphics/Bitmap;", (void*)Surface_screenshot }, - {"setLayer", "(I)V", (void*)Surface_setLayer }, - {"setPosition", "(FF)V",(void*)Surface_setPosition }, - {"setSize", "(II)V",(void*)Surface_setSize }, - {"hide", "()V", (void*)Surface_hide }, - {"show", "()V", (void*)Surface_show }, - {"setFlags", "(II)V",(void*)Surface_setFlags }, - {"setTransparentRegionHint","(Landroid/graphics/Region;)V", (void*)Surface_setTransparentRegion }, - {"setAlpha", "(F)V", (void*)Surface_setAlpha }, - {"setMatrix", "(FFFF)V", (void*)Surface_setMatrix }, - {"readFromParcel", "(Landroid/os/Parcel;)V", (void*)Surface_readFromParcel }, - {"writeToParcel", "(Landroid/os/Parcel;I)V", (void*)Surface_writeToParcel }, - {"isConsumerRunningBehind", "()Z", (void*)Surface_isConsumerRunningBehind }, - {"setWindowCrop", "(Landroid/graphics/Rect;)V", (void*)Surface_setWindowCrop }, - {"setLayerStack", "(I)V", (void*)Surface_setLayerStack }, + {"nativeCreate", "(Landroid/view/SurfaceSession;Ljava/lang/String;IIII)V", + (void*)nativeCreate }, + {"nativeCreateFromSurfaceTexture", "(Landroid/graphics/SurfaceTexture;)V", + (void*)nativeCreateFromSurfaceTexture }, + {"nativeRelease", "()V", + (void*)nativeRelease }, + {"nativeDestroy", "()V", + (void*)nativeDestroy }, + {"nativeIsValid", "()Z", + (void*)nativeIsValid }, + {"nativeGetIdentity", "()I", + (void*)nativeGetIdentity }, + {"nativeIsConsumerRunningBehind", "()Z", + (void*)nativeIsConsumerRunningBehind }, + {"nativeLockCanvas", "(Landroid/graphics/Rect;)Landroid/graphics/Canvas;", + (void*)nativeLockCanvas }, + {"nativeUnlockCanvasAndPost", "(Landroid/graphics/Canvas;)V", + (void*)nativeUnlockCanvasAndPost }, + {"nativeScreenshot", "(Landroid/os/IBinder;IIIIZ)Landroid/graphics/Bitmap;", + (void*)nativeScreenshot }, + {"nativeOpenTransaction", "()V", + (void*)nativeOpenTransaction }, + {"nativeCloseTransaction", "()V", + (void*)nativeCloseTransaction }, + {"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;)Landroid/os/IBinder;", + (void*)nativeCreateDisplay }, + {"nativeSetDisplaySurface", "(Landroid/os/IBinder;Landroid/graphics/SurfaceTexture;)V", + (void*)nativeSetDisplaySurface }, + {"nativeSetDisplayLayerStack", "(Landroid/os/IBinder;I)V", + (void*)nativeSetDisplayLayerStack }, + {"nativeSetDisplayOrientation", "(Landroid/os/IBinder;I)V", + (void*)nativeSetDisplayOrientation }, + {"nativeSetDisplayViewport", "(Landroid/os/IBinder;Landroid/graphics/Rect;)V", + (void*)nativeSetDisplayViewport }, + {"nativeSetDisplayFrame", "(Landroid/os/IBinder;Landroid/graphics/Rect;)V", + (void*)nativeSetDisplayFrame }, + {"nativeGetDisplayInfo", "(Landroid/os/IBinder;Landroid/view/Surface$PhysicalDisplayInfo;)Z", + (void*)nativeGetDisplayInfo }, + {"nativeCopyFrom", "(Landroid/view/Surface;)V", + (void*)nativeCopyFrom }, + {"nativeTransferFrom", "(Landroid/view/Surface;)V", + (void*)nativeTransferFrom }, + {"nativeReadFromParcel", "(Landroid/os/Parcel;)V", + (void*)nativeReadFromParcel }, + {"nativeWriteToParcel", "(Landroid/os/Parcel;)V", + (void*)nativeWriteToParcel }, }; -void nativeClassInit(JNIEnv* env, jclass clazz) -{ - so.surface = env->GetFieldID(clazz, ANDROID_VIEW_SURFACE_JNI_ID, "I"); - so.surfaceGenerationId = env->GetFieldID(clazz, "mSurfaceGenerationId", "I"); - so.surfaceControl = env->GetFieldID(clazz, "mSurfaceControl", "I"); - so.saveCount = env->GetFieldID(clazz, "mSaveCount", "I"); - so.canvas = env->GetFieldID(clazz, "mCanvas", "Landroid/graphics/Canvas;"); - - jclass surfaceSession = env->FindClass("android/view/SurfaceSession"); - sso.client = env->GetFieldID(surfaceSession, "mClient", "I"); - - jclass canvas = env->FindClass("android/graphics/Canvas"); - no.native_canvas = env->GetFieldID(canvas, "mNativeCanvas", "I"); - co.surfaceFormat = env->GetFieldID(canvas, "mSurfaceFormat", "I"); - - jclass region = env->FindClass("android/graphics/Region"); - no.native_region = env->GetFieldID(region, "mNativeRegion", "I"); - - jclass parcel = env->FindClass("android/os/Parcel"); - no.native_parcel = env->GetFieldID(parcel, "mNativePtr", "I"); - - jclass rect = env->FindClass("android/graphics/Rect"); - ro.l = env->GetFieldID(rect, "left", "I"); - ro.t = env->GetFieldID(rect, "top", "I"); - ro.r = env->GetFieldID(rect, "right", "I"); - ro.b = env->GetFieldID(rect, "bottom", "I"); - - jclass point = env->FindClass("android/graphics/Point"); - po.x = env->GetFieldID(point, "x", "I"); - po.y = env->GetFieldID(point, "y", "I"); -} - int register_android_view_Surface(JNIEnv* env) { - int err; - err = AndroidRuntime::registerNativeMethods(env, kSurfaceSessionClassPathName, - gSurfaceSessionMethods, NELEM(gSurfaceSessionMethods)); - - err |= AndroidRuntime::registerNativeMethods(env, kSurfaceClassPathName, + int err = AndroidRuntime::registerNativeMethods(env, "android/view/Surface", gSurfaceMethods, NELEM(gSurfaceMethods)); + + 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.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"); + + clazz = env->FindClass("android/graphics/Canvas"); + gCanvasClassInfo.mNativeCanvas = env->GetFieldID(clazz, "mNativeCanvas", "I"); + gCanvasClassInfo.mSurfaceFormat = env->GetFieldID(clazz, "mSurfaceFormat", "I"); + + clazz = env->FindClass("android/graphics/Rect"); + gRectClassInfo.left = env->GetFieldID(clazz, "left", "I"); + gRectClassInfo.top = env->GetFieldID(clazz, "top", "I"); + 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"); return err; } diff --git a/core/jni/android_view_SurfaceSession.cpp b/core/jni/android_view_SurfaceSession.cpp new file mode 100644 index 0000000..1494bc5 --- /dev/null +++ b/core/jni/android_view_SurfaceSession.cpp @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "SurfaceSession" + +#include "JNIHelp.h" + +#include <android_runtime/AndroidRuntime.h> +#include <android_runtime/android_view_SurfaceSession.h> +#include <utils/Log.h> +#include <utils/RefBase.h> + +#include <gui/SurfaceComposerClient.h> + +namespace android { + +static struct { + jfieldID mNativeClient; +} gSurfaceSessionClassInfo; + + +sp<SurfaceComposerClient> android_view_SurfaceSession_getClient( + JNIEnv* env, jobject surfaceSessionObj) { + return reinterpret_cast<SurfaceComposerClient*>( + env->GetIntField(surfaceSessionObj, gSurfaceSessionClassInfo.mNativeClient)); +} + + +static jint nativeCreate(JNIEnv* env, jclass clazz) { + SurfaceComposerClient* client = new SurfaceComposerClient(); + client->incStrong(clazz); + return reinterpret_cast<jint>(client); +} + +static void nativeDestroy(JNIEnv* env, jclass clazz, jint ptr) { + SurfaceComposerClient* client = reinterpret_cast<SurfaceComposerClient*>(ptr); + client->decStrong(clazz); +} + +static void nativeKill(JNIEnv* env, jclass clazz, jint ptr) { + SurfaceComposerClient* client = reinterpret_cast<SurfaceComposerClient*>(ptr); + client->dispose(); +} + + +static JNINativeMethod gMethods[] = { + /* name, signature, funcPtr */ + { "nativeCreate", "()I", + (void*)nativeCreate }, + { "nativeDestroy", "(I)V", + (void*)nativeDestroy }, + { "nativeKill", "(I)V", + (void*)nativeKill } +}; + +int register_android_view_SurfaceSession(JNIEnv* env) { + int res = jniRegisterNativeMethods(env, "android/view/SurfaceSession", + gMethods, NELEM(gMethods)); + LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods."); + + jclass clazz = env->FindClass("android/view/SurfaceSession"); + gSurfaceSessionClassInfo.mNativeClient = env->GetFieldID(clazz, "mNativeClient", "I"); + return 0; +} + +} // namespace android diff --git a/core/jni/com_google_android_gles_jni_EGLImpl.cpp b/core/jni/com_google_android_gles_jni_EGLImpl.cpp index 9c6c7de..f8904bd 100644 --- a/core/jni/com_google_android_gles_jni_EGLImpl.cpp +++ b/core/jni/com_google_android_gles_jni_EGLImpl.cpp @@ -326,7 +326,7 @@ not_valid_surface: return 0; } - window = android_Surface_getNativeWindow(_env, native_window); + window = android_view_Surface_getNativeWindow(_env, native_window); if (window == NULL) goto not_valid_surface; diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp index a073c1a..2109a01 100644 --- a/graphics/jni/android_renderscript_RenderScript.cpp +++ b/graphics/jni/android_renderscript_RenderScript.cpp @@ -230,7 +230,7 @@ nContextSetSurface(JNIEnv *_env, jobject _this, RsContext con, jint width, jint if (wnd == NULL) { } else { - window = android_Surface_getNativeWindow(_env, wnd).get(); + window = android_view_Surface_getNativeWindow(_env, wnd).get(); } rsContextSetSurface(con, width, height, window); @@ -494,7 +494,7 @@ nAllocationSetSurface(JNIEnv *_env, jobject _this, RsContext con, RsAllocation a sp<Surface> s; if (sur != 0) { - s = Surface_getSurface(_env, sur); + s = android_view_Surface_getSurface(_env, sur); } rsAllocationSetSurface(con, alloc, static_cast<ANativeWindow *>(s.get())); diff --git a/include/android_runtime/android_view_Surface.h b/include/android_runtime/android_view_Surface.h index fb0b057..e50186d 100644 --- a/include/android_runtime/android_view_Surface.h +++ b/include/android_runtime/android_view_Surface.h @@ -25,12 +25,15 @@ namespace android { class Surface; -extern sp<ANativeWindow> android_Surface_getNativeWindow( - JNIEnv* env, jobject clazz); -extern bool android_Surface_isInstanceOf(JNIEnv* env, jobject obj); +/* Gets the underlying ANativeWindow for a Surface. */ +extern sp<ANativeWindow> android_view_Surface_getNativeWindow( + JNIEnv* env, jobject surfaceObj); + +/* Returns true if the object is an instance of Surface. */ +extern bool android_view_Surface_isInstanceOf(JNIEnv* env, jobject obj); /* Gets the underlying Surface from a Surface Java object. */ -extern sp<Surface> Surface_getSurface(JNIEnv* env, jobject thiz); +extern sp<Surface> android_view_Surface_getSurface(JNIEnv* env, jobject surfaceObj); } // namespace android diff --git a/include/android_runtime/android_view_SurfaceSession.h b/include/android_runtime/android_view_SurfaceSession.h new file mode 100644 index 0000000..3748f6c --- /dev/null +++ b/include/android_runtime/android_view_SurfaceSession.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _ANDROID_VIEW_SURFACE_SESSION_H +#define _ANDROID_VIEW_SURFACE_SESSION_H + +#include "jni.h" + +namespace android { + +class SurfaceComposerClient; + +/* Gets the underlying SurfaceComposerClient for a SurfaceSession. */ +extern sp<SurfaceComposerClient> android_view_SurfaceSession_getClient( + JNIEnv* env, jobject surfaceSessionObj); + +} // namespace android + +#endif // _ANDROID_VIEW_SURFACE_SESSION_H diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp index 4941ae5..f91c9a0 100644 --- a/media/jni/android_media_MediaCodec.cpp +++ b/media/jni/android_media_MediaCodec.cpp @@ -370,7 +370,7 @@ static void android_media_MediaCodec_native_configure( sp<ISurfaceTexture> surfaceTexture; if (jsurface != NULL) { - sp<Surface> surface(Surface_getSurface(env, jsurface)); + sp<Surface> surface(android_view_Surface_getSurface(env, jsurface)); if (surface != NULL) { surfaceTexture = surface->getSurfaceTexture(); } else { diff --git a/media/jni/android_media_MediaPlayer.cpp b/media/jni/android_media_MediaPlayer.cpp index c2a6889..04ba348 100644 --- a/media/jni/android_media_MediaPlayer.cpp +++ b/media/jni/android_media_MediaPlayer.cpp @@ -271,7 +271,7 @@ setVideoSurface(JNIEnv *env, jobject thiz, jobject jsurface, jboolean mediaPlaye sp<ISurfaceTexture> new_st; if (jsurface) { - sp<Surface> surface(Surface_getSurface(env, jsurface)); + sp<Surface> surface(android_view_Surface_getSurface(env, jsurface)); if (surface != NULL) { new_st = surface->getSurfaceTexture(); new_st->incStrong(thiz); diff --git a/native/android/native_window.cpp b/native/android/native_window.cpp index 99c0fd3..ca0c902 100644 --- a/native/android/native_window.cpp +++ b/native/android/native_window.cpp @@ -25,7 +25,7 @@ using namespace android; ANativeWindow* ANativeWindow_fromSurface(JNIEnv* env, jobject surface) { - sp<ANativeWindow> win = android_Surface_getNativeWindow(env, surface); + sp<ANativeWindow> win = android_view_Surface_getNativeWindow(env, surface); if (win != NULL) { win->incStrong((void*)ANativeWindow_acquire); } diff --git a/services/input/SpriteController.cpp b/services/input/SpriteController.cpp index 5bbaa48..8bb9d7f 100644 --- a/services/input/SpriteController.cpp +++ b/services/input/SpriteController.cpp @@ -369,7 +369,8 @@ sp<SurfaceControl> SpriteController::obtainSurface(int32_t width, int32_t height ensureSurfaceComposerClient(); sp<SurfaceControl> surfaceControl = mSurfaceComposerClient->createSurface( - String8("Sprite"), width, height, PIXEL_FORMAT_RGBA_8888); + String8("Sprite"), width, height, PIXEL_FORMAT_RGBA_8888, + ISurfaceComposerClient::eHidden); if (surfaceControl == NULL || !surfaceControl->isValid() || !surfaceControl->getSurface()->isValid()) { ALOGE("Error creating sprite surface."); diff --git a/services/java/com/android/server/display/DisplayDevice.java b/services/java/com/android/server/display/DisplayDevice.java index 57002ff..4a6dd66 100644 --- a/services/java/com/android/server/display/DisplayDevice.java +++ b/services/java/com/android/server/display/DisplayDevice.java @@ -16,6 +16,8 @@ package com.android.server.display; +import android.os.IBinder; + /** * Represents a physical display device such as the built-in display * an external monitor, or a WiFi display. @@ -29,6 +31,14 @@ public abstract class DisplayDevice { public abstract DisplayAdapter getAdapter(); /** + * Gets the Surface Flinger display token for this display. + * + * @return The display token, or null if the display is not being managed + * by Surface Flinger. + */ + public abstract IBinder getDisplayToken(); + + /** * Gets information about the display device. * * @param outInfo The object to populate with the information. diff --git a/services/java/com/android/server/display/DisplayManagerService.java b/services/java/com/android/server/display/DisplayManagerService.java index 2ebad1d..1463780 100644 --- a/services/java/com/android/server/display/DisplayManagerService.java +++ b/services/java/com/android/server/display/DisplayManagerService.java @@ -22,6 +22,7 @@ import android.content.pm.PackageManager; import android.hardware.display.DisplayManager; import android.hardware.display.IDisplayManager; import android.os.Binder; +import android.os.IBinder; import android.os.SystemProperties; import android.view.Display; import android.view.DisplayInfo; @@ -51,6 +52,7 @@ public final class DisplayManagerService extends IDisplayManager.Stub { private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>(); private final DisplayInfo mDefaultDisplayInfo = new DisplayInfo(); + private DisplayDevice mDefaultDisplayDevice; public DisplayManagerService(Context context) { mContext = context; @@ -63,7 +65,7 @@ public final class DisplayManagerService extends IDisplayManager.Stub { if (mHeadless) { registerDisplayAdapter(new HeadlessDisplayAdapter(mContext)); } else { - registerDisplayAdapter(new SurfaceFlingerDisplayAdapter(mContext)); + registerDisplayAdapter(new LocalDisplayAdapter(mContext)); } } @@ -85,8 +87,31 @@ public final class DisplayManagerService extends IDisplayManager.Stub { } /** + * Set the new display orientation. + * @param displayId The logical display id. + * @param orientation One of the Surface.ROTATION_* constants. + */ + public void setDisplayOrientation(int displayId, int orientation) { + synchronized (mLock) { + if (displayId != Display.DEFAULT_DISPLAY) { + throw new UnsupportedOperationException(); + } + + IBinder displayToken = mDefaultDisplayDevice.getDisplayToken(); + if (displayToken != null) { + Surface.openTransaction(); + try { + Surface.setDisplayOrientation(displayToken, orientation); + } finally { + Surface.closeTransaction(); + } + } + } + } + + /** * Save away new DisplayInfo data. - * @param displayId The local DisplayInfo to store the new data in. + * @param displayId The logical display id. * @param info The new data to be stored. */ public void setDisplayInfo(int displayId, DisplayInfo info) { @@ -119,6 +144,7 @@ public final class DisplayManagerService extends IDisplayManager.Stub { adapter.register(new DisplayAdapter.Listener() { @Override public void onDisplayDeviceAdded(DisplayDevice device) { + mDefaultDisplayDevice = device; DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo(); device.getInfo(deviceInfo); copyDisplayInfoFromDeviceInfo(mDefaultDisplayInfo, deviceInfo); diff --git a/services/java/com/android/server/display/HeadlessDisplayAdapter.java b/services/java/com/android/server/display/HeadlessDisplayAdapter.java index 17c2360..f984c5d 100644 --- a/services/java/com/android/server/display/HeadlessDisplayAdapter.java +++ b/services/java/com/android/server/display/HeadlessDisplayAdapter.java @@ -17,6 +17,7 @@ package com.android.server.display; import android.content.Context; +import android.os.IBinder; import android.util.DisplayMetrics; /** @@ -48,6 +49,11 @@ public final class HeadlessDisplayAdapter extends DisplayAdapter { } @Override + public IBinder getDisplayToken() { + return null; + } + + @Override public void getInfo(DisplayDeviceInfo outInfo) { outInfo.name = mContext.getResources().getString( com.android.internal.R.string.display_manager_built_in_display); diff --git a/services/java/com/android/server/display/LocalDisplayAdapter.java b/services/java/com/android/server/display/LocalDisplayAdapter.java new file mode 100644 index 0000000..fa77878 --- /dev/null +++ b/services/java/com/android/server/display/LocalDisplayAdapter.java @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.server.display; + +import android.content.Context; +import android.os.IBinder; +import android.view.Surface; +import android.view.Surface.PhysicalDisplayInfo; + +/** + * A display adapter for the local displays managed by Surface Flinger. + */ +public final class LocalDisplayAdapter extends DisplayAdapter { + private final Context mContext; + private final LocalDisplayDevice mDefaultDisplayDevice; + + public LocalDisplayAdapter(Context context) { + mContext = context; + + IBinder token = Surface.getBuiltInDisplay(Surface.BUILT_IN_DISPLAY_ID_MAIN); + mDefaultDisplayDevice = new LocalDisplayDevice(token); + } + + @Override + public String getName() { + return "LocalDisplayAdapter"; + } + + @Override + public void register(Listener listener) { + listener.onDisplayDeviceAdded(mDefaultDisplayDevice); + } + + private final class LocalDisplayDevice extends DisplayDevice { + private final IBinder mDisplayToken; + + public LocalDisplayDevice(IBinder token) { + mDisplayToken = token; + } + + @Override + public DisplayAdapter getAdapter() { + return LocalDisplayAdapter.this; + } + + @Override + public IBinder getDisplayToken() { + return mDisplayToken; + } + + @Override + public void getInfo(DisplayDeviceInfo outInfo) { + PhysicalDisplayInfo phys = new PhysicalDisplayInfo(); + Surface.getDisplayInfo(mDisplayToken, phys); + + outInfo.name = mContext.getResources().getString( + com.android.internal.R.string.display_manager_built_in_display); + outInfo.width = phys.width; + outInfo.height = phys.height; + outInfo.refreshRate = phys.refreshRate; + outInfo.densityDpi = (int)(phys.density * 160 + 0.5f); + outInfo.xDpi = phys.xDpi; + outInfo.yDpi = phys.yDpi; + } + } +} diff --git a/services/java/com/android/server/display/SurfaceFlingerDisplayAdapter.java b/services/java/com/android/server/display/SurfaceFlingerDisplayAdapter.java deleted file mode 100644 index 9531acb..0000000 --- a/services/java/com/android/server/display/SurfaceFlingerDisplayAdapter.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.android.server.display; - -import android.content.Context; - -/** - * A display adapter for the displays managed by Surface Flinger. - */ -public final class SurfaceFlingerDisplayAdapter extends DisplayAdapter { - private final Context mContext; - private final SurfaceFlingerDisplayDevice mDefaultDisplayDevice; - - private static native void nativeGetDefaultDisplayDeviceInfo(DisplayDeviceInfo outInfo); - - public SurfaceFlingerDisplayAdapter(Context context) { - mContext = context; - mDefaultDisplayDevice = new SurfaceFlingerDisplayDevice(); - } - - @Override - public String getName() { - return "SurfaceFlingerDisplayAdapter"; - } - - @Override - public void register(Listener listener) { - listener.onDisplayDeviceAdded(mDefaultDisplayDevice); - } - - private final class SurfaceFlingerDisplayDevice extends DisplayDevice { - @Override - public DisplayAdapter getAdapter() { - return SurfaceFlingerDisplayAdapter.this; - } - - @Override - public void getInfo(DisplayDeviceInfo outInfo) { - outInfo.name = mContext.getResources().getString( - com.android.internal.R.string.display_manager_built_in_display); - nativeGetDefaultDisplayDeviceInfo(outInfo); - } - } -} diff --git a/services/java/com/android/server/power/ElectronBeam.java b/services/java/com/android/server/power/ElectronBeam.java index aad5a9a..0c68997 100644 --- a/services/java/com/android/server/power/ElectronBeam.java +++ b/services/java/com/android/server/power/ElectronBeam.java @@ -481,8 +481,8 @@ final class ElectronBeam { try { if (mSurface == null) { try { - mSurface = new Surface(mSurfaceSession, Process.myPid(), - "ElectronBeam", mDisplayLayerStack, mDisplayWidth, mDisplayHeight, + mSurface = new Surface(mSurfaceSession, + "ElectronBeam", mDisplayWidth, mDisplayHeight, PixelFormat.OPAQUE, Surface.OPAQUE | Surface.HIDDEN); } catch (Surface.OutOfResourcesException ex) { Slog.e(TAG, "Unable to create surface.", ex); @@ -490,6 +490,7 @@ final class ElectronBeam { } } + mSurface.setLayerStack(mDisplayLayerStack); mSurface.setSize(mDisplayWidth, mDisplayHeight); switch (mDisplayRotation) { diff --git a/services/java/com/android/server/wm/BlackFrame.java b/services/java/com/android/server/wm/BlackFrame.java index 64d2602..5b77b20 100644 --- a/services/java/com/android/server/wm/BlackFrame.java +++ b/services/java/com/android/server/wm/BlackFrame.java @@ -43,14 +43,15 @@ public class BlackFrame { int w = r-l; int h = b-t; if (WindowManagerService.DEBUG_SURFACE_TRACE) { - surface = new WindowStateAnimator.SurfaceTrace(session, 0, "BlackSurface(" - + l + ", " + t + ")", layerStack, - w, h, PixelFormat.OPAQUE, Surface.FX_SURFACE_DIM); + surface = new WindowStateAnimator.SurfaceTrace(session, "BlackSurface(" + + l + ", " + t + ")", + w, h, PixelFormat.OPAQUE, Surface.FX_SURFACE_DIM | Surface.HIDDEN); } else { - surface = new Surface(session, 0, "BlackSurface", layerStack, - w, h, PixelFormat.OPAQUE, Surface.FX_SURFACE_DIM); + surface = new Surface(session, "BlackSurface", + w, h, PixelFormat.OPAQUE, Surface.FX_SURFACE_DIM | Surface.HIDDEN); } surface.setAlpha(1); + surface.setLayerStack(layerStack); surface.setLayer(layer); surface.show(); if (WindowManagerService.SHOW_TRANSACTIONS || diff --git a/services/java/com/android/server/wm/DimAnimator.java b/services/java/com/android/server/wm/DimAnimator.java index 81daac6..afcf339 100644 --- a/services/java/com/android/server/wm/DimAnimator.java +++ b/services/java/com/android/server/wm/DimAnimator.java @@ -43,20 +43,21 @@ class DimAnimator { if (mDimSurface == null) { try { if (WindowManagerService.DEBUG_SURFACE_TRACE) { - mDimSurface = new WindowStateAnimator.SurfaceTrace(session, 0, + mDimSurface = new WindowStateAnimator.SurfaceTrace(session, "DimAnimator", - layerStack, 16, 16, PixelFormat.OPAQUE, - Surface.FX_SURFACE_DIM); + 16, 16, PixelFormat.OPAQUE, + Surface.FX_SURFACE_DIM | Surface.HIDDEN); } else { - mDimSurface = new Surface(session, 0, - "DimAnimator", - layerStack, 16, 16, PixelFormat.OPAQUE, - Surface.FX_SURFACE_DIM); + mDimSurface = new Surface(session, "DimAnimator", + 16, 16, PixelFormat.OPAQUE, + Surface.FX_SURFACE_DIM | Surface.HIDDEN); } if (WindowManagerService.SHOW_TRANSACTIONS || WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG, " DIM " + mDimSurface + ": CREATE"); + mDimSurface.setLayerStack(layerStack); mDimSurface.setAlpha(0.0f); + mDimSurface.show(); } catch (Exception e) { Slog.e(WindowManagerService.TAG, "Exception creating Dim surface", e); } @@ -212,4 +213,4 @@ class DimAnimator { mDimTarget = dimTarget; } } -}
\ No newline at end of file +} diff --git a/services/java/com/android/server/wm/DimSurface.java b/services/java/com/android/server/wm/DimSurface.java index 4ab8ce1..ddbd70d 100644 --- a/services/java/com/android/server/wm/DimSurface.java +++ b/services/java/com/android/server/wm/DimSurface.java @@ -34,20 +34,21 @@ class DimSurface { if (mDimSurface == null) { try { if (WindowManagerService.DEBUG_SURFACE_TRACE) { - mDimSurface = new WindowStateAnimator.SurfaceTrace(session, 0, + mDimSurface = new WindowStateAnimator.SurfaceTrace(session, "DimSurface", - layerStack, 16, 16, PixelFormat.OPAQUE, - Surface.FX_SURFACE_DIM); + 16, 16, PixelFormat.OPAQUE, + Surface.FX_SURFACE_DIM | Surface.HIDDEN); } else { - mDimSurface = new Surface(session, 0, - "DimSurface", - layerStack, 16, 16, PixelFormat.OPAQUE, - Surface.FX_SURFACE_DIM); + mDimSurface = new Surface(session, "DimSurface", + 16, 16, PixelFormat.OPAQUE, + Surface.FX_SURFACE_DIM | Surface.HIDDEN); } if (WindowManagerService.SHOW_TRANSACTIONS || WindowManagerService.SHOW_SURFACE_ALLOC) Slog.i(WindowManagerService.TAG, " DIM " + mDimSurface + ": CREATE"); + mDimSurface.setLayerStack(layerStack); mDimSurface.setAlpha(0.0f); + mDimSurface.show(); } catch (Exception e) { Slog.e(WindowManagerService.TAG, "Exception creating Dim surface", e); } diff --git a/services/java/com/android/server/wm/ScreenRotationAnimation.java b/services/java/com/android/server/wm/ScreenRotationAnimation.java index 7679413..acf3249 100644 --- a/services/java/com/android/server/wm/ScreenRotationAnimation.java +++ b/services/java/com/android/server/wm/ScreenRotationAnimation.java @@ -215,12 +215,12 @@ class ScreenRotationAnimation { try { try { if (WindowManagerService.DEBUG_SURFACE_TRACE) { - mSurface = new SurfaceTrace(session, 0, "FreezeSurface", - mDisplay.getLayerStack(), mWidth, mHeight, + mSurface = new SurfaceTrace(session, "FreezeSurface", + mWidth, mHeight, PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT | Surface.HIDDEN); } else { - mSurface = new Surface(session, 0, "FreezeSurface", - mDisplay.getLayerStack(), mWidth, mHeight, + mSurface = new Surface(session, "FreezeSurface", + mWidth, mHeight, PixelFormat.OPAQUE, Surface.FX_SURFACE_SCREENSHOT | Surface.HIDDEN); } if (!mSurface.isValid()) { @@ -228,6 +228,7 @@ class ScreenRotationAnimation { mSurface = null; return; } + mSurface.setLayerStack(mDisplay.getLayerStack()); mSurface.setLayer(FREEZE_LAYER + 1); mSurface.setAlpha(0); mSurface.show(); diff --git a/services/java/com/android/server/wm/StrictModeFlash.java b/services/java/com/android/server/wm/StrictModeFlash.java index 775aa0f..90bbd08 100644 --- a/services/java/com/android/server/wm/StrictModeFlash.java +++ b/services/java/com/android/server/wm/StrictModeFlash.java @@ -37,14 +37,16 @@ class StrictModeFlash { public StrictModeFlash(Display display, SurfaceSession session) { try { - mSurface = new Surface(session, 0, "StrictModeFlash", display.getLayerStack(), - 1, 1, PixelFormat.TRANSLUCENT, 0); + mSurface = new Surface(session, "StrictModeFlash", + 1, 1, PixelFormat.TRANSLUCENT, Surface.HIDDEN); } catch (Surface.OutOfResourcesException e) { return; } + mSurface.setLayerStack(display.getLayerStack()); mSurface.setLayer(WindowManagerService.TYPE_LAYER_MULTIPLIER * 101); // one more than Watermark? arbitrary. mSurface.setPosition(0, 0); + mSurface.show(); mDrawNeeded = true; } diff --git a/services/java/com/android/server/wm/Watermark.java b/services/java/com/android/server/wm/Watermark.java index 5901cc8..ac152c9 100644 --- a/services/java/com/android/server/wm/Watermark.java +++ b/services/java/com/android/server/wm/Watermark.java @@ -113,9 +113,9 @@ class Watermark { mTextPaint.setShadowLayer(shadowRadius, shadowDx, shadowDy, shadowColor); try { - mSurface = new Surface(session, 0, - "WatermarkSurface", mDisplay.getLayerStack(), - 1, 1, PixelFormat.TRANSLUCENT, 0); + 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(); @@ -174,4 +174,4 @@ class Watermark { } } } -}
\ No newline at end of file +} diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index 42bc7ce..c1047a9 100755 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -5847,7 +5847,8 @@ public class WindowManagerService extends IWindowManager.Stub updateLayoutToAnimationLocked(); } } - Surface.setOrientation(0, rotation); + mDisplayManagerService.setDisplayOrientation( + displayContent.getDisplayId(), rotation); } finally { if (!inTransaction) { Surface.closeTransaction(); @@ -6711,9 +6712,9 @@ public class WindowManagerService extends IWindowManager.Stub synchronized (mWindowMap) { try { if (mDragState == null) { - Surface surface = new Surface(session, callerPid, "drag surface", - mDefaultDisplay.getLayerStack(), + Surface surface = new Surface(session, "drag surface", width, height, PixelFormat.TRANSLUCENT, Surface.HIDDEN); + surface.setLayerStack(mDefaultDisplay.getLayerStack()); if (SHOW_TRANSACTIONS) Slog.i(TAG, " DRAG " + surface + ": CREATE"); outSurface.copyFrom(surface); @@ -8342,10 +8343,11 @@ public class WindowManagerService extends IWindowManager.Stub Rect dirty = new Rect(0, 0, mNextAppTransitionThumbnail.getWidth(), mNextAppTransitionThumbnail.getHeight()); try { - Surface surface = new Surface(mFxSession, Process.myPid(), - "thumbnail anim", mDefaultDisplay.getLayerStack(), + Surface surface = new Surface(mFxSession, + "thumbnail anim", dirty.width(), dirty.height(), PixelFormat.TRANSLUCENT, Surface.HIDDEN); + surface.setLayerStack(mDefaultDisplay.getLayerStack()); topOpeningApp.mAppAnimator.thumbnail = surface; if (SHOW_TRANSACTIONS) Slog.i(TAG, " THUMBNAIL " + surface + ": CREATE"); diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java index 982f60d..1bda22a 100644 --- a/services/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/java/com/android/server/wm/WindowStateAnimator.java @@ -481,9 +481,9 @@ class WindowStateAnimator { private String mName; public SurfaceTrace(SurfaceSession s, - int pid, String name, int layerStack, int w, int h, int format, int flags) + String name, int w, int h, int format, int flags) throws OutOfResourcesException { - super(s, pid, name, layerStack, w, h, format, flags); + super(s, name, w, h, format, flags); mName = name != null ? name : "Not named"; mSize.set(w, h); Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by " @@ -608,7 +608,7 @@ class WindowStateAnimator { mService.makeWindowFreezingScreenIfNeededLocked(mWin); - int flags = 0; + int flags = Surface.HIDDEN; final WindowManager.LayoutParams attrs = mWin.mAttrs; if ((attrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) { @@ -652,14 +652,14 @@ class WindowStateAnimator { } if (DEBUG_SURFACE_TRACE) { mSurface = new SurfaceTrace( - mSession.mSurfaceSession, mSession.mPid, + mSession.mSurfaceSession, attrs.getTitle().toString(), - mLayerStack, w, h, format, flags); + w, h, format, flags); } else { mSurface = new Surface( - mSession.mSurfaceSession, mSession.mPid, + mSession.mSurfaceSession, attrs.getTitle().toString(), - mLayerStack, w, h, format, flags); + w, h, format, flags); } mWin.mHasSurface = true; if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG, @@ -701,10 +701,10 @@ class WindowStateAnimator { mSurfaceY = mWin.mFrame.top + mWin.mYOffset; mSurface.setPosition(mSurfaceX, mSurfaceY); mSurfaceLayer = mAnimLayer; + mSurface.setLayerStack(mLayerStack); mSurface.setLayer(mAnimLayer); mSurface.setAlpha(0); mSurfaceShown = false; - mSurface.hide(); } catch (RuntimeException e) { Slog.w(TAG, "Error creating surface in " + w, e); mService.reclaimSomeSurfaceMemoryLocked(this, "create-init", true); diff --git a/services/jni/Android.mk b/services/jni/Android.mk index 43e59b2..d097a93 100644 --- a/services/jni/Android.mk +++ b/services/jni/Android.mk @@ -4,7 +4,6 @@ include $(CLEAR_VARS) LOCAL_SRC_FILES:= \ com_android_server_AlarmManagerService.cpp \ com_android_server_BatteryService.cpp \ - com_android_server_display_SurfaceFlingerDisplayAdapter.cpp \ com_android_server_input_InputApplicationHandle.cpp \ com_android_server_input_InputManagerService.cpp \ com_android_server_input_InputWindowHandle.cpp \ diff --git a/services/jni/com_android_server_display_SurfaceFlingerDisplayAdapter.cpp b/services/jni/com_android_server_display_SurfaceFlingerDisplayAdapter.cpp deleted file mode 100644 index 709d225..0000000 --- a/services/jni/com_android_server_display_SurfaceFlingerDisplayAdapter.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "SurfaceFlingerDisplayAdapter" - -#include "JNIHelp.h" -#include "jni.h" -#include <android_runtime/AndroidRuntime.h> - -#include <gui/ISurfaceComposer.h> -#include <gui/SurfaceComposerClient.h> -#include <ui/DisplayInfo.h> - -#include <utils/Log.h> - -namespace android { - -static struct { - jfieldID width; - jfieldID height; - jfieldID refreshRate; - jfieldID densityDpi; - jfieldID xDpi; - jfieldID yDpi; -} gDisplayDeviceInfoClassInfo; - - -static void nativeGetDefaultDisplayDeviceInfo(JNIEnv* env, jclass clazz, jobject infoObj) { - sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay( - ISurfaceComposer::eDisplayIdMain)); - - DisplayInfo info; - status_t err = SurfaceComposerClient::getDisplayInfo(display, &info); - if (err < 0) { - jniThrowExceptionFmt(env, "java/lang/RuntimeException", - "Could not get display info. err=%d", err); - return; - } - - env->SetIntField(infoObj, gDisplayDeviceInfoClassInfo.width, info.w); - env->SetIntField(infoObj, gDisplayDeviceInfoClassInfo.height, info.h); - env->SetFloatField(infoObj, gDisplayDeviceInfoClassInfo.refreshRate, info.fps); - env->SetIntField(infoObj, gDisplayDeviceInfoClassInfo.densityDpi, - (jint)((info.density*160) + .5f)); - env->SetFloatField(infoObj, gDisplayDeviceInfoClassInfo.xDpi, info.xdpi); - env->SetFloatField(infoObj, gDisplayDeviceInfoClassInfo.yDpi, info.ydpi); -} - - -static JNINativeMethod gSurfaceFlingerDisplayAdapterMethods[] = { - /* name, signature, funcPtr */ - { "nativeGetDefaultDisplayDeviceInfo", - "(Lcom/android/server/display/DisplayDeviceInfo;)V", - (void*) nativeGetDefaultDisplayDeviceInfo }, -}; - -#define FIND_CLASS(var, className) \ - var = env->FindClass(className); \ - LOG_FATAL_IF(! var, "Unable to find class " className); - -#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \ - var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \ - LOG_FATAL_IF(! var, "Unable to find field " fieldName); - -int register_android_server_display_SurfaceFlingerDisplayAdapter(JNIEnv* env) { - int res = jniRegisterNativeMethods(env, - "com/android/server/display/SurfaceFlingerDisplayAdapter", - gSurfaceFlingerDisplayAdapterMethods, NELEM(gSurfaceFlingerDisplayAdapterMethods)); - LOG_FATAL_IF(res < 0, "Unable to register native methods."); - - jclass clazz; - FIND_CLASS(clazz, "com/android/server/display/DisplayDeviceInfo"); - GET_FIELD_ID(gDisplayDeviceInfoClassInfo.width, clazz, "width", "I"); - GET_FIELD_ID(gDisplayDeviceInfoClassInfo.height, clazz, "height", "I"); - GET_FIELD_ID(gDisplayDeviceInfoClassInfo.refreshRate, clazz, "refreshRate", "F"); - GET_FIELD_ID(gDisplayDeviceInfoClassInfo.densityDpi, clazz, "densityDpi", "I"); - GET_FIELD_ID(gDisplayDeviceInfoClassInfo.xDpi, clazz, "xDpi", "F"); - GET_FIELD_ID(gDisplayDeviceInfoClassInfo.yDpi, clazz, "yDpi", "F"); - return 0; -} - -} /* namespace android */ diff --git a/services/jni/onload.cpp b/services/jni/onload.cpp index 50873fc..423ebd1 100644 --- a/services/jni/onload.cpp +++ b/services/jni/onload.cpp @@ -22,7 +22,6 @@ namespace android { int register_android_server_AlarmManagerService(JNIEnv* env); int register_android_server_BatteryService(JNIEnv* env); -int register_android_server_display_SurfaceFlingerDisplayAdapter(JNIEnv* env); int register_android_server_InputApplicationHandle(JNIEnv* env); int register_android_server_InputWindowHandle(JNIEnv* env); int register_android_server_InputManager(JNIEnv* env); @@ -52,7 +51,6 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved) register_android_server_PowerManagerService(env); register_android_server_SerialService(env); - register_android_server_display_SurfaceFlingerDisplayAdapter(env); register_android_server_InputApplicationHandle(env); register_android_server_InputWindowHandle(env); register_android_server_InputManager(env); |