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