WebSettings.java revision a172e7d0d96e4a4db5e2b408e8ee3e96948df9a4
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.content.SharedPreferences; 21import android.content.pm.PackageManager; 22import android.content.res.Configuration; 23import android.os.Build; 24import android.os.Handler; 25import android.os.Message; 26import android.util.EventLog; 27import java.lang.SecurityException; 28import java.util.Locale; 29 30/** 31 * Manages settings state for a WebView. When a WebView is first created, it 32 * obtains a set of default settings. These default settings will be returned 33 * from any getter call. A WebSettings object obtained from 34 * WebView.getSettings() is tied to the life of the WebView. If a WebView has 35 * been destroyed, any method call on WebSettings will throw an 36 * IllegalStateException. 37 */ 38public class WebSettings { 39 /** 40 * Enum for controlling the layout of html. 41 * NORMAL means no rendering changes. 42 * SINGLE_COLUMN moves all content into one column that is the width of the 43 * view. 44 * NARROW_COLUMNS makes all columns no wider than the screen if possible. 45 */ 46 // XXX: These must match LayoutAlgorithm in Settings.h in WebCore. 47 public enum LayoutAlgorithm { 48 NORMAL, 49 SINGLE_COLUMN, 50 NARROW_COLUMNS 51 } 52 53 /** 54 * Enum for specifying the text size. 55 * SMALLEST is 50% 56 * SMALLER is 75% 57 * NORMAL is 100% 58 * LARGER is 150% 59 * LARGEST is 200% 60 */ 61 public enum TextSize { 62 SMALLEST(50), 63 SMALLER(75), 64 NORMAL(100), 65 LARGER(150), 66 LARGEST(200); 67 TextSize(int size) { 68 value = size; 69 } 70 int value; 71 } 72 73 /** 74 * Enum for specifying the WebView's desired density. 75 * FAR makes 100% looking like in 240dpi 76 * MEDIUM makes 100% looking like in 160dpi 77 * CLOSE makes 100% looking like in 120dpi 78 */ 79 public enum ZoomDensity { 80 FAR(150), // 240dpi 81 MEDIUM(100), // 160dpi 82 CLOSE(75); // 120dpi 83 ZoomDensity(int size) { 84 value = size; 85 } 86 int value; 87 } 88 89 /** 90 * Default cache usage pattern Use with {@link #setCacheMode}. 91 */ 92 public static final int LOAD_DEFAULT = -1; 93 94 /** 95 * Normal cache usage pattern Use with {@link #setCacheMode}. 96 */ 97 public static final int LOAD_NORMAL = 0; 98 99 /** 100 * Use cache if content is there, even if expired (eg, history nav) 101 * If it is not in the cache, load from network. 102 * Use with {@link #setCacheMode}. 103 */ 104 public static final int LOAD_CACHE_ELSE_NETWORK = 1; 105 106 /** 107 * Don't use the cache, load from network 108 * Use with {@link #setCacheMode}. 109 */ 110 public static final int LOAD_NO_CACHE = 2; 111 112 /** 113 * Don't use the network, load from cache only. 114 * Use with {@link #setCacheMode}. 115 */ 116 public static final int LOAD_CACHE_ONLY = 3; 117 118 public enum RenderPriority { 119 NORMAL, 120 HIGH, 121 LOW 122 } 123 124 /** 125 * The plugin state effects how plugins are treated on a page. ON means 126 * that any object will be loaded even if a plugin does not exist to handle 127 * the content. ON_DEMAND means that if there is a plugin installed that 128 * can handle the content, a placeholder is shown until the user clicks on 129 * the placeholder. Once clicked, the plugin will be enabled on the page. 130 * OFF means that all plugins will be turned off and any fallback content 131 * will be used. 132 */ 133 public enum PluginState { 134 ON, 135 ON_DEMAND, 136 OFF 137 } 138 139 // WebView associated with this WebSettings. 140 private WebView mWebView; 141 // BrowserFrame used to access the native frame pointer. 142 private BrowserFrame mBrowserFrame; 143 // Flag to prevent multiple SYNC messages at one time. 144 private boolean mSyncPending = false; 145 // Custom handler that queues messages until the WebCore thread is active. 146 private final EventHandler mEventHandler; 147 148 // Private settings so we don't have to go into native code to 149 // retrieve the values. After setXXX, postSync() needs to be called. 150 // 151 // The default values need to match those in WebSettings.cpp 152 // If the defaults change, please also update the JavaDocs so developers 153 // know what they are. 154 private LayoutAlgorithm mLayoutAlgorithm = LayoutAlgorithm.NARROW_COLUMNS; 155 private Context mContext; 156 private TextSize mTextSize = TextSize.NORMAL; 157 private String mStandardFontFamily = "sans-serif"; 158 private String mFixedFontFamily = "monospace"; 159 private String mSansSerifFontFamily = "sans-serif"; 160 private String mSerifFontFamily = "serif"; 161 private String mCursiveFontFamily = "cursive"; 162 private String mFantasyFontFamily = "fantasy"; 163 private String mDefaultTextEncoding; 164 private String mUserAgent; 165 private boolean mUseDefaultUserAgent; 166 private String mAcceptLanguage; 167 private int mMinimumFontSize = 8; 168 private int mMinimumLogicalFontSize = 8; 169 private int mDefaultFontSize = 16; 170 private int mDefaultFixedFontSize = 13; 171 private int mPageCacheCapacity = 0; 172 private boolean mLoadsImagesAutomatically = true; 173 private boolean mBlockNetworkImage = false; 174 private boolean mBlockNetworkLoads; 175 private boolean mJavaScriptEnabled = false; 176 private PluginState mPluginState = PluginState.OFF; 177 private boolean mJavaScriptCanOpenWindowsAutomatically = false; 178 private boolean mUseDoubleTree = false; 179 private boolean mUseWideViewport = false; 180 private boolean mSupportMultipleWindows = false; 181 private boolean mShrinksStandaloneImagesToFit = false; 182 private long mMaximumDecodedImageSize = 0; // 0 means default 183 // HTML5 API flags 184 private boolean mAppCacheEnabled = false; 185 private boolean mDatabaseEnabled = false; 186 private boolean mDomStorageEnabled = false; 187 private boolean mWorkersEnabled = false; // only affects V8. 188 private boolean mGeolocationEnabled = true; 189 private boolean mXSSAuditorEnabled = false; 190 // HTML5 configuration parameters 191 private long mAppCacheMaxSize = Long.MAX_VALUE; 192 private String mAppCachePath = ""; 193 private String mDatabasePath = ""; 194 // The WebCore DatabaseTracker only allows the database path to be set 195 // once. Keep track of when the path has been set. 196 private boolean mDatabasePathHasBeenSet = false; 197 private String mGeolocationDatabasePath = ""; 198 // Don't need to synchronize the get/set methods as they 199 // are basic types, also none of these values are used in 200 // native WebCore code. 201 private ZoomDensity mDefaultZoom = ZoomDensity.MEDIUM; 202 private RenderPriority mRenderPriority = RenderPriority.NORMAL; 203 private int mOverrideCacheMode = LOAD_DEFAULT; 204 private boolean mSaveFormData = true; 205 private boolean mSavePassword = true; 206 private boolean mLightTouchEnabled = false; 207 private boolean mNeedInitialFocus = true; 208 private boolean mNavDump = false; 209 private boolean mSupportZoom = true; 210 private boolean mBuiltInZoomControls = false; 211 private boolean mAllowFileAccess = true; 212 private boolean mLoadWithOverviewMode = false; 213 private boolean mEnableSmoothTransition = false; 214 215 // private WebSettings, not accessible by the host activity 216 static private int mDoubleTapToastCount = 3; 217 218 private static final String PREF_FILE = "WebViewSettings"; 219 private static final String DOUBLE_TAP_TOAST_COUNT = "double_tap_toast_count"; 220 221 // Class to handle messages before WebCore is ready. 222 private class EventHandler { 223 // Message id for syncing 224 static final int SYNC = 0; 225 // Message id for setting priority 226 static final int PRIORITY = 1; 227 // Message id for writing double-tap toast count 228 static final int SET_DOUBLE_TAP_TOAST_COUNT = 2; 229 // Actual WebCore thread handler 230 private Handler mHandler; 231 232 private synchronized void createHandler() { 233 // as mRenderPriority can be set before thread is running, sync up 234 setRenderPriority(); 235 236 // create a new handler 237 mHandler = new Handler() { 238 @Override 239 public void handleMessage(Message msg) { 240 switch (msg.what) { 241 case SYNC: 242 synchronized (WebSettings.this) { 243 if (mBrowserFrame.mNativeFrame != 0) { 244 nativeSync(mBrowserFrame.mNativeFrame); 245 } 246 mSyncPending = false; 247 } 248 break; 249 250 case PRIORITY: { 251 setRenderPriority(); 252 break; 253 } 254 255 case SET_DOUBLE_TAP_TOAST_COUNT: { 256 SharedPreferences.Editor editor = mContext 257 .getSharedPreferences(PREF_FILE, 258 Context.MODE_PRIVATE).edit(); 259 editor.putInt(DOUBLE_TAP_TOAST_COUNT, 260 mDoubleTapToastCount); 261 editor.commit(); 262 break; 263 } 264 } 265 } 266 }; 267 } 268 269 private void setRenderPriority() { 270 synchronized (WebSettings.this) { 271 if (mRenderPriority == RenderPriority.NORMAL) { 272 android.os.Process.setThreadPriority( 273 android.os.Process.THREAD_PRIORITY_DEFAULT); 274 } else if (mRenderPriority == RenderPriority.HIGH) { 275 android.os.Process.setThreadPriority( 276 android.os.Process.THREAD_PRIORITY_FOREGROUND + 277 android.os.Process.THREAD_PRIORITY_LESS_FAVORABLE); 278 } else if (mRenderPriority == RenderPriority.LOW) { 279 android.os.Process.setThreadPriority( 280 android.os.Process.THREAD_PRIORITY_BACKGROUND); 281 } 282 } 283 } 284 285 /** 286 * Send a message to the private queue or handler. 287 */ 288 private synchronized boolean sendMessage(Message msg) { 289 if (mHandler != null) { 290 mHandler.sendMessage(msg); 291 return true; 292 } else { 293 return false; 294 } 295 } 296 } 297 298 // User agent strings. 299 private static final String DESKTOP_USERAGENT = 300 "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_5_7; en-us)" 301 + " AppleWebKit/530.17 (KHTML, like Gecko) Version/4.0" 302 + " Safari/530.17"; 303 private static final String IPHONE_USERAGENT = 304 "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us)" 305 + " AppleWebKit/528.18 (KHTML, like Gecko) Version/4.0" 306 + " Mobile/7A341 Safari/528.16"; 307 private static Locale sLocale; 308 private static Object sLockForLocaleSettings; 309 310 /** 311 * Package constructor to prevent clients from creating a new settings 312 * instance. 313 */ 314 WebSettings(Context context, WebView webview) { 315 mEventHandler = new EventHandler(); 316 mContext = context; 317 mWebView = webview; 318 mDefaultTextEncoding = context.getString(com.android.internal. 319 R.string.default_text_encoding); 320 321 if (sLockForLocaleSettings == null) { 322 sLockForLocaleSettings = new Object(); 323 sLocale = Locale.getDefault(); 324 } 325 mAcceptLanguage = getCurrentAcceptLanguage(); 326 mUserAgent = getCurrentUserAgent(); 327 mUseDefaultUserAgent = true; 328 329 mBlockNetworkLoads = mContext.checkPermission( 330 "android.permission.INTERNET", android.os.Process.myPid(), 331 android.os.Process.myUid()) != PackageManager.PERMISSION_GRANTED; 332 } 333 334 private static final String ACCEPT_LANG_FOR_US_LOCALE = "en-US"; 335 336 /** 337 * Looks at sLocale and returns current AcceptLanguage String. 338 * @return Current AcceptLanguage String. 339 */ 340 private String getCurrentAcceptLanguage() { 341 Locale locale; 342 synchronized(sLockForLocaleSettings) { 343 locale = sLocale; 344 } 345 StringBuilder buffer = new StringBuilder(); 346 addLocaleToHttpAcceptLanguage(buffer, locale); 347 348 if (!Locale.US.equals(locale)) { 349 if (buffer.length() > 0) { 350 buffer.append(", "); 351 } 352 buffer.append(ACCEPT_LANG_FOR_US_LOCALE); 353 } 354 355 return buffer.toString(); 356 } 357 358 /** 359 * Convert obsolete language codes, including Hebrew/Indonesian/Yiddish, 360 * to new standard. 361 */ 362 private static String convertObsoleteLanguageCodeToNew(String langCode) { 363 if (langCode == null) { 364 return null; 365 } 366 if ("iw".equals(langCode)) { 367 // Hebrew 368 return "he"; 369 } else if ("in".equals(langCode)) { 370 // Indonesian 371 return "id"; 372 } else if ("ji".equals(langCode)) { 373 // Yiddish 374 return "yi"; 375 } 376 return langCode; 377 } 378 379 private static void addLocaleToHttpAcceptLanguage(StringBuilder builder, 380 Locale locale) { 381 String language = convertObsoleteLanguageCodeToNew(locale.getLanguage()); 382 if (language != null) { 383 builder.append(language); 384 String country = locale.getCountry(); 385 if (country != null) { 386 builder.append("-"); 387 builder.append(country); 388 } 389 } 390 } 391 392 /** 393 * Looks at sLocale and mContext and returns current UserAgent String. 394 * @return Current UserAgent String. 395 */ 396 private synchronized String getCurrentUserAgent() { 397 Locale locale; 398 synchronized(sLockForLocaleSettings) { 399 locale = sLocale; 400 } 401 StringBuffer buffer = new StringBuffer(); 402 // Add version 403 final String version = Build.VERSION.RELEASE; 404 if (version.length() > 0) { 405 buffer.append(version); 406 } else { 407 // default to "1.0" 408 buffer.append("1.0"); 409 } 410 buffer.append("; "); 411 final String language = locale.getLanguage(); 412 if (language != null) { 413 buffer.append(convertObsoleteLanguageCodeToNew(language)); 414 final String country = locale.getCountry(); 415 if (country != null) { 416 buffer.append("-"); 417 buffer.append(country.toLowerCase()); 418 } 419 } else { 420 // default to "en" 421 buffer.append("en"); 422 } 423 // add the model for the release build 424 if ("REL".equals(Build.VERSION.CODENAME)) { 425 final String model = Build.MODEL; 426 if (model.length() > 0) { 427 buffer.append("; "); 428 buffer.append(model); 429 } 430 } 431 final String id = Build.ID; 432 if (id.length() > 0) { 433 buffer.append(" Build/"); 434 buffer.append(id); 435 } 436 String mobile = ((mContext.getResources().getConfiguration().screenLayout 437 & Configuration.SCREENLAYOUT_SIZE_MASK) 438 == Configuration.SCREENLAYOUT_SIZE_XLARGE) ? "" : "Mobile "; 439 final String base = mContext.getResources().getText( 440 com.android.internal.R.string.web_user_agent).toString(); 441 return String.format(base, buffer, mobile); 442 } 443 444 /** 445 * Enables dumping the pages navigation cache to a text file. 446 */ 447 public void setNavDump(boolean enabled) { 448 mNavDump = enabled; 449 } 450 451 /** 452 * Returns true if dumping the navigation cache is enabled. 453 */ 454 public boolean getNavDump() { 455 return mNavDump; 456 } 457 458 /** 459 * If WebView only supports touch, a different navigation model will be 460 * applied. Otherwise, the navigation to support both touch and keyboard 461 * will be used. 462 * @hide 463 public void setSupportTouchOnly(boolean touchOnly) { 464 mSupportTounchOnly = touchOnly; 465 } 466 */ 467 468 boolean supportTouchOnly() { 469 // for debug only, use mLightTouchEnabled for mSupportTounchOnly 470 return mLightTouchEnabled; 471 } 472 473 /** 474 * Set whether the WebView supports zoom 475 */ 476 public void setSupportZoom(boolean support) { 477 mSupportZoom = support; 478 mWebView.updateMultiTouchSupport(mContext); 479 } 480 481 /** 482 * Returns whether the WebView supports zoom 483 */ 484 public boolean supportZoom() { 485 return mSupportZoom; 486 } 487 488 /** 489 * Sets whether the zoom mechanism built into WebView is used. 490 */ 491 public void setBuiltInZoomControls(boolean enabled) { 492 mBuiltInZoomControls = enabled; 493 mWebView.updateMultiTouchSupport(mContext); 494 } 495 496 /** 497 * Returns true if the zoom mechanism built into WebView is being used. 498 */ 499 public boolean getBuiltInZoomControls() { 500 return mBuiltInZoomControls; 501 } 502 503 /** 504 * Enable or disable file access within WebView. File access is enabled by 505 * default. 506 */ 507 public void setAllowFileAccess(boolean allow) { 508 mAllowFileAccess = allow; 509 } 510 511 /** 512 * Returns true if this WebView supports file access. 513 */ 514 public boolean getAllowFileAccess() { 515 return mAllowFileAccess; 516 } 517 518 /** 519 * Set whether the WebView loads a page with overview mode. 520 */ 521 public void setLoadWithOverviewMode(boolean overview) { 522 mLoadWithOverviewMode = overview; 523 } 524 525 /** 526 * Returns true if this WebView loads page with overview mode 527 */ 528 public boolean getLoadWithOverviewMode() { 529 return mLoadWithOverviewMode; 530 } 531 532 /** 533 * Set whether the WebView will enable smooth transition while panning or 534 * zooming. If it is true, WebView will choose a solution to maximize the 535 * performance. e.g. the WebView's content may not be updated during the 536 * transition. If it is false, WebView will keep its fidelity. The default 537 * value is false. 538 */ 539 public void setEnableSmoothTransition(boolean enable) { 540 mEnableSmoothTransition = enable; 541 } 542 543 /** 544 * Returns true if the WebView enables smooth transition while panning or 545 * zooming. 546 */ 547 public boolean enableSmoothTransition() { 548 return mEnableSmoothTransition; 549 } 550 551 /** 552 * Store whether the WebView is saving form data. 553 */ 554 public void setSaveFormData(boolean save) { 555 mSaveFormData = save; 556 } 557 558 /** 559 * Return whether the WebView is saving form data. 560 */ 561 public boolean getSaveFormData() { 562 return mSaveFormData; 563 } 564 565 /** 566 * Store whether the WebView is saving password. 567 */ 568 public void setSavePassword(boolean save) { 569 mSavePassword = save; 570 } 571 572 /** 573 * Return whether the WebView is saving password. 574 */ 575 public boolean getSavePassword() { 576 return mSavePassword; 577 } 578 579 /** 580 * Set the text size of the page. 581 * @param t A TextSize value for increasing or decreasing the text. 582 * @see WebSettings.TextSize 583 */ 584 public synchronized void setTextSize(TextSize t) { 585 if (WebView.mLogEvent && mTextSize != t ) { 586 EventLog.writeEvent(EventLogTags.BROWSER_TEXT_SIZE_CHANGE, 587 mTextSize.value, t.value); 588 } 589 mTextSize = t; 590 postSync(); 591 } 592 593 /** 594 * Get the text size of the page. 595 * @return A TextSize enum value describing the text size. 596 * @see WebSettings.TextSize 597 */ 598 public synchronized TextSize getTextSize() { 599 return mTextSize; 600 } 601 602 /** 603 * Set the default zoom density of the page. This should be called from UI 604 * thread. 605 * @param zoom A ZoomDensity value 606 * @see WebSettings.ZoomDensity 607 */ 608 public void setDefaultZoom(ZoomDensity zoom) { 609 if (mDefaultZoom != zoom) { 610 mDefaultZoom = zoom; 611 mWebView.updateDefaultZoomDensity(zoom.value); 612 } 613 } 614 615 /** 616 * Get the default zoom density of the page. This should be called from UI 617 * thread. 618 * @return A ZoomDensity value 619 * @see WebSettings.ZoomDensity 620 */ 621 public ZoomDensity getDefaultZoom() { 622 return mDefaultZoom; 623 } 624 625 /** 626 * Enables using light touches to make a selection and activate mouseovers. 627 */ 628 public void setLightTouchEnabled(boolean enabled) { 629 mLightTouchEnabled = enabled; 630 } 631 632 /** 633 * Returns true if light touches are enabled. 634 */ 635 public boolean getLightTouchEnabled() { 636 return mLightTouchEnabled; 637 } 638 639 /** 640 * @deprecated This setting controlled a rendering optimization 641 * that is no longer present. Setting it now has no effect. 642 */ 643 @Deprecated 644 public synchronized void setUseDoubleTree(boolean use) { 645 return; 646 } 647 648 /** 649 * @deprecated This setting controlled a rendering optimization 650 * that is no longer present. Setting it now has no effect. 651 */ 652 @Deprecated 653 public synchronized boolean getUseDoubleTree() { 654 return false; 655 } 656 657 /** 658 * Tell the WebView about user-agent string. 659 * @param ua 0 if the WebView should use an Android user-agent string, 660 * 1 if the WebView should use a desktop user-agent string. 661 * 662 * @deprecated Please use setUserAgentString instead. 663 */ 664 @Deprecated 665 public synchronized void setUserAgent(int ua) { 666 String uaString = null; 667 if (ua == 1) { 668 if (DESKTOP_USERAGENT.equals(mUserAgent)) { 669 return; // do nothing 670 } else { 671 uaString = DESKTOP_USERAGENT; 672 } 673 } else if (ua == 2) { 674 if (IPHONE_USERAGENT.equals(mUserAgent)) { 675 return; // do nothing 676 } else { 677 uaString = IPHONE_USERAGENT; 678 } 679 } else if (ua != 0) { 680 return; // do nothing 681 } 682 setUserAgentString(uaString); 683 } 684 685 /** 686 * Return user-agent as int 687 * @return int 0 if the WebView is using an Android user-agent string. 688 * 1 if the WebView is using a desktop user-agent string. 689 * -1 if the WebView is using user defined user-agent string. 690 * 691 * @deprecated Please use getUserAgentString instead. 692 */ 693 @Deprecated 694 public synchronized int getUserAgent() { 695 if (DESKTOP_USERAGENT.equals(mUserAgent)) { 696 return 1; 697 } else if (IPHONE_USERAGENT.equals(mUserAgent)) { 698 return 2; 699 } else if (mUseDefaultUserAgent) { 700 return 0; 701 } 702 return -1; 703 } 704 705 /** 706 * Tell the WebView to use the wide viewport 707 */ 708 public synchronized void setUseWideViewPort(boolean use) { 709 if (mUseWideViewport != use) { 710 mUseWideViewport = use; 711 postSync(); 712 } 713 } 714 715 /** 716 * @return True if the WebView is using a wide viewport 717 */ 718 public synchronized boolean getUseWideViewPort() { 719 return mUseWideViewport; 720 } 721 722 /** 723 * Tell the WebView whether it supports multiple windows. TRUE means 724 * that {@link WebChromeClient#onCreateWindow(WebView, boolean, 725 * boolean, Message)} is implemented by the host application. 726 */ 727 public synchronized void setSupportMultipleWindows(boolean support) { 728 if (mSupportMultipleWindows != support) { 729 mSupportMultipleWindows = support; 730 postSync(); 731 } 732 } 733 734 /** 735 * @return True if the WebView is supporting multiple windows. This means 736 * that {@link WebChromeClient#onCreateWindow(WebView, boolean, 737 * boolean, Message)} is implemented by the host application. 738 */ 739 public synchronized boolean supportMultipleWindows() { 740 return mSupportMultipleWindows; 741 } 742 743 /** 744 * Set the underlying layout algorithm. This will cause a relayout of the 745 * WebView. 746 * @param l A LayoutAlgorithm enum specifying the algorithm to use. 747 * @see WebSettings.LayoutAlgorithm 748 */ 749 public synchronized void setLayoutAlgorithm(LayoutAlgorithm l) { 750 // XXX: This will only be affective if libwebcore was built with 751 // ANDROID_LAYOUT defined. 752 if (mLayoutAlgorithm != l) { 753 mLayoutAlgorithm = l; 754 postSync(); 755 } 756 } 757 758 /** 759 * Return the current layout algorithm. The default is NARROW_COLUMNS. 760 * @return LayoutAlgorithm enum value describing the layout algorithm 761 * being used. 762 * @see WebSettings.LayoutAlgorithm 763 */ 764 public synchronized LayoutAlgorithm getLayoutAlgorithm() { 765 return mLayoutAlgorithm; 766 } 767 768 /** 769 * Set the standard font family name. 770 * @param font A font family name. 771 */ 772 public synchronized void setStandardFontFamily(String font) { 773 if (font != null && !font.equals(mStandardFontFamily)) { 774 mStandardFontFamily = font; 775 postSync(); 776 } 777 } 778 779 /** 780 * Get the standard font family name. The default is "sans-serif". 781 * @return The standard font family name as a string. 782 */ 783 public synchronized String getStandardFontFamily() { 784 return mStandardFontFamily; 785 } 786 787 /** 788 * Set the fixed font family name. 789 * @param font A font family name. 790 */ 791 public synchronized void setFixedFontFamily(String font) { 792 if (font != null && !font.equals(mFixedFontFamily)) { 793 mFixedFontFamily = font; 794 postSync(); 795 } 796 } 797 798 /** 799 * Get the fixed font family name. The default is "monospace". 800 * @return The fixed font family name as a string. 801 */ 802 public synchronized String getFixedFontFamily() { 803 return mFixedFontFamily; 804 } 805 806 /** 807 * Set the sans-serif font family name. 808 * @param font A font family name. 809 */ 810 public synchronized void setSansSerifFontFamily(String font) { 811 if (font != null && !font.equals(mSansSerifFontFamily)) { 812 mSansSerifFontFamily = font; 813 postSync(); 814 } 815 } 816 817 /** 818 * Get the sans-serif font family name. 819 * @return The sans-serif font family name as a string. 820 */ 821 public synchronized String getSansSerifFontFamily() { 822 return mSansSerifFontFamily; 823 } 824 825 /** 826 * Set the serif font family name. The default is "sans-serif". 827 * @param font A font family name. 828 */ 829 public synchronized void setSerifFontFamily(String font) { 830 if (font != null && !font.equals(mSerifFontFamily)) { 831 mSerifFontFamily = font; 832 postSync(); 833 } 834 } 835 836 /** 837 * Get the serif font family name. The default is "serif". 838 * @return The serif font family name as a string. 839 */ 840 public synchronized String getSerifFontFamily() { 841 return mSerifFontFamily; 842 } 843 844 /** 845 * Set the cursive font family name. 846 * @param font A font family name. 847 */ 848 public synchronized void setCursiveFontFamily(String font) { 849 if (font != null && !font.equals(mCursiveFontFamily)) { 850 mCursiveFontFamily = font; 851 postSync(); 852 } 853 } 854 855 /** 856 * Get the cursive font family name. The default is "cursive". 857 * @return The cursive font family name as a string. 858 */ 859 public synchronized String getCursiveFontFamily() { 860 return mCursiveFontFamily; 861 } 862 863 /** 864 * Set the fantasy font family name. 865 * @param font A font family name. 866 */ 867 public synchronized void setFantasyFontFamily(String font) { 868 if (font != null && !font.equals(mFantasyFontFamily)) { 869 mFantasyFontFamily = font; 870 postSync(); 871 } 872 } 873 874 /** 875 * Get the fantasy font family name. The default is "fantasy". 876 * @return The fantasy font family name as a string. 877 */ 878 public synchronized String getFantasyFontFamily() { 879 return mFantasyFontFamily; 880 } 881 882 /** 883 * Set the minimum font size. 884 * @param size A non-negative integer between 1 and 72. 885 * Any number outside the specified range will be pinned. 886 */ 887 public synchronized void setMinimumFontSize(int size) { 888 size = pin(size); 889 if (mMinimumFontSize != size) { 890 mMinimumFontSize = size; 891 postSync(); 892 } 893 } 894 895 /** 896 * Get the minimum font size. The default is 8. 897 * @return A non-negative integer between 1 and 72. 898 */ 899 public synchronized int getMinimumFontSize() { 900 return mMinimumFontSize; 901 } 902 903 /** 904 * Set the minimum logical font size. 905 * @param size A non-negative integer between 1 and 72. 906 * Any number outside the specified range will be pinned. 907 */ 908 public synchronized void setMinimumLogicalFontSize(int size) { 909 size = pin(size); 910 if (mMinimumLogicalFontSize != size) { 911 mMinimumLogicalFontSize = size; 912 postSync(); 913 } 914 } 915 916 /** 917 * Get the minimum logical font size. The default is 8. 918 * @return A non-negative integer between 1 and 72. 919 */ 920 public synchronized int getMinimumLogicalFontSize() { 921 return mMinimumLogicalFontSize; 922 } 923 924 /** 925 * Set the default font size. 926 * @param size A non-negative integer between 1 and 72. 927 * Any number outside the specified range will be pinned. 928 */ 929 public synchronized void setDefaultFontSize(int size) { 930 size = pin(size); 931 if (mDefaultFontSize != size) { 932 mDefaultFontSize = size; 933 postSync(); 934 } 935 } 936 937 /** 938 * Get the default font size. The default is 16. 939 * @return A non-negative integer between 1 and 72. 940 */ 941 public synchronized int getDefaultFontSize() { 942 return mDefaultFontSize; 943 } 944 945 /** 946 * Set the default fixed font size. 947 * @param size A non-negative integer between 1 and 72. 948 * Any number outside the specified range will be pinned. 949 */ 950 public synchronized void setDefaultFixedFontSize(int size) { 951 size = pin(size); 952 if (mDefaultFixedFontSize != size) { 953 mDefaultFixedFontSize = size; 954 postSync(); 955 } 956 } 957 958 /** 959 * Get the default fixed font size. The default is 16. 960 * @return A non-negative integer between 1 and 72. 961 */ 962 public synchronized int getDefaultFixedFontSize() { 963 return mDefaultFixedFontSize; 964 } 965 966 /** 967 * Set the number of pages cached by the WebKit for the history navigation. 968 * @param size A non-negative integer between 0 (no cache) and 20 (max). 969 * @hide 970 */ 971 public synchronized void setPageCacheCapacity(int size) { 972 if (size < 0) size = 0; 973 if (size > 20) size = 20; 974 if (mPageCacheCapacity != size) { 975 mPageCacheCapacity = size; 976 postSync(); 977 } 978 } 979 980 /** 981 * Tell the WebView to load image resources automatically. 982 * @param flag True if the WebView should load images automatically. 983 */ 984 public synchronized void setLoadsImagesAutomatically(boolean flag) { 985 if (mLoadsImagesAutomatically != flag) { 986 mLoadsImagesAutomatically = flag; 987 postSync(); 988 } 989 } 990 991 /** 992 * Return true if the WebView will load image resources automatically. 993 * The default is true. 994 * @return True if the WebView loads images automatically. 995 */ 996 public synchronized boolean getLoadsImagesAutomatically() { 997 return mLoadsImagesAutomatically; 998 } 999 1000 /** 1001 * Tell the WebView to block network images. This is only checked when 1002 * {@link #getLoadsImagesAutomatically} is true. If you set the value to 1003 * false, images will automatically be loaded. Use this api to reduce 1004 * bandwidth only. Use {@link #setBlockNetworkLoads} if possible. 1005 * @param flag True if the WebView should block network images. 1006 * @see #setBlockNetworkLoads 1007 */ 1008 public synchronized void setBlockNetworkImage(boolean flag) { 1009 if (mBlockNetworkImage != flag) { 1010 mBlockNetworkImage = flag; 1011 postSync(); 1012 } 1013 } 1014 1015 /** 1016 * Return true if the WebView will block network images. The default is 1017 * false. 1018 * @return True if the WebView blocks network images. 1019 */ 1020 public synchronized boolean getBlockNetworkImage() { 1021 return mBlockNetworkImage; 1022 } 1023 1024 /** 1025 * Tell the WebView to block all network load requests. If you set the 1026 * value to false, you must call {@link android.webkit.WebView#reload} to 1027 * fetch remote resources. This flag supercedes the value passed to 1028 * {@link #setBlockNetworkImage}. 1029 * @param flag True if the WebView should block all network loads. 1030 * @see android.webkit.WebView#reload 1031 */ 1032 public synchronized void setBlockNetworkLoads(boolean flag) { 1033 if (mBlockNetworkLoads != flag) { 1034 mBlockNetworkLoads = flag; 1035 verifyNetworkAccess(); 1036 } 1037 } 1038 1039 /** 1040 * Return true if the WebView will block all network loads. The default is 1041 * false. 1042 * @return True if the WebView blocks all network loads. 1043 */ 1044 public synchronized boolean getBlockNetworkLoads() { 1045 return mBlockNetworkLoads; 1046 } 1047 1048 1049 private void verifyNetworkAccess() { 1050 if (!mBlockNetworkLoads) { 1051 if (mContext.checkPermission("android.permission.INTERNET", 1052 android.os.Process.myPid(), android.os.Process.myUid()) != 1053 PackageManager.PERMISSION_GRANTED) { 1054 throw new SecurityException 1055 ("Permission denied - " + 1056 "application missing INTERNET permission"); 1057 } 1058 } 1059 } 1060 1061 /** 1062 * Tell the WebView to enable javascript execution. 1063 * @param flag True if the WebView should execute javascript. 1064 */ 1065 public synchronized void setJavaScriptEnabled(boolean flag) { 1066 if (mJavaScriptEnabled != flag) { 1067 mJavaScriptEnabled = flag; 1068 postSync(); 1069 } 1070 } 1071 1072 /** 1073 * Tell the WebView to enable plugins. 1074 * @param flag True if the WebView should load plugins. 1075 * @deprecated This method has been deprecated in favor of 1076 * {@link #setPluginState} 1077 */ 1078 @Deprecated 1079 public synchronized void setPluginsEnabled(boolean flag) { 1080 setPluginState(PluginState.ON); 1081 } 1082 1083 /** 1084 * Tell the WebView to enable, disable, or have plugins on demand. On 1085 * demand mode means that if a plugin exists that can handle the embedded 1086 * content, a placeholder icon will be shown instead of the plugin. When 1087 * the placeholder is clicked, the plugin will be enabled. 1088 * @param state One of the PluginState values. 1089 */ 1090 public synchronized void setPluginState(PluginState state) { 1091 if (mPluginState != state) { 1092 mPluginState = state; 1093 postSync(); 1094 } 1095 } 1096 1097 /** 1098 * TODO: need to add @Deprecated 1099 */ 1100 public synchronized void setPluginsPath(String pluginsPath) { 1101 } 1102 1103 /** 1104 * Set the path to where database storage API databases should be saved. 1105 * Nota that the WebCore Database Tracker only allows the path to be set once. 1106 * This will update WebCore when the Sync runs in the C++ side. 1107 * @param databasePath String path to the directory where databases should 1108 * be saved. May be the empty string but should never be null. 1109 */ 1110 public synchronized void setDatabasePath(String databasePath) { 1111 if (databasePath != null && !mDatabasePathHasBeenSet) { 1112 mDatabasePath = databasePath; 1113 mDatabasePathHasBeenSet = true; 1114 postSync(); 1115 } 1116 } 1117 1118 /** 1119 * Set the path where the Geolocation permissions database should be saved. 1120 * This will update WebCore when the Sync runs in the C++ side. 1121 * @param databasePath String path to the directory where the Geolocation 1122 * permissions database should be saved. May be the empty string but 1123 * should never be null. 1124 */ 1125 public synchronized void setGeolocationDatabasePath(String databasePath) { 1126 if (databasePath != null 1127 && !databasePath.equals(mGeolocationDatabasePath)) { 1128 mGeolocationDatabasePath = databasePath; 1129 postSync(); 1130 } 1131 } 1132 1133 /** 1134 * Tell the WebView to enable Application Caches API. 1135 * @param flag True if the WebView should enable Application Caches. 1136 */ 1137 public synchronized void setAppCacheEnabled(boolean flag) { 1138 if (mAppCacheEnabled != flag) { 1139 mAppCacheEnabled = flag; 1140 postSync(); 1141 } 1142 } 1143 1144 /** 1145 * Set a custom path to the Application Caches files. The client 1146 * must ensure it exists before this call. 1147 * @param appCachePath String path to the directory containing Application 1148 * Caches files. The appCache path can be the empty string but should not 1149 * be null. Passing null for this parameter will result in a no-op. 1150 */ 1151 public synchronized void setAppCachePath(String appCachePath) { 1152 if (appCachePath != null && !appCachePath.equals(mAppCachePath)) { 1153 mAppCachePath = appCachePath; 1154 postSync(); 1155 } 1156 } 1157 1158 /** 1159 * Set the maximum size for the Application Caches content. 1160 * @param appCacheMaxSize the maximum size in bytes. 1161 */ 1162 public synchronized void setAppCacheMaxSize(long appCacheMaxSize) { 1163 if (appCacheMaxSize != mAppCacheMaxSize) { 1164 mAppCacheMaxSize = appCacheMaxSize; 1165 postSync(); 1166 } 1167 } 1168 1169 /** 1170 * Set whether the database storage API is enabled. 1171 * @param flag boolean True if the WebView should use the database storage 1172 * API. 1173 */ 1174 public synchronized void setDatabaseEnabled(boolean flag) { 1175 if (mDatabaseEnabled != flag) { 1176 mDatabaseEnabled = flag; 1177 postSync(); 1178 } 1179 } 1180 1181 /** 1182 * Set whether the DOM storage API is enabled. 1183 * @param flag boolean True if the WebView should use the DOM storage 1184 * API. 1185 */ 1186 public synchronized void setDomStorageEnabled(boolean flag) { 1187 if (mDomStorageEnabled != flag) { 1188 mDomStorageEnabled = flag; 1189 postSync(); 1190 } 1191 } 1192 1193 /** 1194 * Returns true if the DOM Storage API's are enabled. 1195 * @return True if the DOM Storage API's are enabled. 1196 */ 1197 public synchronized boolean getDomStorageEnabled() { 1198 return mDomStorageEnabled; 1199 } 1200 1201 /** 1202 * Return the path to where database storage API databases are saved for 1203 * the current WebView. 1204 * @return the String path to the database storage API databases. 1205 */ 1206 public synchronized String getDatabasePath() { 1207 return mDatabasePath; 1208 } 1209 1210 /** 1211 * Returns true if database storage API is enabled. 1212 * @return True if the database storage API is enabled. 1213 */ 1214 public synchronized boolean getDatabaseEnabled() { 1215 return mDatabaseEnabled; 1216 } 1217 1218 /** 1219 * Tell the WebView to enable WebWorkers API. 1220 * @param flag True if the WebView should enable WebWorkers. 1221 * Note that this flag only affects V8. JSC does not have 1222 * an equivalent setting. 1223 * @hide pending api council approval 1224 */ 1225 public synchronized void setWorkersEnabled(boolean flag) { 1226 if (mWorkersEnabled != flag) { 1227 mWorkersEnabled = flag; 1228 postSync(); 1229 } 1230 } 1231 1232 /** 1233 * Sets whether Geolocation is enabled. 1234 * @param flag Whether Geolocation should be enabled. 1235 */ 1236 public synchronized void setGeolocationEnabled(boolean flag) { 1237 if (mGeolocationEnabled != flag) { 1238 mGeolocationEnabled = flag; 1239 postSync(); 1240 } 1241 } 1242 1243 /** 1244 * Sets whether XSS Auditor is enabled. 1245 * @param flag Whether XSS Auditor should be enabled. 1246 * @hide Only used by LayoutTestController. 1247 */ 1248 public synchronized void setXSSAuditorEnabled(boolean flag) { 1249 if (mXSSAuditorEnabled != flag) { 1250 mXSSAuditorEnabled = flag; 1251 postSync(); 1252 } 1253 } 1254 1255 /** 1256 * Return true if javascript is enabled. <b>Note: The default is false.</b> 1257 * @return True if javascript is enabled. 1258 */ 1259 public synchronized boolean getJavaScriptEnabled() { 1260 return mJavaScriptEnabled; 1261 } 1262 1263 /** 1264 * Return true if plugins are enabled. 1265 * @return True if plugins are enabled. 1266 * @deprecated This method has been replaced by {@link #getPluginState} 1267 */ 1268 @Deprecated 1269 public synchronized boolean getPluginsEnabled() { 1270 return mPluginState == PluginState.ON; 1271 } 1272 1273 /** 1274 * Return the current plugin state. 1275 * @return A value corresponding to the enum PluginState. 1276 */ 1277 public synchronized PluginState getPluginState() { 1278 return mPluginState; 1279 } 1280 1281 /** 1282 * TODO: need to add @Deprecated 1283 */ 1284 public synchronized String getPluginsPath() { 1285 return ""; 1286 } 1287 1288 /** 1289 * Tell javascript to open windows automatically. This applies to the 1290 * javascript function window.open(). 1291 * @param flag True if javascript can open windows automatically. 1292 */ 1293 public synchronized void setJavaScriptCanOpenWindowsAutomatically( 1294 boolean flag) { 1295 if (mJavaScriptCanOpenWindowsAutomatically != flag) { 1296 mJavaScriptCanOpenWindowsAutomatically = flag; 1297 postSync(); 1298 } 1299 } 1300 1301 /** 1302 * Return true if javascript can open windows automatically. The default 1303 * is false. 1304 * @return True if javascript can open windows automatically during 1305 * window.open(). 1306 */ 1307 public synchronized boolean getJavaScriptCanOpenWindowsAutomatically() { 1308 return mJavaScriptCanOpenWindowsAutomatically; 1309 } 1310 1311 /** 1312 * Set the default text encoding name to use when decoding html pages. 1313 * @param encoding The text encoding name. 1314 */ 1315 public synchronized void setDefaultTextEncodingName(String encoding) { 1316 if (encoding != null && !encoding.equals(mDefaultTextEncoding)) { 1317 mDefaultTextEncoding = encoding; 1318 postSync(); 1319 } 1320 } 1321 1322 /** 1323 * Get the default text encoding name. The default is "Latin-1". 1324 * @return The default text encoding name as a string. 1325 */ 1326 public synchronized String getDefaultTextEncodingName() { 1327 return mDefaultTextEncoding; 1328 } 1329 1330 /** 1331 * Set the WebView's user-agent string. If the string "ua" is null or empty, 1332 * it will use the system default user-agent string. 1333 */ 1334 public synchronized void setUserAgentString(String ua) { 1335 if (ua == null || ua.length() == 0) { 1336 synchronized(sLockForLocaleSettings) { 1337 Locale currentLocale = Locale.getDefault(); 1338 if (!sLocale.equals(currentLocale)) { 1339 sLocale = currentLocale; 1340 mAcceptLanguage = getCurrentAcceptLanguage(); 1341 } 1342 } 1343 ua = getCurrentUserAgent(); 1344 mUseDefaultUserAgent = true; 1345 } else { 1346 mUseDefaultUserAgent = false; 1347 } 1348 1349 if (!ua.equals(mUserAgent)) { 1350 mUserAgent = ua; 1351 postSync(); 1352 } 1353 } 1354 1355 /** 1356 * Return the WebView's user-agent string. 1357 */ 1358 public synchronized String getUserAgentString() { 1359 if (DESKTOP_USERAGENT.equals(mUserAgent) || 1360 IPHONE_USERAGENT.equals(mUserAgent) || 1361 !mUseDefaultUserAgent) { 1362 return mUserAgent; 1363 } 1364 1365 boolean doPostSync = false; 1366 synchronized(sLockForLocaleSettings) { 1367 Locale currentLocale = Locale.getDefault(); 1368 if (!sLocale.equals(currentLocale)) { 1369 sLocale = currentLocale; 1370 mUserAgent = getCurrentUserAgent(); 1371 mAcceptLanguage = getCurrentAcceptLanguage(); 1372 doPostSync = true; 1373 } 1374 } 1375 if (doPostSync) { 1376 postSync(); 1377 } 1378 return mUserAgent; 1379 } 1380 1381 /* package api to grab the Accept Language string. */ 1382 /*package*/ synchronized String getAcceptLanguage() { 1383 synchronized(sLockForLocaleSettings) { 1384 Locale currentLocale = Locale.getDefault(); 1385 if (!sLocale.equals(currentLocale)) { 1386 sLocale = currentLocale; 1387 mAcceptLanguage = getCurrentAcceptLanguage(); 1388 } 1389 } 1390 return mAcceptLanguage; 1391 } 1392 1393 /** 1394 * Tell the WebView whether it needs to set a node to have focus when 1395 * {@link WebView#requestFocus(int, android.graphics.Rect)} is called. 1396 * 1397 * @param flag 1398 */ 1399 public void setNeedInitialFocus(boolean flag) { 1400 if (mNeedInitialFocus != flag) { 1401 mNeedInitialFocus = flag; 1402 } 1403 } 1404 1405 /* Package api to get the choice whether it needs to set initial focus. */ 1406 /* package */ boolean getNeedInitialFocus() { 1407 return mNeedInitialFocus; 1408 } 1409 1410 /** 1411 * Set the priority of the Render thread. Unlike the other settings, this 1412 * one only needs to be called once per process. The default is NORMAL. 1413 * 1414 * @param priority RenderPriority, can be normal, high or low. 1415 */ 1416 public synchronized void setRenderPriority(RenderPriority priority) { 1417 if (mRenderPriority != priority) { 1418 mRenderPriority = priority; 1419 mEventHandler.sendMessage(Message.obtain(null, 1420 EventHandler.PRIORITY)); 1421 } 1422 } 1423 1424 /** 1425 * Override the way the cache is used. The way the cache is used is based 1426 * on the navigation option. For a normal page load, the cache is checked 1427 * and content is re-validated as needed. When navigating back, content is 1428 * not revalidated, instead the content is just pulled from the cache. 1429 * This function allows the client to override this behavior. 1430 * @param mode One of the LOAD_ values. 1431 */ 1432 public void setCacheMode(int mode) { 1433 if (mode != mOverrideCacheMode) { 1434 mOverrideCacheMode = mode; 1435 } 1436 } 1437 1438 /** 1439 * Return the current setting for overriding the cache mode. For a full 1440 * description, see the {@link #setCacheMode(int)} function. 1441 */ 1442 public int getCacheMode() { 1443 return mOverrideCacheMode; 1444 } 1445 1446 /** 1447 * If set, webkit alternately shrinks and expands images viewed outside 1448 * of an HTML page to fit the screen. This conflicts with attempts by 1449 * the UI to zoom in and out of an image, so it is set false by default. 1450 * @param shrink Set true to let webkit shrink the standalone image to fit. 1451 * {@hide} 1452 */ 1453 public void setShrinksStandaloneImagesToFit(boolean shrink) { 1454 if (mShrinksStandaloneImagesToFit != shrink) { 1455 mShrinksStandaloneImagesToFit = shrink; 1456 postSync(); 1457 } 1458 } 1459 1460 /** 1461 * Specify the maximum decoded image size. The default is 1462 * 2 megs for small memory devices and 8 megs for large memory devices. 1463 * @param size The maximum decoded size, or zero to set to the default. 1464 * @hide pending api council approval 1465 */ 1466 public void setMaximumDecodedImageSize(long size) { 1467 if (mMaximumDecodedImageSize != size) { 1468 mMaximumDecodedImageSize = size; 1469 postSync(); 1470 } 1471 } 1472 1473 int getDoubleTapToastCount() { 1474 return mDoubleTapToastCount; 1475 } 1476 1477 void setDoubleTapToastCount(int count) { 1478 if (mDoubleTapToastCount != count) { 1479 mDoubleTapToastCount = count; 1480 // write the settings in the non-UI thread 1481 mEventHandler.sendMessage(Message.obtain(null, 1482 EventHandler.SET_DOUBLE_TAP_TOAST_COUNT)); 1483 } 1484 } 1485 1486 /** 1487 * Transfer messages from the queue to the new WebCoreThread. Called from 1488 * WebCore thread. 1489 */ 1490 /*package*/ 1491 synchronized void syncSettingsAndCreateHandler(BrowserFrame frame) { 1492 mBrowserFrame = frame; 1493 if (DebugFlags.WEB_SETTINGS) { 1494 junit.framework.Assert.assertTrue(frame.mNativeFrame != 0); 1495 } 1496 1497 SharedPreferences sp = mContext.getSharedPreferences(PREF_FILE, 1498 Context.MODE_PRIVATE); 1499 if (mDoubleTapToastCount > 0) { 1500 mDoubleTapToastCount = sp.getInt(DOUBLE_TAP_TOAST_COUNT, 1501 mDoubleTapToastCount); 1502 } 1503 nativeSync(frame.mNativeFrame); 1504 mSyncPending = false; 1505 mEventHandler.createHandler(); 1506 } 1507 1508 /** 1509 * Let the Settings object know that our owner is being destroyed. 1510 */ 1511 /*package*/ 1512 synchronized void onDestroyed() { 1513 } 1514 1515 private int pin(int size) { 1516 // FIXME: 72 is just an arbitrary max text size value. 1517 if (size < 1) { 1518 return 1; 1519 } else if (size > 72) { 1520 return 72; 1521 } 1522 return size; 1523 } 1524 1525 /* Post a SYNC message to handle syncing the native settings. */ 1526 private synchronized void postSync() { 1527 // Only post if a sync is not pending 1528 if (!mSyncPending) { 1529 mSyncPending = mEventHandler.sendMessage( 1530 Message.obtain(null, EventHandler.SYNC)); 1531 } 1532 } 1533 1534 // Synchronize the native and java settings. 1535 private native void nativeSync(int nativeFrame); 1536} 1537