diff options
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); |
