diff options
author | joth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-14 23:40:32 +0000 |
---|---|---|
committer | joth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-06-14 23:40:32 +0000 |
commit | 14a2df0d0dee8e5b861e6f9a13df932a39a05f61 (patch) | |
tree | dac870b1c6aa5827e177252f9e5b663bbdb2d436 /android_webview/java/src | |
parent | f1b149409ab54866b1a1e619ab9d59dc1d8f808d (diff) | |
download | chromium_src-14a2df0d0dee8e5b861e6f9a13df932a39a05f61.zip chromium_src-14a2df0d0dee8e5b861e6f9a13df932a39a05f61.tar.gz chromium_src-14a2df0d0dee8e5b861e6f9a13df932a39a05f61.tar.bz2 |
Fix Popup window flow to work with synchronous compositor gfx mode
This switches around the object lifetimes, so WebContents and AwContents
(native) have identical lifetimes, but now the native AwContents may
exist before its java counterpart, and in the popup flow the java
object may switch from its default peer instance to acquire the pop-up
AwContents/WebContents instead.
Additionally, makes some simplifications to the way AwSettings is created
and also fixes a potential leak (the native instance was never deleted if
destroy() was not called).
NOTRY=true
BUG=245801
Review URL: https://chromiumcodereview.appspot.com/16843008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@206516 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'android_webview/java/src')
3 files changed, 202 insertions, 182 deletions
diff --git a/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java b/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java index 2536d7b..9b0c987 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java +++ b/android_webview/java/src/org/chromium/android_webview/AwBrowserContext.java @@ -24,7 +24,14 @@ public class AwBrowserContext { private AwGeolocationPermissions mGeolocationPermissions; private AwCookieManager mCookieManager; private AwFormDatabase mFormDatabase; + boolean mIsFileAccessGrantedByDefault; + public AwBrowserContext(SharedPreferences sharedPreferences, + boolean isFileAccessGrantedByDefault) { + mIsFileAccessGrantedByDefault = isFileAccessGrantedByDefault; + } + + @Deprecated public AwBrowserContext(SharedPreferences sharedPreferences) { mSharedPreferences = sharedPreferences; } @@ -63,4 +70,4 @@ public class AwBrowserContext { public void resumeTimers() { ContentViewStatics.setWebKitSharedTimersSuspended(false); } -}
\ No newline at end of file +} diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java index 4730d24..9793b06 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContents.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java @@ -4,6 +4,7 @@ package org.chromium.android_webview; +import android.content.pm.PackageManager; import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.Canvas; @@ -15,6 +16,7 @@ import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.Message; +import android.os.Process; import android.text.TextUtils; import android.util.Log; import android.view.KeyEvent; @@ -107,19 +109,20 @@ public class AwContents { } private int mNativeAwContents; - private AwBrowserContext mBrowserContext; - private ViewGroup mContainerView; + private final AwBrowserContext mBrowserContext; + private final ViewGroup mContainerView; private ContentViewCore mContentViewCore; - private AwContentsClient mContentsClient; - private AwContentsClientBridge mContentsClientBridge; - private AwWebContentsDelegate mWebContentsDelegate; - private AwContentsIoThreadClient mIoThreadClient; - private InterceptNavigationDelegateImpl mInterceptNavigationDelegate; - private InternalAccessDelegate mInternalAccessAdapter; + private final AwContentsClient mContentsClient; + private final AwContentsClientBridge mContentsClientBridge; + private final AwWebContentsDelegate mWebContentsDelegate; + private final AwContentsIoThreadClient mIoThreadClient; + private final InterceptNavigationDelegateImpl mInterceptNavigationDelegate; + private final InternalAccessDelegate mInternalAccessAdapter; private final AwLayoutSizer mLayoutSizer; - private AwZoomControls mZoomControls; + private final AwZoomControls mZoomControls; // This can be accessed on any thread after construction. See AwContentsIoThreadClient. private final AwSettings mSettings; + private boolean mIsPaused; private Bitmap mFavicon; private boolean mHasRequestedVisitedHistoryFromClient; @@ -127,7 +130,7 @@ public class AwContents { private final double mDIPScale; // Must call nativeUpdateLastHitTestData first to update this before use. - private final HitTestData mPossiblyStaleHitTestData; + private final HitTestData mPossiblyStaleHitTestData = new HitTestData(); private DefaultVideoPosterRequestHandler mDefaultVideoPosterRequestHandler; @@ -313,15 +316,24 @@ public class AwContents { * @param containerView the view-hierarchy item this object will be bound to. * @param internalAccessAdapter to access private methods on containerView. * @param contentsClient will receive API callbacks from this WebView Contents - * @param isAccessFromFileURLsGrantedByDefault passed to AwSettings. * * This constructor uses the default view sizing policy. */ public AwContents(AwBrowserContext browserContext, ViewGroup containerView, + InternalAccessDelegate internalAccessAdapter, AwContentsClient contentsClient) { + this(browserContext, containerView, internalAccessAdapter, contentsClient, + new AwLayoutSizer()); + } + + // TODO(joth): Remove this overload when downstream no-longer passing + // isAccessFromFileURLsGrantedByDefault. + @Deprecated + public AwContents(AwBrowserContext browserContext, ViewGroup containerView, InternalAccessDelegate internalAccessAdapter, AwContentsClient contentsClient, boolean isAccessFromFileURLsGrantedByDefault) { this(browserContext, containerView, internalAccessAdapter, contentsClient, - isAccessFromFileURLsGrantedByDefault, new AwLayoutSizer()); + new AwLayoutSizer()); + browserContext.mIsFileAccessGrantedByDefault = isAccessFromFileURLsGrantedByDefault; } private static ContentViewCore createAndInitializeContentViewCore(ViewGroup containerView, @@ -348,96 +360,130 @@ public class AwContents { */ public AwContents(AwBrowserContext browserContext, ViewGroup containerView, InternalAccessDelegate internalAccessAdapter, AwContentsClient contentsClient, - boolean isAccessFromFileURLsGrantedByDefault, AwLayoutSizer layoutSizer) { + AwLayoutSizer layoutSizer) { mBrowserContext = browserContext; mContainerView = containerView; mInternalAccessAdapter = internalAccessAdapter; - mDIPScale = DeviceDisplayInfo.create(containerView.getContext()).getDIPScale(); - // Note that ContentViewCore must be set up before AwContents, as ContentViewCore - // setup performs process initialisation work needed by AwContents. - mContentsClientBridge = new AwContentsClientBridge(contentsClient); + mContentsClient = contentsClient; mLayoutSizer = layoutSizer; + mDIPScale = DeviceDisplayInfo.create(containerView.getContext()).getDIPScale(); mLayoutSizer.setDelegate(new AwLayoutSizerDelegate()); mLayoutSizer.setDIPScale(mDIPScale); mWebContentsDelegate = new AwWebContentsDelegateAdapter(contentsClient, mLayoutSizer.getPreferredSizeChangedListener()); - mNativeAwContents = nativeInit(mWebContentsDelegate, mContentsClientBridge); - mContentsClient = contentsClient; + mContentsClientBridge = new AwContentsClientBridge(contentsClient); + mZoomControls = new AwZoomControls(this); + mIoThreadClient = new IoThreadClientImpl(); + mInterceptNavigationDelegate = new InterceptNavigationDelegateImpl(); + + boolean hasInternetPermission = containerView.getContext().checkPermission( + android.Manifest.permission.INTERNET, + Process.myPid(), + Process.myUid()) == PackageManager.PERMISSION_GRANTED; + AwSettings.ZoomSupportChangeListener zoomListener = + new AwSettings.ZoomSupportChangeListener() { + @Override + public void onMultiTouchZoomSupportChanged(boolean supportsMultiTouchZoom) { + mContentViewCore.updateMultiTouchZoomSupport(supportsMultiTouchZoom); + } + }; + mSettings = new AwSettings(hasInternetPermission, zoomListener, + mBrowserContext.mIsFileAccessGrantedByDefault, mDIPScale); + mDefaultVideoPosterRequestHandler = new DefaultVideoPosterRequestHandler(mContentsClient); + mSettings.setDefaultVideoPosterURL( + mDefaultVideoPosterRequestHandler.getDefaultVideoPosterURL()); + mContentsClient.setDIPScale(mDIPScale); + + setNewAwContents(nativeInit(browserContext)); + } + + /** + * Common initialization routine for adopting a native AwContents instance into this + * java instance. + * + * TAKE CARE! This method can get called multiple times per java instance. Code accordingly. + * ^^^^^^^^^ See the native class declaration for more details on relative object lifetimes. + */ + private void setNewAwContents(int newAwContentsPtr) { + if (mNativeAwContents != 0) { + destroy(); + mContentViewCore = null; + } + + assert mNativeAwContents == 0 && mCleanupReference == null && mContentViewCore == null; + + mNativeAwContents = newAwContentsPtr; + // TODO(joth): when the native and java counterparts of AwBrowserContext are hooked up to + // each other, we should update |mBrowserContext| according to the newly received native + // WebContent's browser context. + + // The native side object has been bound to this java instance, so now is the time to + // bind all the native->java relationships. mCleanupReference = new CleanupReference(this, new DestroyRunnable(mNativeAwContents)); int nativeWebContents = nativeGetWebContents(mNativeAwContents); - mZoomControls = new AwZoomControls(this); mContentViewCore = createAndInitializeContentViewCore( - containerView, internalAccessAdapter, nativeWebContents, + mContainerView, mInternalAccessAdapter, nativeWebContents, new AwPinchGestureStateListener(), mContentsClient.getContentViewClient(), mZoomControls); + nativeSetJavaPeers(mNativeAwContents, this, mWebContentsDelegate, mContentsClientBridge, + mIoThreadClient, mInterceptNavigationDelegate); mContentsClient.installWebContentsObserver(mContentViewCore); + mSettings.setWebContents(nativeWebContents); + } - mSettings = new AwSettings(mContentViewCore.getContext(), nativeWebContents, - mContentViewCore, isAccessFromFileURLsGrantedByDefault); - setIoThreadClient(new IoThreadClientImpl()); - setInterceptNavigationDelegate(new InterceptNavigationDelegateImpl()); - - mPossiblyStaleHitTestData = new HitTestData(); - nativeDidInitializeContentViewCore(mNativeAwContents, - mContentViewCore.getNativeContentViewCore()); - - mContentsClient.setDIPScale(mDIPScale); - mSettings.setDIPScale(mDIPScale); - mDefaultVideoPosterRequestHandler = new DefaultVideoPosterRequestHandler(mContentsClient); - mSettings.setDefaultVideoPosterURL( - mDefaultVideoPosterRequestHandler.getDefaultVideoPosterURL()); - } - - // Only valid within updatePhysicalBackingSizeIfNeeded(). - private final Rect mGlobalVisibleBoundsTemporary = new Rect(); - - private void updatePhysicalBackingSizeIfNeeded() { - // We musn't let the physical backing size get too big, otherwise we - // will try to allocate a SurfaceTexture beyond what the GL driver can - // cope with. In most cases, limiting the SurfaceTexture size to that - // of the visible bounds of the WebView will be good enough i.e. the maximum - // SurfaceTexture dimensions will match the screen dimensions). - mContainerView.getGlobalVisibleRect(mGlobalVisibleBoundsTemporary); - int width = mGlobalVisibleBoundsTemporary.width(); - int height = mGlobalVisibleBoundsTemporary.height(); - if (width != mLastGlobalVisibleWidth || height != mLastGlobalVisibleHeight) { - mLastGlobalVisibleWidth = width; - mLastGlobalVisibleHeight = height; - mContentViewCore.onPhysicalBackingSizeChanged(width, height); + /** + * Called on the "source" AwContents that is opening the popup window to + * provide the AwContents to host the pop up content. + */ + public void supplyContentsForPopup(AwContents newContents) { + int popupNativeAwContents = nativeReleasePopupAwContents(mNativeAwContents); + if (popupNativeAwContents == 0) { + Log.w(TAG, "Popup WebView bind failed: no pending content."); + if (newContents != null) newContents.destroy(); + return; + } + if (newContents == null) { + nativeDestroy(popupNativeAwContents); + return; } - } - - @VisibleForTesting - public ContentViewCore getContentViewCore() { - return mContentViewCore; - } - // Can be called from any thread. - public AwSettings getSettings() { - return mSettings; + newContents.receivePopupContents(popupNativeAwContents); } - public void setIoThreadClient(AwContentsIoThreadClient ioThreadClient) { - mIoThreadClient = ioThreadClient; - nativeSetIoThreadClient(mNativeAwContents, mIoThreadClient); - } + // Recap: supplyContentsForPopup() is called on the parent window's content, this method is + // called on the popup window's content. + private void receivePopupContents(int popupNativeAwContents) { + setNewAwContents(popupNativeAwContents); - private void setInterceptNavigationDelegate(InterceptNavigationDelegateImpl delegate) { - mInterceptNavigationDelegate = delegate; - nativeSetInterceptNavigationDelegate(mNativeAwContents, delegate); + // Finally refresh view size and visibility, to poke new values into ContentViewCore. + mLastGlobalVisibleWidth = 0; + mLastGlobalVisibleHeight = 0; + onSizeChanged(mContainerView.getWidth(), mContainerView.getHeight(), 0, 0); + updateVisiblityState(); + onWindowFocusChanged(mWindowFocused); } public void destroy() { mContentViewCore.destroy(); - // The native part of AwSettings isn't needed for the IoThreadClient instance. - mSettings.destroy(); // We explicitly do not null out the mContentViewCore reference here // because ContentViewCore already has code to deal with the case // methods are called on it after it's been destroyed, and other // code relies on AwContents.mContentViewCore to be non-null. + mCleanupReference.cleanupNow(); mNativeAwContents = 0; + mCleanupReference = null; + } + + @VisibleForTesting + public ContentViewCore getContentViewCore() { + return mContentViewCore; + } + + // Can be called from any thread. + public AwSettings getSettings() { + return mSettings; } public static void setAwDrawSWFunctionTable(int functionTablePointer) { @@ -458,6 +504,29 @@ public class AwContents { return nativeGetAwDrawGLViewContext(mNativeAwContents); } + // Only valid within updatePhysicalBackingSizeIfNeeded(). + private final Rect mGlobalVisibleBoundsTemporary = new Rect(); + + private void updatePhysicalBackingSizeIfNeeded() { + // We musn't let the physical backing size get too big, otherwise we + // will try to allocate a SurfaceTexture beyond what the GL driver can + // cope with. In most cases, limiting the SurfaceTexture size to that + // of the visible bounds of the WebView will be good enough i.e. the maximum + // SurfaceTexture dimensions will match the screen dimensions). + mContainerView.getGlobalVisibleRect(mGlobalVisibleBoundsTemporary); + int width = mGlobalVisibleBoundsTemporary.width(); + int height = mGlobalVisibleBoundsTemporary.height(); + if (width != mLastGlobalVisibleWidth || height != mLastGlobalVisibleHeight) { + mLastGlobalVisibleWidth = width; + mLastGlobalVisibleHeight = height; + mContentViewCore.onPhysicalBackingSizeChanged(width, height); + } + } + + //-------------------------------------------------------------------------------------------- + // WebView[Provider] method implementations (where not provided by ContentViewCore) + //-------------------------------------------------------------------------------------------- + // Only valid within onDraw(). private final Rect mClipBoundsTemporary = new Rect(); @@ -602,50 +671,6 @@ public class AwContents { if (url == null || url.trim().isEmpty()) return null; return url; } - /** - * Called on the "source" AwContents that is opening the popup window to - * provide the AwContents to host the pop up content. - */ - public void supplyContentsForPopup(AwContents newContents) { - int popupWebContents = nativeReleasePopupWebContents(mNativeAwContents); - assert popupWebContents != 0; - newContents.setNewWebContents(popupWebContents); - } - - private void setNewWebContents(int newWebContentsPtr) { - // When setting a new WebContents, we new up a ContentViewCore that will - // wrap it and then swap it. - ContentViewCore newCore = createAndInitializeContentViewCore( - mContainerView, mInternalAccessAdapter, newWebContentsPtr, - new AwPinchGestureStateListener(), mContentsClient.getContentViewClient(), - mZoomControls); - mContentsClient.installWebContentsObserver(newCore); - - // Now swap the Java side reference. - mContentViewCore.destroy(); - mContentViewCore = newCore; - - // Now rewire native side to use the new WebContents. - nativeSetWebContents(mNativeAwContents, newWebContentsPtr); - nativeSetIoThreadClient(mNativeAwContents, mIoThreadClient); - nativeSetInterceptNavigationDelegate(mNativeAwContents, mInterceptNavigationDelegate); - - // This will also apply settings to the new WebContents. - mSettings.setWebContents(newWebContentsPtr); - - // Finally poke the new ContentViewCore with the size of the container view and show it. - if (mContainerView.getWidth() != 0 || mContainerView.getHeight() != 0) { - mContentViewCore.onSizeChanged( - mContainerView.getWidth(), mContainerView.getHeight(), 0, 0); - } - nativeDidInitializeContentViewCore(mNativeAwContents, - mContentViewCore.getNativeContentViewCore()); - if (mContainerView.getVisibility() == View.VISIBLE) { - // The popup window was hidden when we prompted the embedder to display - // it, so show it again now we have a container. - mContentViewCore.onShow(); - } - } public void requestFocus() { if (!mContainerView.isInTouchMode() && mSettings.shouldFocusFirstNode()) { @@ -661,10 +686,6 @@ public class AwContents { return mZoomControls.getZoomControlsViewForTest(); } - //-------------------------------------------------------------------------------------------- - // WebView[Provider] method implementations (where not provided by ContentViewCore) - //-------------------------------------------------------------------------------------------- - /** * @see ContentViewCore#getContentSettings() */ @@ -1425,26 +1446,22 @@ public class AwContents { // Native methods //-------------------------------------------------------------------------------------------- - private native int nativeInit(AwWebContentsDelegate webViewWebContentsDelegate, - AwContentsClientBridge contentsClientBridge); + private static native int nativeInit(AwBrowserContext browserContext); private static native void nativeDestroy(int nativeAwContents); private static native void nativeSetAwDrawSWFunctionTable(int functionTablePointer); private static native void nativeSetAwDrawGLFunctionTable(int functionTablePointer); private static native int nativeGetAwDrawGLFunction(); - + private native void nativeSetJavaPeers(int nativeAwContents, AwContents awContents, + AwWebContentsDelegate webViewWebContentsDelegate, + AwContentsClientBridge contentsClientBridge, + AwContentsIoThreadClient ioThreadClient, + InterceptNavigationDelegate navigationInterceptionDelegate); private native int nativeGetWebContents(int nativeAwContents); - private native void nativeDidInitializeContentViewCore(int nativeAwContents, - int nativeContentViewCore); private native void nativeDocumentHasImages(int nativeAwContents, Message message); private native void nativeGenerateMHTML( int nativeAwContents, String path, ValueCallback<String> callback); - private native void nativeSetIoThreadClient(int nativeAwContents, - AwContentsIoThreadClient ioThreadClient); - private native void nativeSetInterceptNavigationDelegate(int nativeAwContents, - InterceptNavigationDelegate navigationInterceptionDelegate); - private native void nativeAddVisitedLinks(int nativeAwContents, String[] visitedLinks); private native boolean nativeOnDraw(int nativeAwContents, Canvas canvas, boolean isHardwareAccelerated, int scrollX, int ScrollY, @@ -1471,8 +1488,7 @@ public class AwContents { // Returns false if restore state fails. private native boolean nativeRestoreFromOpaqueState(int nativeAwContents, byte[] state); - private native int nativeReleasePopupWebContents(int nativeAwContents); - private native void nativeSetWebContents(int nativeAwContents, int nativeNewWebContents); + private native int nativeReleasePopupAwContents(int nativeAwContents); private native void nativeFocusFirstNode(int nativeAwContents); private native int nativeGetAwDrawGLViewContext(int nativeAwContents); diff --git a/android_webview/java/src/org/chromium/android_webview/AwSettings.java b/android_webview/java/src/org/chromium/android_webview/AwSettings.java index 2be4d46..0f3ddc2 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwSettings.java +++ b/android_webview/java/src/org/chromium/android_webview/AwSettings.java @@ -4,12 +4,9 @@ package org.chromium.android_webview; -import android.content.Context; -import android.content.pm.PackageManager; import android.os.Handler; import android.os.Looper; import android.os.Message; -import android.os.Process; import android.webkit.WebSettings.PluginState; import android.webkit.WebSettings; import android.webkit.WebView; @@ -43,12 +40,14 @@ public class AwSettings { // used from any thread. Internally, the class uses a message queue // to call native code on the UI thread only. + // Values passed in on construction. + private final boolean mHasInternetPermission; + private final ZoomSupportChangeListener mZoomChangeListener; + private final double mDIPScale; + // Lock to protect all settings. private final Object mAwSettingsLock = new Object(); - private final Context mContext; - private double mDIPScale; - private LayoutAlgorithm mLayoutAlgorithm = LayoutAlgorithm.NARROW_COLUMNS; private int mTextSizePercent = 100; private String mStandardFontFamily = "sans-serif"; @@ -94,6 +93,7 @@ public class AwSettings { private boolean mSupportZoom = true; private boolean mBuiltInZoomControls = false; private boolean mDisplayZoomControls = true; + static class LazyDefaultUserAgent{ // Lazy Holder pattern private static final String sInstance = nativeGetDefaultUserAgent(); @@ -106,11 +106,9 @@ public class AwSettings { // client. private static boolean sAppCachePathIsSet = false; - // The native side of this object. + // The native side of this object. It's lifetime is bounded by the WebContent it is attached to. private int mNativeAwSettings = 0; - private ContentViewCore mContentViewCore; - // A flag to avoid sending superfluous synchronization messages. private boolean mIsUpdateWebkitPrefsMessagePending = false; // Custom handler that queues messages to call native code on the UI thread. @@ -166,44 +164,39 @@ public class AwSettings { } } - public AwSettings(Context context, - int nativeWebContents, - ContentViewCore contentViewCore, - boolean isAccessFromFileURLsGrantedByDefault) { - ThreadUtils.assertOnUiThread(); - mContext = context; - mBlockNetworkLoads = mContext.checkPermission( - android.Manifest.permission.INTERNET, - Process.myPid(), - Process.myUid()) != PackageManager.PERMISSION_GRANTED; - mContentViewCore = contentViewCore; - mContentViewCore.updateMultiTouchZoomSupport(supportsMultiTouchZoomLocked()); + interface ZoomSupportChangeListener { + public void onMultiTouchZoomSupportChanged(boolean supportsMultiTouchZoom); + } - if (isAccessFromFileURLsGrantedByDefault) { - mAllowUniversalAccessFromFileURLs = true; - mAllowFileAccessFromFileURLs = true; - } + public AwSettings(boolean hasInternetPermission, + ZoomSupportChangeListener zoomChangeListener, + boolean isAccessFromFileURLsGrantedByDefault, + double dipScale) { + ThreadUtils.assertOnUiThread(); + synchronized (mAwSettingsLock) { + mHasInternetPermission = hasInternetPermission; + mZoomChangeListener = zoomChangeListener; + mDIPScale = dipScale; + mEventHandler = new EventHandler(); + mBlockNetworkLoads = !hasInternetPermission; - mEventHandler = new EventHandler(); - mUserAgent = LazyDefaultUserAgent.sInstance; + if (isAccessFromFileURLsGrantedByDefault) { + mAllowUniversalAccessFromFileURLs = true; + mAllowFileAccessFromFileURLs = true; + } - synchronized (mAwSettingsLock) { - mNativeAwSettings = nativeInit(nativeWebContents); + mUserAgent = LazyDefaultUserAgent.sInstance; + onMultiTouchZoomSupportChanged(supportsMultiTouchZoomLocked()); } - assert mNativeAwSettings != 0; + // Defer initializing the native side until a native WebContents instance is set. } - public void destroy() { - nativeDestroy(mNativeAwSettings); + @CalledByNative + private void nativeAwSettingsGone(int nativeAwSettings) { + assert mNativeAwSettings != 0 && mNativeAwSettings == nativeAwSettings; mNativeAwSettings = 0; } - public void setDIPScale(double dipScale) { - synchronized (mAwSettingsLock) { - mDIPScale = dipScale; - } - } - @CalledByNative private double getDIPScaleLocked() { return mDIPScale; @@ -211,7 +204,14 @@ public class AwSettings { public void setWebContents(int nativeWebContents) { synchronized (mAwSettingsLock) { - nativeSetWebContentsLocked(mNativeAwSettings, nativeWebContents); + if (mNativeAwSettings != 0) { + nativeDestroy(mNativeAwSettings); + assert mNativeAwSettings == 0; // nativeAwSettingsGone should have been called. + } + if (nativeWebContents != 0) { + mNativeAwSettings = nativeInit(nativeWebContents); + nativeUpdateEverythingLocked(mNativeAwSettings); + } } } @@ -220,10 +220,7 @@ public class AwSettings { */ public void setBlockNetworkLoads(boolean flag) { synchronized (mAwSettingsLock) { - if (!flag && mContext.checkPermission( - android.Manifest.permission.INTERNET, - Process.myPid(), - Process.myUid()) != PackageManager.PERMISSION_GRANTED) { + if (!flag && !mHasInternetPermission) { throw new SecurityException("Permission denied - " + "application missing INTERNET permission"); } @@ -1239,11 +1236,12 @@ public class AwSettings { return mDefaultVideoPosterURL; } - private void updateMultiTouchZoomSupport(final boolean supportsMultiTouchZoom) { - ThreadUtils.runOnUiThreadBlocking(new Runnable() { + private void onMultiTouchZoomSupportChanged(final boolean supportsMultiTouchZoom) { + // Always post asynchronously here, to avoid doubling back onto the caller. + ThreadUtils.postOnUiThread(new Runnable() { @Override public void run() { - mContentViewCore.updateMultiTouchZoomSupport(supportsMultiTouchZoom); + mZoomChangeListener.onMultiTouchZoomSupportChanged(supportsMultiTouchZoom); } }); } @@ -1255,7 +1253,7 @@ public class AwSettings { synchronized (mAwSettingsLock) { if (mSupportZoom != support) { mSupportZoom = support; - updateMultiTouchZoomSupport(supportsMultiTouchZoomLocked()); + onMultiTouchZoomSupportChanged(supportsMultiTouchZoomLocked()); } } } @@ -1276,7 +1274,7 @@ public class AwSettings { synchronized (mAwSettingsLock) { if (mBuiltInZoomControls != enabled) { mBuiltInZoomControls = enabled; - updateMultiTouchZoomSupport(supportsMultiTouchZoomLocked()); + onMultiTouchZoomSupportChanged(supportsMultiTouchZoomLocked()); } } } @@ -1309,6 +1307,7 @@ public class AwSettings { } private boolean supportsMultiTouchZoomLocked() { + assert Thread.holdsLock(mAwSettingsLock); return mSupportZoom && mBuiltInZoomControls; } @@ -1353,8 +1352,6 @@ public class AwSettings { private native void nativeResetScrollAndScaleState(int nativeAwSettings); - private native void nativeSetWebContentsLocked(int nativeAwSettings, int nativeWebContents); - private native void nativeUpdateEverythingLocked(int nativeAwSettings); private native void nativeUpdateInitialPageScaleLocked(int nativeAwSettings); |