• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.webkit;
18 
19 import android.content.Context;
20 import android.content.SharedPreferences;
21 import android.content.pm.PackageManager;
22 import android.os.Build;
23 import android.os.Handler;
24 import android.os.Message;
25 import android.provider.Settings;
26 import android.provider.Settings.SettingNotFoundException;
27 import android.util.EventLog;
28 
29 import java.util.Locale;
30 
31 /**
32  * WebSettings implementation for the WebViewClassic implementation of WebView.
33  * @hide
34  */
35 public class WebSettingsClassic extends WebSettings {
36     // TODO: Keep this up to date
37     private static final String PREVIOUS_VERSION = "4.1.1";
38 
39     // WebView associated with this WebSettings.
40     private WebViewClassic mWebView;
41     // BrowserFrame used to access the native frame pointer.
42     private BrowserFrame mBrowserFrame;
43     // Flag to prevent multiple SYNC messages at one time.
44     private boolean mSyncPending = false;
45     // Custom handler that queues messages until the WebCore thread is active.
46     private final EventHandler mEventHandler;
47 
48     // Private settings so we don't have to go into native code to
49     // retrieve the values. After setXXX, postSync() needs to be called.
50     //
51     // The default values need to match those in WebSettings.cpp
52     // If the defaults change, please also update the JavaDocs so developers
53     // know what they are.
54     private LayoutAlgorithm mLayoutAlgorithm = LayoutAlgorithm.NARROW_COLUMNS;
55     private Context         mContext;
56     private int             mTextSize = 100;
57     private String          mStandardFontFamily = "sans-serif";
58     private String          mFixedFontFamily = "monospace";
59     private String          mSansSerifFontFamily = "sans-serif";
60     private String          mSerifFontFamily = "serif";
61     private String          mCursiveFontFamily = "cursive";
62     private String          mFantasyFontFamily = "fantasy";
63     private String          mDefaultTextEncoding;
64     private String          mUserAgent;
65     private boolean         mUseDefaultUserAgent;
66     private String          mAcceptLanguage;
67     private int             mMinimumFontSize = 8;
68     private int             mMinimumLogicalFontSize = 8;
69     private int             mDefaultFontSize = 16;
70     private int             mDefaultFixedFontSize = 13;
71     private int             mPageCacheCapacity = 0;
72     private boolean         mLoadsImagesAutomatically = true;
73     private boolean         mBlockNetworkImage = false;
74     private boolean         mBlockNetworkLoads;
75     private boolean         mJavaScriptEnabled = false;
76     private boolean         mAllowUniversalAccessFromFileURLs = false;
77     private boolean         mAllowFileAccessFromFileURLs = false;
78     private boolean         mHardwareAccelSkia = false;
79     private boolean         mShowVisualIndicator = false;
80     private PluginState     mPluginState = PluginState.OFF;
81     private boolean         mJavaScriptCanOpenWindowsAutomatically = false;
82     private boolean         mUseDoubleTree = false;
83     private boolean         mUseWideViewport = false;
84     private boolean         mSupportMultipleWindows = false;
85     private boolean         mShrinksStandaloneImagesToFit = false;
86     private long            mMaximumDecodedImageSize = 0; // 0 means default
87     private boolean         mPrivateBrowsingEnabled = false;
88     private boolean         mSyntheticLinksEnabled = true;
89     // HTML5 API flags
90     private boolean         mAppCacheEnabled = false;
91     private boolean         mDatabaseEnabled = false;
92     private boolean         mDomStorageEnabled = false;
93     private boolean         mWorkersEnabled = false;  // only affects V8.
94     private boolean         mGeolocationEnabled = true;
95     private boolean         mXSSAuditorEnabled = false;
96     private boolean         mLinkPrefetchEnabled = false;
97     // HTML5 configuration parameters
98     private long            mAppCacheMaxSize = Long.MAX_VALUE;
99     private String          mAppCachePath = null;
100     private String          mDatabasePath = "";
101     // The WebCore DatabaseTracker only allows the database path to be set
102     // once. Keep track of when the path has been set.
103     private boolean         mDatabasePathHasBeenSet = false;
104     private String          mGeolocationDatabasePath = "";
105     // Don't need to synchronize the get/set methods as they
106     // are basic types, also none of these values are used in
107     // native WebCore code.
108     private ZoomDensity     mDefaultZoom = ZoomDensity.MEDIUM;
109     private RenderPriority  mRenderPriority = RenderPriority.NORMAL;
110     private int             mOverrideCacheMode = LOAD_DEFAULT;
111     private int             mDoubleTapZoom = 100;
112     private boolean         mSaveFormData = true;
113     private boolean         mAutoFillEnabled = false;
114     private boolean         mSavePassword = true;
115     private boolean         mLightTouchEnabled = false;
116     private boolean         mNeedInitialFocus = true;
117     private boolean         mNavDump = false;
118     private boolean         mSupportZoom = true;
119     private boolean         mMediaPlaybackRequiresUserGesture = true;
120     private boolean         mBuiltInZoomControls = false;
121     private boolean         mDisplayZoomControls = true;
122     private boolean         mAllowFileAccess = true;
123     private boolean         mAllowContentAccess = true;
124     private boolean         mLoadWithOverviewMode = false;
125     private boolean         mEnableSmoothTransition = false;
126     private boolean         mForceUserScalable = false;
127     private boolean         mPasswordEchoEnabled = true;
128 
129     // AutoFill Profile data
130     public static class AutoFillProfile {
131         private int mUniqueId;
132         private String mFullName;
133         private String mEmailAddress;
134         private String mCompanyName;
135         private String mAddressLine1;
136         private String mAddressLine2;
137         private String mCity;
138         private String mState;
139         private String mZipCode;
140         private String mCountry;
141         private String mPhoneNumber;
142 
AutoFillProfile(int uniqueId, String fullName, String email, String companyName, String addressLine1, String addressLine2, String city, String state, String zipCode, String country, String phoneNumber)143         public AutoFillProfile(int uniqueId, String fullName, String email,
144                 String companyName, String addressLine1, String addressLine2,
145                 String city, String state, String zipCode, String country,
146                 String phoneNumber) {
147             mUniqueId = uniqueId;
148             mFullName = fullName;
149             mEmailAddress = email;
150             mCompanyName = companyName;
151             mAddressLine1 = addressLine1;
152             mAddressLine2 = addressLine2;
153             mCity = city;
154             mState = state;
155             mZipCode = zipCode;
156             mCountry = country;
157             mPhoneNumber = phoneNumber;
158         }
159 
getUniqueId()160         public int getUniqueId() { return mUniqueId; }
getFullName()161         public String getFullName() { return mFullName; }
getEmailAddress()162         public String getEmailAddress() { return mEmailAddress; }
getCompanyName()163         public String getCompanyName() { return mCompanyName; }
getAddressLine1()164         public String getAddressLine1() { return mAddressLine1; }
getAddressLine2()165         public String getAddressLine2() { return mAddressLine2; }
getCity()166         public String getCity() { return mCity; }
getState()167         public String getState() { return mState; }
getZipCode()168         public String getZipCode() { return mZipCode; }
getCountry()169         public String getCountry() { return mCountry; }
getPhoneNumber()170         public String getPhoneNumber() { return mPhoneNumber; }
171     }
172 
173 
174     private AutoFillProfile mAutoFillProfile;
175 
176     private boolean         mUseWebViewBackgroundForOverscroll = true;
177 
178     // private WebSettings, not accessible by the host activity
179     static private int      mDoubleTapToastCount = 3;
180 
181     private static final String PREF_FILE = "WebViewSettings";
182     private static final String DOUBLE_TAP_TOAST_COUNT = "double_tap_toast_count";
183 
184     // Class to handle messages before WebCore is ready.
185     private class EventHandler {
186         // Message id for syncing
187         static final int SYNC = 0;
188         // Message id for setting priority
189         static final int PRIORITY = 1;
190         // Message id for writing double-tap toast count
191         static final int SET_DOUBLE_TAP_TOAST_COUNT = 2;
192         // Actual WebCore thread handler
193         private Handler mHandler;
194 
createHandler()195         private synchronized void createHandler() {
196             // as mRenderPriority can be set before thread is running, sync up
197             setRenderPriority();
198 
199             // create a new handler
200             mHandler = new Handler() {
201                 @Override
202                 public void handleMessage(Message msg) {
203                     switch (msg.what) {
204                         case SYNC:
205                             synchronized (WebSettingsClassic.this) {
206                                 if (mBrowserFrame.mNativeFrame != 0) {
207                                     nativeSync(mBrowserFrame.mNativeFrame);
208                                 }
209                                 mSyncPending = false;
210                             }
211                             break;
212 
213                         case PRIORITY: {
214                             setRenderPriority();
215                             break;
216                         }
217 
218                         case SET_DOUBLE_TAP_TOAST_COUNT: {
219                             SharedPreferences.Editor editor = mContext
220                                     .getSharedPreferences(PREF_FILE,
221                                             Context.MODE_PRIVATE).edit();
222                             editor.putInt(DOUBLE_TAP_TOAST_COUNT,
223                                     mDoubleTapToastCount);
224                             editor.commit();
225                             break;
226                         }
227                     }
228                 }
229             };
230         }
231 
setRenderPriority()232         private void setRenderPriority() {
233             synchronized (WebSettingsClassic.this) {
234                 if (mRenderPriority == RenderPriority.NORMAL) {
235                     android.os.Process.setThreadPriority(
236                             android.os.Process.THREAD_PRIORITY_DEFAULT);
237                 } else if (mRenderPriority == RenderPriority.HIGH) {
238                     android.os.Process.setThreadPriority(
239                             android.os.Process.THREAD_PRIORITY_FOREGROUND +
240                             android.os.Process.THREAD_PRIORITY_LESS_FAVORABLE);
241                 } else if (mRenderPriority == RenderPriority.LOW) {
242                     android.os.Process.setThreadPriority(
243                             android.os.Process.THREAD_PRIORITY_BACKGROUND);
244                 }
245             }
246         }
247 
248         /**
249          * Send a message to the private queue or handler.
250          */
sendMessage(Message msg)251         private synchronized boolean sendMessage(Message msg) {
252             if (mHandler != null) {
253                 mHandler.sendMessage(msg);
254                 return true;
255             } else {
256                 return false;
257             }
258         }
259     }
260 
261     // User agent strings.
262     private static final String DESKTOP_USERAGENT = "Mozilla/5.0 (X11; " +
263         "Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) " +
264         "Chrome/11.0.696.34 Safari/534.24";
265     private static final String IPHONE_USERAGENT =
266             "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us)"
267             + " AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0"
268             + " Mobile/7A341 Safari/528.16";
269     private static Locale sLocale;
270     private static Object sLockForLocaleSettings;
271 
272     /**
273      * Package constructor to prevent clients from creating a new settings
274      * instance.
275      */
WebSettingsClassic(Context context, WebViewClassic webview)276     WebSettingsClassic(Context context, WebViewClassic webview) {
277         mEventHandler = new EventHandler();
278         mContext = context;
279         mWebView = webview;
280         mDefaultTextEncoding = context.getString(com.android.internal.
281                                                  R.string.default_text_encoding);
282 
283         if (sLockForLocaleSettings == null) {
284             sLockForLocaleSettings = new Object();
285             sLocale = Locale.getDefault();
286         }
287         mAcceptLanguage = getCurrentAcceptLanguage();
288         mUserAgent = getCurrentUserAgent();
289         mUseDefaultUserAgent = true;
290 
291         mBlockNetworkLoads = mContext.checkPermission(
292                 "android.permission.INTERNET", android.os.Process.myPid(),
293                 android.os.Process.myUid()) != PackageManager.PERMISSION_GRANTED;
294 
295         // SDK specific settings. See issue 6212665
296         if (mContext.getApplicationInfo().targetSdkVersion <
297                 Build.VERSION_CODES.JELLY_BEAN) {
298             mAllowUniversalAccessFromFileURLs = true;
299             mAllowFileAccessFromFileURLs = true;
300         }
301         try {
302             mPasswordEchoEnabled =
303                     Settings.System.getInt(context.getContentResolver(),
304                         Settings.System.TEXT_SHOW_PASSWORD) != 0;
305         } catch (SettingNotFoundException e) {
306             mPasswordEchoEnabled = true;
307         }
308     }
309 
310     private static final String ACCEPT_LANG_FOR_US_LOCALE = "en-US";
311 
312     /**
313      * Looks at sLocale and returns current AcceptLanguage String.
314      * @return Current AcceptLanguage String.
315      */
getCurrentAcceptLanguage()316     private String getCurrentAcceptLanguage() {
317         Locale locale;
318         synchronized(sLockForLocaleSettings) {
319             locale = sLocale;
320         }
321         StringBuilder buffer = new StringBuilder();
322         addLocaleToHttpAcceptLanguage(buffer, locale);
323 
324         if (!Locale.US.equals(locale)) {
325             if (buffer.length() > 0) {
326                 buffer.append(", ");
327             }
328             buffer.append(ACCEPT_LANG_FOR_US_LOCALE);
329         }
330 
331         return buffer.toString();
332     }
333 
334     /**
335      * Convert obsolete language codes, including Hebrew/Indonesian/Yiddish,
336      * to new standard.
337      */
convertObsoleteLanguageCodeToNew(String langCode)338     private static String convertObsoleteLanguageCodeToNew(String langCode) {
339         if (langCode == null) {
340             return null;
341         }
342         if ("iw".equals(langCode)) {
343             // Hebrew
344             return "he";
345         } else if ("in".equals(langCode)) {
346             // Indonesian
347             return "id";
348         } else if ("ji".equals(langCode)) {
349             // Yiddish
350             return "yi";
351         }
352         return langCode;
353     }
354 
addLocaleToHttpAcceptLanguage(StringBuilder builder, Locale locale)355     private static void addLocaleToHttpAcceptLanguage(StringBuilder builder,
356                                                       Locale locale) {
357         String language = convertObsoleteLanguageCodeToNew(locale.getLanguage());
358         if (language != null) {
359             builder.append(language);
360             String country = locale.getCountry();
361             if (country != null) {
362                 builder.append("-");
363                 builder.append(country);
364             }
365         }
366     }
367 
368     /**
369      * Looks at sLocale and mContext and returns current UserAgent String.
370      * @return Current UserAgent String.
371      */
getCurrentUserAgent()372     private synchronized String getCurrentUserAgent() {
373         Locale locale;
374         synchronized(sLockForLocaleSettings) {
375             locale = sLocale;
376         }
377         return getDefaultUserAgentForLocale(mContext, locale);
378     }
379 
380     /**
381      * Returns the default User-Agent used by a WebView.
382      * An instance of WebView could use a different User-Agent if a call
383      * is made to {@link WebSettings#setUserAgent(int)} or
384      * {@link WebSettings#setUserAgentString(String)}.
385      *
386      * @param context a Context object used to access application assets
387      * @param locale The Locale to use in the User-Agent string.
388      * @see WebViewFactoryProvider#getDefaultUserAgent(Context)
389      * @see WebView#getDefaultUserAgent(Context)
390      */
getDefaultUserAgentForLocale(Context context, Locale locale)391     public static String getDefaultUserAgentForLocale(Context context, Locale locale) {
392         StringBuffer buffer = new StringBuffer();
393         // Add version
394         final String version = Build.VERSION.RELEASE;
395         if (version.length() > 0) {
396             if (Character.isDigit(version.charAt(0))) {
397                 // Release is a version, eg "3.1"
398                 buffer.append(version);
399             } else {
400                 // Release is a codename, eg "Honeycomb"
401                 // In this case, use the previous release's version
402                 buffer.append(PREVIOUS_VERSION);
403             }
404         } else {
405             // default to "1.0"
406             buffer.append("1.0");
407         }
408         buffer.append("; ");
409         final String language = locale.getLanguage();
410         if (language != null) {
411             buffer.append(convertObsoleteLanguageCodeToNew(language));
412             final String country = locale.getCountry();
413             if (country != null) {
414                 buffer.append("-");
415                 buffer.append(country.toLowerCase());
416             }
417         } else {
418             // default to "en"
419             buffer.append("en");
420         }
421         buffer.append(";");
422         // add the model for the release build
423         if ("REL".equals(Build.VERSION.CODENAME)) {
424             final String model = Build.MODEL;
425             if (model.length() > 0) {
426                 buffer.append(" ");
427                 buffer.append(model);
428             }
429         }
430         final String id = Build.ID;
431         if (id.length() > 0) {
432             buffer.append(" Build/");
433             buffer.append(id);
434         }
435         String mobile = context.getResources().getText(
436             com.android.internal.R.string.web_user_agent_target_content).toString();
437         final String base = context.getResources().getText(
438                 com.android.internal.R.string.web_user_agent).toString();
439         return String.format(base, buffer, mobile);
440     }
441 
442     /**
443      * @see android.webkit.WebSettings#setNavDump(boolean)
444      */
445     @Override
446     @Deprecated
setNavDump(boolean enabled)447     public void setNavDump(boolean enabled) {
448         mNavDump = enabled;
449     }
450 
451     /**
452      * @see android.webkit.WebSettings#getNavDump()
453      */
454     @Override
455     @Deprecated
getNavDump()456     public boolean getNavDump() {
457         return mNavDump;
458     }
459 
460     /**
461      * @see android.webkit.WebSettings#setSupportZoom(boolean)
462      */
463     @Override
setSupportZoom(boolean support)464     public void setSupportZoom(boolean support) {
465         mSupportZoom = support;
466         mWebView.updateMultiTouchSupport(mContext);
467     }
468 
469     /**
470      * @see android.webkit.WebSettings#supportZoom()
471      */
472     @Override
supportZoom()473     public boolean supportZoom() {
474         return mSupportZoom;
475     }
476 
477     /**
478      * @see android.webkit.WebSettings#setMediaPlaybackRequiresUserGesture(boolean)
479      */
480     @Override
setMediaPlaybackRequiresUserGesture(boolean support)481     public void setMediaPlaybackRequiresUserGesture(boolean support) {
482         if (mMediaPlaybackRequiresUserGesture != support) {
483             mMediaPlaybackRequiresUserGesture = support;
484             postSync();
485         }
486     }
487 
488     /**
489      * @see android.webkit.WebSettings#getMediaPlaybackRequiresUserGesture()
490      */
491     @Override
getMediaPlaybackRequiresUserGesture()492     public boolean getMediaPlaybackRequiresUserGesture() {
493         return mMediaPlaybackRequiresUserGesture;
494     }
495 
496     /**
497      * @see android.webkit.WebSettings#setBuiltInZoomControls(boolean)
498      */
499     @Override
setBuiltInZoomControls(boolean enabled)500     public void setBuiltInZoomControls(boolean enabled) {
501         mBuiltInZoomControls = enabled;
502         mWebView.updateMultiTouchSupport(mContext);
503     }
504 
505     /**
506      * @see android.webkit.WebSettings#getBuiltInZoomControls()
507      */
508     @Override
getBuiltInZoomControls()509     public boolean getBuiltInZoomControls() {
510         return mBuiltInZoomControls;
511     }
512 
513     /**
514      * @see android.webkit.WebSettings#setDisplayZoomControls(boolean)
515      */
516     @Override
setDisplayZoomControls(boolean enabled)517     public void setDisplayZoomControls(boolean enabled) {
518         mDisplayZoomControls = enabled;
519         mWebView.updateMultiTouchSupport(mContext);
520     }
521 
522     /**
523      * @see android.webkit.WebSettings#getDisplayZoomControls()
524      */
525     @Override
getDisplayZoomControls()526     public boolean getDisplayZoomControls() {
527         return mDisplayZoomControls;
528     }
529 
530     /**
531      * @see android.webkit.WebSettings#setAllowFileAccess(boolean)
532      */
533     @Override
setAllowFileAccess(boolean allow)534     public void setAllowFileAccess(boolean allow) {
535         mAllowFileAccess = allow;
536     }
537 
538     /**
539      * @see android.webkit.WebSettings#getAllowFileAccess()
540      */
541     @Override
getAllowFileAccess()542     public boolean getAllowFileAccess() {
543         return mAllowFileAccess;
544     }
545 
546     /**
547      * @see android.webkit.WebSettings#setAllowContentAccess(boolean)
548      */
549     @Override
setAllowContentAccess(boolean allow)550     public void setAllowContentAccess(boolean allow) {
551         mAllowContentAccess = allow;
552     }
553 
554     /**
555      * @see android.webkit.WebSettings#getAllowContentAccess()
556      */
557     @Override
getAllowContentAccess()558     public boolean getAllowContentAccess() {
559         return mAllowContentAccess;
560     }
561 
562     /**
563      * @see android.webkit.WebSettings#setLoadWithOverviewMode(boolean)
564      */
565     @Override
setLoadWithOverviewMode(boolean overview)566     public void setLoadWithOverviewMode(boolean overview) {
567         mLoadWithOverviewMode = overview;
568     }
569 
570     /**
571      * @see android.webkit.WebSettings#getLoadWithOverviewMode()
572      */
573     @Override
getLoadWithOverviewMode()574     public boolean getLoadWithOverviewMode() {
575         return mLoadWithOverviewMode;
576     }
577 
578     /**
579      * @see android.webkit.WebSettings#setEnableSmoothTransition(boolean)
580      */
581     @Override
setEnableSmoothTransition(boolean enable)582     public void setEnableSmoothTransition(boolean enable) {
583         mEnableSmoothTransition = enable;
584     }
585 
586     /**
587      * @see android.webkit.WebSettings#enableSmoothTransition()
588      */
589     @Override
enableSmoothTransition()590     public boolean enableSmoothTransition() {
591         return mEnableSmoothTransition;
592     }
593 
594     /**
595      * @see android.webkit.WebSettings#setUseWebViewBackgroundForOverscrollBackground(boolean)
596      */
597     @Override
598     @Deprecated
setUseWebViewBackgroundForOverscrollBackground(boolean view)599     public void setUseWebViewBackgroundForOverscrollBackground(boolean view) {
600         mUseWebViewBackgroundForOverscroll = view;
601     }
602 
603     /**
604      * @see android.webkit.WebSettings#getUseWebViewBackgroundForOverscrollBackground()
605      */
606     @Override
607     @Deprecated
getUseWebViewBackgroundForOverscrollBackground()608     public boolean getUseWebViewBackgroundForOverscrollBackground() {
609         return mUseWebViewBackgroundForOverscroll;
610     }
611 
612     /**
613      * @see android.webkit.WebSettings#setSaveFormData(boolean)
614      */
615     @Override
setSaveFormData(boolean save)616     public void setSaveFormData(boolean save) {
617         mSaveFormData = save;
618     }
619 
620     /**
621      * @see android.webkit.WebSettings#getSaveFormData()
622      */
623     @Override
getSaveFormData()624     public boolean getSaveFormData() {
625         return mSaveFormData && !mPrivateBrowsingEnabled;
626     }
627 
628     /**
629      * @see android.webkit.WebSettings#setSavePassword(boolean)
630      */
631     @Override
setSavePassword(boolean save)632     public void setSavePassword(boolean save) {
633         mSavePassword = save;
634     }
635 
636     /**
637      * @see android.webkit.WebSettings#getSavePassword()
638      */
639     @Override
getSavePassword()640     public boolean getSavePassword() {
641         return mSavePassword;
642     }
643 
644     /**
645      * @see android.webkit.WebSettings#setTextZoom(int)
646      */
647     @Override
setTextZoom(int textZoom)648     public synchronized void setTextZoom(int textZoom) {
649         if (mTextSize != textZoom) {
650             if (WebViewClassic.mLogEvent) {
651                 EventLog.writeEvent(EventLogTags.BROWSER_TEXT_SIZE_CHANGE,
652                         mTextSize, textZoom);
653             }
654             mTextSize = textZoom;
655             postSync();
656         }
657     }
658 
659     /**
660      * @see android.webkit.WebSettings#getTextZoom()
661      */
662     @Override
getTextZoom()663     public synchronized int getTextZoom() {
664         return mTextSize;
665     }
666 
667     /**
668      * Set the double-tap zoom of the page in percent. Default is 100.
669      * @param doubleTapZoom A percent value for increasing or decreasing the double-tap zoom.
670      */
setDoubleTapZoom(int doubleTapZoom)671     public void setDoubleTapZoom(int doubleTapZoom) {
672         if (mDoubleTapZoom != doubleTapZoom) {
673             mDoubleTapZoom = doubleTapZoom;
674             mWebView.updateDoubleTapZoom(doubleTapZoom);
675         }
676     }
677 
678     /**
679      * Get the double-tap zoom of the page in percent.
680      * @return A percent value describing the double-tap zoom.
681      */
getDoubleTapZoom()682     public int getDoubleTapZoom() {
683         return mDoubleTapZoom;
684     }
685 
686     /**
687      * @see android.webkit.WebSettings#setDefaultZoom(android.webkit.WebSettingsClassic.ZoomDensity)
688      */
689     @Override
setDefaultZoom(ZoomDensity zoom)690     public void setDefaultZoom(ZoomDensity zoom) {
691         if (mDefaultZoom != zoom) {
692             mDefaultZoom = zoom;
693             mWebView.adjustDefaultZoomDensity(zoom.value);
694         }
695     }
696 
697     /**
698      * @see android.webkit.WebSettings#getDefaultZoom()
699      */
700     @Override
getDefaultZoom()701     public ZoomDensity getDefaultZoom() {
702         return mDefaultZoom;
703     }
704 
705     /**
706      * @see android.webkit.WebSettings#setLightTouchEnabled(boolean)
707      */
708     @Override
setLightTouchEnabled(boolean enabled)709     public void setLightTouchEnabled(boolean enabled) {
710         mLightTouchEnabled = enabled;
711     }
712 
713     /**
714      * @see android.webkit.WebSettings#getLightTouchEnabled()
715      */
716     @Override
getLightTouchEnabled()717     public boolean getLightTouchEnabled() {
718         return mLightTouchEnabled;
719     }
720 
721     /**
722      * @see android.webkit.WebSettings#setUseDoubleTree(boolean)
723      */
724     @Override
725     @Deprecated
setUseDoubleTree(boolean use)726     public synchronized void setUseDoubleTree(boolean use) {
727         return;
728     }
729 
730     /**
731      * @see android.webkit.WebSettings#getUseDoubleTree()
732      */
733     @Override
734     @Deprecated
getUseDoubleTree()735     public synchronized boolean getUseDoubleTree() {
736         return false;
737     }
738 
739     /**
740      * @see android.webkit.WebSettings#setUserAgent(int)
741      */
742     @Override
743     @Deprecated
setUserAgent(int ua)744     public synchronized void setUserAgent(int ua) {
745         String uaString = null;
746         if (ua == 1) {
747             if (DESKTOP_USERAGENT.equals(mUserAgent)) {
748                 return; // do nothing
749             } else {
750                 uaString = DESKTOP_USERAGENT;
751             }
752         } else if (ua == 2) {
753             if (IPHONE_USERAGENT.equals(mUserAgent)) {
754                 return; // do nothing
755             } else {
756                 uaString = IPHONE_USERAGENT;
757             }
758         } else if (ua != 0) {
759             return; // do nothing
760         }
761         setUserAgentString(uaString);
762     }
763 
764     /**
765      * @see android.webkit.WebSettings#getUserAgent()
766      */
767     @Override
768     @Deprecated
getUserAgent()769     public synchronized int getUserAgent() {
770         if (DESKTOP_USERAGENT.equals(mUserAgent)) {
771             return 1;
772         } else if (IPHONE_USERAGENT.equals(mUserAgent)) {
773             return 2;
774         } else if (mUseDefaultUserAgent) {
775             return 0;
776         }
777         return -1;
778     }
779 
780     /**
781      * @see android.webkit.WebSettings#setUseWideViewPort(boolean)
782      */
783     @Override
setUseWideViewPort(boolean use)784     public synchronized void setUseWideViewPort(boolean use) {
785         if (mUseWideViewport != use) {
786             mUseWideViewport = use;
787             postSync();
788         }
789     }
790 
791     /**
792      * @see android.webkit.WebSettings#getUseWideViewPort()
793      */
794     @Override
getUseWideViewPort()795     public synchronized boolean getUseWideViewPort() {
796         return mUseWideViewport;
797     }
798 
799     /**
800      * @see android.webkit.WebSettings#setSupportMultipleWindows(boolean)
801      */
802     @Override
setSupportMultipleWindows(boolean support)803     public synchronized void setSupportMultipleWindows(boolean support) {
804         if (mSupportMultipleWindows != support) {
805             mSupportMultipleWindows = support;
806             postSync();
807         }
808     }
809 
810     /**
811      * @see android.webkit.WebSettings#supportMultipleWindows()
812      */
813     @Override
supportMultipleWindows()814     public synchronized boolean supportMultipleWindows() {
815         return mSupportMultipleWindows;
816     }
817 
818     /**
819      * @see android.webkit.WebSettings#setLayoutAlgorithm(android.webkit.WebSettingsClassic.LayoutAlgorithm)
820      */
821     @Override
setLayoutAlgorithm(LayoutAlgorithm l)822     public synchronized void setLayoutAlgorithm(LayoutAlgorithm l) {
823         // XXX: This will only be affective if libwebcore was built with
824         // ANDROID_LAYOUT defined.
825         if (mLayoutAlgorithm != l) {
826             mLayoutAlgorithm = l;
827             postSync();
828         }
829     }
830 
831     /**
832      * @see android.webkit.WebSettings#getLayoutAlgorithm()
833      */
834     @Override
getLayoutAlgorithm()835     public synchronized LayoutAlgorithm getLayoutAlgorithm() {
836         return mLayoutAlgorithm;
837     }
838 
839     /**
840      * @see android.webkit.WebSettings#setStandardFontFamily(java.lang.String)
841      */
842     @Override
setStandardFontFamily(String font)843     public synchronized void setStandardFontFamily(String font) {
844         if (font != null && !font.equals(mStandardFontFamily)) {
845             mStandardFontFamily = font;
846             postSync();
847         }
848     }
849 
850     /**
851      * @see android.webkit.WebSettings#getStandardFontFamily()
852      */
853     @Override
getStandardFontFamily()854     public synchronized String getStandardFontFamily() {
855         return mStandardFontFamily;
856     }
857 
858     /**
859      * @see android.webkit.WebSettings#setFixedFontFamily(java.lang.String)
860      */
861     @Override
setFixedFontFamily(String font)862     public synchronized void setFixedFontFamily(String font) {
863         if (font != null && !font.equals(mFixedFontFamily)) {
864             mFixedFontFamily = font;
865             postSync();
866         }
867     }
868 
869     /**
870      * @see android.webkit.WebSettings#getFixedFontFamily()
871      */
872     @Override
getFixedFontFamily()873     public synchronized String getFixedFontFamily() {
874         return mFixedFontFamily;
875     }
876 
877     /**
878      * @see android.webkit.WebSettings#setSansSerifFontFamily(java.lang.String)
879      */
880     @Override
setSansSerifFontFamily(String font)881     public synchronized void setSansSerifFontFamily(String font) {
882         if (font != null && !font.equals(mSansSerifFontFamily)) {
883             mSansSerifFontFamily = font;
884             postSync();
885         }
886     }
887 
888     /**
889      * @see android.webkit.WebSettings#getSansSerifFontFamily()
890      */
891     @Override
getSansSerifFontFamily()892     public synchronized String getSansSerifFontFamily() {
893         return mSansSerifFontFamily;
894     }
895 
896     /**
897      * @see android.webkit.WebSettings#setSerifFontFamily(java.lang.String)
898      */
899     @Override
setSerifFontFamily(String font)900     public synchronized void setSerifFontFamily(String font) {
901         if (font != null && !font.equals(mSerifFontFamily)) {
902             mSerifFontFamily = font;
903             postSync();
904         }
905     }
906 
907     /**
908      * @see android.webkit.WebSettings#getSerifFontFamily()
909      */
910     @Override
getSerifFontFamily()911     public synchronized String getSerifFontFamily() {
912         return mSerifFontFamily;
913     }
914 
915     /**
916      * @see android.webkit.WebSettings#setCursiveFontFamily(java.lang.String)
917      */
918     @Override
setCursiveFontFamily(String font)919     public synchronized void setCursiveFontFamily(String font) {
920         if (font != null && !font.equals(mCursiveFontFamily)) {
921             mCursiveFontFamily = font;
922             postSync();
923         }
924     }
925 
926     /**
927      * @see android.webkit.WebSettings#getCursiveFontFamily()
928      */
929     @Override
getCursiveFontFamily()930     public synchronized String getCursiveFontFamily() {
931         return mCursiveFontFamily;
932     }
933 
934     /**
935      * @see android.webkit.WebSettings#setFantasyFontFamily(java.lang.String)
936      */
937     @Override
setFantasyFontFamily(String font)938     public synchronized void setFantasyFontFamily(String font) {
939         if (font != null && !font.equals(mFantasyFontFamily)) {
940             mFantasyFontFamily = font;
941             postSync();
942         }
943     }
944 
945     /**
946      * @see android.webkit.WebSettings#getFantasyFontFamily()
947      */
948     @Override
getFantasyFontFamily()949     public synchronized String getFantasyFontFamily() {
950         return mFantasyFontFamily;
951     }
952 
953     /**
954      * @see android.webkit.WebSettings#setMinimumFontSize(int)
955      */
956     @Override
setMinimumFontSize(int size)957     public synchronized void setMinimumFontSize(int size) {
958         size = pin(size);
959         if (mMinimumFontSize != size) {
960             mMinimumFontSize = size;
961             postSync();
962         }
963     }
964 
965     /**
966      * @see android.webkit.WebSettings#getMinimumFontSize()
967      */
968     @Override
getMinimumFontSize()969     public synchronized int getMinimumFontSize() {
970         return mMinimumFontSize;
971     }
972 
973     /**
974      * @see android.webkit.WebSettings#setMinimumLogicalFontSize(int)
975      */
976     @Override
setMinimumLogicalFontSize(int size)977     public synchronized void setMinimumLogicalFontSize(int size) {
978         size = pin(size);
979         if (mMinimumLogicalFontSize != size) {
980             mMinimumLogicalFontSize = size;
981             postSync();
982         }
983     }
984 
985     /**
986      * @see android.webkit.WebSettings#getMinimumLogicalFontSize()
987      */
988     @Override
getMinimumLogicalFontSize()989     public synchronized int getMinimumLogicalFontSize() {
990         return mMinimumLogicalFontSize;
991     }
992 
993     /**
994      * @see android.webkit.WebSettings#setDefaultFontSize(int)
995      */
996     @Override
setDefaultFontSize(int size)997     public synchronized void setDefaultFontSize(int size) {
998         size = pin(size);
999         if (mDefaultFontSize != size) {
1000             mDefaultFontSize = size;
1001             postSync();
1002         }
1003     }
1004 
1005     /**
1006      * @see android.webkit.WebSettings#getDefaultFontSize()
1007      */
1008     @Override
getDefaultFontSize()1009     public synchronized int getDefaultFontSize() {
1010         return mDefaultFontSize;
1011     }
1012 
1013     /**
1014      * @see android.webkit.WebSettings#setDefaultFixedFontSize(int)
1015      */
1016     @Override
setDefaultFixedFontSize(int size)1017     public synchronized void setDefaultFixedFontSize(int size) {
1018         size = pin(size);
1019         if (mDefaultFixedFontSize != size) {
1020             mDefaultFixedFontSize = size;
1021             postSync();
1022         }
1023     }
1024 
1025     /**
1026      * @see android.webkit.WebSettings#getDefaultFixedFontSize()
1027      */
1028     @Override
getDefaultFixedFontSize()1029     public synchronized int getDefaultFixedFontSize() {
1030         return mDefaultFixedFontSize;
1031     }
1032 
1033     /**
1034      * Set the number of pages cached by the WebKit for the history navigation.
1035      * @param size A non-negative integer between 0 (no cache) and 20 (max).
1036      */
setPageCacheCapacity(int size)1037     public synchronized void setPageCacheCapacity(int size) {
1038         if (size < 0) size = 0;
1039         if (size > 20) size = 20;
1040         if (mPageCacheCapacity != size) {
1041             mPageCacheCapacity = size;
1042             postSync();
1043         }
1044     }
1045 
1046     /**
1047      * @see android.webkit.WebSettings#setLoadsImagesAutomatically(boolean)
1048      */
1049     @Override
setLoadsImagesAutomatically(boolean flag)1050     public synchronized void setLoadsImagesAutomatically(boolean flag) {
1051         if (mLoadsImagesAutomatically != flag) {
1052             mLoadsImagesAutomatically = flag;
1053             postSync();
1054         }
1055     }
1056 
1057     /**
1058      * @see android.webkit.WebSettings#getLoadsImagesAutomatically()
1059      */
1060     @Override
getLoadsImagesAutomatically()1061     public synchronized boolean getLoadsImagesAutomatically() {
1062         return mLoadsImagesAutomatically;
1063     }
1064 
1065     /**
1066      * @see android.webkit.WebSettings#setBlockNetworkImage(boolean)
1067      */
1068     @Override
setBlockNetworkImage(boolean flag)1069     public synchronized void setBlockNetworkImage(boolean flag) {
1070         if (mBlockNetworkImage != flag) {
1071             mBlockNetworkImage = flag;
1072             postSync();
1073         }
1074     }
1075 
1076     /**
1077      * @see android.webkit.WebSettings#getBlockNetworkImage()
1078      */
1079     @Override
getBlockNetworkImage()1080     public synchronized boolean getBlockNetworkImage() {
1081         return mBlockNetworkImage;
1082     }
1083 
1084     /**
1085      * @see android.webkit.WebSettings#setBlockNetworkLoads(boolean)
1086      */
1087     @Override
setBlockNetworkLoads(boolean flag)1088     public synchronized void setBlockNetworkLoads(boolean flag) {
1089         if (mBlockNetworkLoads != flag) {
1090             mBlockNetworkLoads = flag;
1091             verifyNetworkAccess();
1092             postSync();
1093         }
1094     }
1095 
1096     /**
1097      * @see android.webkit.WebSettings#getBlockNetworkLoads()
1098      */
1099     @Override
getBlockNetworkLoads()1100     public synchronized boolean getBlockNetworkLoads() {
1101         return mBlockNetworkLoads;
1102     }
1103 
1104 
verifyNetworkAccess()1105     private void verifyNetworkAccess() {
1106         if (!mBlockNetworkLoads) {
1107             if (mContext.checkPermission("android.permission.INTERNET",
1108                     android.os.Process.myPid(), android.os.Process.myUid()) !=
1109                         PackageManager.PERMISSION_GRANTED) {
1110                 throw new SecurityException
1111                         ("Permission denied - " +
1112                                 "application missing INTERNET permission");
1113             }
1114         }
1115     }
1116 
1117     /**
1118      * @see android.webkit.WebSettings#setJavaScriptEnabled(boolean)
1119      */
1120     @Override
setJavaScriptEnabled(boolean flag)1121     public synchronized void setJavaScriptEnabled(boolean flag) {
1122         if (mJavaScriptEnabled != flag) {
1123             mJavaScriptEnabled = flag;
1124             postSync();
1125             mWebView.updateJavaScriptEnabled(flag);
1126         }
1127     }
1128 
1129     /**
1130      * @see android.webkit.WebSettings#setAllowUniversalAccessFromFileURLs
1131      */
1132     @Override
setAllowUniversalAccessFromFileURLs(boolean flag)1133     public synchronized void setAllowUniversalAccessFromFileURLs(boolean flag) {
1134         if (mAllowUniversalAccessFromFileURLs != flag) {
1135             mAllowUniversalAccessFromFileURLs = flag;
1136             postSync();
1137         }
1138     }
1139 
1140     /**
1141      * @see android.webkit.WebSettings#setAllowFileAccessFromFileURLs
1142      */
1143     @Override
setAllowFileAccessFromFileURLs(boolean flag)1144     public synchronized void setAllowFileAccessFromFileURLs(boolean flag) {
1145         if (mAllowFileAccessFromFileURLs != flag) {
1146             mAllowFileAccessFromFileURLs = flag;
1147             postSync();
1148         }
1149     }
1150 
1151     /**
1152      * Tell the WebView to use Skia's hardware accelerated rendering path
1153      * @param flag True if the WebView should use Skia's hw-accel path
1154      */
setHardwareAccelSkiaEnabled(boolean flag)1155     public synchronized void setHardwareAccelSkiaEnabled(boolean flag) {
1156         if (mHardwareAccelSkia != flag) {
1157             mHardwareAccelSkia = flag;
1158             postSync();
1159         }
1160     }
1161 
1162     /**
1163      * @return True if the WebView is using hardware accelerated skia
1164      */
getHardwareAccelSkiaEnabled()1165     public synchronized boolean getHardwareAccelSkiaEnabled() {
1166         return mHardwareAccelSkia;
1167     }
1168 
1169     /**
1170      * Tell the WebView to show the visual indicator
1171      * @param flag True if the WebView should show the visual indicator
1172      */
setShowVisualIndicator(boolean flag)1173     public synchronized void setShowVisualIndicator(boolean flag) {
1174         if (mShowVisualIndicator != flag) {
1175             mShowVisualIndicator = flag;
1176             postSync();
1177         }
1178     }
1179 
1180     /**
1181      * @return True if the WebView is showing the visual indicator
1182      */
getShowVisualIndicator()1183     public synchronized boolean getShowVisualIndicator() {
1184         return mShowVisualIndicator;
1185     }
1186 
1187     /**
1188      * @see android.webkit.WebSettings#setPluginsEnabled(boolean)
1189      */
1190     @Override
1191     @Deprecated
setPluginsEnabled(boolean flag)1192     public synchronized void setPluginsEnabled(boolean flag) {
1193         setPluginState(flag ? PluginState.ON : PluginState.OFF);
1194     }
1195 
1196     /**
1197      * @see android.webkit.WebSettings#setPluginState(android.webkit.WebSettingsClassic.PluginState)
1198      */
1199     @Override
setPluginState(PluginState state)1200     public synchronized void setPluginState(PluginState state) {
1201         if (mPluginState != state) {
1202             mPluginState = state;
1203             postSync();
1204         }
1205     }
1206 
1207     /**
1208      * @see android.webkit.WebSettings#setPluginsPath(java.lang.String)
1209      */
1210     @Override
1211     @Deprecated
setPluginsPath(String pluginsPath)1212     public synchronized void setPluginsPath(String pluginsPath) {
1213     }
1214 
1215     /**
1216      * @see android.webkit.WebSettings#setDatabasePath(java.lang.String)
1217      */
1218     @Override
setDatabasePath(String databasePath)1219     public synchronized void setDatabasePath(String databasePath) {
1220         if (databasePath != null && !mDatabasePathHasBeenSet) {
1221             mDatabasePath = databasePath;
1222             mDatabasePathHasBeenSet = true;
1223             postSync();
1224         }
1225     }
1226 
1227     /**
1228      * @see android.webkit.WebSettings#setGeolocationDatabasePath(java.lang.String)
1229      */
1230     @Override
setGeolocationDatabasePath(String databasePath)1231     public synchronized void setGeolocationDatabasePath(String databasePath) {
1232         if (databasePath != null
1233                 && !databasePath.equals(mGeolocationDatabasePath)) {
1234             mGeolocationDatabasePath = databasePath;
1235             postSync();
1236         }
1237     }
1238 
1239     /**
1240      * @see android.webkit.WebSettings#setAppCacheEnabled(boolean)
1241      */
1242     @Override
setAppCacheEnabled(boolean flag)1243     public synchronized void setAppCacheEnabled(boolean flag) {
1244         if (mAppCacheEnabled != flag) {
1245             mAppCacheEnabled = flag;
1246             postSync();
1247         }
1248     }
1249 
1250     /**
1251      * @see android.webkit.WebSettings#setAppCachePath(java.lang.String)
1252      */
1253     @Override
setAppCachePath(String path)1254     public synchronized void setAppCachePath(String path) {
1255         // We test for a valid path and for repeated setting on the native
1256         // side, but we can avoid syncing in some simple cases.
1257         if (mAppCachePath == null && path != null && !path.isEmpty()) {
1258             mAppCachePath = path;
1259             postSync();
1260         }
1261     }
1262 
1263     /**
1264      * @see android.webkit.WebSettings#setAppCacheMaxSize(long)
1265      */
1266     @Override
setAppCacheMaxSize(long appCacheMaxSize)1267     public synchronized void setAppCacheMaxSize(long appCacheMaxSize) {
1268         if (appCacheMaxSize != mAppCacheMaxSize) {
1269             mAppCacheMaxSize = appCacheMaxSize;
1270             postSync();
1271         }
1272     }
1273 
1274     /**
1275      * @see android.webkit.WebSettings#setDatabaseEnabled(boolean)
1276      */
1277     @Override
setDatabaseEnabled(boolean flag)1278     public synchronized void setDatabaseEnabled(boolean flag) {
1279        if (mDatabaseEnabled != flag) {
1280            mDatabaseEnabled = flag;
1281            postSync();
1282        }
1283     }
1284 
1285     /**
1286      * @see android.webkit.WebSettings#setDomStorageEnabled(boolean)
1287      */
1288     @Override
setDomStorageEnabled(boolean flag)1289     public synchronized void setDomStorageEnabled(boolean flag) {
1290        if (mDomStorageEnabled != flag) {
1291            mDomStorageEnabled = flag;
1292            postSync();
1293        }
1294     }
1295 
1296     /**
1297      * @see android.webkit.WebSettings#getDomStorageEnabled()
1298      */
1299     @Override
getDomStorageEnabled()1300     public synchronized boolean getDomStorageEnabled() {
1301        return mDomStorageEnabled;
1302     }
1303 
1304     /**
1305      * @see android.webkit.WebSettings#getDatabasePath()
1306      */
1307     @Override
getDatabasePath()1308     public synchronized String getDatabasePath() {
1309         return mDatabasePath;
1310     }
1311 
1312     /**
1313      * @see android.webkit.WebSettings#getDatabaseEnabled()
1314      */
1315     @Override
getDatabaseEnabled()1316     public synchronized boolean getDatabaseEnabled() {
1317         return mDatabaseEnabled;
1318     }
1319 
1320     /**
1321      * Tell the WebView to enable WebWorkers API.
1322      * @param flag True if the WebView should enable WebWorkers.
1323      * Note that this flag only affects V8. JSC does not have
1324      * an equivalent setting.
1325      */
setWorkersEnabled(boolean flag)1326     public synchronized void setWorkersEnabled(boolean flag) {
1327         if (mWorkersEnabled != flag) {
1328             mWorkersEnabled = flag;
1329             postSync();
1330         }
1331     }
1332 
1333     /**
1334      * @see android.webkit.WebSettings#setGeolocationEnabled(boolean)
1335      */
1336     @Override
setGeolocationEnabled(boolean flag)1337     public synchronized void setGeolocationEnabled(boolean flag) {
1338         if (mGeolocationEnabled != flag) {
1339             mGeolocationEnabled = flag;
1340             postSync();
1341         }
1342     }
1343 
1344     /**
1345      * Sets whether XSS Auditor is enabled.
1346      * Only used by LayoutTestController.
1347      * @param flag Whether XSS Auditor should be enabled.
1348      */
setXSSAuditorEnabled(boolean flag)1349     public synchronized void setXSSAuditorEnabled(boolean flag) {
1350         if (mXSSAuditorEnabled != flag) {
1351             mXSSAuditorEnabled = flag;
1352             postSync();
1353         }
1354     }
1355 
1356     /**
1357      * Enables/disables HTML5 link "prefetch" parameter.
1358      */
setLinkPrefetchEnabled(boolean flag)1359     public synchronized void setLinkPrefetchEnabled(boolean flag) {
1360         if (mLinkPrefetchEnabled != flag) {
1361             mLinkPrefetchEnabled = flag;
1362             postSync();
1363         }
1364     }
1365 
1366     /**
1367      * @see android.webkit.WebSettings#getJavaScriptEnabled()
1368      */
1369     @Override
getJavaScriptEnabled()1370     public synchronized boolean getJavaScriptEnabled() {
1371         return mJavaScriptEnabled;
1372     }
1373 
1374     /**
1375      * @see android.webkit.WebSettings#getAllowUniversalFileAccessFromFileURLs
1376      */
1377     @Override
getAllowUniversalAccessFromFileURLs()1378     public synchronized boolean getAllowUniversalAccessFromFileURLs() {
1379         return mAllowUniversalAccessFromFileURLs;
1380     }
1381 
1382     /**
1383      * @see android.webkit.WebSettings#getAllowFileAccessFromFileURLs
1384      */
1385     @Override
getAllowFileAccessFromFileURLs()1386     public synchronized boolean getAllowFileAccessFromFileURLs() {
1387         return mAllowFileAccessFromFileURLs;
1388     }
1389 
1390     /**
1391      * @see android.webkit.WebSettings#getPluginsEnabled()
1392      */
1393     @Override
1394     @Deprecated
getPluginsEnabled()1395     public synchronized boolean getPluginsEnabled() {
1396         return mPluginState == PluginState.ON;
1397     }
1398 
1399     /**
1400      * @see android.webkit.WebSettings#getPluginState()
1401      */
1402     @Override
getPluginState()1403     public synchronized PluginState getPluginState() {
1404         return mPluginState;
1405     }
1406 
1407     /**
1408      * @see android.webkit.WebSettings#getPluginsPath()
1409      */
1410     @Override
1411     @Deprecated
getPluginsPath()1412     public synchronized String getPluginsPath() {
1413         return "";
1414     }
1415 
1416     /**
1417      * @see android.webkit.WebSettings#setJavaScriptCanOpenWindowsAutomatically(boolean)
1418      */
1419     @Override
setJavaScriptCanOpenWindowsAutomatically( boolean flag)1420     public synchronized void setJavaScriptCanOpenWindowsAutomatically(
1421             boolean flag) {
1422         if (mJavaScriptCanOpenWindowsAutomatically != flag) {
1423             mJavaScriptCanOpenWindowsAutomatically = flag;
1424             postSync();
1425         }
1426     }
1427 
1428     /**
1429      * @see android.webkit.WebSettings#getJavaScriptCanOpenWindowsAutomatically()
1430      */
1431     @Override
getJavaScriptCanOpenWindowsAutomatically()1432     public synchronized boolean getJavaScriptCanOpenWindowsAutomatically() {
1433         return mJavaScriptCanOpenWindowsAutomatically;
1434     }
1435 
1436     /**
1437      * @see android.webkit.WebSettings#setDefaultTextEncodingName(java.lang.String)
1438      */
1439     @Override
setDefaultTextEncodingName(String encoding)1440     public synchronized void setDefaultTextEncodingName(String encoding) {
1441         if (encoding != null && !encoding.equals(mDefaultTextEncoding)) {
1442             mDefaultTextEncoding = encoding;
1443             postSync();
1444         }
1445     }
1446 
1447     /**
1448      * @see android.webkit.WebSettings#getDefaultTextEncodingName()
1449      */
1450     @Override
getDefaultTextEncodingName()1451     public synchronized String getDefaultTextEncodingName() {
1452         return mDefaultTextEncoding;
1453     }
1454 
1455     /**
1456      * @see android.webkit.WebSettings#setUserAgentString(java.lang.String)
1457      */
1458     @Override
setUserAgentString(String ua)1459     public synchronized void setUserAgentString(String ua) {
1460         if (ua == null || ua.length() == 0) {
1461             synchronized(sLockForLocaleSettings) {
1462                 Locale currentLocale = Locale.getDefault();
1463                 if (!sLocale.equals(currentLocale)) {
1464                     sLocale = currentLocale;
1465                     mAcceptLanguage = getCurrentAcceptLanguage();
1466                 }
1467             }
1468             ua = getCurrentUserAgent();
1469             mUseDefaultUserAgent = true;
1470         } else  {
1471             mUseDefaultUserAgent = false;
1472         }
1473 
1474         if (!ua.equals(mUserAgent)) {
1475             mUserAgent = ua;
1476             postSync();
1477         }
1478     }
1479 
1480     /**
1481      * @see android.webkit.WebSettings#getUserAgentString()
1482      */
1483     @Override
getUserAgentString()1484     public synchronized String getUserAgentString() {
1485         if (DESKTOP_USERAGENT.equals(mUserAgent) ||
1486                 IPHONE_USERAGENT.equals(mUserAgent) ||
1487                 !mUseDefaultUserAgent) {
1488             return mUserAgent;
1489         }
1490 
1491         boolean doPostSync = false;
1492         synchronized(sLockForLocaleSettings) {
1493             Locale currentLocale = Locale.getDefault();
1494             if (!sLocale.equals(currentLocale)) {
1495                 sLocale = currentLocale;
1496                 mUserAgent = getCurrentUserAgent();
1497                 mAcceptLanguage = getCurrentAcceptLanguage();
1498                 doPostSync = true;
1499             }
1500         }
1501         if (doPostSync) {
1502             postSync();
1503         }
1504         return mUserAgent;
1505     }
1506 
1507     /* package api to grab the Accept Language string. */
getAcceptLanguage()1508     /*package*/ synchronized String getAcceptLanguage() {
1509         synchronized(sLockForLocaleSettings) {
1510             Locale currentLocale = Locale.getDefault();
1511             if (!sLocale.equals(currentLocale)) {
1512                 sLocale = currentLocale;
1513                 mAcceptLanguage = getCurrentAcceptLanguage();
1514             }
1515         }
1516         return mAcceptLanguage;
1517     }
1518 
isNarrowColumnLayout()1519     /* package */ boolean isNarrowColumnLayout() {
1520         return getLayoutAlgorithm() == LayoutAlgorithm.NARROW_COLUMNS;
1521     }
1522 
1523     /**
1524      * @see android.webkit.WebSettings#setNeedInitialFocus(boolean)
1525      */
1526     @Override
setNeedInitialFocus(boolean flag)1527     public void setNeedInitialFocus(boolean flag) {
1528         if (mNeedInitialFocus != flag) {
1529             mNeedInitialFocus = flag;
1530         }
1531     }
1532 
1533     /* Package api to get the choice whether it needs to set initial focus. */
getNeedInitialFocus()1534     /* package */ boolean getNeedInitialFocus() {
1535         return mNeedInitialFocus;
1536     }
1537 
1538     /**
1539      * @see android.webkit.WebSettings#setRenderPriority(android.webkit.WebSettingsClassic.RenderPriority)
1540      */
1541     @Override
setRenderPriority(RenderPriority priority)1542     public synchronized void setRenderPriority(RenderPriority priority) {
1543         if (mRenderPriority != priority) {
1544             mRenderPriority = priority;
1545             mEventHandler.sendMessage(Message.obtain(null,
1546                     EventHandler.PRIORITY));
1547         }
1548     }
1549 
1550     /**
1551      * @see android.webkit.WebSettings#setCacheMode(int)
1552      */
1553     @Override
setCacheMode(int mode)1554     public void setCacheMode(int mode) {
1555         if (mode != mOverrideCacheMode) {
1556             mOverrideCacheMode = mode;
1557             postSync();
1558         }
1559     }
1560 
1561     /**
1562      * @see android.webkit.WebSettings#getCacheMode()
1563      */
1564     @Override
getCacheMode()1565     public int getCacheMode() {
1566         return mOverrideCacheMode;
1567     }
1568 
1569     /**
1570      * If set, webkit alternately shrinks and expands images viewed outside
1571      * of an HTML page to fit the screen. This conflicts with attempts by
1572      * the UI to zoom in and out of an image, so it is set false by default.
1573      * @param shrink Set true to let webkit shrink the standalone image to fit.
1574      */
setShrinksStandaloneImagesToFit(boolean shrink)1575     public void setShrinksStandaloneImagesToFit(boolean shrink) {
1576         if (mShrinksStandaloneImagesToFit != shrink) {
1577             mShrinksStandaloneImagesToFit = shrink;
1578             postSync();
1579         }
1580      }
1581 
1582     /**
1583      * Specify the maximum decoded image size. The default is
1584      * 2 megs for small memory devices and 8 megs for large memory devices.
1585      * @param size The maximum decoded size, or zero to set to the default.
1586      */
setMaximumDecodedImageSize(long size)1587     public void setMaximumDecodedImageSize(long size) {
1588         if (mMaximumDecodedImageSize != size) {
1589             mMaximumDecodedImageSize = size;
1590             postSync();
1591         }
1592     }
1593 
1594     /**
1595      * Returns whether to use fixed viewport.  Use fixed viewport
1596      * whenever wide viewport is on.
1597      */
getUseFixedViewport()1598     /* package */ boolean getUseFixedViewport() {
1599         return getUseWideViewPort();
1600     }
1601 
1602     /**
1603      * Returns whether private browsing is enabled.
1604      */
isPrivateBrowsingEnabled()1605     /* package */ boolean isPrivateBrowsingEnabled() {
1606         return mPrivateBrowsingEnabled;
1607     }
1608 
1609     /**
1610      * Sets whether private browsing is enabled.
1611      * @param flag Whether private browsing should be enabled.
1612      */
setPrivateBrowsingEnabled(boolean flag)1613     /* package */ synchronized void setPrivateBrowsingEnabled(boolean flag) {
1614         if (mPrivateBrowsingEnabled != flag) {
1615             mPrivateBrowsingEnabled = flag;
1616 
1617             // AutoFill is dependant on private browsing being enabled so
1618             // reset it to take account of the new value of mPrivateBrowsingEnabled.
1619             setAutoFillEnabled(mAutoFillEnabled);
1620 
1621             postSync();
1622         }
1623     }
1624 
1625     /**
1626      * Returns whether the viewport metatag can disable zooming
1627      */
forceUserScalable()1628     public boolean forceUserScalable() {
1629         return mForceUserScalable;
1630     }
1631 
1632     /**
1633      * Sets whether viewport metatag can disable zooming.
1634      * @param flag Whether or not to forceably enable user scalable.
1635      */
setForceUserScalable(boolean flag)1636     public synchronized void setForceUserScalable(boolean flag) {
1637         mForceUserScalable = flag;
1638     }
1639 
setSyntheticLinksEnabled(boolean flag)1640     synchronized void setSyntheticLinksEnabled(boolean flag) {
1641         if (mSyntheticLinksEnabled != flag) {
1642             mSyntheticLinksEnabled = flag;
1643             postSync();
1644         }
1645     }
1646 
setAutoFillEnabled(boolean enabled)1647     public synchronized void setAutoFillEnabled(boolean enabled) {
1648         // AutoFill is always disabled in private browsing mode.
1649         boolean autoFillEnabled = enabled && !mPrivateBrowsingEnabled;
1650         if (mAutoFillEnabled != autoFillEnabled) {
1651             mAutoFillEnabled = autoFillEnabled;
1652             postSync();
1653         }
1654     }
1655 
getAutoFillEnabled()1656     public synchronized boolean getAutoFillEnabled() {
1657         return mAutoFillEnabled;
1658     }
1659 
setAutoFillProfile(AutoFillProfile profile)1660     public synchronized void setAutoFillProfile(AutoFillProfile profile) {
1661         if (mAutoFillProfile != profile) {
1662             mAutoFillProfile = profile;
1663             postSync();
1664         }
1665     }
1666 
getAutoFillProfile()1667     public synchronized AutoFillProfile getAutoFillProfile() {
1668         return mAutoFillProfile;
1669     }
1670 
getDoubleTapToastCount()1671     int getDoubleTapToastCount() {
1672         return mDoubleTapToastCount;
1673     }
1674 
setDoubleTapToastCount(int count)1675     void setDoubleTapToastCount(int count) {
1676         if (mDoubleTapToastCount != count) {
1677             mDoubleTapToastCount = count;
1678             // write the settings in the non-UI thread
1679             mEventHandler.sendMessage(Message.obtain(null,
1680                     EventHandler.SET_DOUBLE_TAP_TOAST_COUNT));
1681         }
1682     }
1683 
setProperty(String key, String value)1684     public void setProperty(String key, String value) {
1685         if (mWebView.nativeSetProperty(key, value)) {
1686             mWebView.invalidate();
1687         }
1688     }
1689 
getProperty(String key)1690     public String getProperty(String key) {
1691         return mWebView.nativeGetProperty(key);
1692     }
1693 
1694     /**
1695      * Transfer messages from the queue to the new WebCoreThread. Called from
1696      * WebCore thread.
1697      */
1698     /*package*/
syncSettingsAndCreateHandler(BrowserFrame frame)1699     synchronized void syncSettingsAndCreateHandler(BrowserFrame frame) {
1700         mBrowserFrame = frame;
1701         if (DebugFlags.WEB_SETTINGS) {
1702             junit.framework.Assert.assertTrue(frame.mNativeFrame != 0);
1703         }
1704 
1705         SharedPreferences sp = mContext.getSharedPreferences(PREF_FILE,
1706                 Context.MODE_PRIVATE);
1707         if (mDoubleTapToastCount > 0) {
1708             mDoubleTapToastCount = sp.getInt(DOUBLE_TAP_TOAST_COUNT,
1709                     mDoubleTapToastCount);
1710         }
1711         nativeSync(frame.mNativeFrame);
1712         mSyncPending = false;
1713         mEventHandler.createHandler();
1714     }
1715 
1716     /**
1717      * Let the Settings object know that our owner is being destroyed.
1718      */
1719     /*package*/
onDestroyed()1720     synchronized void onDestroyed() {
1721     }
1722 
pin(int size)1723     private int pin(int size) {
1724         // FIXME: 72 is just an arbitrary max text size value.
1725         if (size < 1) {
1726             return 1;
1727         } else if (size > 72) {
1728             return 72;
1729         }
1730         return size;
1731     }
1732 
1733     /* Post a SYNC message to handle syncing the native settings. */
postSync()1734     private synchronized void postSync() {
1735         // Only post if a sync is not pending
1736         if (!mSyncPending) {
1737             mSyncPending = mEventHandler.sendMessage(
1738                     Message.obtain(null, EventHandler.SYNC));
1739         }
1740     }
1741 
1742     // Synchronize the native and java settings.
nativeSync(int nativeFrame)1743     private native void nativeSync(int nativeFrame);
1744 }
1745