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