WebSettings.java revision 0d8b77c2453d0e597f94e39212e4bfeed8affffa
1/*
2 * Copyright (C) 2007 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
17package android.webkit;
18
19import android.content.Context;
20import android.os.Build;
21import android.os.Handler;
22import android.os.Message;
23import android.provider.Checkin;
24
25import java.lang.SecurityException;
26import android.content.pm.PackageManager;
27
28import java.util.Locale;
29
30/**
31 * Manages settings state for a WebView. When a WebView is first created, it
32 * obtains a set of default settings. These default settings will be returned
33 * from any getter call. A WebSettings object obtained from
34 * WebView.getSettings() is tied to the life of the WebView. If a WebView has
35 * been destroyed, any method call on WebSettings will throw an
36 * IllegalStateException.
37 */
38public class WebSettings {
39    /**
40     * Enum for controlling the layout of html.
41     * NORMAL means no rendering changes.
42     * SINGLE_COLUMN moves all content into one column that is the width of the
43     * view.
44     * NARROW_COLUMNS makes all columns no wider than the screen if possible.
45     */
46    // XXX: These must match LayoutAlgorithm in Settings.h in WebCore.
47    public enum LayoutAlgorithm {
48        NORMAL,
49        SINGLE_COLUMN,
50        NARROW_COLUMNS
51    }
52
53    /**
54     * Enum for specifying the text size.
55     * SMALLEST is 50%
56     * SMALLER is 75%
57     * NORMAL is 100%
58     * LARGER is 150%
59     * LARGEST is 200%
60     */
61    public enum TextSize {
62        SMALLEST(50),
63        SMALLER(75),
64        NORMAL(100),
65        LARGER(150),
66        LARGEST(200);
67        TextSize(int size) {
68            value = size;
69        }
70        int value;
71    }
72
73    /**
74     * Enum for specifying the WebView's desired density.
75     * FAR makes 100% looking like in 240dpi
76     * MEDIUM makes 100% looking like in 160dpi
77     * CLOSE makes 100% looking like in 120dpi
78     * @hide Pending API council approval
79     */
80    public enum ZoomDensity {
81        FAR(150),      // 240dpi
82        MEDIUM(100),    // 160dpi
83        CLOSE(75);     // 120dpi
84        ZoomDensity(int size) {
85            value = size;
86        }
87        int value;
88    }
89
90    /**
91     * Default cache usage pattern  Use with {@link #setCacheMode}.
92     */
93    public static final int LOAD_DEFAULT = -1;
94
95    /**
96     * Normal cache usage pattern  Use with {@link #setCacheMode}.
97     */
98    public static final int LOAD_NORMAL = 0;
99
100    /**
101     * Use cache if content is there, even if expired (eg, history nav)
102     * If it is not in the cache, load from network.
103     * Use with {@link #setCacheMode}.
104     */
105    public static final int LOAD_CACHE_ELSE_NETWORK = 1;
106
107    /**
108     * Don't use the cache, load from network
109     * Use with {@link #setCacheMode}.
110     */
111    public static final int LOAD_NO_CACHE = 2;
112
113    /**
114     * Don't use the network, load from cache only.
115     * Use with {@link #setCacheMode}.
116     */
117    public static final int LOAD_CACHE_ONLY = 3;
118
119    public enum RenderPriority {
120        NORMAL,
121        HIGH,
122        LOW
123    }
124
125    // WebView associated with this WebSettings.
126    private WebView mWebView;
127    // BrowserFrame used to access the native frame pointer.
128    private BrowserFrame mBrowserFrame;
129    // Flag to prevent multiple SYNC messages at one time.
130    private boolean mSyncPending = false;
131    // Custom handler that queues messages until the WebCore thread is active.
132    private final EventHandler mEventHandler;
133    // Private settings so we don't have to go into native code to
134    // retrieve the values. After setXXX, postSync() needs to be called.
135    // XXX: The default values need to match those in WebSettings.cpp
136    private LayoutAlgorithm mLayoutAlgorithm = LayoutAlgorithm.NARROW_COLUMNS;
137    private Context         mContext;
138    private TextSize        mTextSize = TextSize.NORMAL;
139    private String          mStandardFontFamily = "sans-serif";
140    private String          mFixedFontFamily = "monospace";
141    private String          mSansSerifFontFamily = "sans-serif";
142    private String          mSerifFontFamily = "serif";
143    private String          mCursiveFontFamily = "cursive";
144    private String          mFantasyFontFamily = "fantasy";
145    private String          mDefaultTextEncoding;
146    private String          mUserAgent;
147    private boolean         mUseDefaultUserAgent;
148    private String          mAcceptLanguage;
149    private String          mPluginsPath = "";
150    private int             mMinimumFontSize = 8;
151    private int             mMinimumLogicalFontSize = 8;
152    private int             mDefaultFontSize = 16;
153    private int             mDefaultFixedFontSize = 13;
154    private boolean         mLoadsImagesAutomatically = true;
155    private boolean         mBlockNetworkImage = false;
156    private boolean         mBlockNetworkLoads;
157    private boolean         mJavaScriptEnabled = false;
158    private boolean         mPluginsEnabled = false;
159    private boolean         mJavaScriptCanOpenWindowsAutomatically = false;
160    private boolean         mUseDoubleTree = false;
161    private boolean         mUseWideViewport = false;
162    private boolean         mSupportMultipleWindows = false;
163    private boolean         mShrinksStandaloneImagesToFit = false;
164    // Don't need to synchronize the get/set methods as they
165    // are basic types, also none of these values are used in
166    // native WebCore code.
167    private ZoomDensity     mDefaultZoom = ZoomDensity.MEDIUM;
168    private RenderPriority  mRenderPriority = RenderPriority.NORMAL;
169    private int             mOverrideCacheMode = LOAD_DEFAULT;
170    private boolean         mSaveFormData = true;
171    private boolean         mSavePassword = true;
172    private boolean         mLightTouchEnabled = false;
173    private boolean         mNeedInitialFocus = true;
174    private boolean         mNavDump = false;
175    private boolean         mSupportZoom = true;
176    private boolean         mBuiltInZoomControls = false;
177    private boolean         mAllowFileAccess = true;
178
179    // Class to handle messages before WebCore is ready.
180    private class EventHandler {
181        // Message id for syncing
182        static final int SYNC = 0;
183        // Message id for setting priority
184        static final int PRIORITY = 1;
185        // Actual WebCore thread handler
186        private Handler mHandler;
187
188        private synchronized void createHandler() {
189            // as mRenderPriority can be set before thread is running, sync up
190            setRenderPriority();
191
192            // create a new handler
193            mHandler = new Handler() {
194                @Override
195                public void handleMessage(Message msg) {
196                    switch (msg.what) {
197                        case SYNC:
198                            synchronized (WebSettings.this) {
199                                if (mBrowserFrame.mNativeFrame != 0) {
200                                    nativeSync(mBrowserFrame.mNativeFrame);
201                                }
202                                mSyncPending = false;
203                            }
204                            break;
205
206                        case PRIORITY: {
207                            setRenderPriority();
208                            break;
209                        }
210                    }
211                }
212            };
213        }
214
215        private void setRenderPriority() {
216            synchronized (WebSettings.this) {
217                if (mRenderPriority == RenderPriority.NORMAL) {
218                    android.os.Process.setThreadPriority(
219                            android.os.Process.THREAD_PRIORITY_DEFAULT);
220                } else if (mRenderPriority == RenderPriority.HIGH) {
221                    android.os.Process.setThreadPriority(
222                            android.os.Process.THREAD_PRIORITY_FOREGROUND +
223                            android.os.Process.THREAD_PRIORITY_LESS_FAVORABLE);
224                } else if (mRenderPriority == RenderPriority.LOW) {
225                    android.os.Process.setThreadPriority(
226                            android.os.Process.THREAD_PRIORITY_BACKGROUND);
227                }
228            }
229        }
230
231        /**
232         * Send a message to the private queue or handler.
233         */
234        private synchronized boolean sendMessage(Message msg) {
235            if (mHandler != null) {
236                mHandler.sendMessage(msg);
237                return true;
238            } else {
239                return false;
240            }
241        }
242    }
243
244    // User agent strings.
245    private static final String DESKTOP_USERAGENT =
246            "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en)"
247            + " AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2"
248            + " Safari/525.20.1";
249    private static final String IPHONE_USERAGENT =
250            "Mozilla/5.0 (iPhone; U; CPU iPhone 2_1 like Mac OS X; en)"
251            + " AppleWebKit/528.5+ (KHTML, like Gecko) Version/3.1.2"
252            + " Mobile/5F136 Safari/525.20.1";
253    private static Locale sLocale;
254    private static Object sLockForLocaleSettings;
255
256    /**
257     * Package constructor to prevent clients from creating a new settings
258     * instance.
259     */
260    WebSettings(Context context, WebView webview) {
261        mEventHandler = new EventHandler();
262        mContext = context;
263        mWebView = webview;
264        mDefaultTextEncoding = context.getString(com.android.internal.
265                                                 R.string.default_text_encoding);
266
267        if (sLockForLocaleSettings == null) {
268            sLockForLocaleSettings = new Object();
269            sLocale = Locale.getDefault();
270        }
271        mAcceptLanguage = getCurrentAcceptLanguage();
272        mUserAgent = getCurrentUserAgent();
273        mUseDefaultUserAgent = true;
274
275        mBlockNetworkLoads = mContext.checkPermission(
276                "android.permission.INTERNET", android.os.Process.myPid(),
277                android.os.Process.myUid()) != PackageManager.PERMISSION_GRANTED;
278    }
279
280    /**
281     * Looks at sLocale and returns current AcceptLanguage String.
282     * @return Current AcceptLanguage String.
283     */
284    private String getCurrentAcceptLanguage() {
285        Locale locale;
286        synchronized(sLockForLocaleSettings) {
287            locale = sLocale;
288        }
289        StringBuffer buffer = new StringBuffer();
290        final String language = locale.getLanguage();
291        if (language != null) {
292            buffer.append(language);
293            final String country = locale.getCountry();
294            if (country != null) {
295                buffer.append("-");
296                buffer.append(country);
297            }
298        }
299        if (!locale.equals(Locale.US)) {
300            buffer.append(", ");
301            java.util.Locale us = Locale.US;
302            if (us.getLanguage() != null) {
303                buffer.append(us.getLanguage());
304                final String country = us.getCountry();
305                if (country != null) {
306                    buffer.append("-");
307                    buffer.append(country);
308                }
309            }
310        }
311
312        return buffer.toString();
313    }
314
315    /**
316     * Looks at sLocale and mContext and returns current UserAgent String.
317     * @return Current UserAgent String.
318     */
319    private synchronized String getCurrentUserAgent() {
320        Locale locale;
321        synchronized(sLockForLocaleSettings) {
322            locale = sLocale;
323        }
324        StringBuffer buffer = new StringBuffer();
325        // Add version
326        final String version = Build.VERSION.RELEASE;
327        if (version.length() > 0) {
328            buffer.append(version);
329        } else {
330            // default to "1.0"
331            buffer.append("1.0");
332        }
333        buffer.append("; ");
334        final String language = locale.getLanguage();
335        if (language != null) {
336            buffer.append(language.toLowerCase());
337            final String country = locale.getCountry();
338            if (country != null) {
339                buffer.append("-");
340                buffer.append(country.toLowerCase());
341            }
342        } else {
343            // default to "en"
344            buffer.append("en");
345        }
346
347        final String model = Build.MODEL;
348        if (model.length() > 0) {
349            buffer.append("; ");
350            buffer.append(model);
351        }
352        final String id = Build.ID;
353        if (id.length() > 0) {
354            buffer.append(" Build/");
355            buffer.append(id);
356        }
357        final String base = mContext.getResources().getText(
358                com.android.internal.R.string.web_user_agent).toString();
359        return String.format(base, buffer);
360    }
361
362    /**
363     * Enables dumping the pages navigation cache to a text file.
364     */
365    public void setNavDump(boolean enabled) {
366        mNavDump = enabled;
367    }
368
369    /**
370     * Returns true if dumping the navigation cache is enabled.
371     */
372    public boolean getNavDump() {
373        return mNavDump;
374    }
375
376    /**
377     * Set whether the WebView supports zoom
378     */
379    public void setSupportZoom(boolean support) {
380        mSupportZoom = support;
381    }
382
383    /**
384     * Returns whether the WebView supports zoom
385     */
386    public boolean supportZoom() {
387        return mSupportZoom;
388    }
389
390    /**
391     * Sets whether the zoom mechanism built into WebView is used.
392     */
393    public void setBuiltInZoomControls(boolean enabled) {
394        mBuiltInZoomControls = enabled;
395    }
396
397    /**
398     * Returns true if the zoom mechanism built into WebView is being used.
399     */
400    public boolean getBuiltInZoomControls() {
401        return mBuiltInZoomControls;
402    }
403
404    /**
405     * Enable or disable file access within WebView. File access is enabled by
406     * default.
407     */
408    public void setAllowFileAccess(boolean allow) {
409        mAllowFileAccess = allow;
410    }
411
412    /**
413     * Returns true if this WebView supports file access.
414     */
415    public boolean getAllowFileAccess() {
416        return mAllowFileAccess;
417    }
418
419    /**
420     * Store whether the WebView is saving form data.
421     */
422    public void setSaveFormData(boolean save) {
423        mSaveFormData = save;
424    }
425
426    /**
427     *  Return whether the WebView is saving form data.
428     */
429    public boolean getSaveFormData() {
430        return mSaveFormData;
431    }
432
433    /**
434     *  Store whether the WebView is saving password.
435     */
436    public void setSavePassword(boolean save) {
437        mSavePassword = save;
438    }
439
440    /**
441     *  Return whether the WebView is saving password.
442     */
443    public boolean getSavePassword() {
444        return mSavePassword;
445    }
446
447    /**
448     * Set the text size of the page.
449     * @param t A TextSize value for increasing or decreasing the text.
450     * @see WebSettings.TextSize
451     */
452    public synchronized void setTextSize(TextSize t) {
453        if (WebView.mLogEvent && mTextSize != t ) {
454            Checkin.updateStats(mContext.getContentResolver(),
455                    Checkin.Stats.Tag.BROWSER_TEXT_SIZE_CHANGE, 1, 0.0);
456        }
457        mTextSize = t;
458        postSync();
459    }
460
461    /**
462     * Get the text size of the page.
463     * @return A TextSize enum value describing the text size.
464     * @see WebSettings.TextSize
465     */
466    public synchronized TextSize getTextSize() {
467        return mTextSize;
468    }
469
470    /**
471     * Set the default zoom density of the page. This should be called from UI
472     * thread.
473     * @param zoom A ZoomDensity value
474     * @see WebSettings.ZoomDensity
475     * @hide Pending API council approval
476     */
477    public void setDefaultZoom(ZoomDensity zoom) {
478        if (mDefaultZoom != zoom) {
479            mDefaultZoom = zoom;
480            mWebView.updateDefaultZoomDensity(zoom.value);
481        }
482    }
483
484    /**
485     * Get the default zoom density of the page. This should be called from UI
486     * thread.
487     * @return A ZoomDensity value
488     * @see WebSettings.ZoomDensity
489     * @hide Pending API council approval
490     */
491    public ZoomDensity getDefaultZoom() {
492        return mDefaultZoom;
493    }
494
495    /**
496     * Enables using light touches to make a selection and activate mouseovers.
497     */
498    public void setLightTouchEnabled(boolean enabled) {
499        mLightTouchEnabled = enabled;
500    }
501
502    /**
503     * Returns true if light touches are enabled.
504     */
505    public boolean getLightTouchEnabled() {
506        return mLightTouchEnabled;
507    }
508
509    /**
510     * Tell the WebView to use the double tree rendering algorithm.
511     * @param use True if the WebView is to use double tree rendering, false
512     *            otherwise.
513     */
514    public synchronized void setUseDoubleTree(boolean use) {
515        if (mUseDoubleTree != use) {
516            mUseDoubleTree = use;
517            postSync();
518        }
519    }
520
521    /**
522     * Return true if the WebView is using the double tree rendering algorithm.
523     * @return True if the WebView is using the double tree rendering
524     *         algorithm.
525     */
526    public synchronized boolean getUseDoubleTree() {
527        return mUseDoubleTree;
528    }
529
530    /**
531     * Tell the WebView about user-agent string.
532     * @param ua 0 if the WebView should use an Android user-agent string,
533     *           1 if the WebView should use a desktop user-agent string.
534     *
535     * @deprecated Please use setUserAgentString instead.
536     */
537    @Deprecated
538    public synchronized void setUserAgent(int ua) {
539        String uaString = null;
540        if (ua == 1) {
541            if (DESKTOP_USERAGENT.equals(mUserAgent)) {
542                return; // do nothing
543            } else {
544                uaString = DESKTOP_USERAGENT;
545            }
546        } else if (ua == 2) {
547            if (IPHONE_USERAGENT.equals(mUserAgent)) {
548                return; // do nothing
549            } else {
550                uaString = IPHONE_USERAGENT;
551            }
552        } else if (ua != 0) {
553            return; // do nothing
554        }
555        setUserAgentString(uaString);
556    }
557
558    /**
559     * Return user-agent as int
560     * @return int  0 if the WebView is using an Android user-agent string.
561     *              1 if the WebView is using a desktop user-agent string.
562     *             -1 if the WebView is using user defined user-agent string.
563     *
564     * @deprecated Please use getUserAgentString instead.
565     */
566    @Deprecated
567    public synchronized int getUserAgent() {
568        if (DESKTOP_USERAGENT.equals(mUserAgent)) {
569            return 1;
570        } else if (IPHONE_USERAGENT.equals(mUserAgent)) {
571            return 2;
572        } else if (mUseDefaultUserAgent) {
573            return 0;
574        }
575        return -1;
576    }
577
578    /**
579     * Tell the WebView to use the wide viewport
580     */
581    public synchronized void setUseWideViewPort(boolean use) {
582        if (mUseWideViewport != use) {
583            mUseWideViewport = use;
584            postSync();
585        }
586    }
587
588    /**
589     * @return True if the WebView is using a wide viewport
590     */
591    public synchronized boolean getUseWideViewPort() {
592        return mUseWideViewport;
593    }
594
595    /**
596     * Tell the WebView whether it supports multiple windows. TRUE means
597     *         that {@link WebChromeClient#onCreateWindow(WebView, boolean,
598     *         boolean, Message)} is implemented by the host application.
599     */
600    public synchronized void setSupportMultipleWindows(boolean support) {
601        if (mSupportMultipleWindows != support) {
602            mSupportMultipleWindows = support;
603            postSync();
604        }
605    }
606
607    /**
608     * @return True if the WebView is supporting multiple windows. This means
609     *         that {@link WebChromeClient#onCreateWindow(WebView, boolean,
610     *         boolean, Message)} is implemented by the host application.
611     */
612    public synchronized boolean supportMultipleWindows() {
613        return mSupportMultipleWindows;
614    }
615
616    /**
617     * Set the underlying layout algorithm. This will cause a relayout of the
618     * WebView.
619     * @param l A LayoutAlgorithm enum specifying the algorithm to use.
620     * @see WebSettings.LayoutAlgorithm
621     */
622    public synchronized void setLayoutAlgorithm(LayoutAlgorithm l) {
623        // XXX: This will only be affective if libwebcore was built with
624        // ANDROID_LAYOUT defined.
625        if (mLayoutAlgorithm != l) {
626            mLayoutAlgorithm = l;
627            postSync();
628        }
629    }
630
631    /**
632     * Return the current layout algorithm.
633     * @return LayoutAlgorithm enum value describing the layout algorithm
634     *         being used.
635     * @see WebSettings.LayoutAlgorithm
636     */
637    public synchronized LayoutAlgorithm getLayoutAlgorithm() {
638        return mLayoutAlgorithm;
639    }
640
641    /**
642     * Set the standard font family name.
643     * @param font A font family name.
644     */
645    public synchronized void setStandardFontFamily(String font) {
646        if (font != null && !font.equals(mStandardFontFamily)) {
647            mStandardFontFamily = font;
648            postSync();
649        }
650    }
651
652    /**
653     * Get the standard font family name.
654     * @return The standard font family name as a string.
655     */
656    public synchronized String getStandardFontFamily() {
657        return mStandardFontFamily;
658    }
659
660    /**
661     * Set the fixed font family name.
662     * @param font A font family name.
663     */
664    public synchronized void setFixedFontFamily(String font) {
665        if (font != null && !font.equals(mFixedFontFamily)) {
666            mFixedFontFamily = font;
667            postSync();
668        }
669    }
670
671    /**
672     * Get the fixed font family name.
673     * @return The fixed font family name as a string.
674     */
675    public synchronized String getFixedFontFamily() {
676        return mFixedFontFamily;
677    }
678
679    /**
680     * Set the sans-serif font family name.
681     * @param font A font family name.
682     */
683    public synchronized void setSansSerifFontFamily(String font) {
684        if (font != null && !font.equals(mSansSerifFontFamily)) {
685            mSansSerifFontFamily = font;
686            postSync();
687        }
688    }
689
690    /**
691     * Get the sans-serif font family name.
692     * @return The sans-serif font family name as a string.
693     */
694    public synchronized String getSansSerifFontFamily() {
695        return mSansSerifFontFamily;
696    }
697
698    /**
699     * Set the serif font family name.
700     * @param font A font family name.
701     */
702    public synchronized void setSerifFontFamily(String font) {
703        if (font != null && !font.equals(mSerifFontFamily)) {
704            mSerifFontFamily = font;
705            postSync();
706        }
707    }
708
709    /**
710     * Get the serif font family name.
711     * @return The serif font family name as a string.
712     */
713    public synchronized String getSerifFontFamily() {
714        return mSerifFontFamily;
715    }
716
717    /**
718     * Set the cursive font family name.
719     * @param font A font family name.
720     */
721    public synchronized void setCursiveFontFamily(String font) {
722        if (font != null && !font.equals(mCursiveFontFamily)) {
723            mCursiveFontFamily = font;
724            postSync();
725        }
726    }
727
728    /**
729     * Get the cursive font family name.
730     * @return The cursive font family name as a string.
731     */
732    public synchronized String getCursiveFontFamily() {
733        return mCursiveFontFamily;
734    }
735
736    /**
737     * Set the fantasy font family name.
738     * @param font A font family name.
739     */
740    public synchronized void setFantasyFontFamily(String font) {
741        if (font != null && !font.equals(mFantasyFontFamily)) {
742            mFantasyFontFamily = font;
743            postSync();
744        }
745    }
746
747    /**
748     * Get the fantasy font family name.
749     * @return The fantasy font family name as a string.
750     */
751    public synchronized String getFantasyFontFamily() {
752        return mFantasyFontFamily;
753    }
754
755    /**
756     * Set the minimum font size.
757     * @param size A non-negative integer between 1 and 72.
758     * Any number outside the specified range will be pinned.
759     */
760    public synchronized void setMinimumFontSize(int size) {
761        size = pin(size);
762        if (mMinimumFontSize != size) {
763            mMinimumFontSize = size;
764            postSync();
765        }
766    }
767
768    /**
769     * Get the minimum font size.
770     * @return A non-negative integer between 1 and 72.
771     */
772    public synchronized int getMinimumFontSize() {
773        return mMinimumFontSize;
774    }
775
776    /**
777     * Set the minimum logical font size.
778     * @param size A non-negative integer between 1 and 72.
779     * Any number outside the specified range will be pinned.
780     */
781    public synchronized void setMinimumLogicalFontSize(int size) {
782        size = pin(size);
783        if (mMinimumLogicalFontSize != size) {
784            mMinimumLogicalFontSize = size;
785            postSync();
786        }
787    }
788
789    /**
790     * Get the minimum logical font size.
791     * @return A non-negative integer between 1 and 72.
792     */
793    public synchronized int getMinimumLogicalFontSize() {
794        return mMinimumLogicalFontSize;
795    }
796
797    /**
798     * Set the default font size.
799     * @param size A non-negative integer between 1 and 72.
800     * Any number outside the specified range will be pinned.
801     */
802    public synchronized void setDefaultFontSize(int size) {
803        size = pin(size);
804        if (mDefaultFontSize != size) {
805            mDefaultFontSize = size;
806            postSync();
807        }
808    }
809
810    /**
811     * Get the default font size.
812     * @return A non-negative integer between 1 and 72.
813     */
814    public synchronized int getDefaultFontSize() {
815        return mDefaultFontSize;
816    }
817
818    /**
819     * Set the default fixed font size.
820     * @param size A non-negative integer between 1 and 72.
821     * Any number outside the specified range will be pinned.
822     */
823    public synchronized void setDefaultFixedFontSize(int size) {
824        size = pin(size);
825        if (mDefaultFixedFontSize != size) {
826            mDefaultFixedFontSize = size;
827            postSync();
828        }
829    }
830
831    /**
832     * Get the default fixed font size.
833     * @return A non-negative integer between 1 and 72.
834     */
835    public synchronized int getDefaultFixedFontSize() {
836        return mDefaultFixedFontSize;
837    }
838
839    /**
840     * Tell the WebView to load image resources automatically.
841     * @param flag True if the WebView should load images automatically.
842     */
843    public synchronized void setLoadsImagesAutomatically(boolean flag) {
844        if (mLoadsImagesAutomatically != flag) {
845            mLoadsImagesAutomatically = flag;
846            postSync();
847        }
848    }
849
850    /**
851     * Return true if the WebView will load image resources automatically.
852     * @return True if the WebView loads images automatically.
853     */
854    public synchronized boolean getLoadsImagesAutomatically() {
855        return mLoadsImagesAutomatically;
856    }
857
858    /**
859     * Tell the WebView to block network image. This is only checked when
860     * getLoadsImagesAutomatically() is true.
861     * @param flag True if the WebView should block network image
862     */
863    public synchronized void setBlockNetworkImage(boolean flag) {
864        if (mBlockNetworkImage != flag) {
865            mBlockNetworkImage = flag;
866            postSync();
867        }
868    }
869
870    /**
871     * Return true if the WebView will block network image.
872     * @return True if the WebView blocks network image.
873     */
874    public synchronized boolean getBlockNetworkImage() {
875        return mBlockNetworkImage;
876    }
877
878    /**
879     * @hide
880     * Tell the WebView to block all network load requests.
881     * @param flag True if the WebView should block all network loads
882     */
883    public synchronized void setBlockNetworkLoads(boolean flag) {
884        if (mBlockNetworkLoads != flag) {
885            mBlockNetworkLoads = flag;
886            verifyNetworkAccess();
887        }
888    }
889
890    /**
891     * @hide
892     * Return true if the WebView will block all network loads.
893     * @return True if the WebView blocks all network loads.
894     */
895    public synchronized boolean getBlockNetworkLoads() {
896        return mBlockNetworkLoads;
897    }
898
899
900    private void verifyNetworkAccess() {
901        if (!mBlockNetworkLoads) {
902            if (mContext.checkPermission("android.permission.INTERNET",
903                    android.os.Process.myPid(), android.os.Process.myUid()) !=
904                        PackageManager.PERMISSION_GRANTED) {
905                throw new SecurityException
906                        ("Permission denied - " +
907                                "application missing INTERNET permission");
908            }
909        }
910    }
911
912    /**
913     * Tell the WebView to enable javascript execution.
914     * @param flag True if the WebView should execute javascript.
915     */
916    public synchronized void setJavaScriptEnabled(boolean flag) {
917        if (mJavaScriptEnabled != flag) {
918            mJavaScriptEnabled = flag;
919            postSync();
920        }
921    }
922
923    /**
924     * Tell the WebView to enable plugins.
925     * @param flag True if the WebView should load plugins.
926     */
927    public synchronized void setPluginsEnabled(boolean flag) {
928        if (mPluginsEnabled != flag) {
929            mPluginsEnabled = flag;
930            postSync();
931        }
932    }
933
934    /**
935     * Set a custom path to plugins used by the WebView. The client
936     * must ensure it exists before this call.
937     * @param pluginsPath String path to the directory containing plugins.
938     */
939    public synchronized void setPluginsPath(String pluginsPath) {
940        if (pluginsPath != null && !pluginsPath.equals(mPluginsPath)) {
941            mPluginsPath = pluginsPath;
942            postSync();
943        }
944    }
945
946    /**
947     * Return true if javascript is enabled.
948     * @return True if javascript is enabled.
949     */
950    public synchronized boolean getJavaScriptEnabled() {
951        return mJavaScriptEnabled;
952    }
953
954    /**
955     * Return true if plugins are enabled.
956     * @return True if plugins are enabled.
957     */
958    public synchronized boolean getPluginsEnabled() {
959        return mPluginsEnabled;
960    }
961
962    /**
963     * Return the current path used for plugins in the WebView.
964     * @return The string path to the WebView plugins.
965     */
966    public synchronized String getPluginsPath() {
967        return mPluginsPath;
968    }
969
970    /**
971     * Tell javascript to open windows automatically. This applies to the
972     * javascript function window.open().
973     * @param flag True if javascript can open windows automatically.
974     */
975    public synchronized void setJavaScriptCanOpenWindowsAutomatically(
976            boolean flag) {
977        if (mJavaScriptCanOpenWindowsAutomatically != flag) {
978            mJavaScriptCanOpenWindowsAutomatically = flag;
979            postSync();
980        }
981    }
982
983    /**
984     * Return true if javascript can open windows automatically.
985     * @return True if javascript can open windows automatically during
986     *         window.open().
987     */
988    public synchronized boolean getJavaScriptCanOpenWindowsAutomatically() {
989        return mJavaScriptCanOpenWindowsAutomatically;
990    }
991
992    /**
993     * Set the default text encoding name to use when decoding html pages.
994     * @param encoding The text encoding name.
995     */
996    public synchronized void setDefaultTextEncodingName(String encoding) {
997        if (encoding != null && !encoding.equals(mDefaultTextEncoding)) {
998            mDefaultTextEncoding = encoding;
999            postSync();
1000        }
1001    }
1002
1003    /**
1004     * Get the default text encoding name.
1005     * @return The default text encoding name as a string.
1006     */
1007    public synchronized String getDefaultTextEncodingName() {
1008        return mDefaultTextEncoding;
1009    }
1010
1011    /**
1012     * Set the WebView's user-agent string. If the string "ua" is null or empty,
1013     * it will use the system default user-agent string.
1014     */
1015    public synchronized void setUserAgentString(String ua) {
1016        if (ua == null || ua.length() == 0) {
1017            synchronized(sLockForLocaleSettings) {
1018                Locale currentLocale = Locale.getDefault();
1019                if (!sLocale.equals(currentLocale)) {
1020                    sLocale = currentLocale;
1021                    mAcceptLanguage = getCurrentAcceptLanguage();
1022                }
1023            }
1024            ua = getCurrentUserAgent();
1025            mUseDefaultUserAgent = true;
1026        } else  {
1027            mUseDefaultUserAgent = false;
1028        }
1029
1030        if (!ua.equals(mUserAgent)) {
1031            mUserAgent = ua;
1032            postSync();
1033        }
1034    }
1035
1036    /**
1037     * Return the WebView's user-agent string.
1038     */
1039    public synchronized String getUserAgentString() {
1040        if (DESKTOP_USERAGENT.equals(mUserAgent) ||
1041                IPHONE_USERAGENT.equals(mUserAgent) ||
1042                !mUseDefaultUserAgent) {
1043            return mUserAgent;
1044        }
1045
1046        boolean doPostSync = false;
1047        synchronized(sLockForLocaleSettings) {
1048            Locale currentLocale = Locale.getDefault();
1049            if (!sLocale.equals(currentLocale)) {
1050                sLocale = currentLocale;
1051                mUserAgent = getCurrentUserAgent();
1052                mAcceptLanguage = getCurrentAcceptLanguage();
1053                doPostSync = true;
1054            }
1055        }
1056        if (doPostSync) {
1057            postSync();
1058        }
1059        return mUserAgent;
1060    }
1061
1062    /* package api to grab the Accept Language string. */
1063    /*package*/ synchronized String getAcceptLanguage() {
1064        synchronized(sLockForLocaleSettings) {
1065            Locale currentLocale = Locale.getDefault();
1066            if (!sLocale.equals(currentLocale)) {
1067                sLocale = currentLocale;
1068                mAcceptLanguage = getCurrentAcceptLanguage();
1069            }
1070        }
1071        return mAcceptLanguage;
1072    }
1073
1074    /**
1075     * Tell the WebView whether it needs to set a node to have focus when
1076     * {@link WebView#requestFocus(int, android.graphics.Rect)} is called.
1077     *
1078     * @param flag
1079     */
1080    public void setNeedInitialFocus(boolean flag) {
1081        if (mNeedInitialFocus != flag) {
1082            mNeedInitialFocus = flag;
1083        }
1084    }
1085
1086    /* Package api to get the choice whether it needs to set initial focus. */
1087    /* package */ boolean getNeedInitialFocus() {
1088        return mNeedInitialFocus;
1089    }
1090
1091    /**
1092     * Set the priority of the Render thread. Unlike the other settings, this
1093     * one only needs to be called once per process.
1094     *
1095     * @param priority RenderPriority, can be normal, high or low.
1096     */
1097    public synchronized void setRenderPriority(RenderPriority priority) {
1098        if (mRenderPriority != priority) {
1099            mRenderPriority = priority;
1100            mEventHandler.sendMessage(Message.obtain(null,
1101                    EventHandler.PRIORITY));
1102        }
1103    }
1104
1105    /**
1106     * Override the way the cache is used. The way the cache is used is based
1107     * on the navigation option. For a normal page load, the cache is checked
1108     * and content is re-validated as needed. When navigating back, content is
1109     * not revalidated, instead the content is just pulled from the cache.
1110     * This function allows the client to override this behavior.
1111     * @param mode One of the LOAD_ values.
1112     */
1113    public void setCacheMode(int mode) {
1114        if (mode != mOverrideCacheMode) {
1115            mOverrideCacheMode = mode;
1116        }
1117    }
1118
1119    /**
1120     * Return the current setting for overriding the cache mode. For a full
1121     * description, see the {@link #setCacheMode(int)} function.
1122     */
1123    public int getCacheMode() {
1124        return mOverrideCacheMode;
1125    }
1126
1127    /**
1128     * If set, webkit alternately shrinks and expands images viewed outside
1129     * of an HTML page to fit the screen. This conflicts with attempts by
1130     * the UI to zoom in and out of an image, so it is set false by default.
1131     * @param shrink Set true to let webkit shrink the standalone image to fit.
1132     * {@hide}
1133     */
1134    public void setShrinksStandaloneImagesToFit(boolean shrink) {
1135        if (mShrinksStandaloneImagesToFit != shrink) {
1136            mShrinksStandaloneImagesToFit = shrink;
1137            postSync();
1138        }
1139     }
1140
1141    /**
1142     * Transfer messages from the queue to the new WebCoreThread. Called from
1143     * WebCore thread.
1144     */
1145    /*package*/
1146    synchronized void syncSettingsAndCreateHandler(BrowserFrame frame) {
1147        mBrowserFrame = frame;
1148        if (WebView.DEBUG) {
1149            junit.framework.Assert.assertTrue(frame.mNativeFrame != 0);
1150        }
1151        nativeSync(frame.mNativeFrame);
1152        mSyncPending = false;
1153        mEventHandler.createHandler();
1154    }
1155
1156    private int pin(int size) {
1157        // FIXME: 72 is just an arbitrary max text size value.
1158        if (size < 1) {
1159            return 1;
1160        } else if (size > 72) {
1161            return 72;
1162        }
1163        return size;
1164    }
1165
1166    /* Post a SYNC message to handle syncing the native settings. */
1167    private synchronized void postSync() {
1168        // Only post if a sync is not pending
1169        if (!mSyncPending) {
1170            mSyncPending = mEventHandler.sendMessage(
1171                    Message.obtain(null, EventHandler.SYNC));
1172        }
1173    }
1174
1175    // Synchronize the native and java settings.
1176    private native void nativeSync(int nativeFrame);
1177}
1178