summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
Diffstat (limited to 'core')
-rw-r--r--core/java/android/app/UiAutomationConnection.java4
-rw-r--r--core/java/android/view/Choreographer.java2
-rw-r--r--core/java/android/view/DisplayEventReceiver.java4
-rw-r--r--core/java/android/view/Surface.java571
-rw-r--r--core/java/android/view/SurfaceControl.java575
-rw-r--r--core/jni/Android.mk1
-rw-r--r--core/jni/AndroidRuntime.cpp4
-rw-r--r--core/jni/android_hardware_Camera.cpp9
-rw-r--r--core/jni/android_view_Surface.cpp661
-rw-r--r--core/jni/android_view_SurfaceControl.cpp451
10 files changed, 1179 insertions, 1103 deletions
diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java
index 9b5857f..06ef472 100644
--- a/core/java/android/app/UiAutomationConnection.java
+++ b/core/java/android/app/UiAutomationConnection.java
@@ -27,7 +27,7 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.view.IWindowManager;
import android.view.InputEvent;
-import android.view.Surface;
+import android.view.SurfaceControl;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.IAccessibilityManager;
@@ -135,7 +135,7 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
}
final long identity = Binder.clearCallingIdentity();
try {
- return Surface.screenshot(width, height);
+ return SurfaceControl.screenshot(width, height);
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index b661748..f28e4b5 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -693,7 +693,7 @@ public final class Choreographer {
// At this time Surface Flinger won't send us vsyncs for secondary displays
// but that could change in the future so let's log a message to help us remember
// that we need to fix this.
- if (builtInDisplayId != Surface.BUILT_IN_DISPLAY_ID_MAIN) {
+ if (builtInDisplayId != SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN) {
Log.d(TAG, "Received vsync from secondary display, but we don't support "
+ "this case yet. Choreographer needs a way to explicitly request "
+ "vsync for a specific display to ensure it doesn't lose track "
diff --git a/core/java/android/view/DisplayEventReceiver.java b/core/java/android/view/DisplayEventReceiver.java
index a919ffc..4dade20 100644
--- a/core/java/android/view/DisplayEventReceiver.java
+++ b/core/java/android/view/DisplayEventReceiver.java
@@ -102,7 +102,7 @@ public abstract class DisplayEventReceiver {
* @param timestampNanos The timestamp of the pulse, in the {@link System#nanoTime()}
* timebase.
* @param builtInDisplayId The surface flinger built-in display id such as
- * {@link Surface#BUILT_IN_DISPLAY_ID_MAIN}.
+ * {@link SurfaceControl#BUILT_IN_DISPLAY_ID_MAIN}.
* @param frame The frame number. Increases by one for each vertical sync interval.
*/
public void onVsync(long timestampNanos, int builtInDisplayId, int frame) {
@@ -114,7 +114,7 @@ public abstract class DisplayEventReceiver {
* @param timestampNanos The timestamp of the event, in the {@link System#nanoTime()}
* timebase.
* @param builtInDisplayId The surface flinger built-in display id such as
- * {@link Surface#BUILT_IN_DISPLAY_ID_HDMI}.
+ * {@link SurfaceControl#BUILT_IN_DISPLAY_ID_HDMI}.
* @param connected True if the display is connected, false if it disconnected.
*/
public void onHotplug(long timestampNanos, int builtInDisplayId, boolean connected) {
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 48b7180..5e96dad 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -16,20 +16,15 @@
package android.view;
-import dalvik.system.CloseGuard;
-
import android.content.res.CompatibilityInfo.Translator;
-import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Rect;
-import android.graphics.Region;
import android.graphics.SurfaceTexture;
-import android.os.IBinder;
-import android.os.Parcelable;
import android.os.Parcel;
-import android.os.SystemProperties;
+import android.os.Parcelable;
import android.util.Log;
+import dalvik.system.CloseGuard;
/**
* Handle onto a raw buffer that is being managed by the screen compositor.
@@ -37,9 +32,6 @@ import android.util.Log;
public class Surface implements Parcelable {
private static final String TAG = "Surface";
- private static final boolean HEADLESS = "1".equals(
- SystemProperties.get("ro.config.headless", "0"));
-
public static final Parcelable.Creator<Surface> CREATOR =
new Parcelable.Creator<Surface>() {
public Surface createFromParcel(Parcel source) {
@@ -78,130 +70,6 @@ public class Surface implements Parcelable {
*/
public static final int ROTATION_270 = 3;
- /* built-in physical display ids (keep in sync with ISurfaceComposer.h)
- * these are different from the logical display ids used elsewhere in the framework */
-
- /**
- * Built-in physical display id: Main display.
- * Use only with {@link #getBuiltInDisplay()}.
- * @hide
- */
- public static final int BUILT_IN_DISPLAY_ID_MAIN = 0;
-
- /**
- * Built-in physical display id: Attached HDMI display.
- * Use only with {@link #getBuiltInDisplay()}.
- * @hide
- */
- public static final int BUILT_IN_DISPLAY_ID_HDMI = 1;
-
- /* flags used in constructor (keep in sync with ISurfaceComposerClient.h) */
-
- /**
- * Surface creation flag: Surface is created hidden
- * @hide */
- public static final int HIDDEN = 0x00000004;
-
- /**
- * Surface creation flag: The surface contains secure content, special
- * measures will be taken to disallow the surface's content to be copied
- * from another process. In particular, screenshots and VNC servers will
- * be disabled, but other measures can take place, for instance the
- * surface might not be hardware accelerated.
- * @hide
- */
- public static final int SECURE = 0x00000080;
-
- /**
- * Surface creation flag: Creates a surface where color components are interpreted
- * as "non pre-multiplied" by their alpha channel. Of course this flag is
- * meaningless for surfaces without an alpha channel. By default
- * surfaces are pre-multiplied, which means that each color component is
- * already multiplied by its alpha value. In this case the blending
- * equation used is:
- *
- * DEST = SRC + DEST * (1-SRC_ALPHA)
- *
- * By contrast, non pre-multiplied surfaces use the following equation:
- *
- * DEST = SRC * SRC_ALPHA * DEST * (1-SRC_ALPHA)
- *
- * pre-multiplied surfaces must always be used if transparent pixels are
- * composited on top of each-other into the surface. A pre-multiplied
- * surface can never lower the value of the alpha component of a given
- * pixel.
- *
- * In some rare situations, a non pre-multiplied surface is preferable.
- * @hide
- */
- public static final int NON_PREMULTIPLIED = 0x00000100;
-
- /**
- * Surface creation flag: Indicates that the surface must be considered opaque,
- * even if its pixel format is set to translucent. This can be useful if an
- * application needs full RGBA 8888 support for instance but will
- * still draw every pixel opaque.
- * @hide
- */
- public static final int OPAQUE = 0x00000400;
-
- /**
- * Surface creation flag: Application requires a hardware-protected path to an
- * external display sink. If a hardware-protected path is not available,
- * then this surface will not be displayed on the external sink.
- * @hide
- */
- public static final int PROTECTED_APP = 0x00000800;
-
- // 0x1000 is reserved for an independent DRM protected flag in framework
-
- /**
- * Surface creation flag: Creates a normal surface.
- * This is the default.
- * @hide
- */
- public static final int FX_SURFACE_NORMAL = 0x00000000;
-
- /**
- * Surface creation flag: Creates a Blur surface.
- * Everything behind this surface is blurred by some amount.
- * The quality and refresh speed of the blur effect is not settable or guaranteed.
- * It is an error to lock a Blur surface, since it doesn't have a backing store.
- * @hide
- * @deprecated
- */
- @Deprecated
- public static final int FX_SURFACE_BLUR = 0x00010000;
-
- /**
- * Surface creation flag: Creates a Dim surface.
- * Everything behind this surface is dimmed by the amount specified
- * in {@link #setAlpha}. It is an error to lock a Dim surface, since it
- * doesn't have a backing store.
- * @hide
- */
- public static final int FX_SURFACE_DIM = 0x00020000;
-
- /**
- * @hide
- */
- public static final int FX_SURFACE_SCREENSHOT = 0x00030000;
-
- /**
- * Mask used for FX values above.
- * @hide
- */
- public static final int FX_SURFACE_MASK = 0x000F0000;
-
- /* flags used with setFlags() (keep in sync with ISurfaceComposer.h) */
-
- /**
- * Surface flag: Hide the surface.
- * Equivalent to calling hide().
- * @hide
- */
- public static final int SURFACE_HIDDEN = 0x01;
-
private final CloseGuard mCloseGuard = CloseGuard.get();
private String mName;
@@ -211,8 +79,8 @@ public class Surface implements Parcelable {
// server or system processes. When this class is parceled we defer to the
// mSurfaceControl to do the parceling. Otherwise we parcel the
// mNativeSurface.
- private int mNativeSurface; // Surface*
- private int mNativeSurfaceControl; // SurfaceControl*
+ int mNativeObject; // package scope only for SurfaceControl access
+
private int mGenerationId; // incremented each time mNativeSurface changes
private final Canvas mCanvas = new CompatibleCanvas();
private int mCanvasSaveCount; // Canvas save count at time of lockCanvas()
@@ -225,112 +93,12 @@ public class Surface implements Parcelable {
// non compatibility mode.
private Matrix mCompatibleMatrix;
- private native void nativeCreate(SurfaceSession session, String name,
- int w, int h, int format, int flags)
- throws OutOfResourcesException;
- private native void nativeCreateFromSurfaceTexture(SurfaceTexture surfaceTexture)
- throws OutOfResourcesException;
- private native void nativeRelease();
- private native void nativeDestroy();
-
- private native boolean nativeIsValid();
- private native boolean nativeIsConsumerRunningBehind();
-
- private native Canvas nativeLockCanvas(Rect dirty);
- private native void nativeUnlockCanvasAndPost(Canvas canvas);
-
- private static native Bitmap nativeScreenshot(IBinder displayToken,
- int width, int height, int minLayer, int maxLayer, boolean allLayers);
-
- private static native void nativeOpenTransaction();
- private static native void nativeCloseTransaction();
- private static native void nativeSetAnimationTransaction();
-
- private native void nativeSetLayer(int zorder);
- private native void nativeSetPosition(float x, float y);
- private native void nativeSetSize(int w, int h);
- private native void nativeSetTransparentRegionHint(Region region);
- private native void nativeSetAlpha(float alpha);
- private native void nativeSetMatrix(float dsdx, float dtdx, float dsdy, float dtdy);
- private native void nativeSetFlags(int flags, int mask);
- private native void nativeSetWindowCrop(Rect crop);
- private native void nativeSetLayerStack(int layerStack);
-
- private static native IBinder nativeGetBuiltInDisplay(int physicalDisplayId);
- private static native IBinder nativeCreateDisplay(String name, boolean secure);
- private static native void nativeSetDisplaySurface(
- IBinder displayToken, Surface surface);
- private static native void nativeSetDisplayLayerStack(
- IBinder displayToken, int layerStack);
- private static native void nativeSetDisplayProjection(
- IBinder displayToken, int orientation, Rect layerStackRect, Rect displayRect);
- private static native boolean nativeGetDisplayInfo(
- IBinder displayToken, PhysicalDisplayInfo outInfo);
- private static native void nativeBlankDisplay(IBinder displayToken);
- private static native void nativeUnblankDisplay(IBinder displayToken);
-
- private native void nativeCopyFrom(Surface other);
- private native void nativeTransferFrom(Surface other);
- private native void nativeReadFromParcel(Parcel source);
- private native void nativeWriteToParcel(Parcel dest);
-
/**
* Create an empty surface, which will later be filled in by readFromParcel().
* @hide
*/
public Surface() {
- checkHeadless();
-
- mCloseGuard.open("release");
- }
-
- /**
- * Create a surface with a name.
- *
- * The surface creation flags specify what kind of surface to create and
- * certain options such as whether the surface can be assumed to be opaque
- * and whether it should be initially hidden. Surfaces should always be
- * created with the {@link #HIDDEN} flag set to ensure that they are not
- * made visible prematurely before all of the surface's properties have been
- * configured.
- *
- * Good practice is to first create the surface with the {@link #HIDDEN} flag
- * specified, open a transaction, set the surface layer, layer stack, alpha,
- * and position, call {@link #show} if appropriate, and close the transaction.
- *
- * @param session The surface session, must not be null.
- * @param name The surface name, must not be null.
- * @param w The surface initial width.
- * @param h The surface initial height.
- * @param flags The surface creation flags. Should always include {@link #HIDDEN}
- * in the creation flags.
- * @hide
- */
- public Surface(SurfaceSession session,
- String name, int w, int h, int format, int flags)
- throws OutOfResourcesException {
- if (session == null) {
- throw new IllegalArgumentException("session must not be null");
- }
- if (name == null) {
- throw new IllegalArgumentException("name must not be null");
- }
-
- if ((flags & HIDDEN) == 0) {
- Log.w(TAG, "Surfaces should always be created with the HIDDEN flag set "
- + "to ensure that they are not made visible prematurely before "
- + "all of the surface's properties have been configured. "
- + "Set the other properties and make the surface visible within "
- + "a transaction. New surface name: " + name,
- new Throwable());
- }
-
- checkHeadless();
-
- mName = name;
- nativeCreate(session, name, w, h, format, flags);
-
mCloseGuard.open("release");
}
@@ -349,11 +117,9 @@ public class Surface implements Parcelable {
throw new IllegalArgumentException("surfaceTexture must not be null");
}
- checkHeadless();
-
mName = surfaceTexture.toString();
try {
- nativeCreateFromSurfaceTexture(surfaceTexture);
+ mNativeObject = nativeCreateFromSurfaceTexture(surfaceTexture);
} catch (OutOfResourcesException ex) {
// We can't throw OutOfResourcesException because it would be an API change.
throw new RuntimeException(ex);
@@ -362,13 +128,20 @@ public class Surface implements Parcelable {
mCloseGuard.open("release");
}
+ private Surface(int nativeObject) {
+ mNativeObject = nativeObject;
+ mCloseGuard.open("release");
+ }
+
@Override
protected void finalize() throws Throwable {
try {
if (mCloseGuard != null) {
mCloseGuard.warnIfOpen();
}
- nativeRelease();
+ if (mNativeObject != 0) {
+ nativeRelease(mNativeObject);
+ }
} finally {
super.finalize();
}
@@ -380,7 +153,10 @@ public class Surface implements Parcelable {
* This will make the surface invalid.
*/
public void release() {
- nativeRelease();
+ if (mNativeObject != 0) {
+ nativeRelease(mNativeObject);
+ mNativeObject = 0;
+ }
mCloseGuard.close();
}
@@ -391,7 +167,10 @@ public class Surface implements Parcelable {
* @hide
*/
public void destroy() {
- nativeDestroy();
+ if (mNativeObject != 0) {
+ nativeDestroy(mNativeObject);
+ mNativeObject = 0;
+ }
mCloseGuard.close();
}
@@ -402,7 +181,8 @@ public class Surface implements Parcelable {
* Otherwise returns false.
*/
public boolean isValid() {
- return nativeIsValid();
+ if (mNativeObject == 0) return false;
+ return nativeIsValid(mNativeObject);
}
/**
@@ -423,7 +203,8 @@ public class Surface implements Parcelable {
* @hide
*/
public boolean isConsumerRunningBehind() {
- return nativeIsConsumerRunningBehind();
+ checkNotReleased();
+ return nativeIsConsumerRunningBehind(mNativeObject);
}
/**
@@ -441,9 +222,10 @@ public class Surface implements Parcelable {
* entire surface should be redrawn.
* @return A canvas for drawing into the surface.
*/
- public Canvas lockCanvas(Rect dirty)
+ public Canvas lockCanvas(Rect inOutDirty)
throws OutOfResourcesException, IllegalArgumentException {
- return nativeLockCanvas(dirty);
+ checkNotReleased();
+ return nativeLockCanvas(mNativeObject, inOutDirty);
}
/**
@@ -453,7 +235,8 @@ public class Surface implements Parcelable {
* @param canvas The canvas previously obtained from {@link #lockCanvas}.
*/
public void unlockCanvasAndPost(Canvas canvas) {
- nativeUnlockCanvasAndPost(canvas);
+ checkNotReleased();
+ nativeUnlockCanvasAndPost(mNativeObject, canvas);
}
/**
@@ -476,190 +259,6 @@ public class Surface implements Parcelable {
}
}
- /**
- * Like {@link #screenshot(int, int, int, int)} but includes all
- * Surfaces in the screenshot.
- *
- * @hide
- */
- public static Bitmap screenshot(int width, int height) {
- // TODO: should take the display as a parameter
- IBinder displayToken = getBuiltInDisplay(BUILT_IN_DISPLAY_ID_MAIN);
- return nativeScreenshot(displayToken, width, height, 0, 0, true);
- }
-
- /**
- * Copy the current screen contents into a bitmap and return it.
- *
- * @param width The desired width of the returned bitmap; the raw
- * screen will be scaled down to this size.
- * @param height The desired height of the returned bitmap; the raw
- * screen will be scaled down to this size.
- * @param minLayer The lowest (bottom-most Z order) surface layer to
- * include in the screenshot.
- * @param maxLayer The highest (top-most Z order) surface layer to
- * include in the screenshot.
- * @return Returns a Bitmap containing the screen contents, or null
- * if an error occurs.
- *
- * @hide
- */
- public static Bitmap screenshot(int width, int height, int minLayer, int maxLayer) {
- // TODO: should take the display as a parameter
- IBinder displayToken = getBuiltInDisplay(BUILT_IN_DISPLAY_ID_MAIN);
- return nativeScreenshot(displayToken, width, height, minLayer, maxLayer, false);
- }
-
- /*
- * set surface parameters.
- * needs to be inside open/closeTransaction block
- */
-
- /** start a transaction @hide */
- public static void openTransaction() {
- nativeOpenTransaction();
- }
-
- /** end a transaction @hide */
- public static void closeTransaction() {
- nativeCloseTransaction();
- }
-
- /** flag the transaction as an animation @hide */
- public static void setAnimationTransaction() {
- nativeSetAnimationTransaction();
- }
-
- /** @hide */
- public void setLayer(int zorder) {
- nativeSetLayer(zorder);
- }
-
- /** @hide */
- public void setPosition(int x, int y) {
- nativeSetPosition((float)x, (float)y);
- }
-
- /** @hide */
- public void setPosition(float x, float y) {
- nativeSetPosition(x, y);
- }
-
- /** @hide */
- public void setSize(int w, int h) {
- nativeSetSize(w, h);
- }
-
- /** @hide */
- public void hide() {
- nativeSetFlags(SURFACE_HIDDEN, SURFACE_HIDDEN);
- }
-
- /** @hide */
- public void show() {
- nativeSetFlags(0, SURFACE_HIDDEN);
- }
-
- /** @hide */
- public void setTransparentRegionHint(Region region) {
- nativeSetTransparentRegionHint(region);
- }
-
- /** @hide */
- public void setAlpha(float alpha) {
- nativeSetAlpha(alpha);
- }
-
- /** @hide */
- public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
- nativeSetMatrix(dsdx, dtdx, dsdy, dtdy);
- }
-
- /** @hide */
- public void setFlags(int flags, int mask) {
- nativeSetFlags(flags, mask);
- }
-
- /** @hide */
- public void setWindowCrop(Rect crop) {
- nativeSetWindowCrop(crop);
- }
-
- /** @hide */
- public void setLayerStack(int layerStack) {
- nativeSetLayerStack(layerStack);
- }
-
- /** @hide */
- public static IBinder getBuiltInDisplay(int builtInDisplayId) {
- return nativeGetBuiltInDisplay(builtInDisplayId);
- }
-
- /** @hide */
- public static IBinder createDisplay(String name, boolean secure) {
- if (name == null) {
- throw new IllegalArgumentException("name must not be null");
- }
- return nativeCreateDisplay(name, secure);
- }
-
- /** @hide */
- public static void setDisplaySurface(IBinder displayToken, Surface surface) {
- if (displayToken == null) {
- throw new IllegalArgumentException("displayToken must not be null");
- }
- nativeSetDisplaySurface(displayToken, surface);
- }
-
- /** @hide */
- public static void setDisplayLayerStack(IBinder displayToken, int layerStack) {
- if (displayToken == null) {
- throw new IllegalArgumentException("displayToken must not be null");
- }
- nativeSetDisplayLayerStack(displayToken, layerStack);
- }
-
- /** @hide */
- public static void setDisplayProjection(IBinder displayToken,
- int orientation, Rect layerStackRect, Rect displayRect) {
- if (displayToken == null) {
- throw new IllegalArgumentException("displayToken must not be null");
- }
- if (layerStackRect == null) {
- throw new IllegalArgumentException("layerStackRect must not be null");
- }
- if (displayRect == null) {
- throw new IllegalArgumentException("displayRect must not be null");
- }
- nativeSetDisplayProjection(displayToken, orientation, layerStackRect, displayRect);
- }
-
- /** @hide */
- public static boolean getDisplayInfo(IBinder displayToken, PhysicalDisplayInfo outInfo) {
- if (displayToken == null) {
- throw new IllegalArgumentException("displayToken must not be null");
- }
- if (outInfo == null) {
- throw new IllegalArgumentException("outInfo must not be null");
- }
- return nativeGetDisplayInfo(displayToken, outInfo);
- }
-
- /** @hide */
- public static void blankDisplay(IBinder displayToken) {
- if (displayToken == null) {
- throw new IllegalArgumentException("displayToken must not be null");
- }
- nativeBlankDisplay(displayToken);
- }
-
- /** @hide */
- public static void unblankDisplay(IBinder displayToken) {
- if (displayToken == null) {
- throw new IllegalArgumentException("displayToken must not be null");
- }
- nativeUnblankDisplay(displayToken);
- }
/**
* Copy another surface to this one. This surface now holds a reference
@@ -670,13 +269,15 @@ public class Surface implements Parcelable {
* in to it.
* @hide
*/
- public void copyFrom(Surface other) {
+ public void copyFrom(SurfaceControl other) {
if (other == null) {
throw new IllegalArgumentException("other must not be null");
}
- if (other != this) {
- nativeCopyFrom(other);
+ if (other.mNativeObject == 0) {
+ throw new NullPointerException(
+ "SurfaceControl native object is null. Are you using a released SurfaceControl?");
}
+ mNativeObject = nativeCopyFrom(mNativeObject, other.mNativeObject);
}
/**
@@ -692,7 +293,13 @@ public class Surface implements Parcelable {
throw new IllegalArgumentException("other must not be null");
}
if (other != this) {
- nativeTransferFrom(other);
+ if (mNativeObject != 0) {
+ // release our reference to our native object
+ nativeRelease(mNativeObject);
+ }
+ // transfer the reference from other to us
+ mNativeObject = other.mNativeObject;
+ other.mNativeObject = 0;
}
}
@@ -705,9 +312,8 @@ public class Surface implements Parcelable {
if (source == null) {
throw new IllegalArgumentException("source must not be null");
}
-
mName = source.readString();
- nativeReadFromParcel(source);
+ mNativeObject = nativeReadFromParcel(mNativeObject, source);
}
@Override
@@ -715,9 +321,8 @@ public class Surface implements Parcelable {
if (dest == null) {
throw new IllegalArgumentException("dest must not be null");
}
-
dest.writeString(mName);
- nativeWriteToParcel(dest);
+ nativeWriteToParcel(mNativeObject, dest);
if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) {
release();
}
@@ -728,85 +333,18 @@ public class Surface implements Parcelable {
return "Surface(name=" + mName + ")";
}
- private static void checkHeadless() {
- if (HEADLESS) {
- throw new UnsupportedOperationException("Device is headless");
- }
- }
-
/**
* Exception thrown when a surface couldn't be created or resized.
*/
public static class OutOfResourcesException extends Exception {
public OutOfResourcesException() {
}
-
public OutOfResourcesException(String name) {
super(name);
}
}
/**
- * Describes the properties of a physical display known to surface flinger.
- * @hide
- */
- public static final class PhysicalDisplayInfo {
- public int width;
- public int height;
- public float refreshRate;
- public float density;
- public float xDpi;
- public float yDpi;
- public boolean secure;
-
- public PhysicalDisplayInfo() {
- }
-
- public PhysicalDisplayInfo(PhysicalDisplayInfo other) {
- copyFrom(other);
- }
-
- @Override
- public boolean equals(Object o) {
- return o instanceof PhysicalDisplayInfo && equals((PhysicalDisplayInfo)o);
- }
-
- public boolean equals(PhysicalDisplayInfo other) {
- return other != null
- && width == other.width
- && height == other.height
- && refreshRate == other.refreshRate
- && density == other.density
- && xDpi == other.xDpi
- && yDpi == other.yDpi
- && secure == other.secure;
- }
-
- @Override
- public int hashCode() {
- return 0; // don't care
- }
-
- public void copyFrom(PhysicalDisplayInfo other) {
- width = other.width;
- height = other.height;
- refreshRate = other.refreshRate;
- density = other.density;
- xDpi = other.xDpi;
- yDpi = other.yDpi;
- secure = other.secure;
- }
-
- // For debugging purposes
- @Override
- public String toString() {
- return "PhysicalDisplayInfo{" + width + " x " + height + ", " + refreshRate + " fps, "
- + "density " + density + ", " + xDpi + " x " + yDpi + " dpi, secure " + secure
- + "}";
- }
- }
-
- /**
* Returns a human readable representation of a rotation.
*
* @param rotation The rotation.
@@ -893,4 +431,25 @@ public class Surface implements Parcelable {
mOrigMatrix.set(m);
}
}
+
+ private void checkNotReleased() {
+ if (mNativeObject == 0) throw new NullPointerException(
+ "mNativeObject is null. Have you called release() already?");
+ }
+
+ private native int nativeCreateFromSurfaceTexture(SurfaceTexture surfaceTexture)
+ throws OutOfResourcesException;
+
+ private native void nativeRelease(int nativeObject);
+ private native void nativeDestroy(int nativeObject);
+ private native boolean nativeIsValid(int nativeObject);
+
+ private native boolean nativeIsConsumerRunningBehind(int nativeObject);
+
+ private native Canvas nativeLockCanvas(int nativeObject, Rect dirty);
+ private native void nativeUnlockCanvasAndPost(int nativeObject, Canvas canvas);
+
+ private native int nativeCopyFrom(int nativeObject, int surfaceControlNativeObject);
+ private native int nativeReadFromParcel(int nativeObject, Parcel source);
+ private native void nativeWriteToParcel(int nativeObject, Parcel dest);
}
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
new file mode 100644
index 0000000..dd288b9
--- /dev/null
+++ b/core/java/android/view/SurfaceControl.java
@@ -0,0 +1,575 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import dalvik.system.CloseGuard;
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.graphics.Region;
+import android.os.IBinder;
+import android.os.SystemProperties;
+import android.util.Log;
+
+/**
+ * SurfaceControl
+ * @hide
+ */
+public class SurfaceControl {
+ private static final String TAG = "SurfaceControl";
+ private final CloseGuard mCloseGuard = CloseGuard.get();
+ private String mName;
+ int mNativeObject; // package visibility only for Surface.java access
+
+ private static final boolean HEADLESS = "1".equals(
+ SystemProperties.get("ro.config.headless", "0"));
+
+ /**
+ * Exception thrown when a surface couldn't be created or resized.
+ */
+ public static class OutOfResourcesException extends Exception {
+ public OutOfResourcesException() {
+ }
+ public OutOfResourcesException(String name) {
+ super(name);
+ }
+ }
+
+ /* flags used in constructor (keep in sync with ISurfaceComposerClient.h) */
+
+ /**
+ * Surface creation flag: Surface is created hidden
+ */
+ public static final int HIDDEN = 0x00000004;
+
+ /**
+ * Surface creation flag: The surface contains secure content, special
+ * measures will be taken to disallow the surface's content to be copied
+ * from another process. In particular, screenshots and VNC servers will
+ * be disabled, but other measures can take place, for instance the
+ * surface might not be hardware accelerated.
+ *
+ */
+ public static final int SECURE = 0x00000080;
+
+ /**
+ * Surface creation flag: Creates a surface where color components are interpreted
+ * as "non pre-multiplied" by their alpha channel. Of course this flag is
+ * meaningless for surfaces without an alpha channel. By default
+ * surfaces are pre-multiplied, which means that each color component is
+ * already multiplied by its alpha value. In this case the blending
+ * equation used is:
+ *
+ * DEST = SRC + DEST * (1-SRC_ALPHA)
+ *
+ * By contrast, non pre-multiplied surfaces use the following equation:
+ *
+ * DEST = SRC * SRC_ALPHA * DEST * (1-SRC_ALPHA)
+ *
+ * pre-multiplied surfaces must always be used if transparent pixels are
+ * composited on top of each-other into the surface. A pre-multiplied
+ * surface can never lower the value of the alpha component of a given
+ * pixel.
+ *
+ * In some rare situations, a non pre-multiplied surface is preferable.
+ *
+ */
+ public static final int NON_PREMULTIPLIED = 0x00000100;
+
+ /**
+ * Surface creation flag: Indicates that the surface must be considered opaque,
+ * even if its pixel format is set to translucent. This can be useful if an
+ * application needs full RGBA 8888 support for instance but will
+ * still draw every pixel opaque.
+ *
+ */
+ public static final int OPAQUE = 0x00000400;
+
+ /**
+ * Surface creation flag: Application requires a hardware-protected path to an
+ * external display sink. If a hardware-protected path is not available,
+ * then this surface will not be displayed on the external sink.
+ *
+ */
+ public static final int PROTECTED_APP = 0x00000800;
+
+ // 0x1000 is reserved for an independent DRM protected flag in framework
+
+ /**
+ * Surface creation flag: Creates a normal surface.
+ * This is the default.
+ *
+ */
+ public static final int FX_SURFACE_NORMAL = 0x00000000;
+
+ /**
+ * Surface creation flag: Creates a Blur surface.
+ * Everything behind this surface is blurred by some amount.
+ * The quality and refresh speed of the blur effect is not settable or guaranteed.
+ * It is an error to lock a Blur surface, since it doesn't have a backing store.
+ *
+ * @deprecated
+ */
+ @Deprecated
+ public static final int FX_SURFACE_BLUR = 0x00010000;
+
+ /**
+ * Surface creation flag: Creates a Dim surface.
+ * Everything behind this surface is dimmed by the amount specified
+ * in {@link #setAlpha}. It is an error to lock a Dim surface, since it
+ * doesn't have a backing store.
+ *
+ */
+ public static final int FX_SURFACE_DIM = 0x00020000;
+
+ /**
+ *
+ */
+ public static final int FX_SURFACE_SCREENSHOT = 0x00030000;
+
+ /**
+ * Mask used for FX values above.
+ *
+ */
+ public static final int FX_SURFACE_MASK = 0x000F0000;
+
+ /* flags used with setFlags() (keep in sync with ISurfaceComposer.h) */
+
+ /**
+ * Surface flag: Hide the surface.
+ * Equivalent to calling hide().
+ */
+ public static final int SURFACE_HIDDEN = 0x01;
+
+
+ /* built-in physical display ids (keep in sync with ISurfaceComposer.h)
+ * these are different from the logical display ids used elsewhere in the framework */
+
+ /**
+ * Built-in physical display id: Main display.
+ * Use only with {@link SurfaceControl#getBuiltInDisplay()}.
+ */
+ public static final int BUILT_IN_DISPLAY_ID_MAIN = 0;
+
+ /**
+ * Built-in physical display id: Attached HDMI display.
+ * Use only with {@link SurfaceControl#getBuiltInDisplay()}.
+ */
+ public static final int BUILT_IN_DISPLAY_ID_HDMI = 1;
+
+
+
+ /**
+ * Create a surface with a name.
+ *
+ * The surface creation flags specify what kind of surface to create and
+ * certain options such as whether the surface can be assumed to be opaque
+ * and whether it should be initially hidden. Surfaces should always be
+ * created with the {@link #HIDDEN} flag set to ensure that they are not
+ * made visible prematurely before all of the surface's properties have been
+ * configured.
+ *
+ * Good practice is to first create the surface with the {@link #HIDDEN} flag
+ * specified, open a transaction, set the surface layer, layer stack, alpha,
+ * and position, call {@link #show} if appropriate, and close the transaction.
+ *
+ * @param session The surface session, must not be null.
+ * @param name The surface name, must not be null.
+ * @param w The surface initial width.
+ * @param h The surface initial height.
+ * @param flags The surface creation flags. Should always include {@link #HIDDEN}
+ * in the creation flags.
+ */
+ public SurfaceControl(SurfaceSession session,
+ String name, int w, int h, int format, int flags)
+ throws OutOfResourcesException {
+ if (session == null) {
+ throw new IllegalArgumentException("session must not be null");
+ }
+ if (name == null) {
+ throw new IllegalArgumentException("name must not be null");
+ }
+
+ if ((flags & SurfaceControl.HIDDEN) == 0) {
+ Log.w(TAG, "Surfaces should always be created with the HIDDEN flag set "
+ + "to ensure that they are not made visible prematurely before "
+ + "all of the surface's properties have been configured. "
+ + "Set the other properties and make the surface visible within "
+ + "a transaction. New surface name: " + name,
+ new Throwable());
+ }
+
+ checkHeadless();
+
+ mName = name;
+ mNativeObject = nativeCreate(session, name, w, h, format, flags);
+ if (mNativeObject == 0) {
+ throw new OutOfResourcesException(
+ "Couldn't allocate SurfaceControl native object");
+ }
+
+ mCloseGuard.open("release");
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ try {
+ if (mCloseGuard != null) {
+ mCloseGuard.warnIfOpen();
+ }
+ if (mNativeObject != 0) {
+ nativeRelease(mNativeObject);
+ }
+ } finally {
+ super.finalize();
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "Surface(name=" + mName + ")";
+ }
+
+ /**
+ * Release the local reference to the server-side surface.
+ * Always call release() when you're done with a Surface.
+ * This will make the surface invalid.
+ */
+ public void release() {
+ if (mNativeObject != 0) {
+ nativeRelease(mNativeObject);
+ mNativeObject = 0;
+ }
+ mCloseGuard.close();
+ }
+
+ /**
+ * Free all server-side state associated with this surface and
+ * release this object's reference. This method can only be
+ * called from the process that created the service.
+ */
+ public void destroy() {
+ if (mNativeObject != 0) {
+ nativeDestroy(mNativeObject);
+ mNativeObject = 0;
+ }
+ mCloseGuard.close();
+ }
+
+ private void checkNotReleased() {
+ if (mNativeObject == 0) throw new NullPointerException(
+ "mNativeObject is null. Have you called release() already?");
+ }
+
+ /*
+ * set surface parameters.
+ * needs to be inside open/closeTransaction block
+ */
+
+ /** start a transaction */
+ public static void openTransaction() {
+ nativeOpenTransaction();
+ }
+
+ /** end a transaction */
+ public static void closeTransaction() {
+ nativeCloseTransaction();
+ }
+
+ /** flag the transaction as an animation */
+ public static void setAnimationTransaction() {
+ nativeSetAnimationTransaction();
+ }
+
+ public void setLayer(int zorder) {
+ checkNotReleased();
+ nativeSetLayer(mNativeObject, zorder);
+ }
+
+ public void setPosition(int x, int y) {
+ checkNotReleased();
+ nativeSetPosition(mNativeObject, (float)x, (float)y);
+ }
+
+ public void setPosition(float x, float y) {
+ checkNotReleased();
+ nativeSetPosition(mNativeObject, x, y);
+ }
+
+ public void setSize(int w, int h) {
+ checkNotReleased();
+ nativeSetSize(mNativeObject, w, h);
+ }
+
+ public void hide() {
+ checkNotReleased();
+ nativeSetFlags(mNativeObject, SURFACE_HIDDEN, SURFACE_HIDDEN);
+ }
+
+ public void show() {
+ checkNotReleased();
+ nativeSetFlags(mNativeObject, 0, SURFACE_HIDDEN);
+ }
+
+ public void setTransparentRegionHint(Region region) {
+ checkNotReleased();
+ nativeSetTransparentRegionHint(mNativeObject, region);
+ }
+
+ public void setAlpha(float alpha) {
+ checkNotReleased();
+ nativeSetAlpha(mNativeObject, alpha);
+ }
+
+ public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
+ checkNotReleased();
+ nativeSetMatrix(mNativeObject, dsdx, dtdx, dsdy, dtdy);
+ }
+
+ public void setFlags(int flags, int mask) {
+ checkNotReleased();
+ nativeSetFlags(mNativeObject, flags, mask);
+ }
+
+ public void setWindowCrop(Rect crop) {
+ checkNotReleased();
+ if (crop != null) {
+ nativeSetWindowCrop(mNativeObject,
+ crop.left, crop.top, crop.right, crop.bottom);
+ } else {
+ nativeSetWindowCrop(mNativeObject, 0, 0, 0, 0);
+ }
+ }
+
+ public void setLayerStack(int layerStack) {
+ checkNotReleased();
+ nativeSetLayerStack(mNativeObject, layerStack);
+ }
+
+ /*
+ * set display parameters.
+ * needs to be inside open/closeTransaction block
+ */
+
+ /**
+ * Describes the properties of a physical display known to surface flinger.
+ */
+ public static final class PhysicalDisplayInfo {
+ public int width;
+ public int height;
+ public float refreshRate;
+ public float density;
+ public float xDpi;
+ public float yDpi;
+ public boolean secure;
+
+ public PhysicalDisplayInfo() {
+ }
+
+ public PhysicalDisplayInfo(PhysicalDisplayInfo other) {
+ copyFrom(other);
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return o instanceof PhysicalDisplayInfo && equals((PhysicalDisplayInfo)o);
+ }
+
+ public boolean equals(PhysicalDisplayInfo other) {
+ return other != null
+ && width == other.width
+ && height == other.height
+ && refreshRate == other.refreshRate
+ && density == other.density
+ && xDpi == other.xDpi
+ && yDpi == other.yDpi
+ && secure == other.secure;
+ }
+
+ @Override
+ public int hashCode() {
+ return 0; // don't care
+ }
+
+ public void copyFrom(PhysicalDisplayInfo other) {
+ width = other.width;
+ height = other.height;
+ refreshRate = other.refreshRate;
+ density = other.density;
+ xDpi = other.xDpi;
+ yDpi = other.yDpi;
+ secure = other.secure;
+ }
+
+ // For debugging purposes
+ @Override
+ public String toString() {
+ return "PhysicalDisplayInfo{" + width + " x " + height + ", " + refreshRate + " fps, "
+ + "density " + density + ", " + xDpi + " x " + yDpi + " dpi, secure " + secure
+ + "}";
+ }
+ }
+
+ public static void unblankDisplay(IBinder displayToken) {
+ if (displayToken == null) {
+ throw new IllegalArgumentException("displayToken must not be null");
+ }
+ nativeUnblankDisplay(displayToken);
+ }
+
+ public static void blankDisplay(IBinder displayToken) {
+ if (displayToken == null) {
+ throw new IllegalArgumentException("displayToken must not be null");
+ }
+ nativeBlankDisplay(displayToken);
+ }
+
+ public static boolean getDisplayInfo(IBinder displayToken, SurfaceControl.PhysicalDisplayInfo outInfo) {
+ if (displayToken == null) {
+ throw new IllegalArgumentException("displayToken must not be null");
+ }
+ if (outInfo == null) {
+ throw new IllegalArgumentException("outInfo must not be null");
+ }
+ return nativeGetDisplayInfo(displayToken, outInfo);
+ }
+
+ public static void setDisplayProjection(IBinder displayToken,
+ int orientation, Rect layerStackRect, Rect displayRect) {
+ if (displayToken == null) {
+ throw new IllegalArgumentException("displayToken must not be null");
+ }
+ if (layerStackRect == null) {
+ throw new IllegalArgumentException("layerStackRect must not be null");
+ }
+ if (displayRect == null) {
+ throw new IllegalArgumentException("displayRect must not be null");
+ }
+ nativeSetDisplayProjection(displayToken, orientation,
+ layerStackRect.left, layerStackRect.top, layerStackRect.right, layerStackRect.bottom,
+ displayRect.left, displayRect.top, displayRect.right, displayRect.bottom);
+ }
+
+ public static void setDisplayLayerStack(IBinder displayToken, int layerStack) {
+ if (displayToken == null) {
+ throw new IllegalArgumentException("displayToken must not be null");
+ }
+ nativeSetDisplayLayerStack(displayToken, layerStack);
+ }
+
+ public static void setDisplaySurface(IBinder displayToken, Surface surface) {
+ if (displayToken == null) {
+ throw new IllegalArgumentException("displayToken must not be null");
+ }
+ if (surface == null) {
+ throw new IllegalArgumentException("surface must not be null");
+ }
+ if (surface.mNativeObject == 0)
+ throw new NullPointerException("Surface native object is null. Are you using a released surface?");
+
+ nativeSetDisplaySurface(displayToken, surface.mNativeObject);
+ }
+
+ public static IBinder createDisplay(String name, boolean secure) {
+ if (name == null) {
+ throw new IllegalArgumentException("name must not be null");
+ }
+ return nativeCreateDisplay(name, secure);
+ }
+
+ public static IBinder getBuiltInDisplay(int builtInDisplayId) {
+ return nativeGetBuiltInDisplay(builtInDisplayId);
+ }
+
+
+ /**
+ * Copy the current screen contents into a bitmap and return it.
+ *
+ * @param width The desired width of the returned bitmap; the raw
+ * screen will be scaled down to this size.
+ * @param height The desired height of the returned bitmap; the raw
+ * screen will be scaled down to this size.
+ * @param minLayer The lowest (bottom-most Z order) surface layer to
+ * include in the screenshot.
+ * @param maxLayer The highest (top-most Z order) surface layer to
+ * include in the screenshot.
+ * @return Returns a Bitmap containing the screen contents, or null
+ * if an error occurs.
+ *
+ */
+ public static Bitmap screenshot(int width, int height, int minLayer, int maxLayer) {
+ // TODO: should take the display as a parameter
+ IBinder displayToken = SurfaceControl.getBuiltInDisplay(SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
+ return nativeScreenshot(displayToken, width, height, minLayer, maxLayer, false);
+ }
+
+ /**
+ * Like {@link SurfaceControl#screenshot(int, int, int, int)} but includes all
+ * Surfaces in the screenshot.
+ *
+ */
+ public static Bitmap screenshot(int width, int height) {
+ // TODO: should take the display as a parameter
+ IBinder displayToken = SurfaceControl.getBuiltInDisplay(SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN);
+ return nativeScreenshot(displayToken, width, height, 0, 0, true);
+ }
+
+ private static void checkHeadless() {
+ if (HEADLESS) {
+ throw new UnsupportedOperationException("Device is headless");
+ }
+ }
+
+
+
+ private native int nativeCreate(SurfaceSession session, String name,
+ int w, int h, int format, int flags)
+ throws OutOfResourcesException;
+ private native void nativeRelease(int nativeObject);
+ private native void nativeDestroy(int nativeObject);
+
+ private static native Bitmap nativeScreenshot(IBinder displayToken,
+ int width, int height, int minLayer, int maxLayer, boolean allLayers);
+
+ private static native void nativeOpenTransaction();
+ private static native void nativeCloseTransaction();
+ private static native void nativeSetAnimationTransaction();
+
+ private native void nativeSetLayer(int nativeObject, int zorder);
+ private native void nativeSetPosition(int nativeObject, float x, float y);
+ private native void nativeSetSize(int nativeObject, int w, int h);
+ private native void nativeSetTransparentRegionHint(int nativeObject, Region region);
+ private native void nativeSetAlpha(int nativeObject, float alpha);
+ private native void nativeSetMatrix(int nativeObject, float dsdx, float dtdx, float dsdy, float dtdy);
+ private native void nativeSetFlags(int nativeObject, int flags, int mask);
+ private native void nativeSetWindowCrop(int nativeObject, int l, int t, int r, int b);
+ private native void nativeSetLayerStack(int nativeObject, int layerStack);
+
+ private static native IBinder nativeGetBuiltInDisplay(int physicalDisplayId);
+ private static native IBinder nativeCreateDisplay(String name, boolean secure);
+ private static native void nativeSetDisplaySurface(
+ IBinder displayToken, int nativeSurfaceObject);
+ private static native void nativeSetDisplayLayerStack(
+ IBinder displayToken, int layerStack);
+ private static native void nativeSetDisplayProjection(
+ IBinder displayToken, int orientation,
+ int l, int t, int r, int b,
+ int L, int T, int R, int B);
+ private static native boolean nativeGetDisplayInfo(
+ IBinder displayToken, SurfaceControl.PhysicalDisplayInfo outInfo);
+ private static native void nativeBlankDisplay(IBinder displayToken);
+ private static native void nativeUnblankDisplay(IBinder displayToken);
+}
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index d705024..f47865e 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -42,6 +42,7 @@ LOCAL_SRC_FILES:= \
android_emoji_EmojiFactory.cpp \
android_view_DisplayEventReceiver.cpp \
android_view_Surface.cpp \
+ android_view_SurfaceControl.cpp \
android_view_SurfaceSession.cpp \
android_view_TextureView.cpp \
android_view_InputChannel.cpp \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index 94324f8..74fd391 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -47,8 +47,6 @@
using namespace android;
-extern void register_BindTest();
-
extern int register_android_os_Binder(JNIEnv* env);
extern int register_android_os_Process(JNIEnv* env);
extern int register_android_graphics_Bitmap(JNIEnv*);
@@ -121,6 +119,7 @@ extern int register_android_view_GLES20DisplayList(JNIEnv* env);
extern int register_android_view_GLES20Canvas(JNIEnv* env);
extern int register_android_view_HardwareRenderer(JNIEnv* env);
extern int register_android_view_Surface(JNIEnv* env);
+extern int register_android_view_SurfaceControl(JNIEnv* env);
extern int register_android_view_SurfaceSession(JNIEnv* env);
extern int register_android_view_TextureView(JNIEnv* env);
extern int register_android_database_CursorWindow(JNIEnv* env);
@@ -1112,6 +1111,7 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_view_GLES20Canvas),
REG_JNI(register_android_view_HardwareRenderer),
REG_JNI(register_android_view_Surface),
+ REG_JNI(register_android_view_SurfaceControl),
REG_JNI(register_android_view_SurfaceSession),
REG_JNI(register_android_view_TextureView),
REG_JNI(register_com_google_android_gles_jni_EGLImpl),
diff --git a/core/jni/android_hardware_Camera.cpp b/core/jni/android_hardware_Camera.cpp
index 0e0893b..7c65662 100644
--- a/core/jni/android_hardware_Camera.cpp
+++ b/core/jni/android_hardware_Camera.cpp
@@ -23,6 +23,7 @@
#include "JNIHelp.h"
#include "android_runtime/AndroidRuntime.h"
#include <android_runtime/android_graphics_SurfaceTexture.h>
+#include <android_runtime/android_view_Surface.h>
#include <cutils/properties.h>
#include <utils/Vector.h>
@@ -36,7 +37,6 @@ using namespace android;
struct fields_t {
jfieldID context;
- jfieldID surface;
jfieldID facing;
jfieldID orientation;
jfieldID canDisableShutterSound;
@@ -537,10 +537,8 @@ static void android_hardware_Camera_setPreviewDisplay(JNIEnv *env, jobject thiz,
sp<Camera> camera = get_native_camera(env, thiz, NULL);
if (camera == 0) return;
- sp<Surface> surface = NULL;
- if (jSurface != NULL) {
- surface = reinterpret_cast<Surface*>(env->GetIntField(jSurface, fields.surface));
- }
+ sp<Surface> surface = android_view_Surface_getSurface(env, jSurface);
+
if (camera->setPreviewDisplay(surface) != NO_ERROR) {
jniThrowException(env, "java/io/IOException", "setPreviewDisplay failed");
}
@@ -965,7 +963,6 @@ int register_android_hardware_Camera(JNIEnv *env)
{
field fields_to_find[] = {
{ "android/hardware/Camera", "mNativeContext", "I", &fields.context },
- { "android/view/Surface", ANDROID_VIEW_SURFACE_JNI_ID, "I", &fields.surface },
{ "android/hardware/Camera$CameraInfo", "facing", "I", &fields.facing },
{ "android/hardware/Camera$CameraInfo", "orientation", "I", &fields.orientation },
{ "android/hardware/Camera$CameraInfo", "canDisableShutterSound", "Z",
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 40b505c..6f71868 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -18,41 +18,30 @@
#include <stdio.h>
+#include "jni.h"
+#include "JNIHelp.h"
#include "android_os_Parcel.h"
-#include "android_util_Binder.h"
#include "android/graphics/GraphicsJNI.h"
-#include "android/graphics/Region.h"
-#include <binder/IMemory.h>
+#include <android_runtime/AndroidRuntime.h>
+#include <android_runtime/android_view_Surface.h>
+#include <android_runtime/android_graphics_SurfaceTexture.h>
-#include <gui/ISurfaceComposer.h>
#include <gui/Surface.h>
-#include <gui/SurfaceComposerClient.h>
#include <gui/GLConsumer.h>
-#include <ui/DisplayInfo.h>
#include <ui/Rect.h>
#include <ui/Region.h>
-#include <EGL/egl.h>
-
#include <SkCanvas.h>
#include <SkBitmap.h>
#include <SkRegion.h>
-#include <SkPixelRef.h>
-#include "jni.h"
-#include "JNIHelp.h"
-#include <android_runtime/AndroidRuntime.h>
-#include <android_runtime/android_view_Surface.h>
-#include <android_runtime/android_view_SurfaceSession.h>
-#include <android_runtime/android_graphics_SurfaceTexture.h>
#include <utils/misc.h>
#include <utils/Log.h>
#include <ScopedUtfChars.h>
-
// ----------------------------------------------------------------------------
namespace android {
@@ -62,8 +51,7 @@ static const char* const OutOfResourcesException =
static struct {
jclass clazz;
- jfieldID mNativeSurface;
- jfieldID mNativeSurfaceControl;
+ jfieldID mNativeObject;
jfieldID mGenerationId;
jfieldID mCanvas;
jfieldID mCanvasSaveCount;
@@ -82,166 +70,19 @@ static struct {
jfieldID mSurfaceFormat;
} gCanvasClassInfo;
-static struct {
- jfieldID width;
- jfieldID height;
- jfieldID refreshRate;
- jfieldID density;
- jfieldID xDpi;
- jfieldID yDpi;
- jfieldID secure;
-} gPhysicalDisplayInfoClassInfo;
-
-
-class ScreenshotPixelRef : public SkPixelRef {
-public:
- ScreenshotPixelRef(SkColorTable* ctable) {
- fCTable = ctable;
- SkSafeRef(ctable);
- setImmutable();
- }
-
- virtual ~ScreenshotPixelRef() {
- SkSafeUnref(fCTable);
- }
-
- status_t update(const sp<IBinder>& display, int width, int height,
- int minLayer, int maxLayer, bool allLayers) {
- status_t res = (width > 0 && height > 0)
- ? (allLayers
- ? mScreenshot.update(display, width, height)
- : mScreenshot.update(display, width, height, minLayer, maxLayer))
- : mScreenshot.update(display);
- if (res != NO_ERROR) {
- return res;
- }
-
- return NO_ERROR;
- }
-
- uint32_t getWidth() const {
- return mScreenshot.getWidth();
- }
-
- uint32_t getHeight() const {
- return mScreenshot.getHeight();
- }
-
- uint32_t getStride() const {
- return mScreenshot.getStride();
- }
-
- uint32_t getFormat() const {
- return mScreenshot.getFormat();
- }
-
-protected:
- // overrides from SkPixelRef
- virtual void* onLockPixels(SkColorTable** ct) {
- *ct = fCTable;
- return (void*)mScreenshot.getPixels();
- }
-
- virtual void onUnlockPixels() {
- }
-
-private:
- ScreenshotClient mScreenshot;
- SkColorTable* fCTable;
-
- typedef SkPixelRef INHERITED;
-};
-
-
// ----------------------------------------------------------------------------
-static sp<SurfaceControl> getSurfaceControl(JNIEnv* env, jobject surfaceObj) {
- return reinterpret_cast<SurfaceControl*>(
- env->GetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurfaceControl));
-}
-
-static void setSurfaceControl(JNIEnv* env, jobject surfaceObj,
- const sp<SurfaceControl>& surface) {
- SurfaceControl* const p = reinterpret_cast<SurfaceControl*>(
- env->GetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurfaceControl));
- if (surface.get()) {
- surface->incStrong(surfaceObj);
- }
- if (p) {
- p->decStrong(surfaceObj);
- }
- env->SetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurfaceControl,
- reinterpret_cast<jint>(surface.get()));
-}
-
-static sp<Surface> getSurface(JNIEnv* env, jobject surfaceObj) {
- sp<Surface> result(android_view_Surface_getSurface(env, surfaceObj));
- if (result == NULL) {
- /*
- * if this method is called from the WindowManager's process, it means
- * the client is is not remote, and therefore is allowed to have
- * a Surface (data), so we create it here.
- * If we don't have a SurfaceControl, it means we're in a different
- * process.
- */
-
- SurfaceControl* const control = reinterpret_cast<SurfaceControl*>(
- env->GetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurfaceControl));
- if (control) {
- result = control->getSurface();
- if (result != NULL) {
- result->incStrong(surfaceObj);
- env->SetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurface,
- reinterpret_cast<jint>(result.get()));
- }
- }
- }
- return result;
-}
-
-sp<ANativeWindow> android_view_Surface_getNativeWindow(JNIEnv* env, jobject surfaceObj) {
- return getSurface(env, surfaceObj);
-}
-
bool android_view_Surface_isInstanceOf(JNIEnv* env, jobject obj) {
return env->IsInstanceOf(obj, gSurfaceClassInfo.clazz);
}
-sp<Surface> android_view_Surface_getSurface(JNIEnv* env, jobject surfaceObj) {
- return reinterpret_cast<Surface*>(
- env->GetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurface));
-}
-
-static void setSurface(JNIEnv* env, jobject surfaceObj, const sp<Surface>& surface) {
- Surface* const p = reinterpret_cast<Surface*>(
- env->GetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurface));
- if (surface.get()) {
- surface->incStrong(surfaceObj);
- }
- if (p) {
- p->decStrong(surfaceObj);
- }
- env->SetIntField(surfaceObj, gSurfaceClassInfo.mNativeSurface,
- reinterpret_cast<jint>(surface.get()));
-
- // This test is conservative and it would be better to compare the ISurfaces
- if (p && p != surface.get()) {
- jint generationId = env->GetIntField(surfaceObj,
- gSurfaceClassInfo.mGenerationId);
- generationId++;
- env->SetIntField(surfaceObj,
- gSurfaceClassInfo.mGenerationId, generationId);
- }
+sp<ANativeWindow> android_view_Surface_getNativeWindow(JNIEnv* env, jobject surfaceObj) {
+ return android_view_Surface_getSurface(env, surfaceObj);
}
-static sp<IGraphicBufferProducer> getISurfaceTexture(JNIEnv* env, jobject surfaceObj) {
- if (surfaceObj) {
- sp<Surface> surface(getSurface(env, surfaceObj));
- if (surface != NULL) {
- return surface->getSurfaceTexture();
- }
- }
- return NULL;
+sp<Surface> android_view_Surface_getSurface(JNIEnv* env, jobject surfaceObj) {
+ return reinterpret_cast<Surface *>(
+ env->GetIntField(surfaceObj, gSurfaceClassInfo.mNativeObject));
}
jobject android_view_Surface_createFromISurfaceTexture(JNIEnv* env,
@@ -255,7 +96,7 @@ jobject android_view_Surface_createFromISurfaceTexture(JNIEnv* env,
return NULL;
}
- jobject surfaceObj = env->NewObject(gSurfaceClassInfo.clazz, gSurfaceClassInfo.ctor);
+ jobject surfaceObj = env->NewObject(gSurfaceClassInfo.clazz, gSurfaceClassInfo.ctor, surface.get());
if (surfaceObj == NULL) {
if (env->ExceptionCheck()) {
ALOGE("Could not create instance of Surface from IGraphicBufferProducer.");
@@ -264,82 +105,55 @@ jobject android_view_Surface_createFromISurfaceTexture(JNIEnv* env,
}
return NULL;
}
-
- setSurface(env, surfaceObj, surface);
+ surface->incStrong(surfaceObj);
return surfaceObj;
}
-
// ----------------------------------------------------------------------------
-static void nativeCreate(JNIEnv* env, jobject surfaceObj, jobject sessionObj,
- jstring nameStr, jint w, jint h, jint format, jint flags) {
- ScopedUtfChars name(env, nameStr);
- sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj));
-
- sp<SurfaceControl> surface = client->createSurface(
- String8(name.c_str()), w, h, format, flags);
- if (surface == NULL) {
- jniThrowException(env, OutOfResourcesException, NULL);
- return;
- }
-
- setSurfaceControl(env, surfaceObj, surface);
-}
-
-static void nativeCreateFromSurfaceTexture(JNIEnv* env, jobject surfaceObj,
+static jint nativeCreateFromSurfaceTexture(JNIEnv* env, jobject surfaceObj,
jobject surfaceTextureObj) {
sp<GLConsumer> st(SurfaceTexture_getSurfaceTexture(env, surfaceTextureObj));
if (st == NULL) {
jniThrowException(env, "java/lang/IllegalArgumentException",
"SurfaceTexture has already been released");
- return;
+ return 0;
}
sp<IGraphicBufferProducer> bq = st->getBufferQueue();
-
sp<Surface> surface(new Surface(bq));
if (surface == NULL) {
jniThrowException(env, OutOfResourcesException, NULL);
- return;
+ return 0;
}
- setSurface(env, surfaceObj, surface);
+ surface->incStrong(surfaceObj);
+ return int(surface.get());
}
-static void nativeRelease(JNIEnv* env, jobject surfaceObj) {
- setSurfaceControl(env, surfaceObj, NULL);
- setSurface(env, surfaceObj, NULL);
+static void nativeRelease(JNIEnv* env, jobject surfaceObj, jint nativeObject) {
+ sp<Surface> sur(reinterpret_cast<Surface *>(nativeObject));
+ sur->decStrong(surfaceObj);
}
-static void nativeDestroy(JNIEnv* env, jobject surfaceObj) {
- sp<SurfaceControl> surfaceControl(getSurfaceControl(env, surfaceObj));
- if (SurfaceControl::isValid(surfaceControl)) {
- surfaceControl->clear();
- }
- setSurfaceControl(env, surfaceObj, NULL);
- setSurface(env, surfaceObj, NULL);
+static void nativeDestroy(JNIEnv* env, jobject surfaceObj, jint nativeObject) {
+ sp<Surface> sur(reinterpret_cast<Surface *>(nativeObject));
+ sur->decStrong(surfaceObj);
}
-static jboolean nativeIsValid(JNIEnv* env, jobject surfaceObj) {
- sp<SurfaceControl> surfaceControl(getSurfaceControl(env, surfaceObj));
- if (surfaceControl != NULL) {
- return SurfaceControl::isValid(surfaceControl) ? JNI_TRUE : JNI_FALSE;
- }
-
- sp<Surface> surface(getSurface(env, surfaceObj));
- return Surface::isValid(surface) ? JNI_TRUE : JNI_FALSE;
+static jboolean nativeIsValid(JNIEnv* env, jobject surfaceObj, jint nativeObject) {
+ sp<Surface> sur(reinterpret_cast<Surface *>(nativeObject));
+ return Surface::isValid(sur) ? JNI_TRUE : JNI_FALSE;
}
-static jboolean nativeIsConsumerRunningBehind(JNIEnv* env, jobject surfaceObj) {
- sp<Surface> surface(getSurface(env, surfaceObj));
- if (!Surface::isValid(surface)) {
+static jboolean nativeIsConsumerRunningBehind(JNIEnv* env, jobject surfaceObj, jint nativeObject) {
+ sp<Surface> sur(reinterpret_cast<Surface *>(nativeObject));
+ if (!Surface::isValid(sur)) {
doThrowIAE(env);
return JNI_FALSE;
}
-
int value = 0;
- ANativeWindow* anw = static_cast<ANativeWindow*>(surface.get());
+ ANativeWindow* anw = static_cast<ANativeWindow*>(sur.get());
anw->query(anw, NATIVE_WINDOW_CONSUMER_RUNNING_BEHIND, &value);
return value;
}
@@ -359,8 +173,9 @@ static inline SkBitmap::Config convertPixelFormat(PixelFormat format) {
}
}
-static jobject nativeLockCanvas(JNIEnv* env, jobject surfaceObj, jobject dirtyRectObj) {
- sp<Surface> surface(getSurface(env, surfaceObj));
+static jobject nativeLockCanvas(JNIEnv* env, jobject surfaceObj, jint nativeObject, jobject dirtyRectObj) {
+ sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));
+
if (!Surface::isValid(surface)) {
doThrowIAE(env);
return NULL;
@@ -440,14 +255,14 @@ static jobject nativeLockCanvas(JNIEnv* env, jobject surfaceObj, jobject dirtyRe
return canvasObj;
}
-static void nativeUnlockCanvasAndPost(JNIEnv* env, jobject surfaceObj, jobject canvasObj) {
+static void nativeUnlockCanvasAndPost(JNIEnv* env, jobject surfaceObj, jint nativeObject, jobject canvasObj) {
jobject ownCanvasObj = env->GetObjectField(surfaceObj, gSurfaceClassInfo.mCanvas);
if (!env->IsSameObject(ownCanvasObj, canvasObj)) {
doThrowIAE(env);
return;
}
- sp<Surface> surface(getSurface(env, surfaceObj));
+ sp<Surface> surface(reinterpret_cast<Surface *>(nativeObject));
if (!Surface::isValid(surface)) {
return;
}
@@ -467,393 +282,81 @@ static void nativeUnlockCanvasAndPost(JNIEnv* env, jobject surfaceObj, jobject c
}
}
-static jobject nativeScreenshot(JNIEnv* env, jclass clazz, jobject displayTokenObj,
- jint width, jint height, jint minLayer, jint maxLayer, bool allLayers) {
- sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
- if (displayToken == NULL) {
- return NULL;
- }
-
- ScreenshotPixelRef* pixels = new ScreenshotPixelRef(NULL);
- if (pixels->update(displayToken, width, height,
- minLayer, maxLayer, allLayers) != NO_ERROR) {
- delete pixels;
- return NULL;
- }
-
- uint32_t w = pixels->getWidth();
- uint32_t h = pixels->getHeight();
- uint32_t s = pixels->getStride();
- uint32_t f = pixels->getFormat();
- ssize_t bpr = s * android::bytesPerPixel(f);
-
- SkBitmap* bitmap = new SkBitmap();
- bitmap->setConfig(convertPixelFormat(f), w, h, bpr);
- if (f == PIXEL_FORMAT_RGBX_8888) {
- bitmap->setIsOpaque(true);
- }
-
- if (w > 0 && h > 0) {
- bitmap->setPixelRef(pixels)->unref();
- bitmap->lockPixels();
- } else {
- // be safe with an empty bitmap.
- delete pixels;
- bitmap->setPixels(NULL);
- }
-
- return GraphicsJNI::createBitmap(env, bitmap, false, NULL);
-}
-
-static void nativeOpenTransaction(JNIEnv* env, jclass clazz) {
- SurfaceComposerClient::openGlobalTransaction();
-}
-
-static void nativeCloseTransaction(JNIEnv* env, jclass clazz) {
- SurfaceComposerClient::closeGlobalTransaction();
-}
-
-static void nativeSetAnimationTransaction(JNIEnv* env, jclass clazz) {
- SurfaceComposerClient::setAnimationTransaction();
-}
-
-static void nativeSetLayer(JNIEnv* env, jobject surfaceObj, jint zorder) {
- sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj));
- if (surface == NULL) return;
-
- status_t err = surface->setLayer(zorder);
- if (err < 0 && err != NO_INIT) {
- doThrowIAE(env);
- }
-}
-
-static void nativeSetPosition(JNIEnv* env, jobject surfaceObj, jfloat x, jfloat y) {
- sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj));
- if (surface == NULL) return;
-
- status_t err = surface->setPosition(x, y);
- if (err < 0 && err != NO_INIT) {
- doThrowIAE(env);
- }
-}
-
-static void nativeSetSize(JNIEnv* env, jobject surfaceObj, jint w, jint h) {
- sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj));
- if (surface == NULL) return;
-
- status_t err = surface->setSize(w, h);
- if (err < 0 && err != NO_INIT) {
- doThrowIAE(env);
- }
-}
-
-static void nativeSetFlags(JNIEnv* env, jobject surfaceObj, jint flags, jint mask) {
- sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj));
- if (surface == NULL) return;
-
- status_t err = surface->setFlags(flags, mask);
- if (err < 0 && err != NO_INIT) {
- doThrowIAE(env);
- }
-}
-
-static void nativeSetTransparentRegionHint(JNIEnv* env, jobject surfaceObj, jobject regionObj) {
- sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj));
- if (surface == NULL) return;
-
- SkRegion* region = android_graphics_Region_getSkRegion(env, regionObj);
- if (!region) {
- doThrowIAE(env);
- return;
- }
-
- const SkIRect& b(region->getBounds());
- Region reg(Rect(b.fLeft, b.fTop, b.fRight, b.fBottom));
- if (region->isComplex()) {
- SkRegion::Iterator it(*region);
- while (!it.done()) {
- const SkIRect& r(it.rect());
- reg.addRectUnchecked(r.fLeft, r.fTop, r.fRight, r.fBottom);
- it.next();
- }
- }
-
- status_t err = surface->setTransparentRegionHint(reg);
- if (err < 0 && err != NO_INIT) {
- doThrowIAE(env);
- }
-}
-
-static void nativeSetAlpha(JNIEnv* env, jobject surfaceObj, jfloat alpha) {
- sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj));
- if (surface == NULL) return;
-
- status_t err = surface->setAlpha(alpha);
- if (err < 0 && err != NO_INIT) {
- doThrowIAE(env);
- }
-}
-
-static void nativeSetMatrix(JNIEnv* env, jobject surfaceObj,
- jfloat dsdx, jfloat dtdx, jfloat dsdy, jfloat dtdy) {
- sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj));
- if (surface == NULL) return;
-
- status_t err = surface->setMatrix(dsdx, dtdx, dsdy, dtdy);
- if (err < 0 && err != NO_INIT) {
- doThrowIAE(env);
- }
-}
-
-static void nativeSetWindowCrop(JNIEnv* env, jobject surfaceObj, jobject cropObj) {
- const sp<SurfaceControl>& surface(getSurfaceControl(env, surfaceObj));
- if (surface == NULL) return;
-
- Rect crop;
- if (cropObj) {
- crop.left = env->GetIntField(cropObj, gRectClassInfo.left);
- crop.top = env->GetIntField(cropObj, gRectClassInfo.top);
- crop.right = env->GetIntField(cropObj, gRectClassInfo.right);
- crop.bottom = env->GetIntField(cropObj, gRectClassInfo.bottom);
- } else {
- crop.left = crop.top = crop.right = crop.bottom = 0;
- }
-
- status_t err = surface->setCrop(crop);
- if (err < 0 && err != NO_INIT) {
- doThrowIAE(env);
- }
-}
-
-static void nativeSetLayerStack(JNIEnv* env, jobject surfaceObj, jint layerStack) {
- sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj));
- if (surface == NULL) return;
-
- status_t err = surface->setLayerStack(layerStack);
- if (err < 0 && err != NO_INIT) {
- doThrowIAE(env);
- }
-}
-
-static jobject nativeGetBuiltInDisplay(JNIEnv* env, jclass clazz, jint id) {
- sp<IBinder> token(SurfaceComposerClient::getBuiltInDisplay(id));
- return javaObjectForIBinder(env, token);
-}
-
-static jobject nativeCreateDisplay(JNIEnv* env, jclass clazz, jstring nameObj,
- jboolean secure) {
- ScopedUtfChars name(env, nameObj);
- sp<IBinder> token(SurfaceComposerClient::createDisplay(
- String8(name.c_str()), bool(secure)));
- return javaObjectForIBinder(env, token);
-}
-
-static void nativeSetDisplaySurface(JNIEnv* env, jclass clazz,
- jobject tokenObj, jobject surfaceObj) {
- sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
- if (token == NULL) return;
-
- sp<IGraphicBufferProducer> bufferProducer(getISurfaceTexture(env, surfaceObj));
- SurfaceComposerClient::setDisplaySurface(token, bufferProducer);
-}
-
-static void nativeSetDisplayLayerStack(JNIEnv* env, jclass clazz,
- jobject tokenObj, jint layerStack) {
- sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
- if (token == NULL) return;
-
- SurfaceComposerClient::setDisplayLayerStack(token, layerStack);
-}
-
-static void nativeSetDisplayProjection(JNIEnv* env, jclass clazz,
- jobject tokenObj, jint orientation, jobject layerStackRectObj, jobject displayRectObj) {
- sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
- if (token == NULL) return;
-
- Rect layerStackRect;
- layerStackRect.left = env->GetIntField(layerStackRectObj, gRectClassInfo.left);
- layerStackRect.top = env->GetIntField(layerStackRectObj, gRectClassInfo.top);
- layerStackRect.right = env->GetIntField(layerStackRectObj, gRectClassInfo.right);
- layerStackRect.bottom = env->GetIntField(layerStackRectObj, gRectClassInfo.bottom);
-
- Rect displayRect;
- displayRect.left = env->GetIntField(displayRectObj, gRectClassInfo.left);
- displayRect.top = env->GetIntField(displayRectObj, gRectClassInfo.top);
- displayRect.right = env->GetIntField(displayRectObj, gRectClassInfo.right);
- displayRect.bottom = env->GetIntField(displayRectObj, gRectClassInfo.bottom);
-
- SurfaceComposerClient::setDisplayProjection(token, orientation, layerStackRect, displayRect);
-}
-
-static jboolean nativeGetDisplayInfo(JNIEnv* env, jclass clazz,
- jobject tokenObj, jobject infoObj) {
- sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
- if (token == NULL) return JNI_FALSE;
-
- DisplayInfo info;
- if (SurfaceComposerClient::getDisplayInfo(token, &info)) {
- return JNI_FALSE;
- }
-
- env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.width, info.w);
- env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.height, info.h);
- env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.refreshRate, info.fps);
- env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.density, info.density);
- env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.xDpi, info.xdpi);
- env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.yDpi, info.ydpi);
- env->SetBooleanField(infoObj, gPhysicalDisplayInfoClassInfo.secure, info.secure);
- return JNI_TRUE;
-}
-
-static void nativeBlankDisplay(JNIEnv* env, jclass clazz, jobject tokenObj) {
- sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
- if (token == NULL) return;
-
- ALOGD_IF_SLOW(100, "Excessive delay in blankDisplay() while turning screen off");
- SurfaceComposerClient::blankDisplay(token);
-}
-
-static void nativeUnblankDisplay(JNIEnv* env, jclass clazz, jobject tokenObj) {
- sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
- if (token == NULL) return;
-
- ALOGD_IF_SLOW(100, "Excessive delay in unblankDisplay() while turning screen on");
- SurfaceComposerClient::unblankDisplay(token);
-}
-
// ----------------------------------------------------------------------------
-static void nativeCopyFrom(JNIEnv* env, jobject surfaceObj, jobject otherObj) {
+static jint nativeCopyFrom(JNIEnv* env, jobject surfaceObj,
+ jint nativeObject, jint surfaceControlNativeObj) {
/*
* This is used by the WindowManagerService just after constructing
* a Surface and is necessary for returning the Surface reference to
* the caller. At this point, we should only have a SurfaceControl.
*/
- sp<SurfaceControl> surface(getSurfaceControl(env, surfaceObj));
- sp<SurfaceControl> other(getSurfaceControl(env, otherObj));
- if (!SurfaceControl::isSameSurface(surface, other)) {
- // we reassign the surface only if it's a different one
- // otherwise we would loose our client-side state.
- setSurfaceControl(env, surfaceObj, other);
+ sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(surfaceControlNativeObj));
+ sp<Surface> other(ctrl->getSurface());
+ if (other != NULL) {
+ other->incStrong(surfaceObj);
+ }
+
+ sp<Surface> sur(reinterpret_cast<Surface *>(nativeObject));
+ if (sur != NULL) {
+ sur->decStrong(surfaceObj);
}
-}
-static void nativeTransferFrom(JNIEnv* env, jobject surfaceObj, jobject otherObj) {
- sp<SurfaceControl> control(getSurfaceControl(env, otherObj));
- sp<Surface> surface(android_view_Surface_getSurface(env, otherObj));
- setSurfaceControl(env, surfaceObj, control);
- setSurface(env, surfaceObj, surface);
- setSurfaceControl(env, otherObj, NULL);
- setSurface(env, otherObj, NULL);
+ return int(other.get());
}
-static void nativeReadFromParcel(JNIEnv* env, jobject surfaceObj, jobject parcelObj) {
+static jint nativeReadFromParcel(JNIEnv* env, jobject surfaceObj,
+ jint nativeObject, jobject parcelObj) {
Parcel* parcel = parcelForJavaObject(env, parcelObj);
if (parcel == NULL) {
doThrowNPE(env);
- return;
+ return 0;
}
-
- sp<Surface> surface(Surface::readFromParcel(*parcel));
- setSurfaceControl(env, surfaceObj, NULL);
- setSurface(env, surfaceObj, surface);
+ sp<Surface> self(reinterpret_cast<Surface *>(nativeObject));
+ if (self != NULL) {
+ self->decStrong(surfaceObj);
+ }
+ sp<Surface> sur(Surface::readFromParcel(*parcel));
+ if (sur != NULL) {
+ sur->incStrong(surfaceObj);
+ }
+ return int(sur.get());
}
-static void nativeWriteToParcel(JNIEnv* env, jobject surfaceObj, jobject parcelObj) {
+static void nativeWriteToParcel(JNIEnv* env, jobject surfaceObj,
+ jint nativeObject, jobject parcelObj) {
Parcel* parcel = parcelForJavaObject(env, parcelObj);
if (parcel == NULL) {
doThrowNPE(env);
return;
}
-
- // The Java instance may have a SurfaceControl (in the case of the
- // WindowManager or a system app). In that case, we defer to the
- // SurfaceControl to send its ISurface. Otherwise, if the Surface is
- // available we let it parcel itself. Finally, if the Surface is also
- // NULL we fall back to using the SurfaceControl path which sends an
- // empty surface; this matches legacy behavior.
- sp<SurfaceControl> control(getSurfaceControl(env, surfaceObj));
- if (control != NULL) {
- SurfaceControl::writeSurfaceToParcel(control, parcel);
- } else {
- sp<Surface> surface(android_view_Surface_getSurface(env, surfaceObj));
- if (surface != NULL) {
- Surface::writeToParcel(surface, parcel);
- } else {
- SurfaceControl::writeSurfaceToParcel(NULL, parcel);
- }
- }
+ sp<Surface> self(reinterpret_cast<Surface *>(nativeObject));
+ Surface::writeToParcel(self, parcel);
}
// ----------------------------------------------------------------------------
static JNINativeMethod gSurfaceMethods[] = {
- {"nativeCreate", "(Landroid/view/SurfaceSession;Ljava/lang/String;IIII)V",
- (void*)nativeCreate },
- {"nativeCreateFromSurfaceTexture", "(Landroid/graphics/SurfaceTexture;)V",
+ {"nativeCreateFromSurfaceTexture", "(Landroid/graphics/SurfaceTexture;)I",
(void*)nativeCreateFromSurfaceTexture },
- {"nativeRelease", "()V",
+ {"nativeRelease", "(I)V",
(void*)nativeRelease },
- {"nativeDestroy", "()V",
+ {"nativeDestroy", "(I)V",
(void*)nativeDestroy },
- {"nativeIsValid", "()Z",
+ {"nativeIsValid", "(I)Z",
(void*)nativeIsValid },
- {"nativeIsConsumerRunningBehind", "()Z",
+ {"nativeIsConsumerRunningBehind", "(I)Z",
(void*)nativeIsConsumerRunningBehind },
- {"nativeLockCanvas", "(Landroid/graphics/Rect;)Landroid/graphics/Canvas;",
+ {"nativeLockCanvas", "(ILandroid/graphics/Rect;)Landroid/graphics/Canvas;",
(void*)nativeLockCanvas },
- {"nativeUnlockCanvasAndPost", "(Landroid/graphics/Canvas;)V",
+ {"nativeUnlockCanvasAndPost", "(ILandroid/graphics/Canvas;)V",
(void*)nativeUnlockCanvasAndPost },
- {"nativeScreenshot", "(Landroid/os/IBinder;IIIIZ)Landroid/graphics/Bitmap;",
- (void*)nativeScreenshot },
- {"nativeOpenTransaction", "()V",
- (void*)nativeOpenTransaction },
- {"nativeCloseTransaction", "()V",
- (void*)nativeCloseTransaction },
- {"nativeSetAnimationTransaction", "()V",
- (void*)nativeSetAnimationTransaction },
- {"nativeSetLayer", "(I)V",
- (void*)nativeSetLayer },
- {"nativeSetPosition", "(FF)V",
- (void*)nativeSetPosition },
- {"nativeSetSize", "(II)V",
- (void*)nativeSetSize },
- {"nativeSetTransparentRegionHint", "(Landroid/graphics/Region;)V",
- (void*)nativeSetTransparentRegionHint },
- {"nativeSetAlpha", "(F)V",
- (void*)nativeSetAlpha },
- {"nativeSetMatrix", "(FFFF)V",
- (void*)nativeSetMatrix },
- {"nativeSetFlags", "(II)V",
- (void*)nativeSetFlags },
- {"nativeSetWindowCrop", "(Landroid/graphics/Rect;)V",
- (void*)nativeSetWindowCrop },
- {"nativeSetLayerStack", "(I)V",
- (void*)nativeSetLayerStack },
- {"nativeGetBuiltInDisplay", "(I)Landroid/os/IBinder;",
- (void*)nativeGetBuiltInDisplay },
- {"nativeCreateDisplay", "(Ljava/lang/String;Z)Landroid/os/IBinder;",
- (void*)nativeCreateDisplay },
- {"nativeSetDisplaySurface", "(Landroid/os/IBinder;Landroid/view/Surface;)V",
- (void*)nativeSetDisplaySurface },
- {"nativeSetDisplayLayerStack", "(Landroid/os/IBinder;I)V",
- (void*)nativeSetDisplayLayerStack },
- {"nativeSetDisplayProjection", "(Landroid/os/IBinder;ILandroid/graphics/Rect;Landroid/graphics/Rect;)V",
- (void*)nativeSetDisplayProjection },
- {"nativeGetDisplayInfo", "(Landroid/os/IBinder;Landroid/view/Surface$PhysicalDisplayInfo;)Z",
- (void*)nativeGetDisplayInfo },
- {"nativeBlankDisplay", "(Landroid/os/IBinder;)V",
- (void*)nativeBlankDisplay },
- {"nativeUnblankDisplay", "(Landroid/os/IBinder;)V",
- (void*)nativeUnblankDisplay },
- {"nativeCopyFrom", "(Landroid/view/Surface;)V",
+ {"nativeCopyFrom", "(II)I",
(void*)nativeCopyFrom },
- {"nativeTransferFrom", "(Landroid/view/Surface;)V",
- (void*)nativeTransferFrom },
- {"nativeReadFromParcel", "(Landroid/os/Parcel;)V",
+ {"nativeReadFromParcel", "(ILandroid/os/Parcel;)I",
(void*)nativeReadFromParcel },
- {"nativeWriteToParcel", "(Landroid/os/Parcel;)V",
+ {"nativeWriteToParcel", "(ILandroid/os/Parcel;)V",
(void*)nativeWriteToParcel },
};
@@ -864,17 +367,15 @@ int register_android_view_Surface(JNIEnv* env)
jclass clazz = env->FindClass("android/view/Surface");
gSurfaceClassInfo.clazz = jclass(env->NewGlobalRef(clazz));
- gSurfaceClassInfo.mNativeSurface =
- env->GetFieldID(gSurfaceClassInfo.clazz, ANDROID_VIEW_SURFACE_JNI_ID, "I");
- gSurfaceClassInfo.mNativeSurfaceControl =
- env->GetFieldID(gSurfaceClassInfo.clazz, "mNativeSurfaceControl", "I");
+ gSurfaceClassInfo.mNativeObject =
+ env->GetFieldID(gSurfaceClassInfo.clazz, "mNativeObject", "I");
gSurfaceClassInfo.mGenerationId =
env->GetFieldID(gSurfaceClassInfo.clazz, "mGenerationId", "I");
gSurfaceClassInfo.mCanvas =
env->GetFieldID(gSurfaceClassInfo.clazz, "mCanvas", "Landroid/graphics/Canvas;");
gSurfaceClassInfo.mCanvasSaveCount =
env->GetFieldID(gSurfaceClassInfo.clazz, "mCanvasSaveCount", "I");
- gSurfaceClassInfo.ctor = env->GetMethodID(gSurfaceClassInfo.clazz, "<init>", "()V");
+ gSurfaceClassInfo.ctor = env->GetMethodID(gSurfaceClassInfo.clazz, "<init>", "(I)V");
clazz = env->FindClass("android/graphics/Canvas");
gCanvasClassInfo.mNativeCanvas = env->GetFieldID(clazz, "mNativeCanvas", "I");
@@ -886,14 +387,6 @@ int register_android_view_Surface(JNIEnv* env)
gRectClassInfo.right = env->GetFieldID(clazz, "right", "I");
gRectClassInfo.bottom = env->GetFieldID(clazz, "bottom", "I");
- clazz = env->FindClass("android/view/Surface$PhysicalDisplayInfo");
- gPhysicalDisplayInfoClassInfo.width = env->GetFieldID(clazz, "width", "I");
- gPhysicalDisplayInfoClassInfo.height = env->GetFieldID(clazz, "height", "I");
- gPhysicalDisplayInfoClassInfo.refreshRate = env->GetFieldID(clazz, "refreshRate", "F");
- gPhysicalDisplayInfoClassInfo.density = env->GetFieldID(clazz, "density", "F");
- gPhysicalDisplayInfoClassInfo.xDpi = env->GetFieldID(clazz, "xDpi", "F");
- gPhysicalDisplayInfoClassInfo.yDpi = env->GetFieldID(clazz, "yDpi", "F");
- gPhysicalDisplayInfoClassInfo.secure = env->GetFieldID(clazz, "secure", "Z");
return err;
}
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
new file mode 100644
index 0000000..7398895
--- /dev/null
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -0,0 +1,451 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "SurfaceControl"
+
+#include <stdio.h>
+
+#include "jni.h"
+#include "JNIHelp.h"
+
+#include "android_os_Parcel.h"
+#include "android_util_Binder.h"
+#include "android/graphics/GraphicsJNI.h"
+#include "android/graphics/Region.h"
+
+#include <android_runtime/AndroidRuntime.h>
+#include <android_runtime/android_view_SurfaceSession.h>
+
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
+
+#include <ui/DisplayInfo.h>
+#include <ui/Rect.h>
+#include <ui/Region.h>
+
+#include <utils/Log.h>
+
+#include <ScopedUtfChars.h>
+
+// ----------------------------------------------------------------------------
+
+namespace android {
+
+static const char* const OutOfResourcesException =
+ "android/view/Surface$OutOfResourcesException";
+
+static struct {
+ jfieldID width;
+ jfieldID height;
+ jfieldID refreshRate;
+ jfieldID density;
+ jfieldID xDpi;
+ jfieldID yDpi;
+ jfieldID secure;
+} gPhysicalDisplayInfoClassInfo;
+
+
+class ScreenshotPixelRef : public SkPixelRef {
+public:
+ ScreenshotPixelRef(SkColorTable* ctable) {
+ fCTable = ctable;
+ SkSafeRef(ctable);
+ setImmutable();
+ }
+
+ virtual ~ScreenshotPixelRef() {
+ SkSafeUnref(fCTable);
+ }
+
+ status_t update(const sp<IBinder>& display, int width, int height,
+ int minLayer, int maxLayer, bool allLayers) {
+ status_t res = (width > 0 && height > 0)
+ ? (allLayers
+ ? mScreenshot.update(display, width, height)
+ : mScreenshot.update(display, width, height, minLayer, maxLayer))
+ : mScreenshot.update(display);
+ if (res != NO_ERROR) {
+ return res;
+ }
+
+ return NO_ERROR;
+ }
+
+ uint32_t getWidth() const {
+ return mScreenshot.getWidth();
+ }
+
+ uint32_t getHeight() const {
+ return mScreenshot.getHeight();
+ }
+
+ uint32_t getStride() const {
+ return mScreenshot.getStride();
+ }
+
+ uint32_t getFormat() const {
+ return mScreenshot.getFormat();
+ }
+
+protected:
+ // overrides from SkPixelRef
+ virtual void* onLockPixels(SkColorTable** ct) {
+ *ct = fCTable;
+ return (void*)mScreenshot.getPixels();
+ }
+
+ virtual void onUnlockPixels() {
+ }
+
+private:
+ ScreenshotClient mScreenshot;
+ SkColorTable* fCTable;
+
+ typedef SkPixelRef INHERITED;
+};
+
+
+// ----------------------------------------------------------------------------
+
+static jint nativeCreate(JNIEnv* env, jobject surfaceObj, jobject sessionObj,
+ jstring nameStr, jint w, jint h, jint format, jint flags) {
+ ScopedUtfChars name(env, nameStr);
+ sp<SurfaceComposerClient> client(android_view_SurfaceSession_getClient(env, sessionObj));
+ sp<SurfaceControl> surface = client->createSurface(
+ String8(name.c_str()), w, h, format, flags);
+ if (surface == NULL) {
+ jniThrowException(env, OutOfResourcesException, NULL);
+ return 0;
+ }
+ surface->incStrong(surfaceObj);
+ return int(surface.get());
+}
+
+static void nativeRelease(JNIEnv* env, jobject surfaceObj, jint nativeObject) {
+ sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(nativeObject));
+ ctrl->decStrong(surfaceObj);
+}
+
+static void nativeDestroy(JNIEnv* env, jobject surfaceObj, jint nativeObject) {
+ sp<SurfaceControl> ctrl(reinterpret_cast<SurfaceControl *>(nativeObject));
+ ctrl->clear();
+ ctrl->decStrong(surfaceObj);
+}
+
+static inline SkBitmap::Config convertPixelFormat(PixelFormat format) {
+ /* note: if PIXEL_FORMAT_RGBX_8888 means that all alpha bytes are 0xFF, then
+ we can map to SkBitmap::kARGB_8888_Config, and optionally call
+ bitmap.setIsOpaque(true) on the resulting SkBitmap (as an accelerator)
+ */
+ switch (format) {
+ case PIXEL_FORMAT_RGBX_8888: return SkBitmap::kARGB_8888_Config;
+ case PIXEL_FORMAT_RGBA_8888: return SkBitmap::kARGB_8888_Config;
+ case PIXEL_FORMAT_RGBA_4444: return SkBitmap::kARGB_4444_Config;
+ case PIXEL_FORMAT_RGB_565: return SkBitmap::kRGB_565_Config;
+ case PIXEL_FORMAT_A_8: return SkBitmap::kA8_Config;
+ default: return SkBitmap::kNo_Config;
+ }
+}
+
+static jobject nativeScreenshot(JNIEnv* env, jclass clazz, jobject displayTokenObj,
+ jint width, jint height, jint minLayer, jint maxLayer, bool allLayers) {
+ sp<IBinder> displayToken = ibinderForJavaObject(env, displayTokenObj);
+ if (displayToken == NULL) {
+ return NULL;
+ }
+
+ ScreenshotPixelRef* pixels = new ScreenshotPixelRef(NULL);
+ if (pixels->update(displayToken, width, height,
+ minLayer, maxLayer, allLayers) != NO_ERROR) {
+ delete pixels;
+ return NULL;
+ }
+
+ uint32_t w = pixels->getWidth();
+ uint32_t h = pixels->getHeight();
+ uint32_t s = pixels->getStride();
+ uint32_t f = pixels->getFormat();
+ ssize_t bpr = s * android::bytesPerPixel(f);
+
+ SkBitmap* bitmap = new SkBitmap();
+ bitmap->setConfig(convertPixelFormat(f), w, h, bpr);
+ if (f == PIXEL_FORMAT_RGBX_8888) {
+ bitmap->setIsOpaque(true);
+ }
+
+ if (w > 0 && h > 0) {
+ bitmap->setPixelRef(pixels)->unref();
+ bitmap->lockPixels();
+ } else {
+ // be safe with an empty bitmap.
+ delete pixels;
+ bitmap->setPixels(NULL);
+ }
+
+ return GraphicsJNI::createBitmap(env, bitmap, false, NULL);
+}
+
+static void nativeOpenTransaction(JNIEnv* env, jclass clazz) {
+ SurfaceComposerClient::openGlobalTransaction();
+}
+
+static void nativeCloseTransaction(JNIEnv* env, jclass clazz) {
+ SurfaceComposerClient::closeGlobalTransaction();
+}
+
+static void nativeSetAnimationTransaction(JNIEnv* env, jclass clazz) {
+ SurfaceComposerClient::setAnimationTransaction();
+}
+
+static void nativeSetLayer(JNIEnv* env, jobject surfaceObj, jint nativeObject, jint zorder) {
+ SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+ status_t err = ctrl->setLayer(zorder);
+ if (err < 0 && err != NO_INIT) {
+ doThrowIAE(env);
+ }
+}
+
+static void nativeSetPosition(JNIEnv* env, jobject surfaceObj, jint nativeObject, jfloat x, jfloat y) {
+ SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+ status_t err = ctrl->setPosition(x, y);
+ if (err < 0 && err != NO_INIT) {
+ doThrowIAE(env);
+ }
+}
+
+static void nativeSetSize(JNIEnv* env, jobject surfaceObj, jint nativeObject, jint w, jint h) {
+ SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+ status_t err = ctrl->setSize(w, h);
+ if (err < 0 && err != NO_INIT) {
+ doThrowIAE(env);
+ }
+}
+
+static void nativeSetFlags(JNIEnv* env, jobject surfaceObj, jint nativeObject, jint flags, jint mask) {
+ SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+ status_t err = ctrl->setFlags(flags, mask);
+ if (err < 0 && err != NO_INIT) {
+ doThrowIAE(env);
+ }
+}
+
+static void nativeSetTransparentRegionHint(JNIEnv* env, jobject surfaceObj, jint nativeObject, jobject regionObj) {
+ SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+ SkRegion* region = android_graphics_Region_getSkRegion(env, regionObj);
+ if (!region) {
+ doThrowIAE(env);
+ return;
+ }
+
+ const SkIRect& b(region->getBounds());
+ Region reg(Rect(b.fLeft, b.fTop, b.fRight, b.fBottom));
+ if (region->isComplex()) {
+ SkRegion::Iterator it(*region);
+ while (!it.done()) {
+ const SkIRect& r(it.rect());
+ reg.addRectUnchecked(r.fLeft, r.fTop, r.fRight, r.fBottom);
+ it.next();
+ }
+ }
+
+ status_t err = ctrl->setTransparentRegionHint(reg);
+ if (err < 0 && err != NO_INIT) {
+ doThrowIAE(env);
+ }
+}
+
+static void nativeSetAlpha(JNIEnv* env, jobject surfaceObj, jint nativeObject, jfloat alpha) {
+ SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+ status_t err = ctrl->setAlpha(alpha);
+ if (err < 0 && err != NO_INIT) {
+ doThrowIAE(env);
+ }
+}
+
+static void nativeSetMatrix(JNIEnv* env, jobject surfaceObj, jint nativeObject,
+ jfloat dsdx, jfloat dtdx, jfloat dsdy, jfloat dtdy) {
+ SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+ status_t err = ctrl->setMatrix(dsdx, dtdx, dsdy, dtdy);
+ if (err < 0 && err != NO_INIT) {
+ doThrowIAE(env);
+ }
+}
+
+static void nativeSetWindowCrop(JNIEnv* env, jobject surfaceObj, jint nativeObject,
+ jint l, jint t, jint r, jint b) {
+ SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+ Rect crop(l, t, r, b);
+ status_t err = ctrl->setCrop(crop);
+ if (err < 0 && err != NO_INIT) {
+ doThrowIAE(env);
+ }
+}
+
+static void nativeSetLayerStack(JNIEnv* env, jobject surfaceObj, jint nativeObject, jint layerStack) {
+ SurfaceControl* const ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
+ status_t err = ctrl->setLayerStack(layerStack);
+ if (err < 0 && err != NO_INIT) {
+ doThrowIAE(env);
+ }
+}
+
+static jobject nativeGetBuiltInDisplay(JNIEnv* env, jclass clazz, jint id) {
+ sp<IBinder> token(SurfaceComposerClient::getBuiltInDisplay(id));
+ return javaObjectForIBinder(env, token);
+}
+
+static jobject nativeCreateDisplay(JNIEnv* env, jclass clazz, jstring nameObj,
+ jboolean secure) {
+ ScopedUtfChars name(env, nameObj);
+ sp<IBinder> token(SurfaceComposerClient::createDisplay(
+ String8(name.c_str()), bool(secure)));
+ return javaObjectForIBinder(env, token);
+}
+
+static void nativeSetDisplaySurface(JNIEnv* env, jclass clazz,
+ jobject tokenObj, jint nativeSurfaceObject) {
+ sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
+ if (token == NULL) return;
+ sp<Surface> sur(reinterpret_cast<Surface *>(nativeSurfaceObject));
+ sp<IGraphicBufferProducer> bufferProducer(sur->getSurfaceTexture());
+ SurfaceComposerClient::setDisplaySurface(token, bufferProducer);
+}
+
+static void nativeSetDisplayLayerStack(JNIEnv* env, jclass clazz,
+ jobject tokenObj, jint layerStack) {
+ sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
+ if (token == NULL) return;
+
+ SurfaceComposerClient::setDisplayLayerStack(token, layerStack);
+}
+
+static void nativeSetDisplayProjection(JNIEnv* env, jclass clazz,
+ jobject tokenObj, jint orientation,
+ jint layerStackRect_left, jint layerStackRect_top, jint layerStackRect_right, jint layerStackRect_bottom,
+ jint displayRect_left, jint displayRect_top, jint displayRect_right, jint displayRect_bottom) {
+ sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
+ if (token == NULL) return;
+ Rect layerStackRect(layerStackRect_left, layerStackRect_top, layerStackRect_right, layerStackRect_bottom);
+ Rect displayRect(displayRect_left, displayRect_top, displayRect_right, displayRect_bottom);
+ SurfaceComposerClient::setDisplayProjection(token, orientation, layerStackRect, displayRect);
+}
+
+static jboolean nativeGetDisplayInfo(JNIEnv* env, jclass clazz,
+ jobject tokenObj, jobject infoObj) {
+ sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
+ if (token == NULL) return JNI_FALSE;
+
+ DisplayInfo info;
+ if (SurfaceComposerClient::getDisplayInfo(token, &info)) {
+ return JNI_FALSE;
+ }
+
+ env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.width, info.w);
+ env->SetIntField(infoObj, gPhysicalDisplayInfoClassInfo.height, info.h);
+ env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.refreshRate, info.fps);
+ env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.density, info.density);
+ env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.xDpi, info.xdpi);
+ env->SetFloatField(infoObj, gPhysicalDisplayInfoClassInfo.yDpi, info.ydpi);
+ env->SetBooleanField(infoObj, gPhysicalDisplayInfoClassInfo.secure, info.secure);
+ return JNI_TRUE;
+}
+
+static void nativeBlankDisplay(JNIEnv* env, jclass clazz, jobject tokenObj) {
+ sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
+ if (token == NULL) return;
+
+ ALOGD_IF_SLOW(100, "Excessive delay in blankDisplay() while turning screen off");
+ SurfaceComposerClient::blankDisplay(token);
+}
+
+static void nativeUnblankDisplay(JNIEnv* env, jclass clazz, jobject tokenObj) {
+ sp<IBinder> token(ibinderForJavaObject(env, tokenObj));
+ if (token == NULL) return;
+
+ ALOGD_IF_SLOW(100, "Excessive delay in unblankDisplay() while turning screen on");
+ SurfaceComposerClient::unblankDisplay(token);
+}
+
+// ----------------------------------------------------------------------------
+
+static JNINativeMethod sSurfaceControlMethods[] = {
+ {"nativeCreate", "(Landroid/view/SurfaceSession;Ljava/lang/String;IIII)I",
+ (void*)nativeCreate },
+ {"nativeRelease", "(I)V",
+ (void*)nativeRelease },
+ {"nativeDestroy", "(I)V",
+ (void*)nativeDestroy },
+ {"nativeScreenshot", "(Landroid/os/IBinder;IIIIZ)Landroid/graphics/Bitmap;",
+ (void*)nativeScreenshot },
+ {"nativeOpenTransaction", "()V",
+ (void*)nativeOpenTransaction },
+ {"nativeCloseTransaction", "()V",
+ (void*)nativeCloseTransaction },
+ {"nativeSetAnimationTransaction", "()V",
+ (void*)nativeSetAnimationTransaction },
+ {"nativeSetLayer", "(II)V",
+ (void*)nativeSetLayer },
+ {"nativeSetPosition", "(IFF)V",
+ (void*)nativeSetPosition },
+ {"nativeSetSize", "(III)V",
+ (void*)nativeSetSize },
+ {"nativeSetTransparentRegionHint", "(ILandroid/graphics/Region;)V",
+ (void*)nativeSetTransparentRegionHint },
+ {"nativeSetAlpha", "(IF)V",
+ (void*)nativeSetAlpha },
+ {"nativeSetMatrix", "(IFFFF)V",
+ (void*)nativeSetMatrix },
+ {"nativeSetFlags", "(III)V",
+ (void*)nativeSetFlags },
+ {"nativeSetWindowCrop", "(IIIII)V",
+ (void*)nativeSetWindowCrop },
+ {"nativeSetLayerStack", "(II)V",
+ (void*)nativeSetLayerStack },
+ {"nativeGetBuiltInDisplay", "(I)Landroid/os/IBinder;",
+ (void*)nativeGetBuiltInDisplay },
+ {"nativeCreateDisplay", "(Ljava/lang/String;Z)Landroid/os/IBinder;",
+ (void*)nativeCreateDisplay },
+ {"nativeSetDisplaySurface", "(Landroid/os/IBinder;I)V",
+ (void*)nativeSetDisplaySurface },
+ {"nativeSetDisplayLayerStack", "(Landroid/os/IBinder;I)V",
+ (void*)nativeSetDisplayLayerStack },
+ {"nativeSetDisplayProjection", "(Landroid/os/IBinder;IIIIIIIII)V",
+ (void*)nativeSetDisplayProjection },
+ {"nativeGetDisplayInfo", "(Landroid/os/IBinder;Landroid/view/SurfaceControl$PhysicalDisplayInfo;)Z",
+ (void*)nativeGetDisplayInfo },
+ {"nativeBlankDisplay", "(Landroid/os/IBinder;)V",
+ (void*)nativeBlankDisplay },
+ {"nativeUnblankDisplay", "(Landroid/os/IBinder;)V",
+ (void*)nativeUnblankDisplay },
+};
+
+int register_android_view_SurfaceControl(JNIEnv* env)
+{
+ int err = AndroidRuntime::registerNativeMethods(env, "android/view/SurfaceControl",
+ sSurfaceControlMethods, NELEM(sSurfaceControlMethods));
+
+ jclass clazz = env->FindClass("android/view/SurfaceControl$PhysicalDisplayInfo");
+ gPhysicalDisplayInfoClassInfo.width = env->GetFieldID(clazz, "width", "I");
+ gPhysicalDisplayInfoClassInfo.height = env->GetFieldID(clazz, "height", "I");
+ gPhysicalDisplayInfoClassInfo.refreshRate = env->GetFieldID(clazz, "refreshRate", "F");
+ gPhysicalDisplayInfoClassInfo.density = env->GetFieldID(clazz, "density", "F");
+ gPhysicalDisplayInfoClassInfo.xDpi = env->GetFieldID(clazz, "xDpi", "F");
+ gPhysicalDisplayInfoClassInfo.yDpi = env->GetFieldID(clazz, "yDpi", "F");
+ gPhysicalDisplayInfoClassInfo.secure = env->GetFieldID(clazz, "secure", "Z");
+ return err;
+}
+
+};