Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / android_webview / java / src / org / chromium / android_webview / AwSettings.java
index 645ec6a..9c8f3b4 100644 (file)
@@ -59,8 +59,7 @@ public class AwSettings {
     private String mSerifFontFamily = "serif";
     private String mCursiveFontFamily = "cursive";
     private String mFantasyFontFamily = "fantasy";
-    // TODO(mnaganov): Should be obtained from Android. Problem: it is hidden.
-    private String mDefaultTextEncoding = "Latin-1";
+    private String mDefaultTextEncoding;
     private String mUserAgent;
     private int mMinimumFontSize = 8;
     private int mMinimumLogicalFontSize = 8;
@@ -89,9 +88,6 @@ public class AwSettings {
 
     private final boolean mPasswordEchoEnabled;
 
-    // Font scale factor determined by Android system setting.
-    private final float mFontScale;
-
     // Not accessed by the native side.
     private boolean mBlockNetworkLoads;  // Default depends on permission of embedding APK.
     private boolean mAllowContentUrlAccess = true;
@@ -119,8 +115,6 @@ public class AwSettings {
     // The native side of this object. It's lifetime is bounded by the WebContent it is attached to.
     private long mNativeAwSettings = 0;
 
-    // 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.
     private final EventHandler mEventHandler;
 
@@ -129,10 +123,12 @@ public class AwSettings {
 
     // Class to handle messages to be processed on the UI thread.
     private class EventHandler {
-        // Message id for updating Webkit preferences
-        private static final int UPDATE_WEBKIT_PREFERENCES = 0;
+        // Message id for running a Runnable with mAwSettingsLock held.
+        private static final int RUN_RUNNABLE_BLOCKING = 0;
         // Actual UI thread handler
         private Handler mHandler;
+        // Synchronization flag.
+        private boolean mSynchronizationPending = false;
 
         EventHandler() {
         }
@@ -143,10 +139,12 @@ public class AwSettings {
                 @Override
                 public void handleMessage(Message msg) {
                     switch (msg.what) {
-                        case UPDATE_WEBKIT_PREFERENCES:
+                        case RUN_RUNNABLE_BLOCKING:
                             synchronized (mAwSettingsLock) {
-                                updateWebkitPreferencesOnUiThreadLocked();
-                                mIsUpdateWebkitPrefsMessagePending = false;
+                                if (mNativeAwSettings != 0) {
+                                    ((Runnable)msg.obj).run();
+                                }
+                                mSynchronizationPending = false;
                                 mAwSettingsLock.notifyAll();
                             }
                             break;
@@ -155,46 +153,45 @@ public class AwSettings {
             };
         }
 
-        void maybeRunOnUiThreadBlocking(Runnable r) {
-            if (mHandler != null) {
-                ThreadUtils.runOnUiThreadBlocking(r);
-            }
-        }
-
-        void maybePostOnUiThread(Runnable r) {
-            if (mHandler != null) {
-                mHandler.post(r);
-            }
-        }
-
-        private void updateWebkitPreferencesLocked() {
+        void runOnUiThreadBlockingAndLocked(Runnable r) {
             assert Thread.holdsLock(mAwSettingsLock);
-            if (mNativeAwSettings == 0) return;
             if (mHandler == null) return;
             if (ThreadUtils.runningOnUiThread()) {
-                updateWebkitPreferencesOnUiThreadLocked();
+                r.run();
             } else {
-                // We're being called on a background thread, so post a message.
-                if (mIsUpdateWebkitPrefsMessagePending) {
-                    return;
-                }
-                mIsUpdateWebkitPrefsMessagePending = true;
-                mHandler.sendMessage(Message.obtain(null, UPDATE_WEBKIT_PREFERENCES));
-                // We must block until the settings have been sync'd to native to
-                // ensure that they have taken effect.
+                assert !mSynchronizationPending;
+                mSynchronizationPending = true;
+                mHandler.sendMessage(Message.obtain(null, RUN_RUNNABLE_BLOCKING, r));
                 try {
-                    while (mIsUpdateWebkitPrefsMessagePending) {
+                    while (mSynchronizationPending) {
                         mAwSettingsLock.wait();
                     }
                 } catch (InterruptedException e) {
-                    Log.e(TAG, "Interrupted waiting to sync settings to native", e);
+                    Log.e(TAG, "Interrupted waiting a Runnable to complete", e);
+                    mSynchronizationPending = false;
                 }
             }
         }
+
+        void maybePostOnUiThread(Runnable r) {
+            if (mHandler != null) {
+                mHandler.post(r);
+            }
+        }
+
+        void updateWebkitPreferencesLocked() {
+            runOnUiThreadBlockingAndLocked(new Runnable() {
+                @Override
+                public void run() {
+                    updateWebkitPreferencesOnUiThreadLocked();
+                }
+            });
+        }
     }
 
     interface ZoomSupportChangeListener {
-        public void onGestureZoomSupportChanged(boolean supportsGestureZoom);
+        public void onGestureZoomSupportChanged(
+                boolean supportsDoubleTapZoom, boolean supportsMultiTouchZoom);
     }
 
     public AwSettings(Context context,
@@ -213,6 +210,7 @@ public class AwSettings {
                 mAllowFileAccessFromFileURLs = true;
             }
 
+            mDefaultTextEncoding = AwResource.getDefaultTextEncoding();
             mUserAgent = LazyDefaultUserAgent.sInstance;
 
             // Best-guess a sensible initial value based on the features supported on the device.
@@ -222,8 +220,10 @@ public class AwSettings {
             // Respect the system setting for password echoing.
             mPasswordEchoEnabled = Settings.System.getInt(context.getContentResolver(),
                     Settings.System.TEXT_SHOW_PASSWORD, 1) == 1;
-            mFontScale = context.getResources().getConfiguration().fontScale;
-            mTextSizePercent *= mFontScale;
+
+            // By default, scale the text size by the system font scale factor. Embedders
+            // may override this by invoking setTextZoom().
+            mTextSizePercent *= context.getResources().getConfiguration().fontScale;
 
             mSupportLegacyQuirks = supportsLegacyQuirks;
         }
@@ -238,6 +238,7 @@ public class AwSettings {
 
     @CalledByNative
     private double getDIPScaleLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mDIPScale;
     }
 
@@ -265,7 +266,8 @@ public class AwSettings {
                 mEventHandler.bindUiThread();
                 mNativeAwSettings = nativeInit(nativeWebContents);
                 nativeUpdateEverythingLocked(mNativeAwSettings);
-                onGestureZoomSupportChanged(supportsGestureZoomLocked());
+                onGestureZoomSupportChanged(
+                        supportsDoubleTapZoomLocked(), supportsMultiTouchZoomLocked());
             }
         }
     }
@@ -368,12 +370,10 @@ public class AwSettings {
         synchronized (mAwSettingsLock) {
             if (mInitialPageScalePercent != scaleInPercent) {
                 mInitialPageScalePercent = scaleInPercent;
-                mEventHandler.maybeRunOnUiThreadBlocking(new Runnable() {
+                mEventHandler.runOnUiThreadBlockingAndLocked(new Runnable() {
                     @Override
                     public void run() {
-                        if (mNativeAwSettings != 0) {
-                            nativeUpdateInitialPageScaleLocked(mNativeAwSettings);
-                        }
+                        nativeUpdateInitialPageScaleLocked(mNativeAwSettings);
                     }
                 });
             }
@@ -382,6 +382,7 @@ public class AwSettings {
 
     @CalledByNative
     private float getInitialPageScalePercentLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mInitialPageScalePercent;
     }
 
@@ -396,6 +397,7 @@ public class AwSettings {
 
     @CalledByNative
     private boolean getSpatialNavigationLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mSpatialNavigationEnabled;
     }
 
@@ -410,6 +412,7 @@ public class AwSettings {
 
     @CalledByNative
     private boolean getEnableSupportedHardwareAcceleratedFeaturesLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mEnableSupportedHardwareAcceleratedFeatures;
     }
 
@@ -449,12 +452,10 @@ public class AwSettings {
         synchronized (mAwSettingsLock) {
             if (mAutoCompleteEnabled != enable) {
                 mAutoCompleteEnabled = enable;
-                mEventHandler.maybeRunOnUiThreadBlocking(new Runnable() {
+                mEventHandler.runOnUiThreadBlockingAndLocked(new Runnable() {
                     @Override
                     public void run() {
-                        if (mNativeAwSettings != 0) {
-                            nativeUpdateFormDataPreferencesLocked(mNativeAwSettings);
-                        }
+                        nativeUpdateFormDataPreferencesLocked(mNativeAwSettings);
                     }
                 });
             }
@@ -472,6 +473,7 @@ public class AwSettings {
 
     @CalledByNative
     private boolean getSaveFormDataLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mAutoCompleteEnabled;
     }
 
@@ -495,12 +497,10 @@ public class AwSettings {
                 mUserAgent = ua;
             }
             if (!oldUserAgent.equals(mUserAgent)) {
-                mEventHandler.maybeRunOnUiThreadBlocking(new Runnable() {
+                mEventHandler.runOnUiThreadBlockingAndLocked(new Runnable() {
                     @Override
                     public void run() {
-                        if (mNativeAwSettings != 0) {
-                            nativeUpdateUserAgentLocked(mNativeAwSettings);
-                        }
+                        nativeUpdateUserAgentLocked(mNativeAwSettings);
                     }
                 });
             }
@@ -518,6 +518,7 @@ public class AwSettings {
 
     @CalledByNative
     private String getUserAgentLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mUserAgent;
     }
 
@@ -528,13 +529,11 @@ public class AwSettings {
         synchronized (mAwSettingsLock) {
             if (mLoadWithOverviewMode != overview) {
                 mLoadWithOverviewMode = overview;
-                mEventHandler.updateWebkitPreferencesLocked();
-                mEventHandler.maybeRunOnUiThreadBlocking(new Runnable() {
+                mEventHandler.runOnUiThreadBlockingAndLocked(new Runnable() {
                     @Override
                     public void run() {
-                        if (mNativeAwSettings != 0) {
-                            nativeResetScrollAndScaleState(mNativeAwSettings);
-                        }
+                        updateWebkitPreferencesOnUiThreadLocked();
+                        nativeResetScrollAndScaleState(mNativeAwSettings);
                     }
                 });
             }
@@ -552,6 +551,7 @@ public class AwSettings {
 
     @CalledByNative
     private boolean getLoadWithOverviewModeLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mLoadWithOverviewMode;
     }
 
@@ -560,9 +560,8 @@ public class AwSettings {
      */
     public void setTextZoom(final int textZoom) {
         synchronized (mAwSettingsLock) {
-            int scaledTextZoomPercent = (int)(textZoom * mFontScale);
-            if (mTextSizePercent != scaledTextZoomPercent) {
-                mTextSizePercent = scaledTextZoomPercent;
+            if (mTextSizePercent != textZoom) {
+                mTextSizePercent = textZoom;
                 mEventHandler.updateWebkitPreferencesLocked();
             }
         }
@@ -579,6 +578,7 @@ public class AwSettings {
 
     @CalledByNative
     private int getTextSizePercentLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mTextSizePercent;
     }
 
@@ -605,6 +605,7 @@ public class AwSettings {
 
     @CalledByNative
     private String getStandardFontFamilyLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mStandardFontFamily;
     }
 
@@ -631,6 +632,7 @@ public class AwSettings {
 
     @CalledByNative
     private String getFixedFontFamilyLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mFixedFontFamily;
     }
 
@@ -657,6 +659,7 @@ public class AwSettings {
 
     @CalledByNative
     private String getSansSerifFontFamilyLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mSansSerifFontFamily;
     }
 
@@ -683,6 +686,7 @@ public class AwSettings {
 
     @CalledByNative
     private String getSerifFontFamilyLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mSerifFontFamily;
     }
 
@@ -709,6 +713,7 @@ public class AwSettings {
 
     @CalledByNative
     private String getCursiveFontFamilyLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mCursiveFontFamily;
     }
 
@@ -735,6 +740,7 @@ public class AwSettings {
 
     @CalledByNative
     private String getFantasyFontFamilyLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mFantasyFontFamily;
     }
 
@@ -762,6 +768,7 @@ public class AwSettings {
 
     @CalledByNative
     private int getMinimumFontSizeLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mMinimumFontSize;
     }
 
@@ -789,6 +796,7 @@ public class AwSettings {
 
     @CalledByNative
     private int getMinimumLogicalFontSizeLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mMinimumLogicalFontSize;
     }
 
@@ -816,6 +824,7 @@ public class AwSettings {
 
     @CalledByNative
     private int getDefaultFontSizeLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mDefaultFontSize;
     }
 
@@ -843,6 +852,7 @@ public class AwSettings {
 
     @CalledByNative
     private int getDefaultFixedFontSizeLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mDefaultFixedFontSize;
     }
 
@@ -905,6 +915,7 @@ public class AwSettings {
 
     @CalledByNative
     private boolean getLoadsImagesAutomaticallyLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mLoadsImagesAutomatically;
     }
 
@@ -931,6 +942,7 @@ public class AwSettings {
 
     @CalledByNative
     private boolean getImagesEnabledLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mImagesEnabled;
     }
 
@@ -945,6 +957,7 @@ public class AwSettings {
 
     @CalledByNative
     private boolean getJavaScriptEnabledLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mJavaScriptEnabled;
     }
 
@@ -959,6 +972,7 @@ public class AwSettings {
 
     @CalledByNative
     private boolean getAllowUniversalAccessFromFileURLsLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mAllowUniversalAccessFromFileURLs;
     }
 
@@ -973,6 +987,7 @@ public class AwSettings {
 
     @CalledByNative
     private boolean getAllowFileAccessFromFileURLsLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mAllowFileAccessFromFileURLs;
     }
 
@@ -1007,10 +1022,10 @@ public class AwSettings {
     /**
      * Return true if plugins are disabled.
      * @return True if plugins are disabled.
-     * @hide
      */
     @CalledByNative
     private boolean getPluginsDisabledLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mPluginState == PluginState.OFF;
     }
 
@@ -1047,6 +1062,7 @@ public class AwSettings {
 
     @CalledByNative
     private boolean getJavaScriptCanOpenWindowsAutomaticallyLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mJavaScriptCanOpenWindowsAutomatically;
     }
 
@@ -1075,10 +1091,10 @@ public class AwSettings {
      * Gets whether Text Auto-sizing layout algorithm is enabled.
      *
      * @return true if Text Auto-sizing layout algorithm is enabled
-     * @hide
      */
     @CalledByNative
     private boolean getTextAutosizingEnabledLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mLayoutAlgorithm == LayoutAlgorithm.TEXT_AUTOSIZING;
     }
 
@@ -1105,11 +1121,13 @@ public class AwSettings {
 
     @CalledByNative
     private boolean getSupportMultipleWindowsLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mSupportMultipleWindows;
     }
 
     @CalledByNative
     private boolean getSupportLegacyQuirksLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mSupportLegacyQuirks;
     }
 
@@ -1120,6 +1138,8 @@ public class AwSettings {
         synchronized (mAwSettingsLock) {
             if (mUseWideViewport != use) {
                 mUseWideViewport = use;
+                onGestureZoomSupportChanged(
+                        supportsDoubleTapZoomLocked(), supportsMultiTouchZoomLocked());
                 mEventHandler.updateWebkitPreferencesLocked();
             }
         }
@@ -1136,11 +1156,13 @@ public class AwSettings {
 
     @CalledByNative
     private boolean getUseWideViewportLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mUseWideViewport;
     }
 
     @CalledByNative
     private boolean getPasswordEchoEnabledLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mPasswordEchoEnabled;
     }
 
@@ -1182,10 +1204,10 @@ public class AwSettings {
      * Gets whether Application Cache is enabled.
      *
      * @return true if Application Cache is enabled
-     * @hide
      */
     @CalledByNative
     private boolean getAppCacheEnabledLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         if (!mAppCacheEnabled) {
             return false;
         }
@@ -1217,6 +1239,7 @@ public class AwSettings {
 
     @CalledByNative
     private boolean getDomStorageEnabledLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mDomStorageEnabled;
     }
 
@@ -1243,6 +1266,7 @@ public class AwSettings {
 
     @CalledByNative
     private boolean getDatabaseEnabledLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mDatabaseEnabled;
     }
 
@@ -1269,6 +1293,7 @@ public class AwSettings {
 
     @CalledByNative
     private String getDefaultTextEncodingLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mDefaultTextEncoding;
     }
 
@@ -1295,6 +1320,7 @@ public class AwSettings {
 
     @CalledByNative
     private boolean getMediaPlaybackRequiresUserGestureLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mMediaPlaybackRequiresUserGesture;
     }
 
@@ -1322,17 +1348,20 @@ public class AwSettings {
 
     @CalledByNative
     private String getDefaultVideoPosterURLLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
         return mDefaultVideoPosterURL;
     }
 
-    private void onGestureZoomSupportChanged(final boolean supportsGestureZoom) {
+    private void onGestureZoomSupportChanged(
+            final boolean supportsDoubleTapZoom, final boolean supportsMultiTouchZoom) {
         // Always post asynchronously here, to avoid doubling back onto the caller.
         mEventHandler.maybePostOnUiThread(new Runnable() {
             @Override
             public void run() {
                 synchronized (mAwSettingsLock) {
                     if (mZoomChangeListener != null) {
-                        mZoomChangeListener.onGestureZoomSupportChanged(supportsGestureZoom);
+                        mZoomChangeListener.onGestureZoomSupportChanged(
+                                supportsDoubleTapZoom, supportsMultiTouchZoom);
                     }
                 }
             }
@@ -1346,7 +1375,8 @@ public class AwSettings {
         synchronized (mAwSettingsLock) {
             if (mSupportZoom != support) {
                 mSupportZoom = support;
-                onGestureZoomSupportChanged(supportsGestureZoomLocked());
+                onGestureZoomSupportChanged(
+                        supportsDoubleTapZoomLocked(), supportsMultiTouchZoomLocked());
             }
         }
     }
@@ -1367,7 +1397,8 @@ public class AwSettings {
         synchronized (mAwSettingsLock) {
             if (mBuiltInZoomControls != enabled) {
                 mBuiltInZoomControls = enabled;
-                onGestureZoomSupportChanged(supportsGestureZoomLocked());
+                onGestureZoomSupportChanged(
+                        supportsDoubleTapZoomLocked(), supportsMultiTouchZoomLocked());
             }
         }
     }
@@ -1399,20 +1430,26 @@ public class AwSettings {
         }
     }
 
-    private boolean supportsGestureZoomLocked() {
+    @CalledByNative
+    private boolean supportsDoubleTapZoomLocked() {
+        assert Thread.holdsLock(mAwSettingsLock);
+        return mSupportZoom && mBuiltInZoomControls && mUseWideViewport;
+    }
+
+    private boolean supportsMultiTouchZoomLocked() {
         assert Thread.holdsLock(mAwSettingsLock);
         return mSupportZoom && mBuiltInZoomControls;
     }
 
-    boolean supportsGestureZoom() {
+    boolean supportsMultiTouchZoom() {
         synchronized (mAwSettingsLock) {
-            return supportsGestureZoomLocked();
+            return supportsMultiTouchZoomLocked();
         }
     }
 
     boolean shouldDisplayZoomControls() {
         synchronized (mAwSettingsLock) {
-            return supportsGestureZoomLocked() && mDisplayZoomControls;
+            return supportsMultiTouchZoomLocked() && mDisplayZoomControls;
         }
     }
 
@@ -1432,18 +1469,25 @@ public class AwSettings {
         }
     }
 
-    private void updateWebkitPreferencesOnUiThreadLocked() {
-        if (mNativeAwSettings != 0) {
-            assert mEventHandler.mHandler != null;
-            ThreadUtils.assertOnUiThread();
-            nativeUpdateWebkitPreferencesLocked(mNativeAwSettings);
+    @CalledByNative
+    private void populateWebPreferences(long webPrefsPtr) {
+        synchronized (mAwSettingsLock) {
+            nativePopulateWebPreferencesLocked(mNativeAwSettings, webPrefsPtr);
         }
     }
 
+    private void updateWebkitPreferencesOnUiThreadLocked() {
+        assert mEventHandler.mHandler != null;
+        ThreadUtils.assertOnUiThread();
+        nativeUpdateWebkitPreferencesLocked(mNativeAwSettings);
+    }
+
     private native long nativeInit(long webContentsPtr);
 
     private native void nativeDestroy(long nativeAwSettings);
 
+    private native void nativePopulateWebPreferencesLocked(long nativeAwSettings, long webPrefsPtr);
+
     private native void nativeResetScrollAndScaleState(long nativeAwSettings);
 
     private native void nativeUpdateEverythingLocked(long nativeAwSettings);