10a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott/*
20a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott * Copyright (C) 2009 The Android Open Source Project
30a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott *
40a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott * Licensed under the Apache License, Version 2.0 (the "License");
50a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott * you may not use this file except in compliance with the License.
60a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott * You may obtain a copy of the License at
70a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott *
80a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott *      http://www.apache.org/licenses/LICENSE-2.0
90a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott *
100a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott * Unless required by applicable law or agreed to in writing, software
110a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott * distributed under the License is distributed on an "AS IS" BASIS,
120a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott * See the License for the specific language governing permissions and
140a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott * limitations under the License.
150a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott */
160a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott
170a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scottpackage android.webkit;
180a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott
1941df3f7e15b3d5f77dc7f255ec702e381eb93f35Derek Sollenbergerimport android.view.SurfaceView;
200a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scottimport android.view.View;
21cfe688d8d9d09d2a9e6602361f20a8d5a4fe3621Cary Clarkimport android.view.ViewGroup;
220a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scottimport android.widget.AbsoluteLayout;
230a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott
240a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scottimport java.util.ArrayList;
250a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott
260a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scottclass ViewManager {
270a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott    private final WebView mWebView;
280a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott    private final ArrayList<ChildView> mChildren = new ArrayList<ChildView>();
290a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott    private boolean mHidden;
309a67c82089e43d37f5038c74b0e1dca8edc4ac8aGrace Kloba    private boolean mReadyToDraw;
311fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger    private boolean mZoomInProgress = false;
320a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott
3341df3f7e15b3d5f77dc7f255ec702e381eb93f35Derek Sollenberger    // Threshold at which a surface is prevented from further increasing in size
34f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed    private final int MAX_SURFACE_AREA;
35f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed    // GPU Limit (hard coded for now)
36f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed    private static final int MAX_SURFACE_DIMENSION = 2048;
3741df3f7e15b3d5f77dc7f255ec702e381eb93f35Derek Sollenberger
380a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott    class ChildView {
390a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott        int x;
400a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott        int y;
410a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott        int width;
420a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott        int height;
430a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott        View mView; // generic view to show
440a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott
450a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott        ChildView() {
460a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott        }
470a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott
480a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott        void setBounds(int x, int y, int width, int height) {
490a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott            this.x = x;
500a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott            this.y = y;
510a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott            this.width = width;
520a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott            this.height = height;
530a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott        }
540a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott
550a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott        void attachView(int x, int y, int width, int height) {
560a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott            if (mView == null) {
570a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott                return;
580a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott            }
590a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott            setBounds(x, y, width, height);
6041df3f7e15b3d5f77dc7f255ec702e381eb93f35Derek Sollenberger
610a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott            mWebView.mPrivateHandler.post(new Runnable() {
620a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott                public void run() {
630a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott                    // This method may be called multiple times. If the view is
640a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott                    // already attached, just set the new LayoutParams,
650a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott                    // otherwise attach the view and add it to the list of
660a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott                    // children.
671fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger                    requestLayout(ChildView.this);
6841df3f7e15b3d5f77dc7f255ec702e381eb93f35Derek Sollenberger
691fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger                    if (mView.getParent() == null) {
701fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger                        attachViewOnUIThread();
710a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott                    }
720a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott                }
730a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott            });
740a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott        }
750a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott
761fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger        private void attachViewOnUIThread() {
771fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger            mWebView.addView(mView);
783c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu            mChildren.add(this);
799a67c82089e43d37f5038c74b0e1dca8edc4ac8aGrace Kloba            if (!mReadyToDraw) {
809a67c82089e43d37f5038c74b0e1dca8edc4ac8aGrace Kloba                mView.setVisibility(View.GONE);
819a67c82089e43d37f5038c74b0e1dca8edc4ac8aGrace Kloba            }
823c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu        }
833c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu
840a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott        void removeView() {
850a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott            if (mView == null) {
860a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott                return;
870a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott            }
880a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott            mWebView.mPrivateHandler.post(new Runnable() {
890a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott                public void run() {
903c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu                    removeViewOnUIThread();
910a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott                }
920a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott            });
930a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott        }
943c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu
9541df3f7e15b3d5f77dc7f255ec702e381eb93f35Derek Sollenberger        private void removeViewOnUIThread() {
963c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu            mWebView.removeView(mView);
973c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu            mChildren.remove(this);
983c946a1a9637e85e4256f40b68f3b9d4b9f40c27Andrei Popescu        }
990a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott    }
1000a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott
1010a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott    ViewManager(WebView w) {
1020a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott        mWebView = w;
103d222a16286c65ce1846b8d3b695eb481c94d2724Derek Sollenberger
104d222a16286c65ce1846b8d3b695eb481c94d2724Derek Sollenberger        int pixelArea = w.getResources().getDisplayMetrics().widthPixels *
105d222a16286c65ce1846b8d3b695eb481c94d2724Derek Sollenberger                        w.getResources().getDisplayMetrics().heightPixels;
106d222a16286c65ce1846b8d3b695eb481c94d2724Derek Sollenberger        /* set the threshold to be 275% larger than the screen size. The
107d222a16286c65ce1846b8d3b695eb481c94d2724Derek Sollenberger           percentage is simply an estimation and is not based on anything but
108d222a16286c65ce1846b8d3b695eb481c94d2724Derek Sollenberger           basic trial-and-error tests run on multiple devices.
109d222a16286c65ce1846b8d3b695eb481c94d2724Derek Sollenberger         */
110f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed        MAX_SURFACE_AREA = (int)(pixelArea * 2.75);
1110a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott    }
1120a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott
1130a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott    ChildView createView() {
1140a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott        return new ChildView();
1150a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott    }
1160a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott
1170236e673d8b980fd6333c18505129c6b49e38cd1Leon Scroggins    /**
11841df3f7e15b3d5f77dc7f255ec702e381eb93f35Derek Sollenberger     * This should only be called from the UI thread.
11941df3f7e15b3d5f77dc7f255ec702e381eb93f35Derek Sollenberger     */
1201fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger    private void requestLayout(ChildView v) {
1211fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger
122f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed        int width = mWebView.contentToViewDimension(v.width);
123f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed        int height = mWebView.contentToViewDimension(v.height);
124f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed        int x = mWebView.contentToViewX(v.x);
125f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed        int y = mWebView.contentToViewY(v.y);
12641df3f7e15b3d5f77dc7f255ec702e381eb93f35Derek Sollenberger
127cfe688d8d9d09d2a9e6602361f20a8d5a4fe3621Cary Clark        AbsoluteLayout.LayoutParams lp;
128cfe688d8d9d09d2a9e6602361f20a8d5a4fe3621Cary Clark        ViewGroup.LayoutParams layoutParams = v.mView.getLayoutParams();
12941df3f7e15b3d5f77dc7f255ec702e381eb93f35Derek Sollenberger
130cfe688d8d9d09d2a9e6602361f20a8d5a4fe3621Cary Clark        if (layoutParams instanceof AbsoluteLayout.LayoutParams) {
131cfe688d8d9d09d2a9e6602361f20a8d5a4fe3621Cary Clark            lp = (AbsoluteLayout.LayoutParams) layoutParams;
1321fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger            lp.width = width;
1331fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger            lp.height = height;
1341fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger            lp.x = x;
1351fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger            lp.y = y;
136cfe688d8d9d09d2a9e6602361f20a8d5a4fe3621Cary Clark        } else {
1371fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger            lp = new AbsoluteLayout.LayoutParams(width, height, x, y);
1381fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger        }
1391fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger
1401fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger        // apply the layout to the view
1411fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger        v.mView.setLayoutParams(lp);
1421fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger
1431fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger        if(v.mView instanceof SurfaceView) {
1441fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger
1451fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger            final SurfaceView sView = (SurfaceView) v.mView;
1461fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger
147f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed            if (sView.isFixedSize() && mZoomInProgress) {
148f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                /* If we're already fixed, and we're in a zoom, then do nothing
149f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                   about the size. Just wait until we get called at the end of
150f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                   the zoom session (with mZoomInProgress false) and we'll
151f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                   fixup our size then.
152f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                 */
153f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                return;
154f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed            }
155f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed
156f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed            /* Compute proportional fixed width/height if necessary.
1571fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger             *
1581fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger             * NOTE: plugins (e.g. Flash) must not explicitly fix the size of
1591fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger             * their surface. The logic below will result in unexpected behavior
1601fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger             * for the plugin if they attempt to fix the size of the surface.
1611fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger             */
162f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed            int fixedW = width;
163f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed            int fixedH = height;
164f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed            if (fixedW > MAX_SURFACE_DIMENSION || fixedH > MAX_SURFACE_DIMENSION) {
165f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                if (v.width > v.height) {
166f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                    fixedW = MAX_SURFACE_DIMENSION;
167f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                    fixedH = v.height * MAX_SURFACE_DIMENSION / v.width;
168f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                } else {
169f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                    fixedH = MAX_SURFACE_DIMENSION;
170f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                    fixedW = v.width * MAX_SURFACE_DIMENSION / v.height;
171f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                }
1721fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger            }
173f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed            if (fixedW * fixedH > MAX_SURFACE_AREA) {
174f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                float area = MAX_SURFACE_AREA;
175f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                if (v.width > v.height) {
176f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                    fixedW = (int)Math.sqrt(area * v.width / v.height);
177f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                    fixedH = v.height * fixedW / v.width;
178f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                } else {
179f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                    fixedH = (int)Math.sqrt(area * v.height / v.width);
180f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                    fixedW = v.width * fixedH / v.height;
181f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                }
182f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed            }
183f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed
184f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed            if (fixedW != width || fixedH != height) {
185f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                // if we get here, either our dimensions or area (or both)
186f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                // exeeded our max, so we had to compute fixedW and fixedH
187f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                sView.getHolder().setFixedSize(fixedW, fixedH);
188f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed            } else if (!sView.isFixedSize() && mZoomInProgress) {
189f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                // just freeze where we were (view size) until we're done with
190f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                // the zoom progress
191f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                sView.getHolder().setFixedSize(sView.getWidth(),
192f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed                                               sView.getHeight());
193f066611aab5758b7b2a6b4a525e3f85aa813064aMike Reed            } else if (sView.isFixedSize() && !mZoomInProgress) {
1941fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger                /* The changing of visibility is a hack to get around a bug in
1951fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger                 * the framework that causes the surface to revert to the size
1961fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger                 * it was prior to being fixed before it redraws using the
1971fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger                 * values currently in its layout.
1981fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger                 *
1991fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger                 * The surface is destroyed when it is set to invisible and then
2001fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger                 * recreated at the new dimensions when it is made visible. The
2011fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger                 * same destroy/create step occurs without the change in
2021fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger                 * visibility, but then exhibits the behavior described in the
2031fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger                 * previous paragraph.
2041fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger                 */
2051fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger                if (sView.getVisibility() == View.VISIBLE) {
2061fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger                    sView.setVisibility(View.INVISIBLE);
2071fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger                    sView.getHolder().setSizeFromLayout();
2088aedd10aca67ce988888e99ecc3fcbe81344ea4dGrace Kloba                    // setLayoutParams() only requests the layout. If we set it
2098aedd10aca67ce988888e99ecc3fcbe81344ea4dGrace Kloba                    // to VISIBLE now, it will use the old dimension to set the
2108aedd10aca67ce988888e99ecc3fcbe81344ea4dGrace Kloba                    // size. Post a message to ensure that it shows the new size.
2118aedd10aca67ce988888e99ecc3fcbe81344ea4dGrace Kloba                    mWebView.mPrivateHandler.post(new Runnable() {
2128aedd10aca67ce988888e99ecc3fcbe81344ea4dGrace Kloba                        public void run() {
2138aedd10aca67ce988888e99ecc3fcbe81344ea4dGrace Kloba                            sView.setVisibility(View.VISIBLE);
2148aedd10aca67ce988888e99ecc3fcbe81344ea4dGrace Kloba                        }
2158aedd10aca67ce988888e99ecc3fcbe81344ea4dGrace Kloba                    });
2161fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger                } else {
2171fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger                    sView.getHolder().setSizeFromLayout();
2181fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger                }
2191fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger            }
2201fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger        }
2211fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger    }
2221fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger
2231fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger    void startZoom() {
2241fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger        mZoomInProgress = true;
2251fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger        for (ChildView v : mChildren) {
2261fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger            requestLayout(v);
2271fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger        }
2281fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger    }
2291fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger
2301fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger    void endZoom() {
2311fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger        mZoomInProgress = false;
2321fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger        for (ChildView v : mChildren) {
2331fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger            requestLayout(v);
23441df3f7e15b3d5f77dc7f255ec702e381eb93f35Derek Sollenberger        }
23541df3f7e15b3d5f77dc7f255ec702e381eb93f35Derek Sollenberger    }
23641df3f7e15b3d5f77dc7f255ec702e381eb93f35Derek Sollenberger
23741df3f7e15b3d5f77dc7f255ec702e381eb93f35Derek Sollenberger    void scaleAll() {
23841df3f7e15b3d5f77dc7f255ec702e381eb93f35Derek Sollenberger        for (ChildView v : mChildren) {
2391fa70928d3207c357bc8834f098b52e9f6107480Derek Sollenberger            requestLayout(v);
2400a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott        }
2410a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott    }
2420a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott
2430a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott    void hideAll() {
2440a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott        if (mHidden) {
2450a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott            return;
2460a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott        }
2470a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott        for (ChildView v : mChildren) {
2480a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott            v.mView.setVisibility(View.GONE);
2490a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott        }
2500a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott        mHidden = true;
2510a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott    }
2520a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott
2530a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott    void showAll() {
2540a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott        if (!mHidden) {
2550a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott            return;
2560a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott        }
2570a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott        for (ChildView v : mChildren) {
2580a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott            v.mView.setVisibility(View.VISIBLE);
2590a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott        }
2600a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott        mHidden = false;
2610a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott    }
2629a67c82089e43d37f5038c74b0e1dca8edc4ac8aGrace Kloba
2639a67c82089e43d37f5038c74b0e1dca8edc4ac8aGrace Kloba    void postResetStateAll() {
2649a67c82089e43d37f5038c74b0e1dca8edc4ac8aGrace Kloba        mWebView.mPrivateHandler.post(new Runnable() {
2659a67c82089e43d37f5038c74b0e1dca8edc4ac8aGrace Kloba            public void run() {
2669a67c82089e43d37f5038c74b0e1dca8edc4ac8aGrace Kloba                mReadyToDraw = false;
2679a67c82089e43d37f5038c74b0e1dca8edc4ac8aGrace Kloba            }
2689a67c82089e43d37f5038c74b0e1dca8edc4ac8aGrace Kloba        });
2699a67c82089e43d37f5038c74b0e1dca8edc4ac8aGrace Kloba    }
2709a67c82089e43d37f5038c74b0e1dca8edc4ac8aGrace Kloba
2719a67c82089e43d37f5038c74b0e1dca8edc4ac8aGrace Kloba    void postReadyToDrawAll() {
2729a67c82089e43d37f5038c74b0e1dca8edc4ac8aGrace Kloba        mWebView.mPrivateHandler.post(new Runnable() {
2739a67c82089e43d37f5038c74b0e1dca8edc4ac8aGrace Kloba            public void run() {
2749a67c82089e43d37f5038c74b0e1dca8edc4ac8aGrace Kloba                mReadyToDraw = true;
2759a67c82089e43d37f5038c74b0e1dca8edc4ac8aGrace Kloba                for (ChildView v : mChildren) {
2769a67c82089e43d37f5038c74b0e1dca8edc4ac8aGrace Kloba                    v.mView.setVisibility(View.VISIBLE);
2779a67c82089e43d37f5038c74b0e1dca8edc4ac8aGrace Kloba                }
2789a67c82089e43d37f5038c74b0e1dca8edc4ac8aGrace Kloba            }
2799a67c82089e43d37f5038c74b0e1dca8edc4ac8aGrace Kloba        });
2809a67c82089e43d37f5038c74b0e1dca8edc4ac8aGrace Kloba    }
281c6f95fe5236d8bd60ac01e7feb422f6fac70bf6fGrace Kloba
282c6f95fe5236d8bd60ac01e7feb422f6fac70bf6fGrace Kloba    ChildView hitTest(int contentX, int contentY) {
283c6f95fe5236d8bd60ac01e7feb422f6fac70bf6fGrace Kloba        if (mHidden) {
284c6f95fe5236d8bd60ac01e7feb422f6fac70bf6fGrace Kloba            return null;
285c6f95fe5236d8bd60ac01e7feb422f6fac70bf6fGrace Kloba        }
286c6f95fe5236d8bd60ac01e7feb422f6fac70bf6fGrace Kloba        for (ChildView v : mChildren) {
287c6f95fe5236d8bd60ac01e7feb422f6fac70bf6fGrace Kloba            if (v.mView.getVisibility() == View.VISIBLE) {
288c6f95fe5236d8bd60ac01e7feb422f6fac70bf6fGrace Kloba                if (contentX >= v.x && contentX < (v.x + v.width)
289c6f95fe5236d8bd60ac01e7feb422f6fac70bf6fGrace Kloba                        && contentY >= v.y && contentY < (v.y + v.height)) {
290c6f95fe5236d8bd60ac01e7feb422f6fac70bf6fGrace Kloba                    return v;
291c6f95fe5236d8bd60ac01e7feb422f6fac70bf6fGrace Kloba                }
292c6f95fe5236d8bd60ac01e7feb422f6fac70bf6fGrace Kloba            }
293c6f95fe5236d8bd60ac01e7feb422f6fac70bf6fGrace Kloba        }
294c6f95fe5236d8bd60ac01e7feb422f6fac70bf6fGrace Kloba        return null;
295c6f95fe5236d8bd60ac01e7feb422f6fac70bf6fGrace Kloba    }
2960a5ce01eda210f83619ada0603a80fd883512fe9Patrick Scott}
297