ContentSettings.java revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5package org.chromium.content.browser; 6 7import android.os.Handler; 8import android.os.Looper; 9import android.os.Message; 10import android.webkit.WebSettings.PluginState; 11import android.webkit.WebView; 12 13import org.chromium.base.CalledByNative; 14import org.chromium.base.JNINamespace; 15import org.chromium.base.ThreadUtils; 16 17/** 18 * Manages settings state for a ContentView. A ContentSettings instance is obtained 19 * from ContentView.getContentSettings(). If ContentView is used in the 20 * ContentView.PERSONALITY_VIEW role, all settings are read / write. If ContentView 21 * is in the ContentView.PERSONALITY_CHROME role, setting can only be read. 22 */ 23@JNINamespace("content") 24public class ContentSettings { 25 // This enum corresponds to WebSettings.LayoutAlgorithm. We use our own to be 26 // able to extend it. 27 public enum LayoutAlgorithm { 28 NORMAL, 29 SINGLE_COLUMN, 30 NARROW_COLUMNS, 31 TEXT_AUTOSIZING, 32 } 33 34 private static final String TAG = "ContentSettings"; 35 36 // This class must be created on the UI thread. Afterwards, it can be 37 // used from any thread. Internally, the class uses a message queue 38 // to call native code on the UI thread only. 39 40 // The native side of this object. Ownership is retained native-side by the WebContents 41 // instance that backs the associated ContentViewCore. 42 private int mNativeContentSettings = 0; 43 44 private ContentViewCore mContentViewCore; 45 46 // When ContentView is used in PERSONALITY_CHROME mode, settings can't 47 // be modified through the ContentSettings instance. 48 private boolean mCanModifySettings; 49 50 // A flag to avoid sending superfluous synchronization messages. 51 private boolean mIsSyncMessagePending = false; 52 // Custom handler that queues messages to call native code on the UI thread. 53 private final EventHandler mEventHandler; 54 55 // Protects access to settings fields. 56 private final Object mContentSettingsLock = new Object(); 57 58 private static final int MINIMUM_FONT_SIZE = 1; 59 private static final int MAXIMUM_FONT_SIZE = 72; 60 61 // Private settings so we don't have to go into native code to 62 // retrieve the values. After setXXX, mEventHandler.syncSettingsLocked() needs to be called. 63 // 64 // TODO(mnaganov): populate with the complete set of legacy WebView settings. 65 // Note: If adding a new setting to this class, make sure to add it to the initFrom() 66 // method defined below. 67 68 private LayoutAlgorithm mLayoutAlgorithm = LayoutAlgorithm.NARROW_COLUMNS; 69 private int mTextSizePercent = 100; 70 private String mStandardFontFamily = "sans-serif"; 71 private String mFixedFontFamily = "monospace"; 72 private String mSansSerifFontFamily = "sans-serif"; 73 private String mSerifFontFamily = "serif"; 74 private String mCursiveFontFamily = "cursive"; 75 private String mFantasyFontFamily = "fantasy"; 76 // FIXME: Should be obtained from Android. Problem: it is hidden. 77 private String mDefaultTextEncoding = "Latin-1"; 78 private String mUserAgent; 79 private int mMinimumFontSize = 8; 80 private int mMinimumLogicalFontSize = 8; 81 private int mDefaultFontSize = 16; 82 private int mDefaultFixedFontSize = 13; 83 private boolean mLoadsImagesAutomatically = true; 84 private boolean mImagesEnabled = true; 85 private boolean mJavaScriptEnabled = false; 86 private boolean mAllowUniversalAccessFromFileURLs = false; 87 private boolean mAllowFileAccessFromFileURLs = false; 88 private boolean mJavaScriptCanOpenWindowsAutomatically = false; 89 private boolean mSupportMultipleWindows = false; 90 private PluginState mPluginState = PluginState.OFF; 91 private boolean mAppCacheEnabled = false; 92 private boolean mDomStorageEnabled = false; 93 private boolean mDatabaseEnabled = false; 94 private boolean mUseWideViewport = false; 95 private boolean mLoadWithOverviewMode = false; 96 private boolean mMediaPlaybackRequiresUserGesture = true; 97 private String mDefaultVideoPosterURL; 98 99 // Not accessed by the native side. 100 private boolean mSupportZoom = true; 101 private boolean mBuiltInZoomControls = false; 102 private boolean mDisplayZoomControls = true; 103 static class LazyDefaultUserAgent { 104 // Lazy Holder pattern 105 private static final String sInstance = nativeGetDefaultUserAgent(); 106 } 107 108 // Protects access to settings global fields. 109 private static final Object sGlobalContentSettingsLock = new Object(); 110 // For compatibility with the legacy WebView, we can only enable AppCache when the path is 111 // provided. However, we don't use the path, so we just check if we have received it from the 112 // client. 113 private static boolean sAppCachePathIsSet = false; 114 115 // Class to handle messages to be processed on the UI thread. 116 private class EventHandler { 117 // Message id for syncing 118 private static final int SYNC = 0; 119 // Message id for updating user agent in the view 120 private static final int UPDATE_UA = 1; 121 // Message id for updating multi-touch zoom state in the view 122 private static final int UPDATE_MULTI_TOUCH = 2; 123 // Actual UI thread handler 124 private Handler mHandler; 125 126 EventHandler() { 127 mHandler = mContentViewCore.isPersonalityView() ? 128 new Handler(Looper.getMainLooper()) { 129 @Override 130 public void handleMessage(Message msg) { 131 switch (msg.what) { 132 case SYNC: 133 synchronized (mContentSettingsLock) { 134 syncToNativeOnUiThread(); 135 mIsSyncMessagePending = false; 136 mContentSettingsLock.notifyAll(); 137 } 138 break; 139 case UPDATE_UA: 140 if (mContentViewCore.isAlive()) { 141 mContentViewCore.setAllUserAgentOverridesInHistory(); 142 } 143 break; 144 case UPDATE_MULTI_TOUCH: 145 if (mContentViewCore.isAlive()) { 146 mContentViewCore.updateMultiTouchZoomSupport(); 147 } 148 break; 149 } 150 } 151 } : 152 new Handler(Looper.getMainLooper()) { 153 @Override 154 public void handleMessage(Message msg) { 155 switch (msg.what) { 156 case SYNC: 157 synchronized (mContentSettingsLock) { 158 syncFromNativeOnUiThread(); 159 mIsSyncMessagePending = false; 160 } 161 break; 162 } 163 } 164 }; 165 } 166 167 private void syncSettingsLocked() { 168 assert Thread.holdsLock(mContentSettingsLock); 169 if (mNativeContentSettings == 0) return; 170 if (mContentViewCore.isPersonalityView()) { 171 if (Looper.myLooper() == mHandler.getLooper()) { 172 syncToNativeOnUiThread(); 173 } else { 174 // We're being called on a background thread, so post a message. 175 if (mIsSyncMessagePending) { 176 return; 177 } 178 mIsSyncMessagePending = true; 179 mHandler.sendMessage(Message.obtain(null, SYNC)); 180 // When used in PERSONALITY_VIEW mode, we must block 181 // until the settings have been sync'd to native to 182 // ensure that they have taken effect. 183 try { 184 while (mIsSyncMessagePending) { 185 mContentSettingsLock.wait(); 186 } 187 } catch (InterruptedException e) {} 188 } 189 } else { 190 if (mIsSyncMessagePending) { 191 return; 192 } 193 mIsSyncMessagePending = true; 194 mHandler.sendMessage(Message.obtain(null, SYNC)); 195 } 196 } 197 198 private void sendUpdateUaMessageLocked() { 199 assert Thread.holdsLock(mContentSettingsLock); 200 if (mNativeContentSettings == 0) return; 201 mHandler.sendMessage(Message.obtain(null, UPDATE_UA)); 202 } 203 204 private void sendUpdateMultiTouchMessageLocked() { 205 assert Thread.holdsLock(mContentSettingsLock); 206 if (mNativeContentSettings == 0) return; 207 mHandler.sendMessage(Message.obtain(null, UPDATE_MULTI_TOUCH)); 208 } 209 } 210 211 /** 212 * Package constructor to prevent clients from creating a new settings 213 * instance. Must be called on the UI thread. 214 */ 215 ContentSettings(ContentViewCore contentViewCore, int nativeContentView, 216 boolean isAccessFromFileURLsGrantedByDefault) { 217 ThreadUtils.assertOnUiThread(); 218 mContentViewCore = contentViewCore; 219 mCanModifySettings = mContentViewCore.isPersonalityView(); 220 mNativeContentSettings = nativeInit(nativeContentView, mCanModifySettings); 221 assert mNativeContentSettings != 0; 222 223 if (isAccessFromFileURLsGrantedByDefault) { 224 mAllowUniversalAccessFromFileURLs = true; 225 mAllowFileAccessFromFileURLs = true; 226 } 227 228 mEventHandler = new EventHandler(); 229 if (mCanModifySettings) { 230 // PERSONALITY_VIEW 231 mUserAgent = LazyDefaultUserAgent.sInstance; 232 syncToNativeOnUiThread(); 233 } else { 234 // PERSONALITY_CHROME 235 // Chrome has zooming enabled by default. These settings are not 236 // set by the native code. 237 mBuiltInZoomControls = true; 238 mDisplayZoomControls = false; 239 syncFromNativeOnUiThread(); 240 } 241 } 242 243 /** 244 * Notification from the native side that it is being destroyed. 245 * @param nativeContentSettings the native instance that is going away. 246 */ 247 @CalledByNative 248 private void onNativeContentSettingsDestroyed(int nativeContentSettings) { 249 assert mNativeContentSettings == nativeContentSettings; 250 mNativeContentSettings = 0; 251 } 252 253 /** 254 * @returns the default User-Agent used by each ContentViewCore instance, i.e. unless 255 * overridden by {@link #setUserAgentString()} 256 */ 257 public static String getDefaultUserAgent() { 258 return LazyDefaultUserAgent.sInstance; 259 } 260 261 /** 262 * Set the WebView's user-agent string. If the string "ua" is null or empty, 263 * it will use the system default user-agent string. 264 */ 265 public void setUserAgentString(String ua) { 266 assert mCanModifySettings; 267 synchronized (mContentSettingsLock) { 268 final String oldUserAgent = mUserAgent; 269 if (ua == null || ua.length() == 0) { 270 mUserAgent = LazyDefaultUserAgent.sInstance; 271 } else { 272 mUserAgent = ua; 273 } 274 if (!oldUserAgent.equals(mUserAgent)) { 275 mEventHandler.sendUpdateUaMessageLocked(); 276 } 277 } 278 } 279 280 /** 281 * Gets the WebView's user-agent string. 282 */ 283 public String getUserAgentString() { 284 // TODO(mnaganov): Doesn't reflect changes made by ChromeNativePreferences. 285 synchronized (mContentSettingsLock) { 286 return mUserAgent; 287 } 288 } 289 290 /** 291 * Sets whether the WebView should support zooming using its on-screen zoom 292 * controls and gestures. The particular zoom mechanisms that should be used 293 * can be set with {@link #setBuiltInZoomControls}. This setting does not 294 * affect zooming performed using the {@link WebView#zoomIn()} and 295 * {@link WebView#zoomOut()} methods. The default is true. 296 * 297 * @param support whether the WebView should support zoom 298 */ 299 public void setSupportZoom(boolean support) { 300 synchronized (mContentSettingsLock) { 301 mSupportZoom = support; 302 mEventHandler.sendUpdateMultiTouchMessageLocked(); 303 } 304 } 305 306 /** 307 * Gets whether the WebView supports zoom. 308 * 309 * @return true if the WebView supports zoom 310 * @see #setSupportZoom 311 */ 312 public boolean supportZoom() { 313 return mSupportZoom; 314 } 315 316 /** 317 * Sets whether the WebView should use its built-in zoom mechanisms. The 318 * built-in zoom mechanisms comprise on-screen zoom controls, which are 319 * displayed over the WebView's content, and the use of a pinch gesture to 320 * control zooming. Whether or not these on-screen controls are displayed 321 * can be set with {@link #setDisplayZoomControls}. The default is false, 322 * due to compatibility reasons. 323 * <p> 324 * The built-in mechanisms are the only currently supported zoom 325 * mechanisms, so it is recommended that this setting is always enabled. 326 * In other words, there is no point of calling this method other than 327 * with the 'true' parameter. 328 * 329 * @param enabled whether the WebView should use its built-in zoom mechanisms 330 */ 331 public void setBuiltInZoomControls(boolean enabled) { 332 synchronized (mContentSettingsLock) { 333 mBuiltInZoomControls = enabled; 334 mEventHandler.sendUpdateMultiTouchMessageLocked(); 335 } 336 } 337 338 /** 339 * Gets whether the zoom mechanisms built into WebView are being used. 340 * 341 * @return true if the zoom mechanisms built into WebView are being used 342 * @see #setBuiltInZoomControls 343 */ 344 public boolean getBuiltInZoomControls() { 345 return mBuiltInZoomControls; 346 } 347 348 /** 349 * Sets whether the WebView should display on-screen zoom controls when 350 * using the built-in zoom mechanisms. See {@link #setBuiltInZoomControls}. 351 * The default is true. 352 * 353 * @param enabled whether the WebView should display on-screen zoom controls 354 */ 355 public void setDisplayZoomControls(boolean enabled) { 356 synchronized (mContentSettingsLock) { 357 mDisplayZoomControls = enabled; 358 mEventHandler.sendUpdateMultiTouchMessageLocked(); 359 } 360 } 361 362 /** 363 * Gets whether the WebView displays on-screen zoom controls when using 364 * the built-in zoom mechanisms. 365 * 366 * @return true if the WebView displays on-screen zoom controls when using 367 * the built-in zoom mechanisms 368 * @see #setDisplayZoomControls 369 */ 370 public boolean getDisplayZoomControls() { 371 return mDisplayZoomControls; 372 } 373 374 boolean supportsMultiTouchZoom() { 375 return mSupportZoom && mBuiltInZoomControls; 376 } 377 378 boolean shouldDisplayZoomControls() { 379 return supportsMultiTouchZoom() && mDisplayZoomControls; 380 } 381 382 public void setLoadWithOverviewMode(boolean overview) { 383 assert mCanModifySettings; 384 synchronized (mContentSettingsLock) { 385 if (mLoadWithOverviewMode != overview) { 386 mLoadWithOverviewMode = overview; 387 mEventHandler.syncSettingsLocked(); 388 } 389 } 390 } 391 392 public boolean getLoadWithOverviewMode() { 393 synchronized (mContentSettingsLock) { 394 return mLoadWithOverviewMode; 395 } 396 } 397 398 /** 399 * Sets the text zoom of the page in percent. Default is 100. 400 * 401 * @param textZoom the percent value for increasing or decreasing the text 402 */ 403 public void setTextZoom(int textZoom) { 404 assert mCanModifySettings; 405 synchronized (mContentSettingsLock) { 406 if (mTextSizePercent != textZoom) { 407 mTextSizePercent = textZoom; 408 mEventHandler.syncSettingsLocked(); 409 } 410 } 411 } 412 413 /** 414 * Gets the text zoom of the page in percent. 415 * 416 * @return a percent value describing the text zoom 417 * @see #setTextSizeZoom 418 */ 419 public int getTextZoom() { 420 synchronized (mContentSettingsLock) { 421 return mTextSizePercent; 422 } 423 } 424 425 /** 426 * Set the standard font family name. 427 * @param font A font family name. 428 */ 429 public void setStandardFontFamily(String font) { 430 assert mCanModifySettings; 431 synchronized (mContentSettingsLock) { 432 if (font != null && !mStandardFontFamily.equals(font)) { 433 mStandardFontFamily = font; 434 mEventHandler.syncSettingsLocked(); 435 } 436 } 437 } 438 439 /** 440 * Get the standard font family name. The default is "sans-serif". 441 * @return The standard font family name as a string. 442 */ 443 public String getStandardFontFamily() { 444 synchronized (mContentSettingsLock) { 445 return mStandardFontFamily; 446 } 447 } 448 449 /** 450 * Set the fixed font family name. 451 * @param font A font family name. 452 */ 453 public void setFixedFontFamily(String font) { 454 assert mCanModifySettings; 455 synchronized (mContentSettingsLock) { 456 if (font != null && !mFixedFontFamily.equals(font)) { 457 mFixedFontFamily = font; 458 mEventHandler.syncSettingsLocked(); 459 } 460 } 461 } 462 463 /** 464 * Get the fixed font family name. The default is "monospace". 465 * @return The fixed font family name as a string. 466 */ 467 public String getFixedFontFamily() { 468 synchronized (mContentSettingsLock) { 469 return mFixedFontFamily; 470 } 471 } 472 473 /** 474 * Set the sans-serif font family name. 475 * @param font A font family name. 476 */ 477 public void setSansSerifFontFamily(String font) { 478 assert mCanModifySettings; 479 synchronized (mContentSettingsLock) { 480 if (font != null && !mSansSerifFontFamily.equals(font)) { 481 mSansSerifFontFamily = font; 482 mEventHandler.syncSettingsLocked(); 483 } 484 } 485 } 486 487 /** 488 * Get the sans-serif font family name. 489 * @return The sans-serif font family name as a string. 490 */ 491 public String getSansSerifFontFamily() { 492 synchronized (mContentSettingsLock) { 493 return mSansSerifFontFamily; 494 } 495 } 496 497 /** 498 * Set the serif font family name. The default is "sans-serif". 499 * @param font A font family name. 500 */ 501 public void setSerifFontFamily(String font) { 502 assert mCanModifySettings; 503 synchronized (mContentSettingsLock) { 504 if (font != null && !mSerifFontFamily.equals(font)) { 505 mSerifFontFamily = font; 506 mEventHandler.syncSettingsLocked(); 507 } 508 } 509 } 510 511 /** 512 * Get the serif font family name. The default is "serif". 513 * @return The serif font family name as a string. 514 */ 515 public String getSerifFontFamily() { 516 synchronized (mContentSettingsLock) { 517 return mSerifFontFamily; 518 } 519 } 520 521 /** 522 * Set the cursive font family name. 523 * @param font A font family name. 524 */ 525 public void setCursiveFontFamily(String font) { 526 assert mCanModifySettings; 527 synchronized (mContentSettingsLock) { 528 if (font != null && !mCursiveFontFamily.equals(font)) { 529 mCursiveFontFamily = font; 530 mEventHandler.syncSettingsLocked(); 531 } 532 } 533 } 534 535 /** 536 * Get the cursive font family name. The default is "cursive". 537 * @return The cursive font family name as a string. 538 */ 539 public String getCursiveFontFamily() { 540 synchronized (mContentSettingsLock) { 541 return mCursiveFontFamily; 542 } 543 } 544 545 /** 546 * Set the fantasy font family name. 547 * @param font A font family name. 548 */ 549 public void setFantasyFontFamily(String font) { 550 assert mCanModifySettings; 551 synchronized (mContentSettingsLock) { 552 if (font != null && !mFantasyFontFamily.equals(font)) { 553 mFantasyFontFamily = font; 554 mEventHandler.syncSettingsLocked(); 555 } 556 } 557 } 558 559 /** 560 * Get the fantasy font family name. The default is "fantasy". 561 * @return The fantasy font family name as a string. 562 */ 563 public String getFantasyFontFamily() { 564 synchronized (mContentSettingsLock) { 565 return mFantasyFontFamily; 566 } 567 } 568 569 /** 570 * Set the minimum font size. 571 * @param size A non-negative integer between 1 and 72. 572 * Any number outside the specified range will be pinned. 573 */ 574 public void setMinimumFontSize(int size) { 575 assert mCanModifySettings; 576 synchronized (mContentSettingsLock) { 577 size = clipFontSize(size); 578 if (mMinimumFontSize != size) { 579 mMinimumFontSize = size; 580 mEventHandler.syncSettingsLocked(); 581 } 582 } 583 } 584 585 /** 586 * Get the minimum font size. The default is 8. 587 * @return A non-negative integer between 1 and 72. 588 */ 589 public int getMinimumFontSize() { 590 synchronized (mContentSettingsLock) { 591 return mMinimumFontSize; 592 } 593 } 594 595 /** 596 * Set the minimum logical font size. 597 * @param size A non-negative integer between 1 and 72. 598 * Any number outside the specified range will be pinned. 599 */ 600 public void setMinimumLogicalFontSize(int size) { 601 assert mCanModifySettings; 602 synchronized (mContentSettingsLock) { 603 size = clipFontSize(size); 604 if (mMinimumLogicalFontSize != size) { 605 mMinimumLogicalFontSize = size; 606 mEventHandler.syncSettingsLocked(); 607 } 608 } 609 } 610 611 /** 612 * Get the minimum logical font size. The default is 8. 613 * @return A non-negative integer between 1 and 72. 614 */ 615 public int getMinimumLogicalFontSize() { 616 synchronized (mContentSettingsLock) { 617 return mMinimumLogicalFontSize; 618 } 619 } 620 621 /** 622 * Set the default font size. 623 * @param size A non-negative integer between 1 and 72. 624 * Any number outside the specified range will be pinned. 625 */ 626 public void setDefaultFontSize(int size) { 627 assert mCanModifySettings; 628 synchronized (mContentSettingsLock) { 629 size = clipFontSize(size); 630 if (mDefaultFontSize != size) { 631 mDefaultFontSize = size; 632 mEventHandler.syncSettingsLocked(); 633 } 634 } 635 } 636 637 /** 638 * Get the default font size. The default is 16. 639 * @return A non-negative integer between 1 and 72. 640 */ 641 public int getDefaultFontSize() { 642 synchronized (mContentSettingsLock) { 643 return mDefaultFontSize; 644 } 645 } 646 647 /** 648 * Set the default fixed font size. 649 * @param size A non-negative integer between 1 and 72. 650 * Any number outside the specified range will be pinned. 651 */ 652 public void setDefaultFixedFontSize(int size) { 653 assert mCanModifySettings; 654 synchronized (mContentSettingsLock) { 655 size = clipFontSize(size); 656 if (mDefaultFixedFontSize != size) { 657 mDefaultFixedFontSize = size; 658 mEventHandler.syncSettingsLocked(); 659 } 660 } 661 } 662 663 /** 664 * Get the default fixed font size. The default is 16. 665 * @return A non-negative integer between 1 and 72. 666 */ 667 public int getDefaultFixedFontSize() { 668 synchronized (mContentSettingsLock) { 669 return mDefaultFixedFontSize; 670 } 671 } 672 673 /** 674 * Tell the WebView to enable JavaScript execution. 675 * 676 * @param flag True if the WebView should execute JavaScript. 677 */ 678 public void setJavaScriptEnabled(boolean flag) { 679 assert mCanModifySettings; 680 synchronized (mContentSettingsLock) { 681 if (mJavaScriptEnabled != flag) { 682 mJavaScriptEnabled = flag; 683 mEventHandler.syncSettingsLocked(); 684 } 685 } 686 } 687 688 /** 689 * Sets whether JavaScript running in the context of a file scheme URL 690 * should be allowed to access content from any origin. This includes 691 * access to content from other file scheme URLs. See 692 * {@link #setAllowFileAccessFromFileURLs}. To enable the most restrictive, 693 * and therefore secure policy, this setting should be disabled. 694 * <p> 695 * The default value is true for API level 696 * {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH_MR1} and below, 697 * and false for API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN} 698 * and above. 699 * 700 * @param flag whether JavaScript running in the context of a file scheme 701 * URL should be allowed to access content from any origin 702 */ 703 public void setAllowUniversalAccessFromFileURLs(boolean flag) { 704 assert mCanModifySettings; 705 synchronized (mContentSettingsLock) { 706 if (mAllowUniversalAccessFromFileURLs != flag) { 707 mAllowUniversalAccessFromFileURLs = flag; 708 mEventHandler.syncSettingsLocked(); 709 } 710 } 711 } 712 713 /** 714 * Sets whether JavaScript running in the context of a file scheme URL 715 * should be allowed to access content from other file scheme URLs. To 716 * enable the most restrictive, and therefore secure policy, this setting 717 * should be disabled. Note that the value of this setting is ignored if 718 * the value of {@link #getAllowUniversalAccessFromFileURLs} is true. 719 * <p> 720 * The default value is true for API level 721 * {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH_MR1} and below, 722 * and false for API level {@link android.os.Build.VERSION_CODES#JELLY_BEAN} 723 * and above. 724 * 725 * @param flag whether JavaScript running in the context of a file scheme 726 * URL should be allowed to access content from other file 727 * scheme URLs 728 */ 729 public void setAllowFileAccessFromFileURLs(boolean flag) { 730 assert mCanModifySettings; 731 synchronized (mContentSettingsLock) { 732 if (mAllowFileAccessFromFileURLs != flag) { 733 mAllowFileAccessFromFileURLs = flag; 734 mEventHandler.syncSettingsLocked(); 735 } 736 } 737 } 738 739 /** 740 * Tell the WebView to load image resources automatically. 741 * Note that setting this flag to false this does not block image loads 742 * from WebCore cache. 743 * @param flag True if the WebView should load images automatically. 744 */ 745 public void setLoadsImagesAutomatically(boolean flag) { 746 assert mCanModifySettings; 747 synchronized (mContentSettingsLock) { 748 if (mLoadsImagesAutomatically != flag) { 749 mLoadsImagesAutomatically = flag; 750 mEventHandler.syncSettingsLocked(); 751 } 752 } 753 } 754 755 /** 756 * Return true if the WebView will load image resources automatically. 757 * The default is true. 758 * @return True if the WebView loads images automatically. 759 */ 760 public boolean getLoadsImagesAutomatically() { 761 synchronized (mContentSettingsLock) { 762 return mLoadsImagesAutomatically; 763 } 764 } 765 766 /** 767 * Sets whether images are enabled for this WebView. Setting this from 768 * false to true will reload the blocked images in place. 769 * Note that unlike {@link #setLoadsImagesAutomatically}, setting this 770 * flag to false this will block image loads from WebCore cache as well. 771 * The default is true. 772 * @param flag whether the WebView should enable images. 773 */ 774 public void setImagesEnabled(boolean flag) { 775 assert mCanModifySettings; 776 synchronized (mContentSettingsLock) { 777 if (mImagesEnabled != flag) { 778 mImagesEnabled = flag; 779 mEventHandler.syncSettingsLocked(); 780 } 781 } 782 } 783 784 /** 785 * Gets whether images are enabled for this WebView. 786 * @return true if the WebView has images eanbled 787 */ 788 public boolean getImagesEnabled() { 789 synchronized (mContentSettingsLock) { 790 return mImagesEnabled; 791 } 792 } 793 794 /** 795 * Return true if JavaScript is enabled. <b>Note: The default is false.</b> 796 * 797 * @return True if JavaScript is enabled. 798 */ 799 public boolean getJavaScriptEnabled() { 800 synchronized (mContentSettingsLock) { 801 return mJavaScriptEnabled; 802 } 803 } 804 805 /** 806 * Gets whether JavaScript running in the context of a file scheme URL can 807 * access content from any origin. This includes access to content from 808 * other file scheme URLs. 809 * 810 * @return whether JavaScript running in the context of a file scheme URL 811 * can access content from any origin 812 * @see #setAllowUniversalAccessFromFileURLs 813 */ 814 public boolean getAllowUniversalAccessFromFileURLs() { 815 synchronized (mContentSettingsLock) { 816 return mAllowUniversalAccessFromFileURLs; 817 } 818 } 819 820 /** 821 * Gets whether JavaScript running in the context of a file scheme URL can 822 * access content from other file scheme URLs. 823 * 824 * @return whether JavaScript running in the context of a file scheme URL 825 * can access content from other file scheme URLs 826 * @see #setAllowFileAccessFromFileURLs 827 */ 828 public boolean getAllowFileAccessFromFileURLs() { 829 synchronized (mContentSettingsLock) { 830 return mAllowFileAccessFromFileURLs; 831 } 832 } 833 834 /** 835 * Tell the WebView to enable plugins. 836 * @param flag True if the WebView should load plugins. 837 * @deprecated This method has been deprecated in favor of 838 * {@link #setPluginState} 839 */ 840 @Deprecated 841 public void setPluginsEnabled(boolean flag) { 842 assert mCanModifySettings; 843 setPluginState(flag ? PluginState.ON : PluginState.OFF); 844 } 845 846 /** 847 * Tell the WebView to enable, disable, or have plugins on demand. On 848 * demand mode means that if a plugin exists that can handle the embedded 849 * content, a placeholder icon will be shown instead of the plugin. When 850 * the placeholder is clicked, the plugin will be enabled. 851 * @param state One of the PluginState values. 852 */ 853 public void setPluginState(PluginState state) { 854 assert mCanModifySettings; 855 synchronized (mContentSettingsLock) { 856 if (mPluginState != state) { 857 mPluginState = state; 858 mEventHandler.syncSettingsLocked(); 859 } 860 } 861 } 862 863 /** 864 * Return true if plugins are enabled. 865 * @return True if plugins are enabled. 866 * @deprecated This method has been replaced by {@link #getPluginState} 867 */ 868 @Deprecated 869 public boolean getPluginsEnabled() { 870 synchronized (mContentSettingsLock) { 871 return mPluginState == PluginState.ON; 872 } 873 } 874 875 /** 876 * Return true if plugins are disabled. 877 * @return True if plugins are disabled. 878 * @hide 879 */ 880 @CalledByNative 881 private boolean getPluginsDisabled() { 882 // This should only be called from SyncToNative, which is called 883 // either from the constructor, or with mContentSettingsLock being held. 884 return mPluginState == PluginState.OFF; 885 } 886 887 /** 888 * Sets if plugins are disabled. 889 * @return True if plugins are disabled. 890 * @hide 891 */ 892 @CalledByNative 893 private void setPluginsDisabled(boolean disabled) { 894 // This should only be called from SyncFromToNative, which is called 895 // either from the constructor, or with mContentSettingsLock being held. 896 mPluginState = disabled ? PluginState.OFF : PluginState.ON; 897 } 898 899 /** 900 * Return the current plugin state. 901 * @return A value corresponding to the enum PluginState. 902 */ 903 public PluginState getPluginState() { 904 synchronized (mContentSettingsLock) { 905 return mPluginState; 906 } 907 } 908 909 910 /** 911 * Tell javascript to open windows automatically. This applies to the 912 * javascript function window.open(). 913 * @param flag True if javascript can open windows automatically. 914 */ 915 public void setJavaScriptCanOpenWindowsAutomatically(boolean flag) { 916 assert mCanModifySettings; 917 synchronized (mContentSettingsLock) { 918 if (mJavaScriptCanOpenWindowsAutomatically != flag) { 919 mJavaScriptCanOpenWindowsAutomatically = flag; 920 mEventHandler.syncSettingsLocked(); 921 } 922 } 923 } 924 925 /** 926 * Return true if javascript can open windows automatically. The default 927 * is false. 928 * @return True if javascript can open windows automatically during 929 * window.open(). 930 */ 931 public boolean getJavaScriptCanOpenWindowsAutomatically() { 932 synchronized (mContentSettingsLock) { 933 return mJavaScriptCanOpenWindowsAutomatically; 934 } 935 } 936 937 /** 938 * Sets the underlying layout algorithm. The default is 939 * {@link LayoutAlgorithm#NARROW_COLUMNS}. 940 * 941 * @param l the layout algorithm to use, as a {@link LayoutAlgorithm} value 942 */ 943 public void setLayoutAlgorithm(LayoutAlgorithm l) { 944 assert mCanModifySettings; 945 synchronized (mContentSettingsLock) { 946 if (mLayoutAlgorithm != l) { 947 mLayoutAlgorithm = l; 948 mEventHandler.syncSettingsLocked(); 949 } 950 } 951 } 952 953 /** 954 * Gets the current layout algorithm. 955 * 956 * @return the layout algorithm in use, as a {@link LayoutAlgorithm} value 957 * @see #setLayoutAlgorithm 958 */ 959 public LayoutAlgorithm getLayoutAlgorithm() { 960 synchronized (mContentSettingsLock) { 961 return mLayoutAlgorithm; 962 } 963 } 964 965 /** 966 * Sets whether Text Auto-sizing layout algorithm is enabled. 967 * 968 * @param enabled whether Text Auto-sizing layout algorithm is enabled 969 * @hide 970 */ 971 @CalledByNative 972 private void setTextAutosizingEnabled(boolean enabled) { 973 // This should only be called from SyncFromNative, which is called 974 // either from the constructor, or with mContentSettingsLock being held. 975 mLayoutAlgorithm = enabled ? 976 LayoutAlgorithm.TEXT_AUTOSIZING : LayoutAlgorithm.NARROW_COLUMNS; 977 } 978 979 /** 980 * Gets whether Text Auto-sizing layout algorithm is enabled. 981 * 982 * @return true if Text Auto-sizing layout algorithm is enabled 983 * @hide 984 */ 985 @CalledByNative 986 private boolean getTextAutosizingEnabled() { 987 return mLayoutAlgorithm == LayoutAlgorithm.TEXT_AUTOSIZING; 988 } 989 990 /** 991 * Tells the WebView whether it supports multiple windows. True means 992 * that {@link WebChromeClient#onCreateWindow(WebView, boolean, 993 * boolean, Message)} is implemented by the host application. 994 */ 995 public void setSupportMultipleWindows(boolean support) { 996 assert mCanModifySettings; 997 synchronized (mContentSettingsLock) { 998 if (mSupportMultipleWindows != support) { 999 mSupportMultipleWindows = support; 1000 mEventHandler.syncSettingsLocked(); 1001 } 1002 } 1003 } 1004 1005 /** 1006 * Gets whether the WebView is supporting multiple windows. 1007 * 1008 * @return true if the WebView is supporting multiple windows. This means 1009 * that {@link WebChromeClient#onCreateWindow(WebView, boolean, 1010 * boolean, Message)} is implemented by the host application. 1011 */ 1012 public boolean supportMultipleWindows() { 1013 synchronized (mContentSettingsLock) { 1014 return mSupportMultipleWindows; 1015 } 1016 } 1017 1018 /** 1019 * Sets whether the WebView should enable support for the "viewport" 1020 * HTML meta tag or should use a wide viewport. 1021 * When the value of the setting is false, the layout width is always set to the 1022 * width of the WebView control in device-independent (CSS) pixels. 1023 * When the value is true and the page contains the viewport meta tag, the value 1024 * of the width specified in the tag is used. If the page does not contain the tag or 1025 * does not provide a width, then a wide viewport will be used. 1026 * 1027 * @param use whether to enable support for the viewport meta tag 1028 */ 1029 public void setUseWideViewPort(boolean use) { 1030 assert mCanModifySettings; 1031 synchronized (mContentSettingsLock) { 1032 if (mUseWideViewport != use) { 1033 mUseWideViewport = use; 1034 mEventHandler.syncSettingsLocked(); 1035 } 1036 } 1037 } 1038 1039 /** 1040 * Gets whether the WebView supports the "viewport" 1041 * HTML meta tag or will use a wide viewport. 1042 * 1043 * @return true if the WebView supports the viewport meta tag 1044 * @see #setUseWideViewPort 1045 */ 1046 public boolean getUseWideViewPort() { 1047 synchronized (mContentSettingsLock) { 1048 return mUseWideViewport; 1049 } 1050 } 1051 1052 /** 1053 * Sets whether the Application Caches API should be enabled. The default 1054 * is false. Note that in order for the Application Caches API to be 1055 * enabled, a non-empty database path must also be supplied to 1056 * {@link #setAppCachePath} (this is done for compatibility with the 1057 * legacy implementation). 1058 * 1059 * @param flag true if the WebView should enable Application Caches 1060 */ 1061 public void setAppCacheEnabled(boolean flag) { 1062 assert mCanModifySettings; 1063 synchronized (mContentSettingsLock) { 1064 if (mAppCacheEnabled != flag) { 1065 mAppCacheEnabled = flag; 1066 mEventHandler.syncSettingsLocked(); 1067 } 1068 } 1069 } 1070 1071 /** 1072 * Sets the path to the Application Caches files. In order for the 1073 * Application Caches API to be enabled, this method must be called with a 1074 * non-empty path. This method should only be called once: repeated calls 1075 * are ignored. 1076 * 1077 * @param path a non empty-string 1078 */ 1079 public void setAppCachePath(String path) { 1080 assert mCanModifySettings; 1081 boolean needToSync = false; 1082 synchronized (sGlobalContentSettingsLock) { 1083 // AppCachePath can only be set once. 1084 if (!sAppCachePathIsSet && path != null && !path.isEmpty()) { 1085 sAppCachePathIsSet = true; 1086 needToSync = true; 1087 } 1088 } 1089 // The obvious problem here is that other WebViews will not be updated, 1090 // until they execute synchronization from Java to the native side. 1091 // But this is the same behaviour as it was in the legacy WebView. 1092 if (needToSync) { 1093 synchronized (mContentSettingsLock) { 1094 mEventHandler.syncSettingsLocked(); 1095 } 1096 } 1097 } 1098 1099 /** 1100 * Gets whether Application Cache is enabled. 1101 * 1102 * @return true if Application Cache is enabled 1103 * @hide 1104 */ 1105 @CalledByNative 1106 private boolean getAppCacheEnabled() { 1107 // This should only be called from SyncToNative, which is called 1108 // either from the constructor, or with mContentSettingsLock being held. 1109 if (!mAppCacheEnabled) { 1110 return false; 1111 } 1112 synchronized (sGlobalContentSettingsLock) { 1113 return sAppCachePathIsSet; 1114 } 1115 } 1116 1117 /** 1118 * Sets whether the DOM storage API is enabled. The default value is false. 1119 * 1120 * @param flag true if the ContentView should use the DOM storage API 1121 */ 1122 public void setDomStorageEnabled(boolean flag) { 1123 assert mCanModifySettings; 1124 synchronized (mContentSettingsLock) { 1125 if (mDomStorageEnabled != flag) { 1126 mDomStorageEnabled = flag; 1127 mEventHandler.syncSettingsLocked(); 1128 } 1129 } 1130 } 1131 1132 /** 1133 * Gets whether the DOM Storage APIs are enabled. 1134 * 1135 * @return true if the DOM Storage APIs are enabled 1136 * @see #setDomStorageEnabled 1137 */ 1138 public boolean getDomStorageEnabled() { 1139 synchronized (mContentSettingsLock) { 1140 return mDomStorageEnabled; 1141 } 1142 } 1143 1144 /** 1145 * Sets whether the WebSQL storage API is enabled. The default value is false. 1146 * 1147 * @param flag true if the ContentView should use the WebSQL storage API 1148 */ 1149 public void setDatabaseEnabled(boolean flag) { 1150 assert mCanModifySettings; 1151 synchronized (mContentSettingsLock) { 1152 if (mDatabaseEnabled != flag) { 1153 mDatabaseEnabled = flag; 1154 mEventHandler.syncSettingsLocked(); 1155 } 1156 } 1157 } 1158 1159 /** 1160 * Gets whether the WebSQL Storage APIs are enabled. 1161 * 1162 * @return true if the WebSQL Storage APIs are enabled 1163 * @see #setDatabaseEnabled 1164 */ 1165 public boolean getDatabaseEnabled() { 1166 synchronized (mContentSettingsLock) { 1167 return mDatabaseEnabled; 1168 } 1169 } 1170 1171 /** 1172 * Set the default text encoding name to use when decoding html pages. 1173 * @param encoding The text encoding name. 1174 */ 1175 public void setDefaultTextEncodingName(String encoding) { 1176 assert mCanModifySettings; 1177 synchronized (mContentSettingsLock) { 1178 if (encoding != null && !mDefaultTextEncoding.equals(encoding)) { 1179 mDefaultTextEncoding = encoding; 1180 mEventHandler.syncSettingsLocked(); 1181 } 1182 } 1183 } 1184 1185 /** 1186 * Get the default text encoding name. The default is "Latin-1". 1187 * @return The default text encoding name as a string. 1188 */ 1189 public String getDefaultTextEncodingName() { 1190 synchronized (mContentSettingsLock) { 1191 return mDefaultTextEncoding; 1192 } 1193 } 1194 1195 /** 1196 * Set whether the user gesture is required for media playback. 1197 * @param require true if the user gesture is required. 1198 */ 1199 public void setMediaPlaybackRequiresUserGesture(boolean require) { 1200 assert mCanModifySettings; 1201 synchronized (mContentSettingsLock) { 1202 if (mMediaPlaybackRequiresUserGesture != require) { 1203 mMediaPlaybackRequiresUserGesture = require; 1204 mEventHandler.syncSettingsLocked(); 1205 } 1206 } 1207 } 1208 1209 /** 1210 * Get whether the user gesture is required for Media Playback. 1211 * @return true if the user gesture is required. 1212 */ 1213 public boolean getMediaPlaybackRequiresUserGesture() { 1214 synchronized (mContentSettingsLock) { 1215 return mMediaPlaybackRequiresUserGesture; 1216 } 1217 } 1218 1219 /** 1220 * Set the default video poster URL. 1221 * @param url The url of default video poster. 1222 */ 1223 public void setDefaultVideoPosterURL(String url) { 1224 assert mCanModifySettings; 1225 synchronized (mContentSettingsLock) { 1226 if (mDefaultVideoPosterURL != null && !mDefaultVideoPosterURL.equals(url) || 1227 mDefaultVideoPosterURL == null && url != null) { 1228 mDefaultVideoPosterURL = url; 1229 mEventHandler.syncSettingsLocked(); 1230 } 1231 } 1232 } 1233 1234 /** 1235 * Get the default video poster URL. 1236 */ 1237 public String getDefaultVideoPosterURL() { 1238 synchronized (mContentSettingsLock) { 1239 return mDefaultVideoPosterURL; 1240 } 1241 } 1242 1243 private int clipFontSize(int size) { 1244 if (size < MINIMUM_FONT_SIZE) { 1245 return MINIMUM_FONT_SIZE; 1246 } else if (size > MAXIMUM_FONT_SIZE) { 1247 return MAXIMUM_FONT_SIZE; 1248 } 1249 return size; 1250 } 1251 1252 /** 1253 * Sets the settings in this object to those from another 1254 * ContentSettings. 1255 * Required by WebView when we swap a in a new ContentViewCore 1256 * to an existing AwContents (i.e. to support displaying popup 1257 * windows in an already created WebView) 1258 */ 1259 public void initFrom(ContentSettings settings) { 1260 setLayoutAlgorithm(settings.getLayoutAlgorithm()); 1261 setLoadWithOverviewMode(settings.getLoadWithOverviewMode()); 1262 setTextZoom(settings.getTextZoom()); 1263 setStandardFontFamily(settings.getStandardFontFamily()); 1264 setFixedFontFamily(settings.getFixedFontFamily()); 1265 setSansSerifFontFamily(settings.getSansSerifFontFamily()); 1266 setSerifFontFamily(settings.getSerifFontFamily()); 1267 setCursiveFontFamily(settings.getCursiveFontFamily()); 1268 setFantasyFontFamily(settings.getFantasyFontFamily()); 1269 setDefaultTextEncodingName(settings.getDefaultTextEncodingName()); 1270 setUserAgentString(settings.getUserAgentString()); 1271 setMinimumFontSize(settings.getMinimumFontSize()); 1272 setMinimumLogicalFontSize(settings.getMinimumLogicalFontSize()); 1273 setDefaultFontSize(settings.getDefaultFontSize()); 1274 setDefaultFixedFontSize(settings.getDefaultFixedFontSize()); 1275 setLoadsImagesAutomatically(settings.getLoadsImagesAutomatically()); 1276 setImagesEnabled(settings.getImagesEnabled()); 1277 setJavaScriptEnabled(settings.getJavaScriptEnabled()); 1278 setAllowUniversalAccessFromFileURLs(settings.getAllowUniversalAccessFromFileURLs()); 1279 setAllowFileAccessFromFileURLs(settings.getAllowFileAccessFromFileURLs()); 1280 setJavaScriptCanOpenWindowsAutomatically( 1281 settings.getJavaScriptCanOpenWindowsAutomatically()); 1282 setSupportMultipleWindows(settings.supportMultipleWindows()); 1283 setPluginState(settings.getPluginState()); 1284 setAppCacheEnabled(settings.mAppCacheEnabled); 1285 setDomStorageEnabled(settings.getDomStorageEnabled()); 1286 setDatabaseEnabled(settings.getDatabaseEnabled()); 1287 setSupportZoom(settings.supportZoom()); 1288 setBuiltInZoomControls(settings.getBuiltInZoomControls()); 1289 setDisplayZoomControls(settings.getDisplayZoomControls()); 1290 setMediaPlaybackRequiresUserGesture(settings.getMediaPlaybackRequiresUserGesture()); 1291 setDefaultVideoPosterURL(settings.getDefaultVideoPosterURL()); 1292 } 1293 1294 /** 1295 * Synchronize java side and native side settings. When ContentView 1296 * is running in PERSONALITY_VIEW mode, this needs to be done after 1297 * any java side setting is changed to sync them to native. In 1298 * PERSONALITY_CHROME mode, this needs to be called whenever native 1299 * settings are changed to sync them to java. 1300 */ 1301 void syncSettings() { 1302 synchronized (mContentSettingsLock) { 1303 mEventHandler.syncSettingsLocked(); 1304 } 1305 } 1306 1307 void syncToNativeOnUiThread() { 1308 if (mNativeContentSettings != 0) nativeSyncToNative(mNativeContentSettings); 1309 } 1310 1311 void syncFromNativeOnUiThread() { 1312 if (mNativeContentSettings != 0) nativeSyncFromNative(mNativeContentSettings); 1313 } 1314 1315 // Initialize the ContentSettings native side. 1316 private native int nativeInit(int contentViewPtr, boolean isMasterMode); 1317 1318 private static native String nativeGetDefaultUserAgent(); 1319 1320 // Synchronize Java settings from native settings. 1321 private native void nativeSyncFromNative(int nativeContentSettings); 1322 1323 // Synchronize native settings from Java settings. 1324 private native void nativeSyncToNative(int nativeContentSettings); 1325} 1326