diff options
| author | Derek Sollenberger <djsollen@google.com> | 2010-03-22 16:11:38 -0400 |
|---|---|---|
| committer | Derek Sollenberger <djsollen@google.com> | 2010-03-23 15:34:33 -0400 |
| commit | 1fa70928d3207c357bc8834f098b52e9f6107480 (patch) | |
| tree | 3adb65536ad1d900f553afc687c46914014f8065 /core/java/android/webkit/ViewManager.java | |
| parent | 0ee0a2ea57197cb2f03905454098d9a7a309f77b (diff) | |
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
Diffstat (limited to 'core/java/android/webkit/ViewManager.java')
| -rw-r--r-- | core/java/android/webkit/ViewManager.java | 102 |
1 files changed, 74 insertions, 28 deletions
diff --git a/core/java/android/webkit/ViewManager.java b/core/java/android/webkit/ViewManager.java index fc5c42584e5c..23cf6b8232f2 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); } } |
