summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDerek Sollenberger <djsollen@google.com>2010-03-22 16:11:38 -0400
committerDerek Sollenberger <djsollen@google.com>2010-03-23 15:34:33 -0400
commit1fa70928d3207c357bc8834f098b52e9f6107480 (patch)
tree3adb65536ad1d900f553afc687c46914014f8065
parent0ee0a2ea57197cb2f03905454098d9a7a309f77b (diff)
downloadframeworks_base-1fa70928d3207c357bc8834f098b52e9f6107480.zip
frameworks_base-1fa70928d3207c357bc8834f098b52e9f6107480.tar.gz
frameworks_base-1fa70928d3207c357bc8834f098b52e9f6107480.tar.bz2
fixing problem with allocating too much memory to a surface by fixing
the size of the surface when it exceeds a threshold and resizing the surface when it falls beneath the threshold. This change also causes the surface to fix its size while it is being zoomed in order to prevent the surface from getting multiple surfaceChangedEvents as the result of a zoom. This also allows us to have a smooth zoom animation for the surface. Change-Id: I30e208f98d3a32660032bf1df9de77d0a813d756
-rw-r--r--core/java/android/webkit/ViewManager.java102
-rw-r--r--core/java/android/webkit/WebView.java5
2 files changed, 79 insertions, 28 deletions
diff --git a/core/java/android/webkit/ViewManager.java b/core/java/android/webkit/ViewManager.java
index fc5c425..23cf6b8 100644
--- a/core/java/android/webkit/ViewManager.java
+++ b/core/java/android/webkit/ViewManager.java
@@ -28,6 +28,7 @@ class ViewManager {
private final ArrayList<ChildView> mChildren = new ArrayList<ChildView>();
private boolean mHidden;
private boolean mReadyToDraw;
+ private boolean mZoomInProgress = false;
// Threshold at which a surface is prevented from further increasing in size
private final int MAX_SURFACE_THRESHOLD;
@@ -39,11 +40,6 @@ class ViewManager {
int height;
View mView; // generic view to show
- /* set to true if the view is a surface and it has exceeded the pixel
- threshold specified in MAX_SURFACE_THRESHOLD.
- */
- boolean isFixedSize = false;
-
ChildView() {
}
@@ -66,19 +62,17 @@ class ViewManager {
// already attached, just set the new LayoutParams,
// otherwise attach the view and add it to the list of
// children.
- AbsoluteLayout.LayoutParams lp = computeLayout(ChildView.this);
+ requestLayout(ChildView.this);
- if (mView.getParent() != null) {
- mView.setLayoutParams(lp);
- } else {
- attachViewOnUIThread(lp);
+ if (mView.getParent() == null) {
+ attachViewOnUIThread();
}
}
});
}
- private void attachViewOnUIThread(AbsoluteLayout.LayoutParams lp) {
- mWebView.addView(mView, lp);
+ private void attachViewOnUIThread() {
+ mWebView.addView(mView);
mChildren.add(this);
if (!mReadyToDraw) {
mView.setVisibility(View.GONE);
@@ -146,35 +140,87 @@ class ViewManager {
/**
* This should only be called from the UI thread.
*/
- private AbsoluteLayout.LayoutParams computeLayout(ChildView v) {
+ private void requestLayout(ChildView v) {
- // if the surface has exceed a predefined threshold then fix the size
- // of the surface.
- if (!v.isFixedSize && (v.width * v.height) > MAX_SURFACE_THRESHOLD
- && v.mView instanceof SurfaceView) {
- ((SurfaceView)v.mView).getHolder().setFixedSize(v.width, v.height);
- v.isFixedSize = true;
- }
+ int width = ctvD(v.width);
+ int height = ctvD(v.height);
+ int x = ctvX(v.x);
+ int y = ctvY(v.y);
AbsoluteLayout.LayoutParams lp;
ViewGroup.LayoutParams layoutParams = v.mView.getLayoutParams();
if (layoutParams instanceof AbsoluteLayout.LayoutParams) {
lp = (AbsoluteLayout.LayoutParams) layoutParams;
- lp.width = ctvD(v.width);
- lp.height = ctvD(v.height);
- lp.x = ctvX(v.x);
- lp.y = ctvY(v.y);
+ lp.width = width;
+ lp.height = height;
+ lp.x = x;
+ lp.y = y;
} else {
- lp = new AbsoluteLayout.LayoutParams(ctvD(v.width), ctvD(v.height),
- ctvX(v.x), ctvY(v.y));
+ lp = new AbsoluteLayout.LayoutParams(width, height, x, y);
+ }
+
+ // apply the layout to the view
+ v.mView.setLayoutParams(lp);
+
+ if(v.mView instanceof SurfaceView) {
+
+ final SurfaceView sView = (SurfaceView) v.mView;
+ boolean exceedThreshold = (width * height) > MAX_SURFACE_THRESHOLD;
+
+ /* If the surface has exceeded a predefined threshold or the webview
+ * is currently zoom then fix the size of the surface.
+ *
+ * NOTE: plugins (e.g. Flash) must not explicitly fix the size of
+ * their surface. The logic below will result in unexpected behavior
+ * for the plugin if they attempt to fix the size of the surface.
+ */
+ if (!sView.isFixedSize() && (exceedThreshold || mZoomInProgress)) {
+ sView.getHolder().setFixedSize(width, height);
+ }
+ else if (sView.isFixedSize() && !exceedThreshold && !mZoomInProgress) {
+ /* The changing of visibility is a hack to get around a bug in
+ * the framework that causes the surface to revert to the size
+ * it was prior to being fixed before it redraws using the
+ * values currently in its layout.
+ *
+ * The surface is destroyed when it is set to invisible and then
+ * recreated at the new dimensions when it is made visible. The
+ * same destroy/create step occurs without the change in
+ * visibility, but then exhibits the behavior described in the
+ * previous paragraph.
+ */
+ if (sView.getVisibility() == View.VISIBLE) {
+ sView.setVisibility(View.INVISIBLE);
+ sView.getHolder().setSizeFromLayout();
+ sView.setVisibility(View.VISIBLE);
+ } else {
+ sView.getHolder().setSizeFromLayout();
+ }
+ }
+ else if (sView.isFixedSize() && exceedThreshold) {
+ sView.requestLayout();
+ }
+ }
+ }
+
+ void startZoom() {
+ mZoomInProgress = true;
+ for (ChildView v : mChildren) {
+ requestLayout(v);
+ }
+ }
+
+ void endZoom() {
+ mZoomInProgress = false;
+ for (ChildView v : mChildren) {
+ requestLayout(v);
}
- return lp;
}
void scaleAll() {
for (ChildView v : mChildren) {
- v.mView.setLayoutParams(computeLayout(v));
+ requestLayout(v);
}
}
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 784f886..f886eef 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -4460,6 +4460,9 @@ public class WebView extends AbsoluteLayout
if (inEditingMode() && nativeFocusCandidateIsPassword()) {
mWebTextView.setInPassword(false);
}
+
+ mViewManager.startZoom();
+
return true;
}
@@ -4493,6 +4496,8 @@ public class WebView extends AbsoluteLayout
mConfirmMove = true;
startTouch(detector.getFocusX(), detector.getFocusY(),
mLastTouchTime);
+
+ mViewManager.endZoom();
}
public boolean onScale(ScaleGestureDetector detector) {