Merge "Fix bug 3395349 - Treat Spinner dropDownWidth property properly"
diff --git a/api/current.xml b/api/current.xml
index bd86302..ea86e3b 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -76419,6 +76419,17 @@
visibility="public"
>
</method>
+<method name="getGenerationId"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getHeight"
return="int"
abstract="false"
@@ -76636,6 +76647,19 @@
visibility="public"
>
</method>
+<method name="sameAs"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="other" type="android.graphics.Bitmap">
+</parameter>
+</method>
<method name="setDensity"
return="void"
abstract="false"
@@ -76649,6 +76673,19 @@
<parameter name="density" type="int">
</parameter>
</method>
+<method name="setHasAlpha"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="hasAlpha" type="boolean">
+</parameter>
+</method>
<method name="setPixel"
return="void"
abstract="false"
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 71d55f7..d46dacc 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -42,10 +42,23 @@
/**
* Turn on to only refresh the parts of the screen that need updating.
+ * When turned on the property defined by {@link #RENDER_DIRTY_REGIONS_PROPERTY}
+ * must also have the value "true".
*/
public static final boolean RENDER_DIRTY_REGIONS = true;
/**
+ * System property used to enable or disable dirty regions invalidation.
+ * This property is only queried if {@link #RENDER_DIRTY_REGIONS} is true.
+ * The default value of this property is assumed to be true.
+ *
+ * Possible values:
+ * "true", to enable partial invalidates
+ * "false", to disable partial invalidates
+ */
+ static final String RENDER_DIRTY_REGIONS_PROPERTY = "hwui.render_dirty_regions";
+
+ /**
* Turn on to draw dirty regions every other frame.
*/
private static final boolean DEBUG_DIRTY_REGION = false;
@@ -113,8 +126,23 @@
*/
abstract void setup(int width, int height);
+ /**
+ * Interface used to receive callbacks whenever a view is drawn by
+ * a hardware renderer instance.
+ */
interface HardwareDrawCallbacks {
+ /**
+ * Invoked before a view is drawn by a hardware renderer.
+ *
+ * @param canvas The Canvas used to render the view.
+ */
void onHardwarePreDraw(Canvas canvas);
+
+ /**
+ * Invoked after a view is drawn by a hardware renderer.
+ *
+ * @param canvas The Canvas used to render the view.
+ */
void onHardwarePostDraw(Canvas canvas);
}
@@ -250,6 +278,7 @@
int mFrameCount;
Paint mDebugPaint;
+ boolean mDirtyRegions;
final int mGlVersion;
final boolean mTranslucent;
@@ -259,6 +288,9 @@
GlRenderer(int glVersion, boolean translucent) {
mGlVersion = glVersion;
mTranslucent = translucent;
+ final String dirtyProperty = System.getProperty(RENDER_DIRTY_REGIONS_PROPERTY, "true");
+ //noinspection PointlessBooleanExpression,ConstantConditions
+ mDirtyRegions = RENDER_DIRTY_REGIONS && "true".equalsIgnoreCase(dirtyProperty);
}
/**
@@ -388,10 +420,24 @@
// We can now initialize EGL for that display
int[] version = new int[2];
if (!sEgl.eglInitialize(sEglDisplay, version)) {
- throw new RuntimeException("eglInitialize failed "
- + getEGLErrorString(sEgl.eglGetError()));
+ throw new RuntimeException("eglInitialize failed " +
+ getEGLErrorString(sEgl.eglGetError()));
}
+
sEglConfig = getConfigChooser(mGlVersion).chooseConfig(sEgl, sEglDisplay);
+ if (sEglConfig == null) {
+ // We tried to use EGL_SWAP_BEHAVIOR_PRESERVED_BIT, try again without
+ if (mDirtyRegions) {
+ mDirtyRegions = false;
+
+ sEglConfig = getConfigChooser(mGlVersion).chooseConfig(sEgl, sEglDisplay);
+ if (sEglConfig == null) {
+ throw new RuntimeException("eglConfig not initialized");
+ }
+ } else {
+ throw new RuntimeException("eglConfig not initialized");
+ }
+ }
/*
* Create an EGL context. We want to do this as rarely as we can, because an
@@ -409,7 +455,7 @@
throw new RuntimeException("eglDisplay not initialized");
}
if (sEglConfig == null) {
- throw new RuntimeException("mEglConfig not initialized");
+ throw new RuntimeException("eglConfig not initialized");
}
if (Thread.currentThread() != sEglThread) {
throw new IllegalStateException("HardwareRenderer cannot be used "
@@ -452,7 +498,7 @@
+ getEGLErrorString(sEgl.eglGetError()));
}
- if (RENDER_DIRTY_REGIONS) {
+ if (mDirtyRegions) {
if (!GLES20Canvas.preserveBackBuffer()) {
Log.w(LOG_TAG, "Backbuffer cannot be preserved");
}
@@ -518,15 +564,14 @@
* @return An {@link android.view.HardwareRenderer.GlRenderer.EglConfigChooser}.
*/
EglConfigChooser getConfigChooser(int glVersion) {
- return new ComponentSizeChooser(glVersion, 8, 8, 8, 8, 0, 0);
+ return new ComponentSizeChooser(glVersion, 8, 8, 8, 8, 0, 0, mDirtyRegions);
}
@Override
void draw(View view, View.AttachInfo attachInfo, HardwareDrawCallbacks callbacks,
Rect dirty) {
if (canDraw()) {
- //noinspection PointlessBooleanExpression,ConstantConditions
- if (!HardwareRenderer.RENDER_DIRTY_REGIONS) {
+ if (!mDirtyRegions) {
dirty = null;
}
@@ -676,16 +721,16 @@
static class ComponentSizeChooser extends EglConfigChooser {
private int[] mValue;
- private int mRedSize;
- private int mGreenSize;
- private int mBlueSize;
- private int mAlphaSize;
- private int mDepthSize;
- private int mStencilSize;
+ private final int mRedSize;
+ private final int mGreenSize;
+ private final int mBlueSize;
+ private final int mAlphaSize;
+ private final int mDepthSize;
+ private final int mStencilSize;
+ private final boolean mDirtyRegions;
ComponentSizeChooser(int glVersion, int redSize, int greenSize, int blueSize,
- int alphaSize, int depthSize, int stencilSize) {
- //noinspection PointlessBitwiseExpression
+ int alphaSize, int depthSize, int stencilSize, boolean dirtyRegions) {
super(glVersion, new int[] {
EGL10.EGL_RED_SIZE, redSize,
EGL10.EGL_GREEN_SIZE, greenSize,
@@ -694,7 +739,7 @@
EGL10.EGL_DEPTH_SIZE, depthSize,
EGL10.EGL_STENCIL_SIZE, stencilSize,
EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT |
- (RENDER_DIRTY_REGIONS ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0),
+ (dirtyRegions ? EGL_SWAP_BEHAVIOR_PRESERVED_BIT : 0),
EGL10.EGL_NONE });
mValue = new int[1];
mRedSize = redSize;
@@ -703,7 +748,8 @@
mAlphaSize = alphaSize;
mDepthSize = depthSize;
mStencilSize = stencilSize;
- }
+ mDirtyRegions = dirtyRegions;
+ }
@Override
EGLConfig chooseConfig(EGL10 egl, EGLDisplay display, EGLConfig[] configs) {
@@ -716,7 +762,7 @@
int b = findConfigAttrib(egl, display, config, EGL10.EGL_BLUE_SIZE, 0);
int a = findConfigAttrib(egl, display, config, EGL10.EGL_ALPHA_SIZE, 0);
boolean backBuffer;
- if (RENDER_DIRTY_REGIONS) {
+ if (mDirtyRegions) {
int surfaceType = findConfigAttrib(egl, display, config,
EGL_SURFACE_TYPE, 0);
backBuffer = (surfaceType & EGL_SWAP_BEHAVIOR_PRESERVED_BIT) != 0;
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 26dab81..88bb9fc 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -2617,8 +2617,8 @@
newHeight = 0;
heightWidthRatio = 0;
}
- // Actual visible height.
- int actualViewHeight = getViewHeight();
+ // Actual visible content height.
+ int actualViewHeight = Math.round(getViewHeight() * mZoomManager.getInvScale());
// Avoid sending another message if the dimensions have not changed.
if (newWidth != mLastWidthSent || newHeight != mLastHeightSent || force ||
actualViewHeight != mLastActualHeightSent) {
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index c7ae2cf..bd903da 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -200,8 +200,6 @@
* check if a bitmap has changed.
*
* @return The current generation ID for this bitmap.
- *
- * @hide
*/
public int getGenerationId() {
return nativeGenerationId(mNativeBitmap);
@@ -752,7 +750,7 @@
}
// Scale by tdensity / sdensity, rounding up.
- return ( (size * tdensity) + (sdensity >> 1) ) / sdensity;
+ return ((size * tdensity) + (sdensity >> 1)) / sdensity;
}
/**
@@ -790,14 +788,12 @@
/**
* Tell the bitmap if all of the pixels are known to be opaque (false)
* or if some of the pixels may contain non-opaque alpha values (true).
- * Note, for some configs (e.g. RGB_565) this call is ignore, since it does
- * not support per-pixel alpha values.
+ * Note, for some configs (e.g. RGB_565) this call is ignored, since it
+ * does not support per-pixel alpha values.
*
* This is meant as a drawing hint, as in some cases a bitmap that is known
* to be opaque can take a faster drawing case than one that may have
* non-opaque per-pixel alpha values.
- *
- * @hide
*/
public void setHasAlpha(boolean hasAlpha) {
nativeSetHasAlpha(mNativeBitmap, hasAlpha);
@@ -1066,13 +1062,9 @@
* Given another bitmap, return true if it has the same dimensions, config,
* and pixel data as this bitmap. If any of those differ, return false.
* If other is null, return false.
- *
- * @hide (just needed internally right now)
*/
public boolean sameAs(Bitmap other) {
- return this == other ||
- (other != null &&
- nativeSameAs(mNativeBitmap, other.mNativeBitmap));
+ return this == other || (other != null && nativeSameAs(mNativeBitmap, other.mNativeBitmap));
}
/**
@@ -1099,7 +1091,13 @@
@Override
public void finalize() {
- nativeDestructor(mNativeBitmap);
+ try {
+ super.finalize();
+ } catch (Throwable t) {
+ // Ignore
+ } finally {
+ nativeDestructor(mNativeBitmap);
+ }
}
}
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 82948cb..f7d837a 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -175,6 +175,7 @@
int64_t mSeekTimeUs;
ReadOptions::SeekMode mSeekMode;
int64_t mTargetTimeUs;
+ bool mOutputPortSettingsChangedPending;
MediaBuffer *mLeftOverBuffer;
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 5a43c6a..2f5a202 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -291,9 +291,11 @@
}
dataSource->getDrmInfo(&mDecryptHandle, &mDrmManagerClient);
- if (mDecryptHandle != NULL
- && RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
- notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_NO_LICENSE);
+ if (mDecryptHandle != NULL) {
+ CHECK(mDrmManagerClient);
+ if (RightsStatus::RIGHTS_VALID != mDecryptHandle->status) {
+ notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, ERROR_NO_LICENSE);
+ }
}
return setDataSource_l(extractor);
@@ -1738,6 +1740,7 @@
dataSource->getDrmInfo(&mDecryptHandle, &mDrmManagerClient);
if (mDecryptHandle != NULL) {
+ CHECK(mDrmManagerClient);
if (RightsStatus::RIGHTS_VALID == mDecryptHandle->status) {
if (DecryptApiType::WV_BASED == mDecryptHandle->decryptApiType) {
LOGD("Setting mCachedSource to NULL for WVM\n");
diff --git a/media/libstagefright/DRMExtractor.cpp b/media/libstagefright/DRMExtractor.cpp
index 4b83568..647cf43 100644
--- a/media/libstagefright/DRMExtractor.cpp
+++ b/media/libstagefright/DRMExtractor.cpp
@@ -79,6 +79,7 @@
mTrackId(trackId),
mNALLengthSize(0),
mWantsNALFragments(false) {
+ CHECK(mDrmManagerClient);
mDrmManagerClient->initializeDecryptUnit(
mDecryptHandle, trackId, ipmpBox);
diff --git a/media/libstagefright/FileSource.cpp b/media/libstagefright/FileSource.cpp
index b8e75fd..02a78c9 100644
--- a/media/libstagefright/FileSource.cpp
+++ b/media/libstagefright/FileSource.cpp
@@ -63,6 +63,7 @@
if (mDecryptHandle != NULL) {
// To release mDecryptHandle
+ CHECK(mDrmManagerClient);
mDrmManagerClient->closeDecryptSession(mDecryptHandle);
mDecryptHandle = NULL;
}
diff --git a/media/libstagefright/NuHTTPDataSource.cpp b/media/libstagefright/NuHTTPDataSource.cpp
index af04f93..0376e1c 100644
--- a/media/libstagefright/NuHTTPDataSource.cpp
+++ b/media/libstagefright/NuHTTPDataSource.cpp
@@ -81,6 +81,7 @@
NuHTTPDataSource::~NuHTTPDataSource() {
if (mDecryptHandle != NULL) {
// To release mDecryptHandle
+ CHECK(mDrmManagerClient);
mDrmManagerClient->closeDecryptSession(mDecryptHandle);
mDecryptHandle = NULL;
}
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 247ace7..fccd68c 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1434,6 +1434,7 @@
mSeekTimeUs(-1),
mSeekMode(ReadOptions::SEEK_CLOSEST_SYNC),
mTargetTimeUs(-1),
+ mOutputPortSettingsChangedPending(false),
mLeftOverBuffer(NULL),
mPaused(false),
mNativeWindow(nativeWindow) {
@@ -2344,6 +2345,14 @@
drainInputBuffers();
fillOutputBuffers();
}
+
+ if (mOutputPortSettingsChangedPending) {
+ CODEC_LOGV(
+ "Honoring deferred output port settings change.");
+
+ mOutputPortSettingsChangedPending = false;
+ onPortSettingsChanged(kPortIndexOutput);
+ }
}
break;
@@ -2407,6 +2416,8 @@
CODEC_LOGV("Now Executing.");
+ mOutputPortSettingsChangedPending = false;
+
setState(EXECUTING);
// Buffers will be submitted to the component in the first
@@ -2520,6 +2531,14 @@
CHECK_EQ((int)mState, (int)EXECUTING);
CHECK_EQ(portIndex, (OMX_U32)kPortIndexOutput);
+ CHECK(!mOutputPortSettingsChangedPending);
+
+ if (mPortStatus[kPortIndexOutput] != ENABLED) {
+ CODEC_LOGV("Deferring output port settings change.");
+ mOutputPortSettingsChangedPending = true;
+ return;
+ }
+
setState(RECONFIGURING);
if (mQuirks & kNeedsFlushBeforeDisable) {
@@ -2712,6 +2731,7 @@
if (srcBuffer->meta_data()->findInt64(
kKeyTargetTime, &targetTimeUs)
&& targetTimeUs >= 0) {
+ CODEC_LOGV("targetTimeUs = %lld us", targetTimeUs);
mTargetTimeUs = targetTimeUs;
} else {
mTargetTimeUs = -1;
@@ -3385,6 +3405,14 @@
}
if (seeking) {
+ while (mState == RECONFIGURING) {
+ mBufferFilled.wait(mLock);
+ }
+
+ if (mState != EXECUTING) {
+ return UNKNOWN_ERROR;
+ }
+
CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6);
mSignalledEOS = false;