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