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