Merge korg/donut into korg/master
diff --git a/Android.mk b/Android.mk
index 02ba333..33cd6ab 100644
--- a/Android.mk
+++ b/Android.mk
@@ -3,10 +3,6 @@
LOCAL_MODULE_TAGS := user
-# TODO: Remove dependency of application on the test runner (android.test.runner)
-# library.
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
LOCAL_STATIC_JAVA_LIBRARIES := google-framework
LOCAL_SRC_FILES := $(call all-subdir-java-files)
@@ -14,3 +10,6 @@
LOCAL_PACKAGE_NAME := Browser
include $(BUILD_PACKAGE)
+
+# additionally, build tests in sub-folders in a separate .apk
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index c67cc97..6362cfa 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -28,36 +28,23 @@
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK"/>
- <uses-permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"/>
- <uses-permission android:name="com.android.browser.permission.WRITE_HISTORY_BOOKMARKS"/>
+ <uses-permission android:name="android.permission.READ_HISTORY_BOOKMARKS"/>
+ <uses-permission android:name="android.permission.WRITE_HISTORY_BOOKMARKS"/>
- <!-- Allows an application to read the user Browser's history and bookmarks. -->
- <permission android:name="com.android.browser.permission.READ_HISTORY_BOOKMARKS"
- android:permissionGroup="android.permission-group.PERSONAL_INFO"
- android:label="@string/permlab_readHistoryBookmarks"
- android:description="@string/permdesc_readHistoryBookmarks"
- android:protectionLevel="dangerous" />
-
- <!-- Allows an application to write (but not read) the user Browser's history and bookmarks. -->
- <permission android:name="com.android.browser.permission.WRITE_HISTORY_BOOKMARKS"
- android:permissionGroup="android.permission-group.PERSONAL_INFO"
- android:label="@string/permlab_writeHistoryBookmarks"
- android:description="@string/permdesc_writeHistoryBookmarks"
- android:protectionLevel="dangerous" />
+ <supports-density android:density="160" />
+ <supports-density android:density="240" />
+ <expandable />
<application android:name="Browser"
android:label="@string/application_name"
android:icon="@drawable/ic_launcher_browser"
android:taskAffinity="android.task.browser" >
- <!-- TODO: Remove dependency of application on the test runner
- (android.test) library. -->
- <uses-library android:name="android.test.runner" />
- <provider android:name="BrowserProvider"
- android:authorities="browser"
- android:multiprocess="true"
- android:readPermission="com.android.browser.permission.READ_HISTORY_BOOKMARKS"
- android:writePermission="com.android.browser.permission.WRITE_HISTORY_BOOKMARKS"/>
+ <provider android:name="BrowserProvider"
+ android:authorities="browser"
+ android:multiprocess="true"
+ android:readPermission="android.permission.READ_HISTORY_BOOKMARKS"
+ android:writePermission="android.permission.WRITE_HISTORY_BOOKMARKS"/>
<activity android:name="BrowserActivity"
android:label="@string/application_name"
android:launchMode="singleTask"
@@ -82,6 +69,7 @@
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="http" />
<data android:scheme="https" />
+ <data android:scheme="inline" />
<data android:mimeType="text/html"/>
<data android:mimeType="text/plain"/>
<data android:mimeType="application/xhtml+xml"/>
@@ -111,7 +99,6 @@
<data android:scheme="https" />
</intent-filter>
<intent-filter>
- <action android:name="android.intent.action.WEB_SEARCH" />
<action android:name="android.intent.action.MEDIA_SEARCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
@@ -148,7 +135,7 @@
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
- </activity-alias>
+ </activity-alias>
<activity android:name="BrowserDownloadPage" android:label=""
android:configChanges="orientation|keyboardHidden">
@@ -176,6 +163,19 @@
android:theme="@android:style/Theme.Dialog">
</activity>
+ <activity android:name="BookmarkSearch"
+ android:label="@string/bookmarks_search"
+ android:stateNotNeeded="true"
+ android:theme="@android:style/Theme.NoDisplay"
+ android:excludeFromRecents="true">
+ <intent-filter>
+ <action android:name="android.intent.action.SEARCH" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ <meta-data android:name="android.app.searchable"
+ android:resource="@xml/bookmarks_searchable" />
+ </activity>
+
<service android:name="GearsDialogService"
android:process=":dialog"
android:exported="false">
@@ -199,23 +199,5 @@
</application>
- <!-- Browser tests. Invoke with: -->
- <!-- adb shell am instrument -w com.android.browser/.BrowserTestRunner -->
- <instrumentation android:name="BrowserTestRunner"
- android:targetPackage="com.android.browser"
- android:label="@string/activity_instrumentation_test_runner"
- />
- <!-- Browser tests. Invoke with: -->
- <!-- adb shell am instrument -w com.android.browser/.BrowserFunctionalTestRunner -->
- <instrumentation android:name="BrowserFunctionalTestRunner"
- android:targetPackage="com.android.browser"
- android:label="@string/activity_instrumentation_functional_test_runner"
- />
-
- <instrumentation android:name="BrowserLaunchPerformance"
- android:targetPackage="com.android.browser"
- android:label="Browser Launch Performance"
- />
-
</manifest>
diff --git a/res/drawable/ic_search_category_bookmark.png b/res/drawable/ic_search_category_bookmark.png
index 08b5e74..d228408 100755
--- a/res/drawable/ic_search_category_bookmark.png
+++ b/res/drawable/ic_search_category_bookmark.png
Binary files differ
diff --git a/res/drawable/ic_search_category_history.png b/res/drawable/ic_search_category_history.png
index 894c254..12cd51c 100755
--- a/res/drawable/ic_search_category_history.png
+++ b/res/drawable/ic_search_category_history.png
Binary files differ
diff --git a/res/drawable/ic_search_category_suggest.png b/res/drawable/ic_search_category_suggest.png
index ada07e6..a4ed7aa 100755
--- a/res/drawable/ic_search_category_suggest.png
+++ b/res/drawable/ic_search_category_suggest.png
Binary files differ
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 8379ab6..67ab130 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -236,7 +236,6 @@
<string name="download_length_required">"Nelze stáhnout. Velikost položky nelze určit."</string>
<string name="download_precondition_failed">"Stahování bylo přerušeno a nelze v něm pokračovat."</string>
<string name="activity_instrumentation_test_runner">"Testovací verze prohlížeče"</string>
- <string name="search_google">"Prohledat Google"</string>
<string name="permlab_readHistoryBookmarks">"čtení historie a záložek prohlížeče"</string>
<string name="permdesc_readHistoryBookmarks">"Umožňuje aplikaci číst všechny navštívené adresy URL a záložky prohlížeče."</string>
<string name="permlab_writeHistoryBookmarks">"zápis historie a záložek prohlížeče"</string>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index a6f2f0f..184bc83 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -236,7 +236,6 @@
<string name="download_length_required">"Download kann nicht gestartet werden, da die Größe des Elements nicht bestimmt werden kann."</string>
<string name="download_precondition_failed">"Download wurde unterbrochen und kann nicht fortgesetzt werden."</string>
<string name="activity_instrumentation_test_runner">"Browser Test Runner"</string>
- <string name="search_google">"In Google suchen"</string>
<string name="permlab_readHistoryBookmarks">"Browserverlauf und Lesezeichen lesen"</string>
<string name="permdesc_readHistoryBookmarks">"Ermöglicht der Anwendung, alle URLs, die mit dem Browser besucht wurden, sowie alle Lesezeichen des Browsers zu lesen."</string>
<string name="permlab_writeHistoryBookmarks">"Browserverlauf und Lesezeichen schreiben"</string>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
new file mode 100644
index 0000000..5a5eb6e
--- /dev/null
+++ b/res/values-es-rUS/strings.xml
@@ -0,0 +1,288 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="application_name">"Navegador"</string>
+ <string name="tab_bookmarks">"Marcadores"</string>
+ <string name="tab_most_visited">"Los más visitados"</string>
+ <string name="tab_history">"Historial"</string>
+ <string name="added_to_bookmarks">"Agregado a marcadores"</string>
+ <string name="removed_from_bookmarks">"Suprimido de los marcadores"</string>
+ <string name="sign_in_to">"Iniciar sesión en <xliff:g id="HOSTNAME">%s1</xliff:g> \"<xliff:g id="REALM">%s2</xliff:g>\""</string>
+ <string name="username">"Nombre"</string>
+ <string name="password">"Contraseña"</string>
+ <string name="action">"Iniciar sesión"</string>
+ <string name="cancel">"Cancelar"</string>
+ <string name="ok">"Aceptar"</string>
+ <!-- no translation found for matches_found:zero (6242659159545399963) -->
+ <!-- no translation found for matches_found:one (4352019729062956802) -->
+ <!-- no translation found for matches_found:few (5544267486978946555) -->
+ <!-- no translation found for matches_found:other (6616125067364315405) -->
+ <string name="page_info">"Información de la página"</string>
+ <string name="page_info_view">"Ver información de la página"</string>
+ <string name="page_info_address">"Dirección:"</string>
+ <string name="ssl_warnings_header">"Existen problemas con el certificado de seguridad para este sitio."</string>
+ <string name="ssl_continue">"Continuar"</string>
+ <string name="security_warning">"Advertencia de seguridad"</string>
+ <string name="view_certificate">"Ver certificado"</string>
+ <string name="ssl_untrusted">"Este certificado no proviene de una fuente confiable."</string>
+ <string name="ssl_mismatch">"El nombre del sitio no coincide con el nombre del certificado."</string>
+ <string name="ssl_expired">"Este certificado ha expirado."</string>
+ <string name="ssl_not_yet_valid">"Este certificado aún no es válido."</string>
+ <string name="ssl_certificate">"Certificado de seguridad"</string>
+ <string name="ssl_certificate_is_valid">"Este certificado es válido."</string>
+ <string name="issued_to">"Emitido a:"</string>
+ <string name="common_name">"Nombre habitual:"</string>
+ <string name="org_name">"Organización:"</string>
+ <string name="org_unit">"Unidad organizativa"</string>
+ <string name="issued_by">"Emitido por:"</string>
+ <string name="validity_period">"Validez:"</string>
+ <string name="issued_on">"Enviado el:"</string>
+ <string name="expires_on">"Expira el:"</string>
+ <string name="retrieving_creds_dlg_msg">"Recuperando detalles de inicio de sesión..."</string>
+ <string name="stopping">"Deteniendo..."</string>
+ <string name="stop">"Detener"</string>
+ <string name="reload">"Actualizar"</string>
+ <string name="forward">"Reenviar"</string>
+ <string name="save">"Aceptar"</string>
+ <string name="do_not_save">"Cancelar"</string>
+ <string name="location">"Ubicación"</string>
+ <string name="name">"Nombre"</string>
+ <string name="http">"http://"</string>
+ <string name="save_to_bookmarks">"Marcador"</string>
+ <string name="edit_bookmark">"Editar marcador"</string>
+ <string name="create_shortcut_bookmark">"Agregar acceso directo a la página de inicio"</string>
+ <string name="open_bookmark">"Abrir"</string>
+ <string name="remove_bookmark">"Eliminar marcador"</string>
+ <string name="remove_history_item">"Suprimir del historial"</string>
+ <string name="bookmark_saved">"Guardado en los marcadores."</string>
+ <string name="bookmark_needs_title">"El marcador debe tener un nombre."</string>
+ <string name="bookmark_needs_url">"El marcador debe tener una ubicación."</string>
+ <string name="empty_bookmark">"No es posible crear un marcador vacío."</string>
+ <string name="bookmark_url_not_valid">"La URL no es válida."</string>
+ <string name="delete_bookmark">"Eliminar"</string>
+ <string name="bookmark_page">"Última página vista del marcador"</string>
+ <string name="current_page">"de "</string>
+ <string name="delete_bookmark_warning">"El marcador \"<xliff:g id="BOOKMARK">%s</xliff:g>\" se eliminará."</string>
+ <string name="open_in_new_window">"Abrir en una ventana nueva"</string>
+ <string name="new_window">"Ventana nueva"</string>
+ <string name="goto_dot">"Ir"</string>
+ <string name="find_dot">"Buscar en la página"</string>
+ <string name="select_dot">"Seleccionar texto"</string>
+ <string name="view_tabs">"Descripción general de la ventana"</string>
+ <string name="view_tabs_condensed">"Windows"</string>
+ <string name="tab_picker_title">"Ventana actual"</string>
+ <string name="tab_picker_view_tab">"Ver"</string>
+ <string name="tab_picker_new_tab">"Ventana nueva"</string>
+ <string name="tab_picker_remove_tab">"Cerrar"</string>
+ <string name="tab_picker_bookmark">"Marcador"</string>
+ <string name="tab_picker_send_url">"Compartir enlace"</string>
+ <string name="bookmarks">"Marcadores"</string>
+ <string name="shortcut_bookmark">"Marcador"</string>
+ <string name="history">"Historial"</string>
+ <string name="menu_view_download">"Descargas"</string>
+ <string name="share_page">"Compartir página"</string>
+ <string name="contextmenu_openlink">"Abrir"</string>
+ <string name="contextmenu_openlink_newwindow">"Abrir en una ventana nueva"</string>
+ <string name="contextmenu_bookmark_thislink">"Enlace del marcador"</string>
+ <string name="contextmenu_savelink">"Guardar enlace"</string>
+ <string name="contextmenu_sharelink">"Compartir enlace"</string>
+ <string name="contextmenu_copy">"Copiar"</string>
+ <string name="contextmenu_copylink">"Copiar URL de vínculo"</string>
+ <string name="contextmenu_download_image">"Guardar imagen"</string>
+ <string name="contextmenu_view_image">"Ver imagen"</string>
+ <string name="contextmenu_dial_dot">"Discar..."</string>
+ <string name="contextmenu_add_contact">"Agregar contacto"</string>
+ <string name="contextmenu_send_mail">"Enviar correo electrónico"</string>
+ <string name="contextmenu_map">"Situar en el mapa"</string>
+ <string name="clear">"Borrar"</string>
+ <string name="replace">"Reemplazar"</string>
+ <string name="browser_bookmarks_page_bookmarks_text">"Marcadores"</string>
+ <string name="menu_preferences">"Configuración"</string>
+ <string name="pref_content_title">"Configuración del contenido de la página"</string>
+ <string name="pref_content_load_images">"Cargar imágenes"</string>
+ <string name="pref_content_load_images_summary">"Visualizar imágenes en páginas web"</string>
+ <string name="pref_content_block_popups">"Bloquear ventanas emergentes"</string>
+ <string name="pref_content_javascript">"Habilitar JavaScript"</string>
+ <string name="pref_content_open_in_background">"Abrir en modo subordinado"</string>
+ <string name="pref_content_open_in_background_summary">"Hay ventanas nuevas abiertas detrás de la ventana actual"</string>
+ <string name="pref_content_homepage">"Definir página de inicio"</string>
+ <string name="pref_content_autofit">"Ajuste automático de páginas"</string>
+ <string name="pref_content_autofit_summary">"Formatea las páginas web para que se ajusten a la pantalla"</string>
+ <string name="pref_privacy_title">"Configuración de privacidad"</string>
+ <string name="pref_privacy_clear_cache">"Borrar caché"</string>
+ <string name="pref_privacy_clear_cache_summary">"Eliminar todo el contenido de la página en caché"</string>
+ <string name="pref_privacy_clear_cache_dlg">"Se borrará el caché."</string>
+ <string name="pref_privacy_clear_cookies">"Borrar todos los datos de cookies"</string>
+ <string name="pref_privacy_clear_cookies_summary">"Borrar todas las cookies del navegador"</string>
+ <string name="pref_privacy_clear_cookies_dlg">"Se borrarán todas las cookies."</string>
+ <string name="pref_privacy_clear_history">"Borrar historial"</string>
+ <string name="pref_privacy_clear_history_summary">"Borrar el historial de navegación del navegador"</string>
+ <string name="pref_privacy_clear_history_dlg">"Se borrará el historial del navegador."</string>
+ <string name="pref_privacy_clear_form_data">"Borrar datos del formulario"</string>
+ <string name="pref_privacy_clear_form_data_summary">"Borrar todos los datos guardados del formulario"</string>
+ <string name="pref_privacy_clear_form_data_dlg">"Se borrarán todos los datos guardados del formulario."</string>
+ <string name="pref_privacy_clear_passwords">"Borrar contraseñas"</string>
+ <string name="pref_privacy_clear_passwords_summary">"Borrar todas las contraseñas guardadas"</string>
+ <string name="pref_privacy_clear_passwords_dlg">"Se borrarán todas las contraseñas guardadas."</string>
+ <string name="pref_security_title">"Configuración de seguridad"</string>
+ <string name="pref_security_remember_passwords">"Recordar contraseñas"</string>
+ <string name="pref_security_remember_passwords_summary">"Guardar nombres de usuario y contraseñas para sitios web"</string>
+ <string name="pref_security_save_form_data">"Recordar datos del formulario"</string>
+ <string name="pref_security_save_form_data_summary">"Recordar los datos ingresados en los formularios para uso futuro"</string>
+ <string name="pref_security_show_security_warning">"Mostrar advertencias de seguridad"</string>
+ <string name="pref_security_show_security_warning_summary">"Mostrar una advertencia si hay un problema con la seguridad de un sitio"</string>
+ <string name="pref_security_accept_cookies">"Aceptar cookies"</string>
+ <string name="pref_security_accept_cookies_summary">"Permitir que los sitios guarden y lean datos de las \"cookies\""</string>
+ <string name="pref_text_size">"Definir tamaño del texto"</string>
+ <string-array name="pref_text_size_choices">
+ <item>"Pequeño"</item>
+ <item>"Pequeño"</item>
+ <item>"Normal"</item>
+ <item>"Grande"</item>
+ <item>"Enorme"</item>
+ </string-array>
+ <string name="pref_text_size_dialogtitle">"Tamaño del texto"</string>
+ <string name="pref_extras_title">"Configuración avanzada"</string>
+ <string name="pref_extras_gears_enable">"Habilitar Gears"</string>
+ <string name="pref_extras_gears_enable_summary">"Aplicaciones que amplían la funcionalidad del navegador"</string>
+ <string name="pref_extras_gears_settings">"Configuración de Gears"</string>
+ <string name="pref_plugin_installed">"Lista de complementos"</string>
+ <string name="pref_plugin_installed_empty_list">"No hay complementos instalados."</string>
+ <string name="pref_extras_gears_settings_summary">"Aplicaciones que amplían la funcionalidad del navegador"</string>
+ <string name="pref_extras_reset_default">"Restablecer a los valores predeterminados"</string>
+ <string name="pref_extras_reset_default_summary">"Borrar todos los datos del navegador y restablecer la configuración a los valores predeterminados"</string>
+ <string name="pref_extras_reset_default_dlg">"Se borrarán todos los datos del navegador y la configuración volverá a los valores predeterminados."</string>
+ <string name="pref_extras_reset_default_dlg_title">"Restablecer a los valores predeterminados"</string>
+ <string name="pref_development_title">"Depurar"</string>
+ <string name="pref_default_text_encoding">"Definir codificación de texto"</string>
+ <string-array name="pref_default_text_encoding_choices">
+ <item>"Latino-1 (ISO-8859-1)"</item>
+ <item>"Unicode (UTF-8)"</item>
+ <item>"Japonés (ISO-2022-JP)"</item>
+ <item>"Japonés (SHIFT_JIS)"</item>
+ <item>"Japonés (EUC-JP)"</item>
+ </string-array>
+ <string name="pref_default_text_encoding_dialogtitle">"Codificación de texto"</string>
+ <string name="pref_default_text_encoding_default">"Latino-1"</string>
+ <string name="browserFrameRedirect">"Redireccionamiento"</string>
+ <string name="browserFrame307Post">"Esta página web está siendo redireccionada. ¿Deseas reenviar los datos que ingresaste en tu formulario a la ubicación nueva?"</string>
+ <string name="browserFrameNetworkErrorLabel">"Problema de conectividad de datos"</string>
+ <string name="browserFrameFileErrorLabel">"Problema con el archivo"</string>
+ <string name="browserFrameFormResubmitLabel">"Confirmar"</string>
+ <string name="browserFrameFormResubmitMessage">"La página que intentas ver contiene datos que ya se han suministrado (\"POSTDATA\"). Si vuelves a enviar los datos, se repetirán las acciones que haya realizado el formulario (como una búsqueda o compra en línea)."</string>
+ <string name="loadSuspendedTitle">"No hay conexión a la red"</string>
+ <string name="loadSuspended">"La página continuará cargando cuando se haya restablecido la conexión."</string>
+ <string name="clear_history">"Borrar historial"</string>
+ <string name="browser_history">"Últimas páginas visitadas"</string>
+ <string name="empty_history">"El historial del navegador está vacío."</string>
+ <string name="add_new_bookmark">"Agregar marcador..."</string>
+ <string name="no_database">"No hay base de datos"</string>
+ <string name="search_hint">"Escribe la dirección web"</string>
+ <string name="search_button_text">"Ir"</string>
+ <string name="attention">"Atención"</string>
+ <string name="popup_window_attempt">"Este sitio está intentando abrir una ventana emergente."</string>
+ <string name="allow">"Permitir"</string>
+ <string name="block">"Bloquear"</string>
+ <string name="too_many_windows_dialog_title">"Se alcanzó el límite de la ventana"</string>
+ <string name="too_many_windows_dialog_message">"No se ha podido abrir una ventana nueva porque ya has abierto el máximo permitido."</string>
+ <string name="too_many_subwindows_dialog_title">"Ventana emergente ya abierta"</string>
+ <string name="too_many_subwindows_dialog_message">"No es posible abrir una ventana emergente nueva porque sólo puede abrirse una por vez."</string>
+ <string name="download_title">"Historial de descarga"</string>
+ <string name="download_unknown_filename">"<Desconocido>"</string>
+ <string name="download_menu_open">"Abrir"</string>
+ <string name="download_menu_clear">"Borrar de la lista"</string>
+ <string name="download_menu_cancel">"Cancelar descarga"</string>
+ <string name="download_menu_cancel_all">"Cancelar todas las descargas"</string>
+ <string name="download_menu_clear_all">"Borrar lista"</string>
+ <string name="download_clear_dlg_title">"Borrar"</string>
+ <string name="download_clear_dlg_msg">"Todos los elementos se borrarán de la lista y se suprimirán del caché del navegador."</string>
+ <string name="download_cancel_dlg_title">"Cancelar descargas"</string>
+ <string name="download_cancel_dlg_msg">"Las <xliff:g id="DOWNLOAD_COUNT">%d</xliff:g> descargas se cancelarán y se borrarán del historial de descarga."</string>
+ <string name="download_file_error_dlg_title">"No hay espacio suficiente"</string>
+ <string name="download_file_error_dlg_msg">"<xliff:g id="FILENAME">%s</xliff:g> no se pudo cargar."\n"Libera espacio en tu teléfono y vuelve a intentarlo."</string>
+ <string name="download_failed_generic_dlg_title">"Descarga incorrecta"</string>
+ <string name="download_no_sdcard_dlg_title">"No hay tarjeta SD"</string>
+ <string name="download_no_sdcard_dlg_msg">"Es necesario tener una tarjeta SD para descargar <xliff:g id="FILENAME">%s</xliff:g>."</string>
+ <string name="download_sdcard_busy_dlg_title">"Tarjeta SD no disponible"</string>
+ <string name="download_sdcard_busy_dlg_msg">"La tarjeta SD está llena. Para permitir descargas, selecciona \"Desactivar almacenamiento USB\" en la notificación."</string>
+ <string name="download_no_application">"No se encuentra una aplicación para abrir este archivo."</string>
+ <string name="retry">"¿Intentar nuevamente"</string>
+ <string name="no_downloads">"El historial de descarga está vacío."</string>
+ <string name="download_error">"Descarga incorrecta."</string>
+ <string name="download_success">"<xliff:g id="FILE">%s</xliff:g> Descarga completa."</string>
+ <string name="download_running">"Descargando..."</string>
+ <string name="download_pending">"Iniciando la descarga..."</string>
+ <string name="download_pending_network">"Esperando la conexión de datos..."</string>
+ <string name="download_running_paused">"Esperando la conexión de datos..."</string>
+ <string name="download_canceled">"Descarga cancelada."</string>
+ <string name="download_not_acceptable">"No es posible realizar la descarga. El contenido no se admite en el teléfono."</string>
+ <string name="download_file_error">"No es posible terminar la descarga. No hay espacio suficiente."</string>
+ <string name="download_length_required">"No es posible realizar la descarga. No puede determinarse el tamaño del elemento."</string>
+ <string name="download_precondition_failed">"Descarga interrumpida. No se puede retomar."</string>
+ <string name="activity_instrumentation_test_runner">"Ejecutor de pruebas del navegador"</string>
+ <string name="permlab_readHistoryBookmarks">"leer historial y marcadores del navegador"</string>
+ <string name="permdesc_readHistoryBookmarks">"Permite a la aplicación leer todas las URL que ha visitado el navegador y todos los marcadores del navegador."</string>
+ <string name="permlab_writeHistoryBookmarks">"escribir historial y marcadores del navegador"</string>
+ <string name="permdesc_writeHistoryBookmarks">"Permite a una aplicación modificar el historial y los marcadores del navegador almacenados en tu teléfono. Las aplicaciones maliciosas pueden utilizarlo para borrar o modificar tus datos."</string>
+ <string name="query_data_prompt">"Permitir almacenamiento"</string>
+ <string name="query_data_message">"Este sitio web desea almacenar información en tu teléfono."</string>
+ <string name="location_prompt">"Acceder a tu ubicación"</string>
+ <string name="location_message">"Este sitio web desea acceder a tu ubicación."</string>
+ <string name="shortcut_prompt">"Crear un acceso directo"</string>
+ <string name="shortcut_message">"Este sitio web desea crear un acceso directo a esta página en tu pantalla de inicio"</string>
+ <string name="settings_message">"En la siguiente tabla, se muestran los permisos que has otorgado a cada sitio que ha intentado utilizar Gears."</string>
+ <string name="filepicker_message">"File Picker"</string>
+ <string name="image_message">"Imagen seleccionada"</string>
+ <string name="settings_title">"Configuración de Gears"</string>
+ <string name="privacy_policy">"Lee la política de privacidad del sitio para ver cómo se utilizará tu ubicación."</string>
+ <string name="settings_storage_title">"Permitir almacenamiento local"</string>
+ <string name="settings_storage_subtitle_on">"Este sitio puede guardar información en tu teléfono"</string>
+ <string name="settings_storage_subtitle_off">"Este sitio no puede guardar información en tu teléfono"</string>
+ <string name="settings_location_title">"Permitir detección de ubicación"</string>
+ <string name="settings_location_subtitle_on">"Este sitio puede leer tu ubicación actual"</string>
+ <string name="settings_location_subtitle_off">"Este sitio no puede leer tu ubicación actual"</string>
+ <string name="settings_remove_site">"Suprimir este sitio de Gears"</string>
+ <string name="settings_empty">"No hay permisos definidos"</string>
+ <string name="settings_confirmation_remove_title">"Suprimir este sitio"</string>
+ <string name="settings_confirmation_remove">"Se borrarán todos los permisos y se eliminarán los datos del sitio almacenados en el teléfono."</string>
+ <string name="storage_notification">"Este sitio almacenará información en este teléfono. "\n" Cambia esta configuración en:"\n" Configuración -> Configuración de Gears"</string>
+ <string name="storage_notification_alwaysdeny">"Este sitio nunca almacenará información en este teléfono. "\n" Cambia esta configuración en:"\n" Configuración -> Configuración de Gears"</string>
+ <string name="location_notification">"Este sitio puede acceder a tu ubicación. "\n" Cambia esta configuración en:"\n" Configuración -> Configuración de Gears"</string>
+ <string name="location_notification_alwaysdeny">"Este sitio no accederá a tu ubicación. "\n" Cambia esta configuración en:"\n" Configuración -> Configuración de Gears"</string>
+ <string name="shortcut_notification">"Acceso directo creado"</string>
+ <string name="permission_button_alwaysdeny">"No permitir nunca"</string>
+ <string name="permission_button_allow">"Aceptar"</string>
+ <string name="permission_button_deny">"Cancelar"</string>
+ <string name="shortcut_button_alwaysdeny">"No permitir nunca"</string>
+ <string name="shortcut_button_allow">"Aceptar"</string>
+ <string name="shortcut_button_deny">"Cancelar"</string>
+ <string name="settings_button_allow">"Aplicar"</string>
+ <string name="settings_button_deny">"Cancelar"</string>
+ <string name="filepicker_button_allow">"Aceptar"</string>
+ <string name="filepicker_button_deny">"Cancelar"</string>
+ <string name="filepicker_path">"ruta:"</string>
+ <string name="filepicker_no_files_selected">"No hay archivos seleccionados"</string>
+ <string name="filepicker_one_file_selected">"Un archivo seleccionado"</string>
+ <string name="filepicker_some_files_selected">"archivo seleccionado"</string>
+ <string name="remove">"Eliminar"</string>
+ <string name="local_storage">"Almacenamiento local"</string>
+ <string name="allowed">"Permitido"</string>
+ <string name="denied">"Denegado"</string>
+ <string name="unrecognized_dialog_message">"Tipo de diálogo no reconocido"</string>
+ <string name="default_button">"Aceptar"</string>
+ <string name="zoom_overview_button_text">"Descripción general"</string>
+</resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index 3cde9b4..0ba9501 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -117,12 +117,12 @@
<string name="pref_content_title">"Configuración de contenido de la página"</string>
<string name="pref_content_load_images">"Cargar imágenes"</string>
<string name="pref_content_load_images_summary">"Mostrar imágenes en páginas web"</string>
- <string name="pref_content_block_popups">"Bloquear ventanas emer."</string>
+ <string name="pref_content_block_popups">"Bloquear ventanas emergentes"</string>
<string name="pref_content_javascript">"Habilitar JavaScript"</string>
<string name="pref_content_open_in_background">"Abrir en segundo plano"</string>
<string name="pref_content_open_in_background_summary">"Nuevas ventanas abiertas detrás de la actual"</string>
<string name="pref_content_homepage">"Establecer página principal"</string>
- <string name="pref_content_autofit">"Ajustar páginas automát."</string>
+ <string name="pref_content_autofit">"Ajustar páginas automáticamente"</string>
<string name="pref_content_autofit_summary">"Configurar las páginas web para ajustarlas a la pantalla"</string>
<string name="pref_privacy_title">"Configuración de privacidad"</string>
<string name="pref_privacy_clear_cache">"Borrar caché"</string>
@@ -143,9 +143,9 @@
<string name="pref_security_title">"Configuración de seguridad"</string>
<string name="pref_security_remember_passwords">"Recordar contraseñas"</string>
<string name="pref_security_remember_passwords_summary">"Guardar nombres de usuario y contraseñas de sitios web"</string>
- <string name="pref_security_save_form_data">"Recordar formularios"</string>
+ <string name="pref_security_save_form_data">"Recordar datos de formulario"</string>
<string name="pref_security_save_form_data_summary">"Recordar datos introducidos en formularios"</string>
- <string name="pref_security_show_security_warning">"Mostrar advertencias"</string>
+ <string name="pref_security_show_security_warning">"Mostrar advertencias de seguridad"</string>
<string name="pref_security_show_security_warning_summary">"Mostrar advertencia si hay algún problema con la seguridad del sitio"</string>
<string name="pref_security_accept_cookies">"Aceptar cookies"</string>
<string name="pref_security_accept_cookies_summary">"Permitir que los sitios guarden y lean datos de cookies"</string>
@@ -165,12 +165,12 @@
<string name="pref_plugin_installed">"Lista de complementos"</string>
<string name="pref_plugin_installed_empty_list">"Ningún complemento instalado"</string>
<string name="pref_extras_gears_settings_summary">"Aplicaciones que amplían las funciones del navegador"</string>
- <string name="pref_extras_reset_default">"Restablecer valores pred."</string>
+ <string name="pref_extras_reset_default">"Restablecer valores predeterminados"</string>
<string name="pref_extras_reset_default_summary">"Borrar todos los datos del navegador y restablecer la configuración predeterminada"</string>
<string name="pref_extras_reset_default_dlg">"Se borrarán todos los datos del navegador y se restablecerá la configuración predeterminada."</string>
<string name="pref_extras_reset_default_dlg_title">"Restablecer valores predeterminados"</string>
<string name="pref_development_title">"Depurar"</string>
- <string name="pref_default_text_encoding">"Codificación de texto"</string>
+ <string name="pref_default_text_encoding">"Establecer codificación de texto"</string>
<string-array name="pref_default_text_encoding_choices">
<item>"Latín-1 (ISO-8859-1)"</item>
<item>"Unicode (UTF-8)"</item>
@@ -236,7 +236,6 @@
<string name="download_length_required">"No se puede realizar la descarga, porque no es posible determinar el tamaño del elemento."</string>
<string name="download_precondition_failed">"La descarga se ha interrumpido y no se puede reanudar."</string>
<string name="activity_instrumentation_test_runner">"Realizador de pruebas del navegador"</string>
- <string name="search_google">"Búsqueda de Google"</string>
<string name="permlab_readHistoryBookmarks">"leer información de marcadores y del historial del navegador"</string>
<string name="permdesc_readHistoryBookmarks">"Permite que la aplicación lea todas las URL que ha visitado el navegador y todos sus marcadores."</string>
<string name="permlab_writeHistoryBookmarks">"escribir en marcadores y en el historial del navegador"</string>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index 9093f99..4be49ee 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -122,7 +122,7 @@
<string name="pref_content_open_in_background">"Ouvrir en arrière-plan"</string>
<string name="pref_content_open_in_background_summary">"Les nouvelles fenêtres s\'ouvrent derrière la fenêtre actuelle"</string>
<string name="pref_content_homepage">"Configurer la page d\'accueil"</string>
- <string name="pref_content_autofit">"Redimensionner"</string>
+ <string name="pref_content_autofit">"Redimensionner les pages"</string>
<string name="pref_content_autofit_summary">"Configurer les pages Web pour qu\'elles s\'ajustent à l\'écran"</string>
<string name="pref_privacy_title">"Paramètres de confidentialité"</string>
<string name="pref_privacy_clear_cache">"Effacer le cache"</string>
@@ -134,18 +134,18 @@
<string name="pref_privacy_clear_history">"Effacer l\'historique"</string>
<string name="pref_privacy_clear_history_summary">"Effacer l\'historique du navigateur"</string>
<string name="pref_privacy_clear_history_dlg">"L\'historique du navigateur sera effacé."</string>
- <string name="pref_privacy_clear_form_data">"Eff. données formulaires"</string>
+ <string name="pref_privacy_clear_form_data">"Effacer données formulaire"</string>
<string name="pref_privacy_clear_form_data_summary">"Effacer toutes les données de formulaire enregistrées"</string>
<string name="pref_privacy_clear_form_data_dlg">"Toutes les données de formulaire enregistrées seront effacées."</string>
<string name="pref_privacy_clear_passwords">"Effacer les mots de passe"</string>
<string name="pref_privacy_clear_passwords_summary">"Effacer tous les mots de passe enregistrés"</string>
<string name="pref_privacy_clear_passwords_dlg">"Tous les mots de passe enregistrés seront effacés."</string>
<string name="pref_security_title">"Paramètres de sécurité"</string>
- <string name="pref_security_remember_passwords">"Mém. mots de passe"</string>
+ <string name="pref_security_remember_passwords">"Mémoriser les mots de passe"</string>
<string name="pref_security_remember_passwords_summary">"Enregistrer les noms d\'utilisateur et les mots de passe pour les sites Web"</string>
- <string name="pref_security_save_form_data">"Mém. données formulaire"</string>
- <string name="pref_security_save_form_data_summary">"Mémoriser les données saisies dans les formulaires pour les réutiliser"</string>
- <string name="pref_security_show_security_warning">"Avertiss. de sécurité"</string>
+ <string name="pref_security_save_form_data">"Mémoriser données formulaire"</string>
+ <string name="pref_security_save_form_data_summary">"Mémoriser les données saisies dans les formulaires pour les utiliser ultérieurement"</string>
+ <string name="pref_security_show_security_warning">"Avertissements de sécurité"</string>
<string name="pref_security_show_security_warning_summary">"Afficher un avertissement en cas de problème de sécurité d\'un site"</string>
<string name="pref_security_accept_cookies">"Accepter les cookies"</string>
<string name="pref_security_accept_cookies_summary">"Autoriser les sites à enregistrer et lire les données des cookies"</string>
@@ -236,22 +236,21 @@
<string name="download_length_required">"Téléchargement impossible. La taille de l\'élément n\'a pas pu être déterminée."</string>
<string name="download_precondition_failed">"Téléchargement interrompu. Impossible de reprendre le téléchargement."</string>
<string name="activity_instrumentation_test_runner">"Testeur de navigateur"</string>
- <string name="search_google">"Recherche Google"</string>
<string name="permlab_readHistoryBookmarks">"Lecture de l\'historique du navigateur et des favoris"</string>
<string name="permdesc_readHistoryBookmarks">"Permet à l\'application de lire toutes les URL visitées par le navigateur et tous les favoris."</string>
<string name="permlab_writeHistoryBookmarks">"Enregistrement de l\'historique du navigateur et des favoris"</string>
<string name="permdesc_writeHistoryBookmarks">"Permet à une application de modifier l\'historique du navigateur ou les favoris enregistrés sur votre téléphone. Des applications malveillantes peuvent utiliser cette fonction pour effacer ou modifier les données de votre navigateur."</string>
<string name="query_data_prompt">"Autoriser le stockage"</string>
<string name="query_data_message">"Ce site souhaite enregistrer des informations sur votre téléphone."</string>
- <string name="location_prompt">"Afficher ma position"</string>
+ <string name="location_prompt">"Afficher votre position"</string>
<string name="location_message">"Ce site souhaite afficher votre position."</string>
<string name="shortcut_prompt">"Créer un raccourci"</string>
- <string name="shortcut_message">"Le site souhaite créer un raccourci vers cette page sur votre écran d\'accueil."</string>
+ <string name="shortcut_message">"Le site souhaite créer un raccourci vers cette page sur votre page d\'accueil."</string>
<string name="settings_message">"Le tableau ci-dessous indique les fonctions que vous avez autorisées pour chaque site ayant tenté d\'utiliser Google Gears."</string>
<string name="filepicker_message">"Sélecteur de fichier"</string>
<string name="image_message">"Image sélectionnée"</string>
<string name="settings_title">"Paramètres Google Gears"</string>
- <string name="privacy_policy">"Lisez les règles de confidentialité du site pour savoir comment les informations sur votre localisation seront utilisées."</string>
+ <string name="privacy_policy">"Lisez les règles de confidentialité du site pour voir comment votre emplacement sera utilisé."</string>
<string name="settings_storage_title">"Autoriser le stockage local"</string>
<string name="settings_storage_subtitle_on">"Ce site peut enregistrer des informations sur votre téléphone."</string>
<string name="settings_storage_subtitle_off">"Ce site ne peut enregistrer aucune information sur votre téléphone."</string>
@@ -264,7 +263,7 @@
<string name="settings_confirmation_remove">"Toutes les autorisations seront effacées et toutes les données enregistrées par le site sur votre téléphone seront supprimées."</string>
<string name="storage_notification">"Ce site enregistrera des informations sur votre téléphone."\n" Modifiez ce paramètre dans :"\n" Paramètres -> Paramètres Gears."</string>
<string name="storage_notification_alwaysdeny">"Ce site n\'enregistrera jamais aucune information sur votre téléphone."\n" Modifiez ce paramètre dans :"\n" Paramètres -> Paramètres Gears."</string>
- <string name="location_notification">"Ce site peut afficher votre position actuelle. "\n" Modifiez ce paramètre dans :"\n" Paramètres -> Paramètres Gears."</string>
+ <string name="location_notification">"Ce site peut afficher votre emplacement actuel. "\n" Modifiez ce paramètre dans :"\n" Paramètres -> Paramètres Gears."</string>
<string name="location_notification_alwaysdeny">"Ce site n\'affichera pas votre position actuelle."\n" Modifiez ce paramètre dans :"\n" Paramètres -> Paramètres Gears."</string>
<string name="shortcut_notification">"Raccourci créé"</string>
<string name="permission_button_alwaysdeny">"Ne jamais autoriser"</string>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index b94a285..d441fba 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -145,7 +145,7 @@
<string name="pref_security_remember_passwords_summary">"Salva nomi utente e password per i siti web"</string>
<string name="pref_security_save_form_data">"Memorizza dati moduli"</string>
<string name="pref_security_save_form_data_summary">"Memorizza i dati che digito nei moduli per usi futuri"</string>
- <string name="pref_security_show_security_warning">"Mostra avvisi protezione"</string>
+ <string name="pref_security_show_security_warning">"Mostra avvisi di protezione"</string>
<string name="pref_security_show_security_warning_summary">"Mostra un avviso se esiste un problema di sicurezza con un sito"</string>
<string name="pref_security_accept_cookies">"Accetta cookie"</string>
<string name="pref_security_accept_cookies_summary">"Consenti ai siti di salvare e leggere i dati \"cookie\""</string>
@@ -236,7 +236,6 @@
<string name="download_length_required">"Impossibile effettuare il download. Impossibile determinare le dimensioni dell\'elemento."</string>
<string name="download_precondition_failed">"Download interrotto. Impossibile ripristinarlo."</string>
<string name="activity_instrumentation_test_runner">"Browser Test Runner"</string>
- <string name="search_google">"Cerca su Google"</string>
<string name="permlab_readHistoryBookmarks">"lettura cronologia e segnalibri del browser"</string>
<string name="permdesc_readHistoryBookmarks">"Consente all\'applicazione di leggere tutti gli URL visitati e tutti i segnalibri del browser."</string>
<string name="permlab_writeHistoryBookmarks">"creazione cronologia e segnalibri del browser"</string>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index f6e64b8..be64425 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -202,7 +202,7 @@
<string name="too_many_windows_dialog_title">"ウィンドウの数が最大です"</string>
<string name="too_many_windows_dialog_message">"既にウィンドウの数が最大なので、新しいウィンドウを開けません。"</string>
<string name="too_many_subwindows_dialog_title">"ポップアップが既に開いています"</string>
- <string name="too_many_subwindows_dialog_message">"一度に1つのポップアップウィンドウしか開けません。"</string>
+ <string name="too_many_subwindows_dialog_message">"一度に開けるポップアップウィンドウは1つだけなので、新しいポップアップウィンドウを開けませんでした。"</string>
<string name="download_title">"ダウンロード履歴"</string>
<string name="download_unknown_filename">"<不明>"</string>
<string name="download_menu_open">"開く"</string>
@@ -236,7 +236,6 @@
<string name="download_length_required">"項目のサイズを特定できないため、ダウンロードできません。"</string>
<string name="download_precondition_failed">"ダウンロードが中断されました。再開できません。"</string>
<string name="activity_instrumentation_test_runner">"Browser Test Runner"</string>
- <string name="search_google">"Google検索"</string>
<string name="permlab_readHistoryBookmarks">"ブラウザの履歴とブックマークの読み取り"</string>
<string name="permdesc_readHistoryBookmarks">"ブラウザでアクセスしたすべてのURLとブックマークの読み取りをアプリケーションに許可します。"</string>
<string name="permlab_writeHistoryBookmarks">"ブラウザの履歴とブックマークの書き込み"</string>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index 51a622a..60c1975 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -236,7 +236,6 @@
<string name="download_length_required">"항목의 크기를 확인할 수 없으므로 다운로드할 수 없습니다."</string>
<string name="download_precondition_failed">"다운로드 중단됨. 다시 시작할 수 없습니다."</string>
<string name="activity_instrumentation_test_runner">"브라우저 테스트 실행기"</string>
- <string name="search_google">"Google 검색"</string>
<string name="permlab_readHistoryBookmarks">"브라우저의 기록 및 북마크 읽기"</string>
<string name="permdesc_readHistoryBookmarks">"응용프로그램이 브라우저에서 방문한 모든 URL과 브라우저의 북마크를 모두 읽을 수 있습니다."</string>
<string name="permlab_writeHistoryBookmarks">"브라우저의 기록 및 북마크 쓰기"</string>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index d1a56fe..ad4fee2 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -27,12 +27,10 @@
<string name="action">"Logg inn"</string>
<string name="cancel">"Avbryt"</string>
<string name="ok">"OK"</string>
- <plurals name="matches_found">
- <item quantity="zero">"Ingen treff"</item>
- <item quantity="one">"Ett treff"</item>
- <item quantity="few">"<xliff:g id="NUMBER">%d</xliff:g> treff"</item>
- <item quantity="other">"<xliff:g id="NUMBER">%d</xliff:g> treff"</item>
- </plurals>
+ <!-- no translation found for matches_found:zero (6242659159545399963) -->
+ <!-- no translation found for matches_found:one (4352019729062956802) -->
+ <!-- no translation found for matches_found:few (5544267486978946555) -->
+ <!-- no translation found for matches_found:other (6616125067364315405) -->
<string name="page_info">"Sideinformasjon"</string>
<string name="page_info_view">"Vis sideinformasjon"</string>
<string name="page_info_address">"Adresse:"</string>
@@ -236,7 +234,6 @@
<string name="download_length_required">"Kan ikke laste ned. Klarte ikke bestemme størrelsen på filen."</string>
<string name="download_precondition_failed">"Nedlastingen ble avbrutt. Den kan ikke fortsettes."</string>
<string name="activity_instrumentation_test_runner">"Browser Test Runner"</string>
- <string name="search_google">"Søk på Google"</string>
<string name="permlab_readHistoryBookmarks">"read Browser\'s history and bookmarks"</string>
<string name="permdesc_readHistoryBookmarks">"Allows the application to read all the URLs that the Browser has visited, and all of the Browser\'s bookmarks."</string>
<string name="permlab_writeHistoryBookmarks">"write Browser\'s history and bookmarks"</string>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 87fb6f6..5904587 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -236,7 +236,6 @@
<string name="download_length_required">"Kan niet downloaden. De grootte van het item kan niet worden vastgesteld."</string>
<string name="download_precondition_failed">"Download is onderbroken. Deze kan niet worden voortgezet."</string>
<string name="activity_instrumentation_test_runner">"Browser Test Runner"</string>
- <string name="search_google">"Zoeken met Google"</string>
<string name="permlab_readHistoryBookmarks">"browsergeschiedenis en bladwijzers lezen"</string>
<string name="permdesc_readHistoryBookmarks">"Hiermee kan een toepassing de URL\'s lezen die u via de browser heeft bezocht, evenals alle bladwijzers van de browser."</string>
<string name="permlab_writeHistoryBookmarks">"browsergeschiedenis en bladwijzers schrijven"</string>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index f477763..9b8b29b 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -81,7 +81,7 @@
<string name="delete_bookmark_warning">"Zakładka „<xliff:g id="BOOKMARK">%s</xliff:g>” zostanie usunięta."</string>
<string name="open_in_new_window">"Otwórz w nowym oknie"</string>
<string name="new_window">"Nowe okno"</string>
- <string name="goto_dot">"Przejdź"</string>
+ <string name="goto_dot">"Idź"</string>
<string name="find_dot">"Znajdź na stronie"</string>
<string name="select_dot">"Zaznacz tekst"</string>
<string name="view_tabs">"Przegląd okien"</string>
@@ -108,7 +108,7 @@
<string name="contextmenu_view_image">"Wyświetl obraz"</string>
<string name="contextmenu_dial_dot">"Wybierz numer…"</string>
<string name="contextmenu_add_contact">"Dodaj kontakt"</string>
- <string name="contextmenu_send_mail">"Wyślij e-mail"</string>
+ <string name="contextmenu_send_mail">"Wyślij wiadomość e-mail"</string>
<string name="contextmenu_map">"Mapa"</string>
<string name="clear">"Wyczyść"</string>
<string name="replace">"Zastąp adres"</string>
@@ -128,7 +128,7 @@
<string name="pref_privacy_clear_cache">"Wyczyść pamięć podręczną"</string>
<string name="pref_privacy_clear_cache_summary">"Usuń całą zawartość stron z pamięci podręcznej"</string>
<string name="pref_privacy_clear_cache_dlg">"Pamięć podręczna zostanie wyczyszczona."</string>
- <string name="pref_privacy_clear_cookies">"Wyczyść wszystkie pliki cookie"</string>
+ <string name="pref_privacy_clear_cookies">"Wyczyść wszystkie cookies"</string>
<string name="pref_privacy_clear_cookies_summary">"Wyczyść pliki cookie przeglądarki"</string>
<string name="pref_privacy_clear_cookies_dlg">"Wszystkie pliki cookie zostaną usunięte."</string>
<string name="pref_privacy_clear_history">"Wyczyść historię"</string>
@@ -141,14 +141,14 @@
<string name="pref_privacy_clear_passwords_summary">"Wyczyść wszystkie zapamiętane hasła"</string>
<string name="pref_privacy_clear_passwords_dlg">"Wszystkie zapamiętane hasła zostaną wyczyszczone."</string>
<string name="pref_security_title">"Ustawienia zabezpieczeń"</string>
- <string name="pref_security_remember_passwords">"Pamiętaj hasła"</string>
+ <string name="pref_security_remember_passwords">"Zapamiętuj hasła"</string>
<string name="pref_security_remember_passwords_summary">"Zapamiętuj nazwy użytkownika i hasła do stron WWW"</string>
- <string name="pref_security_save_form_data">"Pamiętaj wpisane dane"</string>
+ <string name="pref_security_save_form_data">"Zapamiętuj wpisane dane"</string>
<string name="pref_security_save_form_data_summary">"Zapamiętuj do późniejszego użycia dane, które wpisuję w formularzach"</string>
<string name="pref_security_show_security_warning">"Wyświetlaj ostrzeżenia"</string>
<string name="pref_security_show_security_warning_summary">"Wyświetl ostrzeżenie w razie problemów z zabezpieczeniami strony"</string>
<string name="pref_security_accept_cookies">"Akceptuj pliki cookie"</string>
- <string name="pref_security_accept_cookies_summary">"Zezwalaj witrynom na zapis i odczyt danych w plikach cookie"</string>
+ <string name="pref_security_accept_cookies_summary">"Zezwalaj witrynom na zapis i odczyt danych plików „cookie”."</string>
<string name="pref_text_size">"Ustaw rozmiar tekstu"</string>
<string-array name="pref_text_size_choices">
<item>"Bardzo mały"</item>
@@ -159,9 +159,9 @@
</string-array>
<string name="pref_text_size_dialogtitle">"Rozmiar tekstu"</string>
<string name="pref_extras_title">"Ustawienia zaawansowane"</string>
- <string name="pref_extras_gears_enable">"Włącz dodatek Gears"</string>
+ <string name="pref_extras_gears_enable">"Włącz technologię Gears"</string>
<string name="pref_extras_gears_enable_summary">"Aplikacje rozszerzające zakres funkcji przeglądarki"</string>
- <string name="pref_extras_gears_settings">"Ustawienia dodatku Gears"</string>
+ <string name="pref_extras_gears_settings">"Gears – ustawienia"</string>
<string name="pref_plugin_installed">"Lista dodatków plug-in"</string>
<string name="pref_plugin_installed_empty_list">"Brak zainstalowanych dodatków plug-in."</string>
<string name="pref_extras_gears_settings_summary">"Aplikacje rozszerzające zakres funkcji przeglądarki"</string>
@@ -236,7 +236,6 @@
<string name="download_length_required">"Pobieranie niemożliwe. Nie można ustalić rozmiaru elementu."</string>
<string name="download_precondition_failed">"Pobieranie zostało przerwane. Nie można go wznowić."</string>
<string name="activity_instrumentation_test_runner">"Uruchamianie testów przeglądarki"</string>
- <string name="search_google">"Szukanie Google"</string>
<string name="permlab_readHistoryBookmarks">"odczytywanie historii i zakładek przeglądarki"</string>
<string name="permdesc_readHistoryBookmarks">"Zezwala aplikacji na odczytanie wszystkich adresów URL odwiedzonych przy użyciu przeglądarki oraz wszystkich zakładek przeglądarki."</string>
<string name="permlab_writeHistoryBookmarks">"zapisać historię i zakładki przeglądarki"</string>
@@ -247,10 +246,10 @@
<string name="location_message">"Ta witryna internetowa chce uzyskać dostęp do informacji o Twojej lokalizacji."</string>
<string name="shortcut_prompt">"Utwórz skrót"</string>
<string name="shortcut_message">"Ta witryna internetowa chce utworzyć skrót do tej strony na Twoim ekranie głównym."</string>
- <string name="settings_message">"W poniższej tabeli przedstawiono uprawnienia udzielone każdej z witryn próbujących użyć dodatku Gears."</string>
+ <string name="settings_message">"W poniższej tabeli przedstawiono uprawnienia udzielone każdej z witryn próbujących użyć Gears."</string>
<string name="filepicker_message">"Wybór plików"</string>
<string name="image_message">"Wybrany obraz"</string>
- <string name="settings_title">"Ustawienia dodatku Gears"</string>
+ <string name="settings_title">"Gears – ustawienia"</string>
<string name="privacy_policy">"Przeczytaj zasady zachowania poufności informacji witryny, aby dowiedzieć się, jak będą użyte informacje o twojej lokalizacji."</string>
<string name="settings_storage_title">"Zezwól na zapis lokalnie"</string>
<string name="settings_storage_subtitle_on">"Ta witryna może zapisać informacje w telefonie"</string>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
new file mode 100644
index 0000000..0522b74
--- /dev/null
+++ b/res/values-pt/strings.xml
@@ -0,0 +1,333 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- no translation found for application_name (1935869255545976415) -->
+ <skip />
+ <!-- no translation found for tab_bookmarks (2305793036003473653) -->
+ <skip />
+ <!-- no translation found for tab_most_visited (1077402532455000703) -->
+ <skip />
+ <!-- no translation found for tab_history (1979267558744613746) -->
+ <skip />
+ <!-- no translation found for added_to_bookmarks (1020224130695956728) -->
+ <skip />
+ <!-- no translation found for removed_from_bookmarks (6063705902028438800) -->
+ <skip />
+ <string name="sign_in_to">"Fazer login em <xliff:g id="HOSTNAME">%s1</xliff:g> \"<xliff:g id="REALM">%s2</xliff:g>\""</string>
+ <string name="username">"Nome"</string>
+ <string name="password">"Senha"</string>
+ <string name="action">"Fazer login"</string>
+ <!-- no translation found for bookmarks_search (5229596268214362873) -->
+ <skip />
+ <string name="cancel">"Cancelar"</string>
+ <string name="ok">"OK"</string>
+ <!-- no translation found for matches_found:zero (6242659159545399963) -->
+ <!-- no translation found for matches_found:one (4352019729062956802) -->
+ <!-- no translation found for matches_found:few (5544267486978946555) -->
+ <!-- no translation found for matches_found:other (6616125067364315405) -->
+ <string name="page_info">"Informações da página"</string>
+ <string name="page_info_view">"Visualizar informações da página"</string>
+ <string name="page_info_address">"Endereço:"</string>
+ <string name="ssl_warnings_header">"Existem problemas no certificado de segurança deste site."</string>
+ <string name="ssl_continue">"Continuar"</string>
+ <string name="security_warning">"Aviso de segurança"</string>
+ <string name="view_certificate">"Visualizar certificado"</string>
+ <string name="ssl_untrusted">"Este certificado não é de uma autoridade confiável."</string>
+ <string name="ssl_mismatch">"O nome do site não coincide com o nome do certificado."</string>
+ <string name="ssl_expired">"Este certificado expirou."</string>
+ <string name="ssl_not_yet_valid">"Este certificado ainda não é válido."</string>
+ <string name="ssl_certificate">"Certificado de segurança"</string>
+ <string name="ssl_certificate_is_valid">"Este certificado é válido."</string>
+ <string name="issued_to">"Emitido para:"</string>
+ <string name="common_name">"Nome comum:"</string>
+ <string name="org_name">"Organização:"</string>
+ <string name="org_unit">"Unidade organizacional:"</string>
+ <string name="issued_by">"Emitido por:"</string>
+ <string name="validity_period">"Validade:"</string>
+ <string name="issued_on">"Emitido em:"</string>
+ <string name="expires_on">"Expira em:"</string>
+ <string name="retrieving_creds_dlg_msg">"Recuperando detalhes de login..."</string>
+ <string name="stopping">"Parando..."</string>
+ <string name="stop">"Parar"</string>
+ <string name="reload">"Atualizar"</string>
+ <string name="forward">"Encaminhar"</string>
+ <string name="save">"OK"</string>
+ <string name="do_not_save">"Cancelar"</string>
+ <string name="location">"Local"</string>
+ <string name="name">"Nome"</string>
+ <string name="http">"http://"</string>
+ <string name="save_to_bookmarks">"Favorito"</string>
+ <string name="edit_bookmark">"Editar favorito"</string>
+ <string name="create_shortcut_bookmark">"Adicionar atalho à página inicial"</string>
+ <string name="open_bookmark">"Abrir"</string>
+ <string name="remove_bookmark">"Excluir favorito"</string>
+ <string name="remove_history_item">"Remover do histórico"</string>
+ <string name="bookmark_saved">"Salvo nos favoritos."</string>
+ <string name="bookmark_needs_title">"O favorito deve ter um nome."</string>
+ <string name="bookmark_needs_url">"O favorito deve ter um local."</string>
+ <string name="empty_bookmark">"Não é possível criar um favorito vazio."</string>
+ <string name="bookmark_url_not_valid">"O URL não é válido."</string>
+ <string name="delete_bookmark">"Excluir"</string>
+ <string name="bookmark_page">"Página do último favorito visualizado"</string>
+ <!-- no translation found for current_page (7510129573681663135) -->
+ <skip />
+ <string name="delete_bookmark_warning">"O favorito \"<xliff:g id="BOOKMARK">%s</xliff:g>\" será excluído."</string>
+ <string name="open_in_new_window">"Abrir em nova janela"</string>
+ <string name="new_window">"Nova janela"</string>
+ <!-- no translation found for goto_dot (3895839050522602723) -->
+ <skip />
+ <string name="find_dot">"Localizar na página"</string>
+ <!-- no translation found for select_dot (6299170761900561967) -->
+ <skip />
+ <string name="view_tabs">"Visão geral da janela"</string>
+ <string name="view_tabs_condensed">"Janelas"</string>
+ <string name="tab_picker_title">"Janelas atuais"</string>
+ <string name="tab_picker_view_tab">"Visualizar"</string>
+ <string name="tab_picker_new_tab">"Nova janela"</string>
+ <string name="tab_picker_remove_tab">"Fechar"</string>
+ <string name="tab_picker_bookmark">"Favorito"</string>
+ <string name="tab_picker_send_url">"Compartilhar link"</string>
+ <string name="bookmarks">"Favoritos"</string>
+ <string name="shortcut_bookmark">"Favorito"</string>
+ <string name="history">"Histórico"</string>
+ <string name="menu_view_download">"Downloads"</string>
+ <string name="share_page">"Compartilhar página"</string>
+ <string name="contextmenu_openlink">"Abrir"</string>
+ <string name="contextmenu_openlink_newwindow">"Abrir em nova janela"</string>
+ <string name="contextmenu_bookmark_thislink">"Link do favorito"</string>
+ <string name="contextmenu_savelink">"Salvar link"</string>
+ <string name="contextmenu_sharelink">"Compartilhar link"</string>
+ <string name="contextmenu_copy">"Copiar"</string>
+ <string name="contextmenu_copylink">"Copiar URL do link"</string>
+ <string name="contextmenu_download_image">"Salvar imagem"</string>
+ <string name="contextmenu_view_image">"Visualizar imagem"</string>
+ <string name="contextmenu_dial_dot">"Discar..."</string>
+ <string name="contextmenu_add_contact">"Adicionar contato"</string>
+ <string name="contextmenu_send_mail">"Enviar e-mail"</string>
+ <string name="contextmenu_map">"Mapa"</string>
+ <string name="clear">"Limpar"</string>
+ <string name="replace">"Substituir"</string>
+ <string name="browser_bookmarks_page_bookmarks_text">"Favoritos"</string>
+ <string name="menu_preferences">"Configurações"</string>
+ <string name="pref_content_title">"Configurações do conteúdo da página"</string>
+ <string name="pref_content_load_images">"Carregar imagens"</string>
+ <string name="pref_content_load_images_summary">"Exibir imagens nas páginas da web"</string>
+ <string name="pref_content_block_popups">"Bloquear janelas pop-up"</string>
+ <string name="pref_content_javascript">"Ativar JavaScript"</string>
+ <string name="pref_content_open_in_background">"Abrir em segundo plano"</string>
+ <string name="pref_content_open_in_background_summary">"As novas janelas são abertas atrás da atual"</string>
+ <string name="pref_content_homepage">"Definir página inicial"</string>
+ <string name="pref_content_autofit">"Ajustar páginas automaticamente"</string>
+ <string name="pref_content_autofit_summary">"Formatar páginas da web para ajustá-las à tela"</string>
+ <string name="pref_privacy_title">"Configurações de privacidade"</string>
+ <string name="pref_privacy_clear_cache">"Limpar cache"</string>
+ <string name="pref_privacy_clear_cache_summary">"Excluir todo o conteúdo da página em cache"</string>
+ <string name="pref_privacy_clear_cache_dlg">"O cache será limpo."</string>
+ <string name="pref_privacy_clear_cookies">"Apagar todos os dados de cookies"</string>
+ <string name="pref_privacy_clear_cookies_summary">"Apagar todos os cookies do navegador"</string>
+ <string name="pref_privacy_clear_cookies_dlg">"Todos os cookies serão apagados."</string>
+ <string name="pref_privacy_clear_history">"Limpar histórico"</string>
+ <string name="pref_privacy_clear_history_summary">"Apagar o histórico de navegação do navegador"</string>
+ <string name="pref_privacy_clear_history_dlg">"O histórico de navegação do navegador será apagado."</string>
+ <string name="pref_privacy_clear_form_data">"Apagar dados de formulário"</string>
+ <string name="pref_privacy_clear_form_data_summary">"Apagar todos os dados de formulário salvos"</string>
+ <string name="pref_privacy_clear_form_data_dlg">"Todos os dados de formulário salvos serão apagados."</string>
+ <string name="pref_privacy_clear_passwords">"Apagar senhas"</string>
+ <string name="pref_privacy_clear_passwords_summary">"Apagar todas as senhas salvas"</string>
+ <string name="pref_privacy_clear_passwords_dlg">"Todas as senhas salvas serão apagadas."</string>
+ <string name="pref_security_title">"Configurações de segurança"</string>
+ <string name="pref_security_remember_passwords">"Lembrar senhas"</string>
+ <string name="pref_security_remember_passwords_summary">"Salvar nomes de usuário e senhas de sites"</string>
+ <string name="pref_security_save_form_data">"Lembrar dados de formulário"</string>
+ <string name="pref_security_save_form_data_summary">"Lembrar dados digitados para uso futuro"</string>
+ <string name="pref_security_show_security_warning">"Mostrar avisos de segurança"</string>
+ <string name="pref_security_show_security_warning_summary">"Mostrar aviso se houver um problema com a segurança de um site"</string>
+ <string name="pref_security_accept_cookies">"Aceitar cookies"</string>
+ <string name="pref_security_accept_cookies_summary">"Permitir que os sites salvem e leiam dados de \"cookie\""</string>
+ <string name="pref_text_size">"Definir tamanho do texto"</string>
+ <string-array name="pref_text_size_choices">
+ <item>"Bem pequeno"</item>
+ <item>"Pequeno"</item>
+ <item>"Normal"</item>
+ <item>"Grande"</item>
+ <item>"Grande"</item>
+ </string-array>
+ <string name="pref_text_size_dialogtitle">"Tamanho do texto"</string>
+ <string name="pref_extras_title">"Configurações avançadas"</string>
+ <string name="pref_extras_gears_enable">"Ativar Google Gears"</string>
+ <string name="pref_extras_gears_enable_summary">"Aplicativos que ampliam a funcionalidade do navegador"</string>
+ <string name="pref_extras_gears_settings">"Configurações do Google Gears"</string>
+ <string name="pref_plugin_installed">"Lista de plug-ins"</string>
+ <string name="pref_plugin_installed_empty_list">"Nenhum plug-in instalado."</string>
+ <string name="pref_extras_gears_settings_summary">"Aplicativos que ampliam a funcionalidade do navegador"</string>
+ <string name="pref_extras_reset_default">"Voltar aos valores padrão"</string>
+ <string name="pref_extras_reset_default_summary">"Apagar todos os dados do navegador e redefinir todas as configurações para os valores padrão"</string>
+ <string name="pref_extras_reset_default_dlg">"Todos os dados do navegador serão apagados e as configurações voltarão aos valores padrão."</string>
+ <string name="pref_extras_reset_default_dlg_title">"Voltar aos valores padrão"</string>
+ <string name="pref_development_title">"Depurar"</string>
+ <string name="pref_default_text_encoding">"Definir codificação do texto"</string>
+ <string-array name="pref_default_text_encoding_choices">
+ <item>"Latim-1 (ISO-8859-1)"</item>
+ <item>"Unicode (UTF-8)"</item>
+ <item>"Japonês (ISO-2022-JP)"</item>
+ <item>"Japonês (SHIFT_JIS)"</item>
+ <item>"Japonês (EUC-JP)"</item>
+ </string-array>
+ <string name="pref_default_text_encoding_dialogtitle">"Codificação do texto"</string>
+ <string name="pref_default_text_encoding_default">"Latim-1"</string>
+ <string name="browserFrameRedirect">"Redirecionar"</string>
+ <string name="browserFrame307Post">"de formulário Esta página da web está sendo redirecionada. Deseja reenviar os dados de formulário digitados para o novo local?"</string>
+ <string name="browserFrameNetworkErrorLabel">"Problema de conectividade dos dados"</string>
+ <string name="browserFrameFileErrorLabel">"Problema com arquivo"</string>
+ <string name="browserFrameFormResubmitLabel">"Confirmar"</string>
+ <string name="browserFrameFormResubmitMessage">"A página que você está tentando visualizar contém dados que já foram enviados (\"POSTDATA\"). Se os dados forem reenviados, qualquer ação realizada na página (como uma pesquisa ou compra on-line) será repetida."</string>
+ <string name="loadSuspendedTitle">"Sem conexão de rede"</string>
+ <string name="loadSuspended">"A página continuará sendo carregada assim que a conexão for restaurada."</string>
+ <string name="clear_history">"Limpar histórico"</string>
+ <string name="browser_history">"Páginas visitadas recentemente"</string>
+ <string name="empty_history">"O histórico do navegador está vazio."</string>
+ <!-- no translation found for add_new_bookmark (8086367791400349049) -->
+ <skip />
+ <string name="no_database">"Nenhum banco de dados."</string>
+ <string name="search_hint">"Digite o endereço da web"</string>
+ <string name="search_button_text">"Ir"</string>
+ <string name="attention">"Atenção"</string>
+ <string name="popup_window_attempt">"Este site está tentando abrir uma janela pop-up."</string>
+ <string name="allow">"Permitir"</string>
+ <string name="block">"Bloquear"</string>
+ <string name="too_many_windows_dialog_title">"Limite da janela atingido"</string>
+ <string name="too_many_windows_dialog_message">"Não foi possível abrir uma nova janela porque você já abriu o número máximo permitido."</string>
+ <string name="too_many_subwindows_dialog_title">"Pop-up já aberto"</string>
+ <string name="too_many_subwindows_dialog_message">"Não foi possível abrir uma nova janela pop-up porque apenas uma pode ser aberta por vez."</string>
+ <string name="download_title">"Histórico de downloads"</string>
+ <string name="download_unknown_filename">"<Desconhecido>"</string>
+ <string name="download_menu_open">"Abrir"</string>
+ <string name="download_menu_clear">"Apagar da lista"</string>
+ <string name="download_menu_cancel">"Cancelar download"</string>
+ <string name="download_menu_cancel_all">"Cancelar todos os dowloads"</string>
+ <string name="download_menu_clear_all">"Limpar lista"</string>
+ <string name="download_clear_dlg_title">"Limpar"</string>
+ <string name="download_clear_dlg_msg">"Todos os itens serão apagados da lista e removidos do cache do navegador."</string>
+ <string name="download_cancel_dlg_title">"Cancelar dowloads"</string>
+ <string name="download_cancel_dlg_msg">"Todos os <xliff:g id="DOWNLOAD_COUNT">%d</xliff:g> downloads serão cancelados e apagados do histórico de downloads."</string>
+ <string name="download_file_error_dlg_title">"Sem espaço"</string>
+ <string name="download_file_error_dlg_msg">"Não foi possível fazer o download de <xliff:g id="FILENAME">%s</xliff:g>."\n"Libere algum espaço no telefone e tente novamente."</string>
+ <string name="download_failed_generic_dlg_title">"Falha de download"</string>
+ <string name="download_no_sdcard_dlg_title">"Sem cartão SD"</string>
+ <string name="download_no_sdcard_dlg_msg">"Para fazer download de <xliff:g id="FILENAME">%s</xliff:g>, é necessário um cartão SD."</string>
+ <string name="download_sdcard_busy_dlg_title">"O cartão SD não está disponível"</string>
+ <!-- no translation found for download_sdcard_busy_dlg_msg (3473883538192835204) -->
+ <skip />
+ <string name="download_no_application">"Não foi possível encontrar nenhum aplicativo para abrir este arquivo."</string>
+ <string name="retry">"Tentar novamente"</string>
+ <string name="no_downloads">"O histórico de downloads está vazio."</string>
+ <string name="download_error">"Falha de download."</string>
+ <string name="download_success">"<xliff:g id="FILE">%s</xliff:g> Download concluído."</string>
+ <string name="download_running">"Fazendo download..."</string>
+ <string name="download_pending">"Iniciando download..."</string>
+ <string name="download_pending_network">"Aguardando conexão dos dados..."</string>
+ <string name="download_running_paused">"Aguardando conexão dos dados..."</string>
+ <string name="download_canceled">"Download cancelado."</string>
+ <string name="download_not_acceptable">"Não é possível fazer download. O conteúdo não é compatível com o telefone."</string>
+ <string name="download_file_error">"Não é possível finalizar o download. Não há espaço suficiente."</string>
+ <string name="download_length_required">"Não é possível fazer download. O tamanho do item não pode ser determinado."</string>
+ <string name="download_precondition_failed">"Download interrompido. Não é possível restaurá-lo."</string>
+ <string name="activity_instrumentation_test_runner">"Executor de testes de navegador"</string>
+ <!-- no translation found for homepage_base (7888126987935305566) -->
+ <skip />
+ <!-- no translation found for search_the_web (6046130189241962337) -->
+ <skip />
+ <string name="permlab_readHistoryBookmarks">"ler histórico e favoritos do navegador"</string>
+ <string name="permdesc_readHistoryBookmarks">"Permite que o aplicativo leia todos os URLs visitados pelo navegador, bem como todos os seus favoritos."</string>
+ <string name="permlab_writeHistoryBookmarks">"gravar histórico e favoritos do navegador"</string>
+ <string name="permdesc_writeHistoryBookmarks">"Permite que um aplicativo modifique o histórico ou os favoritos do navegador armazenados no seu telefone. Aplicativos maliciosos podem usar isso para apagar ou modificar os dados do navegador."</string>
+ <!-- no translation found for query_data_prompt (5474381240981604223) -->
+ <skip />
+ <!-- no translation found for query_data_message (8789381063185445197) -->
+ <skip />
+ <!-- no translation found for location_prompt (226262202057302423) -->
+ <skip />
+ <!-- no translation found for location_message (1729456751935683242) -->
+ <skip />
+ <!-- no translation found for shortcut_prompt (437193299088893596) -->
+ <skip />
+ <!-- no translation found for shortcut_message (4793042709293755892) -->
+ <skip />
+ <string name="settings_message">"A tabela a seguir mostra as permissões que você concedeu a cada site que realizou uma tentativa de utilizar o Google Gears."</string>
+ <!-- no translation found for filepicker_message (4929726371602896039) -->
+ <skip />
+ <!-- no translation found for image_message (5450245866521896891) -->
+ <skip />
+ <string name="settings_title">"Configurações do Google Gears"</string>
+ <string name="privacy_policy">"Leia a política de privacidade do site para saber como sua localização será utilizada."</string>
+ <!-- no translation found for settings_storage_title (7089119630457156408) -->
+ <skip />
+ <!-- no translation found for settings_storage_subtitle_on (2733295483569432111) -->
+ <skip />
+ <!-- no translation found for settings_storage_subtitle_off (1338039396087898813) -->
+ <skip />
+ <!-- no translation found for settings_location_title (4953062923509886651) -->
+ <skip />
+ <!-- no translation found for settings_location_subtitle_on (1496219621849158879) -->
+ <skip />
+ <!-- no translation found for settings_location_subtitle_off (5216466051810596189) -->
+ <skip />
+ <!-- no translation found for settings_remove_site (1822247070226589958) -->
+ <skip />
+ <!-- no translation found for settings_empty (2008952224378583146) -->
+ <skip />
+ <!-- no translation found for settings_confirmation_remove_title (5360857296753219635) -->
+ <skip />
+ <!-- no translation found for settings_confirmation_remove (585560170733446898) -->
+ <skip />
+ <!-- no translation found for storage_notification (6534213782873968255) -->
+ <skip />
+ <!-- no translation found for storage_notification_alwaysdeny (5473208033665783513) -->
+ <skip />
+ <!-- no translation found for location_notification (3495804750470905804) -->
+ <skip />
+ <!-- no translation found for location_notification_alwaysdeny (6184925953783312629) -->
+ <skip />
+ <!-- no translation found for shortcut_notification (1659700220868444568) -->
+ <skip />
+ <!-- no translation found for permission_button_alwaysdeny (3837055994905214848) -->
+ <skip />
+ <!-- no translation found for permission_button_allow (7301874925704148242) -->
+ <skip />
+ <!-- no translation found for permission_button_deny (104712269725153018) -->
+ <skip />
+ <!-- no translation found for shortcut_button_alwaysdeny (4172277731325126605) -->
+ <skip />
+ <string name="shortcut_button_allow">"OK"</string>
+ <string name="shortcut_button_deny">"Cancelar"</string>
+ <string name="settings_button_allow">"Aplicar"</string>
+ <string name="settings_button_deny">"Cancelar"</string>
+ <string name="filepicker_button_allow">"OK"</string>
+ <string name="filepicker_button_deny">"Cancelar"</string>
+ <string name="filepicker_path">"caminho:"</string>
+ <string name="filepicker_no_files_selected">"Nenhum arquivo selecionado"</string>
+ <string name="filepicker_one_file_selected">"Um arquivo selecionado"</string>
+ <string name="filepicker_some_files_selected">"arquivos selecionados"</string>
+ <string name="remove">"Remover"</string>
+ <string name="local_storage">"Armazenamento local"</string>
+ <string name="allowed">"Permitido"</string>
+ <string name="denied">"Rejeitado"</string>
+ <string name="unrecognized_dialog_message">"Tipo de caixa de diálogo desconhecido"</string>
+ <string name="default_button">"OK"</string>
+ <!-- no translation found for zoom_overview_button_text (4146579940085488881) -->
+ <skip />
+</resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 71dbefa..b4aa71b 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -236,7 +236,6 @@
<string name="download_length_required">"Загрузка невозможна. Не удается определить размер элемента."</string>
<string name="download_precondition_failed">"Загрузка прервана и не может быть продолжена."</string>
<string name="activity_instrumentation_test_runner">"Проверка браузера"</string>
- <string name="search_google">"Поиск в Google"</string>
<string name="permlab_readHistoryBookmarks">"считывать историю и закладки браузера"</string>
<string name="permdesc_readHistoryBookmarks">"Позволяет приложению считывать все URL, открытые через браузер, и все закладки браузера."</string>
<string name="permlab_writeHistoryBookmarks">"записывать историю и закладки браузера"</string>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index d0368bb..2928301 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -15,6 +15,10 @@
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Do not translate. This string is an internal URI, not seen in the UI. -->
+ <string name="google_search_base" translatable="false">
+ http://www.google.cn/m?hl=%1$s&gl=%2$s&</string>
+
<string name="application_name">"浏览器"</string>
<string name="tab_bookmarks">"书签"</string>
<string name="tab_most_visited">"访问最多的网站"</string>
@@ -234,7 +238,6 @@
<string name="download_length_required">"无法下载。无法确定该项的大小。"</string>
<string name="download_precondition_failed">"下载中断,无法重新开始。"</string>
<string name="activity_instrumentation_test_runner">"浏览器测试运行器"</string>
- <string name="search_google">"使用 Google 进行搜索"</string>
<string name="permlab_readHistoryBookmarks">"读取浏览器的历史记录和书签"</string>
<string name="permdesc_readHistoryBookmarks">"允许应用程序读取浏览器访问过的所有网址以及浏览器的所有书签。"</string>
<string name="permlab_writeHistoryBookmarks">"写入浏览器的历史记录和书签"</string>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index fd9e65c..b1729d2 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -18,7 +18,7 @@
<string name="application_name">"瀏覽器"</string>
<string name="tab_bookmarks">"書籤"</string>
<string name="tab_most_visited">"常用網頁"</string>
- <string name="tab_history">"紀錄"</string>
+ <string name="tab_history">"記錄"</string>
<string name="added_to_bookmarks">"已加入書籤"</string>
<string name="removed_from_bookmarks">"已自書籤中移除"</string>
<string name="sign_in_to">"登入到 <xliff:g id="HOSTNAME">%s1</xliff:g>「<xliff:g id="REALM">%s2</xliff:g>」"</string>
@@ -27,10 +27,12 @@
<string name="action">"登入"</string>
<string name="cancel">"取消"</string>
<string name="ok">"確定"</string>
- <!-- no translation found for matches_found:zero (6242659159545399963) -->
- <!-- no translation found for matches_found:one (4352019729062956802) -->
- <!-- no translation found for matches_found:few (5544267486978946555) -->
- <!-- no translation found for matches_found:other (6616125067364315405) -->
+ <plurals name="matches_found">
+ <item quantity="zero">"沒有相配項"</item>
+ <item quantity="one">"1 個相配項"</item>
+ <item quantity="few">"<xliff:g id="NUMBER">%d</xliff:g> 個相配項"</item>
+ <item quantity="other">"<xliff:g id="NUMBER">%d</xliff:g> 個相配項"</item>
+ </plurals>
<string name="page_info">"頁面資訊"</string>
<string name="page_info_view">"檢視頁面資訊"</string>
<string name="page_info_address">"位址:"</string>
@@ -67,16 +69,16 @@
<string name="create_shortcut_bookmark">"新增捷徑至首頁"</string>
<string name="open_bookmark">"開啟"</string>
<string name="remove_bookmark">"刪除書籤"</string>
- <string name="remove_history_item">"從紀錄中移除"</string>
- <string name="bookmark_saved">"儲存至書籤。"</string>
- <string name="bookmark_needs_title">"請輸入書籤名字。"</string>
+ <string name="remove_history_item">"從記錄中移除"</string>
+ <string name="bookmark_saved">"已儲存至書籤。"</string>
+ <string name="bookmark_needs_title">"請輸入書籤名稱。"</string>
<string name="bookmark_needs_url">"請選取書籤位置。"</string>
<string name="empty_bookmark">"無法建立空白書籤。"</string>
<string name="bookmark_url_not_valid">"網址無效。"</string>
<string name="delete_bookmark">"刪除"</string>
- <string name="bookmark_page">"最後瀏覽的書籤頁面"</string>
+ <string name="bookmark_page">"將最後瀏覽的網頁加入書籤"</string>
<string name="current_page">"來源 "</string>
- <string name="delete_bookmark_warning">"<xliff:g id="BOOKMARK">%s</xliff:g>"</string>
+ <string name="delete_bookmark_warning">"刪除「<xliff:g id="BOOKMARK">%s</xliff:g>」書籤?"</string>
<string name="open_in_new_window">"在新視窗開啟"</string>
<string name="new_window">"新視窗"</string>
<string name="goto_dot">"前往"</string>
@@ -88,16 +90,16 @@
<string name="tab_picker_view_tab">"檢視"</string>
<string name="tab_picker_new_tab">"新視窗"</string>
<string name="tab_picker_remove_tab">"關閉"</string>
- <string name="tab_picker_bookmark">"書籤"</string>
+ <string name="tab_picker_bookmark">"加入書籤"</string>
<string name="tab_picker_send_url">"分享連結"</string>
<string name="bookmarks">"書籤"</string>
<string name="shortcut_bookmark">"書籤"</string>
- <string name="history">"紀錄"</string>
+ <string name="history">"記錄"</string>
<string name="menu_view_download">"下載"</string>
<string name="share_page">"分享網頁"</string>
<string name="contextmenu_openlink">"開啟"</string>
<string name="contextmenu_openlink_newwindow">"在新視窗開啟"</string>
- <string name="contextmenu_bookmark_thislink">"書籤連結"</string>
+ <string name="contextmenu_bookmark_thislink">"將連結加入書籤"</string>
<string name="contextmenu_savelink">"儲存連結"</string>
<string name="contextmenu_sharelink">"分享連結"</string>
<string name="contextmenu_copy">"複製"</string>
@@ -105,7 +107,7 @@
<string name="contextmenu_download_image">"儲存圖片"</string>
<string name="contextmenu_view_image">"檢視圖片"</string>
<string name="contextmenu_dial_dot">"撥打…"</string>
- <string name="contextmenu_add_contact">"新增連絡人"</string>
+ <string name="contextmenu_add_contact">"新增聯絡人"</string>
<string name="contextmenu_send_mail">"傳送電子郵件"</string>
<string name="contextmenu_map">"地圖"</string>
<string name="clear">"清除"</string>
@@ -114,14 +116,14 @@
<string name="menu_preferences">"設定"</string>
<string name="pref_content_title">"頁面內容設定"</string>
<string name="pref_content_load_images">"載入圖片"</string>
- <string name="pref_content_load_images_summary">"在網頁上顯示圖片"</string>
- <string name="pref_content_block_popups">"阻擋快顯視窗"</string>
+ <string name="pref_content_load_images_summary">"顯示網頁上的圖片"</string>
+ <string name="pref_content_block_popups">"封鎖快顯視窗"</string>
<string name="pref_content_javascript">"啟用 JavaScript"</string>
- <string name="pref_content_open_in_background">"在背景開啟"</string>
- <string name="pref_content_open_in_background_summary">"新分頁開在目前頁面後面"</string>
+ <string name="pref_content_open_in_background">"在背景中開啟"</string>
+ <string name="pref_content_open_in_background_summary">"在目前頁面後面開啟新分頁"</string>
<string name="pref_content_homepage">"設定首頁"</string>
<string name="pref_content_autofit">"自動調整頁面"</string>
- <string name="pref_content_autofit_summary">"將網頁調整至適合螢幕大小"</string>
+ <string name="pref_content_autofit_summary">"將網頁調整至適合螢幕的大小"</string>
<string name="pref_privacy_title">"隱私設定"</string>
<string name="pref_privacy_clear_cache">"清除快取"</string>
<string name="pref_privacy_clear_cache_summary">"刪除所有快取頁面內容"</string>
@@ -129,19 +131,19 @@
<string name="pref_privacy_clear_cookies">"清除所有 cookie"</string>
<string name="pref_privacy_clear_cookies_summary">"清除所有 cookie"</string>
<string name="pref_privacy_clear_cookies_dlg">"所有 cookie 會被清除。"</string>
- <string name="pref_privacy_clear_history">"清除紀錄"</string>
+ <string name="pref_privacy_clear_history">"清除記錄"</string>
<string name="pref_privacy_clear_history_summary">"清除瀏覽記錄"</string>
- <string name="pref_privacy_clear_history_dlg">"瀏覽記錄會被清除。"</string>
- <string name="pref_privacy_clear_form_data">"清除表單資訊"</string>
+ <string name="pref_privacy_clear_history_dlg">"瀏覽記錄將被清除。"</string>
+ <string name="pref_privacy_clear_form_data">"清除表單資料"</string>
<string name="pref_privacy_clear_form_data_summary">"清除所有表單"</string>
<string name="pref_privacy_clear_form_data_dlg">"所有儲存的資料會被清除。"</string>
<string name="pref_privacy_clear_passwords">"清除密碼"</string>
- <string name="pref_privacy_clear_passwords_summary">"清除所有儲存密碼"</string>
+ <string name="pref_privacy_clear_passwords_summary">"清除所有儲存的密碼"</string>
<string name="pref_privacy_clear_passwords_dlg">"所有儲存密碼會被清除"</string>
<string name="pref_security_title">"安全性設定"</string>
<string name="pref_security_remember_passwords">"記住密碼"</string>
<string name="pref_security_remember_passwords_summary">"儲存網站使用者名稱與密碼"</string>
- <string name="pref_security_save_form_data">"儲存表單資訊"</string>
+ <string name="pref_security_save_form_data">"儲存表單資料"</string>
<string name="pref_security_save_form_data_summary">"儲存輸入的表單資料"</string>
<string name="pref_security_show_security_warning">"顯示安全性警告"</string>
<string name="pref_security_show_security_warning_summary">"當網站安全性有問題時,顯示警告訊息"</string>
@@ -149,25 +151,25 @@
<string name="pref_security_accept_cookies_summary">"允許網站存取 cookie"</string>
<string name="pref_text_size">"設定文字大小"</string>
<string-array name="pref_text_size_choices">
- <item>"極小"</item>
+ <item>"最小"</item>
<item>"小"</item>
- <item>"一般"</item>
+ <item>"適中"</item>
<item>"大"</item>
- <item>"特大"</item>
+ <item>"最大"</item>
</string-array>
<string name="pref_text_size_dialogtitle">"文字大小"</string>
<string name="pref_extras_title">"進階設定"</string>
- <string name="pref_extras_gears_enable">"啟用裝置"</string>
+ <string name="pref_extras_gears_enable">"啟用 Gears"</string>
<string name="pref_extras_gears_enable_summary">"可擴充瀏覽器功能的應用程式"</string>
- <string name="pref_extras_gears_settings">"裝置設定"</string>
+ <string name="pref_extras_gears_settings">"Gears 設定"</string>
<string name="pref_plugin_installed">"外掛程式清單"</string>
<string name="pref_plugin_installed_empty_list">"未安裝外掛程式。"</string>
<string name="pref_extras_gears_settings_summary">"可擴充瀏覽器功能的應用程式"</string>
- <string name="pref_extras_reset_default">"回復初始設定"</string>
- <string name="pref_extras_reset_default_summary">"清除瀏覽器所有資料,並回復初始設定"</string>
- <string name="pref_extras_reset_default_dlg">"瀏覽器所有資料會被清除, 並回復初始設定。"</string>
- <string name="pref_extras_reset_default_dlg_title">"回復初始設定"</string>
- <string name="pref_development_title">"除錯"</string>
+ <string name="pref_extras_reset_default">"還原至初始設定"</string>
+ <string name="pref_extras_reset_default_summary">"清除瀏覽器所有資料,並還原至初始設定"</string>
+ <string name="pref_extras_reset_default_dlg">"瀏覽器所有資料會被清除, 並還原至初始設定。"</string>
+ <string name="pref_extras_reset_default_dlg_title">"還原至初始設定"</string>
+ <string name="pref_development_title">"偵錯"</string>
<string name="pref_default_text_encoding">"設定文字編碼"</string>
<string-array name="pref_default_text_encoding_choices">
<item>"Latin-1 (ISO-8859-1)"</item>
@@ -183,10 +185,10 @@
<string name="browserFrameNetworkErrorLabel">"資料連線問題"</string>
<string name="browserFrameFileErrorLabel">"檔案有問題"</string>
<string name="browserFrameFormResubmitLabel">"確認"</string>
- <string name="browserFrameFormResubmitMessage">"您正在瀏覽的頁面包含已傳送的 (「POSTDATA」),若重新送出資料,此頁表單中的資料會重複 (例如:搜尋結果、線上購物狀態)。"</string>
+ <string name="browserFrameFormResubmitMessage">"您想瀏覽的頁面包含已傳送的 (「POSTDATA」),如重新送出資料,此頁表單上執行的操作將會重複 (包括搜尋或線上購物等)。"</string>
<string name="loadSuspendedTitle">"沒有網路連線"</string>
<string name="loadSuspended">"連線恢復後,此頁面會繼續載入。"</string>
- <string name="clear_history">"清除紀錄"</string>
+ <string name="clear_history">"清除記錄"</string>
<string name="browser_history">"最近瀏覽的頁面"</string>
<string name="empty_history">"瀏覽記錄是空的。"</string>
<string name="add_new_bookmark">"加入書籤…"</string>
@@ -196,7 +198,7 @@
<string name="attention">"注意"</string>
<string name="popup_window_attempt">"此網站試圖開啟快顯視窗。"</string>
<string name="allow">"允許"</string>
- <string name="block">"阻擋"</string>
+ <string name="block">"封鎖"</string>
<string name="too_many_windows_dialog_title">"已達視窗數量限制"</string>
<string name="too_many_windows_dialog_message">"已達最大視窗數量限制,無法開啟新視窗。"</string>
<string name="too_many_subwindows_dialog_title">"已開啟快顯視窗"</string>
@@ -218,7 +220,7 @@
<string name="download_no_sdcard_dlg_title">"沒有 SD 卡"</string>
<string name="download_no_sdcard_dlg_msg">"需要 SD 卡下載 <xliff:g id="FILENAME">%s</xliff:g>。"</string>
<string name="download_sdcard_busy_dlg_title">"無法使用 SD 卡"</string>
- <string name="download_sdcard_busy_dlg_msg">"SD 記憶卡忙碌中。若要允許下載,請選取通知區域中的 [停用 USB 儲存裝置]。"</string>
+ <string name="download_sdcard_busy_dlg_msg">"SD 記憶卡忙碌。如要允許下載,請選取通知中的 [停用 USB 儲存裝置]。"</string>
<string name="download_no_application">"找不到可以開啟這個檔案的應用程式。"</string>
<string name="retry">"重試"</string>
<string name="no_downloads">"下載記錄是空的。"</string>
@@ -234,11 +236,10 @@
<string name="download_length_required">"無法下載。物件大小無法估計。"</string>
<string name="download_precondition_failed">"下載中斷。無法續傳。"</string>
<string name="activity_instrumentation_test_runner">"Browser Test Runner"</string>
- <string name="search_google">"搜尋 Google"</string>
<string name="permlab_readHistoryBookmarks">"讀取瀏覽器的瀏覽記錄和書籤"</string>
<string name="permdesc_readHistoryBookmarks">"允許應用程式讀取瀏覽器造訪過的所有 URL 和瀏覽器所有的書籤。"</string>
<string name="permlab_writeHistoryBookmarks">"寫入瀏覽器的瀏覽記錄和書籤"</string>
- <string name="permdesc_writeHistoryBookmarks">"允許應用程式修改儲存在電話上的瀏覽器記錄或書籤。惡意應用程式可能會使用此選項來清除或修改您瀏覽器的資料。"</string>
+ <string name="permdesc_writeHistoryBookmarks">"允許應用程式修改儲存在電話上的瀏覽記錄或書籤。請注意:惡意應用程式可能會使用此選項來清除或修改您瀏覽器的資料。"</string>
<string name="query_data_prompt">"允許儲存"</string>
<string name="query_data_message">"此網站要在您的手機上儲存資訊。"</string>
<string name="location_prompt">"存取您的位置資訊"</string>
@@ -248,7 +249,7 @@
<string name="settings_message">"下表列出您為每個想要使用 Gears 之網站所授予的權限。"</string>
<string name="filepicker_message">"檔案挑選程式"</string>
<string name="image_message">"選擇的影像"</string>
- <string name="settings_title">"裝置設定"</string>
+ <string name="settings_title">"Gears 設定"</string>
<string name="privacy_policy">"讀取網站的隱私權政策,以瞭解網站將如何使用您的位置資訊。"</string>
<string name="settings_storage_title">"允許本機儲存"</string>
<string name="settings_storage_subtitle_on">"此網站可以在您的手機上儲存資訊"</string>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 98142ac..69c17cb 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -38,6 +38,8 @@
<string name="password">Password</string>
<!-- The label on the "sign in" button -->
<string name="action">Sign in</string>
+ <!-- The name of the bookmarks and history search suggestion source. -->
+ <string name="bookmarks_search">Browser</string>
<!-- Label for a cancel button. It is used for multiple cancel buttons in different contexts -->
<string name="cancel">Cancel</string>
@@ -333,7 +335,7 @@
<!-- Settings summary -->
<string name="pref_security_accept_cookies_summary">Allow sites to save and read \"cookie\" data</string>
<!-- Settings label -->
- <string name="pref_text_size">Set text size</string>
+ <string name="pref_text_size">Text size</string>
<!-- Settings text size options; appear in Text size dialog box -->
<string-array name="pref_text_size_choices">
<item>Tiny</item>
@@ -352,6 +354,22 @@
<item><xliff:g>LARGER</xliff:g></item>
<item><xliff:g>LARGEST</xliff:g></item>
</string-array>
+ <!-- Settings label -->
+ <string name="pref_default_zoom">Default zoom</string>
+ <!-- Settings default zoom options; appear in default zoom dialog box -->
+ <string-array name="pref_default_zoom_choices">
+ <item>Far</item>
+ <item>Medium</item>
+ <item>Close</item>
+ </string-array>
+ <!-- Title of dialog for setting the default zoom -->
+ <string name="pref_default_zoom_dialogtitle">Default zoom</string>
+ <!-- Do not translate -->
+ <string-array name="pref_default_zoom_values" translatable="false">
+ <item><xliff:g>FAR</xliff:g></item>
+ <item><xliff:g>MEDIUM</xliff:g></item>
+ <item><xliff:g>CLOSE</xliff:g></item>
+ </string-array>
<!-- Settings screen, section title -->
<string name="pref_extras_title">Advanced settings</string>
<!-- Settings label -->
@@ -386,8 +404,6 @@
<!-- Do not tranlsate. Development option -->
<string name="pref_development_nav_dump" translatable="false">Enable nav cache dump</string>
<!-- Do not tranlsate. Development option -->
- <string name="pref_development_search_url" translatable="false">Set search URL</string>
- <!-- Do not tranlsate. Development option -->
<string name="pref_development_uastring" translatable="false">UAString</string>
<!-- Do not tranlsate. Development option -->
<string-array name="pref_development_ua_choices" translatable="false">
@@ -402,7 +418,7 @@
<item>2</item>
</string-array>
<!-- Settings screen, setting option name -->
- <string name="pref_default_text_encoding">Set text encoding</string>
+ <string name="pref_default_text_encoding">Text encoding</string>
<!-- Options in the Default encoding dialog box -->
<string-array name="pref_default_text_encoding_choices">
<item>Latin-1 (ISO-8859-1)</item>
@@ -462,6 +478,8 @@
<!-- This string is for the browser "Go To" UI. -->
<!-- This is the button label in the "Go To" UI. -->
<string name="search_button_text">Go</string>
+ <!-- The string used to describe the browser as a searchable item within system search settings. -->
+ <string name="search_settings_description">Bookmarks and web history</string>
<!-- Pop-up window dialog -->
<!-- Title for a dialog informing the user that the site is attempting to
@@ -582,6 +600,11 @@
<!-- Do not translate. Testing only -->
<string name="dump_nav" translatable="false">Dump navigation cache</string>
+ <!-- The default homepage. If it starts with "http://www.google" and the
+ user signs up the device with a Google sites account, the site's
+ domain will be appended. -->
+ <string name="homepage_base">http://www.google.com/m?client=ms-{CID}</string>
+
<!-- Bookmarks -->
<string-array name="bookmarks" translatable="false">
<item>Google</item>
@@ -625,23 +648,22 @@
<!-- Do not translate. This string is an internal URI, not seen in the UI. -->
<string name="google_search_base" translatable="false">
http://www.google.com/m?hl=%1$s&gl=%2$s&</string>
+
+ <!-- The description of the suggestion that lets the user search the web for the query currently
+ in the text field. -->
+ <string name="search_the_web">Search the web</string>
- <!-- Used in Goto to indicate Google search -->
- <string name="search_google">Search Google</string>
-
- <!-- Title of an application permission, listed so the user can choose whether
- they want to allow the application to do this. -->
+ <!-- FIXME: the next four strings(read/write history permissions) should be removed.
+ At the moment actually removing them requires manually deleting all of the
+ existing translations. -->
+ <!-- Do not translate -->
<string name="permlab_readHistoryBookmarks">read Browser\'s history and bookmarks</string>
- <!-- Description of an application permission, listed so the user can choose whether
- they want to allow the application to do this. -->
- <string name="permdesc_readHistoryBookmarks">Allows the application to read all
+ <!-- Do not translate -->
+ <string name="permdesc_readHistoryBookmarks">Allows the application to read all
the URLs that the Browser has visited, and all of the Browser\'s bookmarks.</string>
-
- <!-- Title of an application permission, listed so the user can choose whether
- they want to allow the application to do this. -->
+ <!-- Do not translate -->
<string name="permlab_writeHistoryBookmarks">write Browser\'s history and bookmarks</string>
- <!-- Description of an application permission, listed so the user can choose whether
- they want to allow the application to do this. -->
+ <!-- Do not translate -->
<string name="permdesc_writeHistoryBookmarks">Allows an application to modify the
Browser\'s history or bookmarks stored on your phone. Malicious applications
can use this to erase or modify your Browser\'s data.</string>
diff --git a/res/xml/bookmarks_searchable.xml b/res/xml/bookmarks_searchable.xml
new file mode 100644
index 0000000..bc6ac93
--- /dev/null
+++ b/res/xml/bookmarks_searchable.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<searchable xmlns:android="http://schemas.android.com/apk/res/android"
+ android:label="@string/bookmarks_search"
+ android:searchButtonText="@string/search_button_text"
+ android:searchMode="queryRewriteFromData"
+ android:inputType="textUri"
+ android:imeOptions="actionGo"
+
+ android:includeInGlobalSearch="true"
+ android:searchSuggestAuthority="browser"
+ android:searchSuggestPath="bookmarks"
+ android:searchSuggestSelection="url LIKE ?"
+ android:searchSuggestIntentAction="android.intent.action.VIEW"
+/>
diff --git a/res/xml/browser_preferences.xml b/res/xml/browser_preferences.xml
index fdfa839..23618c5 100644
--- a/res/xml/browser_preferences.xml
+++ b/res/xml/browser_preferences.xml
@@ -29,6 +29,14 @@
android:dialogTitle="@string/pref_text_size_dialogtitle" />
<ListPreference
+ android:key="default_zoom"
+ android:title="@string/pref_default_zoom"
+ android:defaultValue="MEDIUM"
+ android:entries="@array/pref_default_zoom_choices"
+ android:entryValues="@array/pref_default_zoom_values"
+ android:dialogTitle="@string/pref_default_zoom_dialogtitle" />
+
+ <ListPreference
android:key="default_text_encoding"
android:title="@string/pref_default_text_encoding"
android:defaultValue="@string/pref_default_text_encoding_default"
diff --git a/res/xml/debug_preferences.xml b/res/xml/debug_preferences.xml
index 4f55f6b..22b5997 100644
--- a/res/xml/debug_preferences.xml
+++ b/res/xml/debug_preferences.xml
@@ -50,11 +50,6 @@
android:defaultValue="false"
android:title="@string/pref_development_nav_dump" />
- <com.android.browser.BrowserSearchpagePreference
- android:key="search_url"
- android:title="@string/pref_development_search_url"
- android:singleLine="true" />
-
<ListPreference
android:key="user_agent"
android:title="@string/pref_development_uastring"
diff --git a/res/xml/searchable.xml b/res/xml/searchable.xml
index bb578c6..a3b2d90 100644
--- a/res/xml/searchable.xml
+++ b/res/xml/searchable.xml
@@ -27,6 +27,7 @@
android:inputType="textUri"
android:imeOptions="actionGo"
+ android:searchSettingsDescription="@string/search_settings_description"
android:searchSuggestAuthority="browser"
android:searchSuggestSelection="url LIKE ?"
android:searchSuggestIntentAction="android.intent.action.VIEW"
diff --git a/src/com/android/browser/BookmarkSearch.java b/src/com/android/browser/BookmarkSearch.java
new file mode 100644
index 0000000..4d3ca0f
--- /dev/null
+++ b/src/com/android/browser/BookmarkSearch.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.browser;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+/**
+ * This activity is never started from the browser. Its purpose is to provide bookmark suggestions
+ * to global search (through its searchable meta-data), and to handle the intents produced
+ * by clicking such suggestions.
+ */
+public class BookmarkSearch extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ Intent intent = getIntent();
+ if (intent != null) {
+ String action = intent.getAction();
+ if (Intent.ACTION_VIEW.equals(action)) {
+ intent.setClass(this, BrowserActivity.class);
+ startActivity(intent);
+ }
+ }
+ finish();
+ }
+
+}
diff --git a/src/com/android/browser/Browser.java b/src/com/android/browser/Browser.java
index 32cee67..524f789 100644
--- a/src/com/android/browser/Browser.java
+++ b/src/com/android/browser/Browser.java
@@ -16,7 +16,6 @@
package com.android.browser;
-import android.util.Config;
import android.util.Log;
import android.app.Application;
@@ -30,6 +29,15 @@
private final static String LOGTAG = "browser";
+ // Set to true to enable extra debugging.
+ final static boolean DEBUG = false;
+
+ // Set to true to enable verbose logging.
+ final static boolean LOGV_ENABLED = DEBUG;
+
+ // Set to true to enable extra debug logging.
+ final static boolean LOGD_ENABLED = true;
+
/**
* Specifies a heap utilization ratio that works better
* for the browser than the default ratio does.
@@ -40,7 +48,7 @@
}
public void onCreate() {
- if (Config.LOGV)
+ if (LOGV_ENABLED)
Log.v(LOGTAG, "Browser.onCreate: this=" + this);
// Fix heap utilization for better heap size characteristics.
VMRuntime.getRuntime().setTargetHeapUtilization(
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java
index ca788a6..d3c38e7 100644
--- a/src/com/android/browser/BrowserActivity.java
+++ b/src/com/android/browser/BrowserActivity.java
@@ -18,7 +18,6 @@
import com.google.android.googleapps.IGoogleLoginService;
import com.google.android.googlelogin.GoogleLoginServiceConstants;
-import com.google.android.providers.GoogleSettings.Partner;
import android.app.Activity;
import android.app.ActivityManager;
@@ -75,8 +74,6 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
-import android.os.SystemProperties;
-import android.preference.PreferenceManager;
import android.provider.Browser;
import android.provider.Contacts;
import android.provider.Downloads;
@@ -86,7 +83,6 @@
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.text.util.Regex;
-import android.util.Config;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Gravity;
@@ -132,6 +128,7 @@
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
+import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLEncoder;
import java.text.ParseException;
@@ -139,7 +136,6 @@
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedList;
-import java.util.Locale;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -151,11 +147,25 @@
View.OnCreateContextMenuListener,
DownloadListener {
+ /* Define some aliases to make these debugging flags easier to refer to.
+ * This file imports android.provider.Browser, so we can't just refer to "Browser.DEBUG".
+ */
+ private final static boolean DEBUG = com.android.browser.Browser.DEBUG;
+ private final static boolean LOGV_ENABLED = com.android.browser.Browser.LOGV_ENABLED;
+ private final static boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED;
+
private IGoogleLoginService mGls = null;
private ServiceConnection mGlsConnection = null;
private SensorManager mSensorManager = null;
+ // These are single-character shortcuts for searching popular sources.
+ private static final int SHORTCUT_INVALID = 0;
+ private static final int SHORTCUT_GOOGLE_SEARCH = 1;
+ private static final int SHORTCUT_WIKIPEDIA_SEARCH = 2;
+ private static final int SHORTCUT_DICTIONARY_SEARCH = 3;
+ private static final int SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH = 4;
+
/* Whitelisted webpages
private static HashSet<String> sWhiteList;
@@ -184,6 +194,9 @@
try {
if (mGls == null) return;
+ if (!homepage.startsWith("http://www.google.")) return;
+ if (homepage.indexOf('?') == -1) return;
+
String hostedUser = mGls.getAccount(GoogleLoginServiceConstants.PREFER_HOSTED);
String googleUser = mGls.getAccount(GoogleLoginServiceConstants.REQUIRE_GOOGLE);
@@ -203,8 +216,7 @@
if (googleUser == null || !hostedUser.equals(googleUser)) {
String domain = hostedUser.substring(hostedUser.lastIndexOf('@')+1);
- homepage = "http://www.google.com/m/a/" + domain + "?client=ms-" +
- Partner.getString(BrowserActivity.this.getContentResolver(), Partner.CLIENT_ID);
+ homepage = homepage.replace("?", "/a/" + domain + "?");
}
} catch (RemoteException ignore) {
// Login service died; carry on
@@ -373,7 +385,7 @@
s.loadFromDb(mContext);
pluginsPath = s.getPluginsPath();
}
- if (Config.LOGV) {
+ if (LOGV_ENABLED) {
Log.v(TAG, "Plugin path: " + pluginsPath);
}
}
@@ -400,7 +412,7 @@
* We delete the directory, then recreate it.
*/
public void cleanPluginsDirectory() {
- if (Config.LOGV) {
+ if (LOGV_ENABLED) {
Log.v(TAG, "delete plugins directory: " + pluginsPath);
}
File pluginsDirectory = new File(pluginsPath);
@@ -416,7 +428,7 @@
*/
public void copyBuildInfos() {
try {
- if (Config.LOGV) {
+ if (LOGV_ENABLED) {
Log.v(TAG, "Copy build infos to the plugins directory");
}
File buildInfoFile = new File(SYSTEM_BUILD_INFOS_FILE);
@@ -448,7 +460,7 @@
File buildInfoFile = new File(SYSTEM_BUILD_INFOS_FILE);
File buildInfoPlugins = new File(pluginsPath, BUILD_INFOS_FILE);
if (!buildInfoPlugins.exists()) {
- if (Config.LOGV) {
+ if (LOGV_ENABLED) {
Log.v(TAG, "build.prop in plugins directory " + pluginsPath
+ " does not exist, therefore it's a new system image");
}
@@ -458,7 +470,7 @@
String buildInfoPlugin = contentsOfFile(buildInfoPlugins);
if (buildInfo == null || buildInfoPlugin == null
|| buildInfo.compareTo(buildInfoPlugin) != 0) {
- if (Config.LOGV) {
+ if (LOGV_ENABLED) {
Log.v(TAG, "build.prop are different, "
+ " therefore it's a new system image");
}
@@ -491,7 +503,7 @@
String path = entry.getName().substring(zipFilterLength);
File outputFile = new File(pluginsPath, path);
if (!outputFile.exists()) {
- if (Config.LOGV) {
+ if (LOGV_ENABLED) {
Log.v(TAG, "checkIsDifferentVersions(): extracted file "
+ path + " does not exist, we have a different version");
}
@@ -536,7 +548,7 @@
outputFile.getParentFile().mkdirs();
if (outputFile.exists() && !mDoOverwrite) {
- if (Config.LOGV) {
+ if (LOGV_ENABLED) {
Log.v(TAG, path + " already extracted.");
}
} else {
@@ -548,7 +560,7 @@
path + TEMPORARY_EXTENSION);
}
FileOutputStream fos = new FileOutputStream(outputFile);
- if (Config.LOGV) {
+ if (LOGV_ENABLED) {
Log.v(TAG, "copy " + entry + " to "
+ pluginsPath + "/" + path);
}
@@ -563,7 +575,7 @@
File renamedFile = (File) elems.nextElement();
File sourceFile = new File(renamedFile.getPath()
+ TEMPORARY_EXTENSION);
- if (Config.LOGV) {
+ if (LOGV_ENABLED) {
Log.v(TAG, "rename " + sourceFile.getPath()
+ " to " + renamedFile.getPath());
}
@@ -623,7 +635,7 @@
}
@Override public void onCreate(Bundle icicle) {
- if (Config.LOGV) {
+ if (LOGV_ENABLED) {
Log.v(LOGTAG, this + " onStart");
}
super.onCreate(icicle);
@@ -639,9 +651,6 @@
mResolver = getContentResolver();
- setBaseSearchUrl(PreferenceManager.getDefaultSharedPreferences(this)
- .getString("search_url", ""));
-
//
// start MASF proxy service
//
@@ -676,6 +685,12 @@
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Browser");
+ // If this was a web search request, pass it on to the default web search provider.
+ if (handleWebSearchIntent(getIntent())) {
+ moveTaskToBack(true);
+ return;
+ }
+
if (!mTabControl.restoreState(icicle)) {
// clear up the thumbnail directory if we can't restore the state as
// none of the files in the directory are referenced any more.
@@ -687,11 +702,12 @@
// If the intent is ACTION_VIEW and data is not null, the Browser is
// invoked to view the content by another application. In this case,
// the tab will be close when exit.
- String url = getUrlFromIntent(intent);
+ UrlData urlData = getUrlDataFromIntent(intent);
+
final TabControl.Tab t = mTabControl.createNewTab(
Intent.ACTION_VIEW.equals(intent.getAction()) &&
intent.getData() != null,
- intent.getStringExtra(Browser.EXTRA_APPLICATION_ID), url);
+ intent.getStringExtra(Browser.EXTRA_APPLICATION_ID), urlData.mUrl);
mTabControl.setCurrentTab(t);
// This is one of the only places we call attachTabToContentView
// without animating from the tab picker.
@@ -713,14 +729,18 @@
}
copyPlugins(true);
- if (url == null || url.length() == 0) {
+ if (urlData.isEmpty()) {
if (mSettings.isLoginInitialized()) {
webView.loadUrl(mSettings.getHomePage());
} else {
waitForCredentials();
}
} else {
- webView.loadUrl(url);
+ if (extra != null) {
+ urlData.setPostData(extra
+ .getByteArray(Browser.EXTRA_POST_DATA));
+ }
+ urlData.loadIn(webView);
}
} else {
// TabControl.restoreState() will create a new tab even if
@@ -774,10 +794,19 @@
|| Intent.ACTION_SEARCH.equals(action)
|| MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
|| Intent.ACTION_WEB_SEARCH.equals(action)) {
- String url = getUrlFromIntent(intent);
- if (url == null || url.length() == 0) {
- url = mSettings.getHomePage();
+ // If this was a search request (e.g. search query directly typed into the address bar),
+ // pass it on to the default web search provider.
+ if (handleWebSearchIntent(intent)) {
+ return;
}
+
+ UrlData urlData = getUrlDataFromIntent(intent);
+ if (urlData.isEmpty()) {
+ urlData = new UrlData(mSettings.getHomePage());
+ }
+ urlData.setPostData(intent
+ .getByteArrayExtra(Browser.EXTRA_POST_DATA));
+
if (Intent.ACTION_VIEW.equals(action) &&
(flags & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
final String appId =
@@ -794,20 +823,21 @@
// If the WebView has the same original url and is on that
// page, it can be reused.
boolean needsLoad =
- mTabControl.recreateWebView(appTab, url);
+ mTabControl.recreateWebView(appTab, urlData.mUrl);
+
if (current != appTab) {
- showTab(appTab, needsLoad ? url : null);
+ showTab(appTab, needsLoad ? urlData : EMPTY_URL_DATA);
} else {
if (mTabOverview != null && mAnimationCount == 0) {
sendAnimateFromOverview(appTab, false,
- needsLoad ? url : null, TAB_OVERVIEW_DELAY,
+ needsLoad ? urlData : EMPTY_URL_DATA, TAB_OVERVIEW_DELAY,
null);
} else {
// If the tab was the current tab, we have to attach
// it to the view system again.
attachTabToContentView(appTab);
if (needsLoad) {
- appTab.getWebView().loadUrl(url);
+ urlData.loadIn(appTab.getWebView());
}
}
}
@@ -817,27 +847,96 @@
// opened in a new tab unless we have reached MAX_TABS. Then the
// url will be opened in the current tab. If a new tab is
// created, it will have "true" for exit on close.
- openTabAndShow(url, null, true, appId);
+ openTabAndShow(urlData, null, true, appId);
} else {
- if ("about:debug".equals(url)) {
+ if ("about:debug".equals(urlData.mUrl)) {
mSettings.toggleDebugSettings();
return;
}
// If the Window overview is up and we are not in the midst of
// an animation, animate away from the Window overview.
if (mTabOverview != null && mAnimationCount == 0) {
- sendAnimateFromOverview(current, false, url,
+ sendAnimateFromOverview(current, false, urlData,
TAB_OVERVIEW_DELAY, null);
} else {
// Get rid of the subwindow if it exists
dismissSubWindow(current);
- current.getWebView().loadUrl(url);
+ urlData.loadIn(current.getWebView());
}
}
}
}
- private String getUrlFromIntent(Intent intent) {
+ private int parseUrlShortcut(String url) {
+ if (url == null) return SHORTCUT_INVALID;
+
+ // FIXME: quick search, need to be customized by setting
+ if (url.length() > 2 && url.charAt(1) == ' ') {
+ switch (url.charAt(0)) {
+ case 'g': return SHORTCUT_GOOGLE_SEARCH;
+ case 'w': return SHORTCUT_WIKIPEDIA_SEARCH;
+ case 'd': return SHORTCUT_DICTIONARY_SEARCH;
+ case 'l': return SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH;
+ }
+ }
+ return SHORTCUT_INVALID;
+ }
+
+ /**
+ * Launches the default web search activity with the query parameters if the given intent's data
+ * are identified as plain search terms and not URLs/shortcuts.
+ * @return true if the intent was handled and web search activity was launched, false if not.
+ */
+ private boolean handleWebSearchIntent(Intent intent) {
+ if (intent == null) return false;
+
+ String url = null;
+ final String action = intent.getAction();
+ if (Intent.ACTION_VIEW.equals(action)) {
+ url = intent.getData().toString();
+ } else if (Intent.ACTION_SEARCH.equals(action)
+ || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
+ || Intent.ACTION_WEB_SEARCH.equals(action)) {
+ url = intent.getStringExtra(SearchManager.QUERY);
+ }
+ return handleWebSearchRequest(url, intent.getBundleExtra(SearchManager.APP_DATA));
+ }
+
+ /**
+ * Launches the default web search activity with the query parameters if the given url string
+ * was identified as plain search terms and not URL/shortcut.
+ * @return true if the request was handled and web search activity was launched, false if not.
+ */
+ private boolean handleWebSearchRequest(String inUrl, Bundle appData) {
+ if (inUrl == null) return false;
+
+ // In general, we shouldn't modify URL from Intent.
+ // But currently, we get the user-typed URL from search box as well.
+ String url = fixUrl(inUrl).trim();
+
+ // URLs and site specific search shortcuts are handled by the regular flow of control, so
+ // return early.
+ if (Regex.WEB_URL_PATTERN.matcher(url).matches()
+ || ACCEPTED_URI_SCHEMA.matcher(url).matches()
+ || parseUrlShortcut(url) != SHORTCUT_INVALID) {
+ return false;
+ }
+
+ Browser.updateVisitedHistory(mResolver, url, false);
+ Browser.addSearchUrl(mResolver, url);
+
+ Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ intent.putExtra(SearchManager.QUERY, url);
+ if (appData != null) {
+ intent.putExtra(SearchManager.APP_DATA, appData);
+ }
+ startActivity(intent);
+
+ return true;
+ }
+
+ private UrlData getUrlDataFromIntent(Intent intent) {
String url = null;
if (intent != null) {
final String action = intent.getAction();
@@ -850,6 +949,13 @@
url += "?" + mimeType;
}
}
+ if ("inline:".equals(url)) {
+ return new InlinedUrlData(
+ intent.getStringExtra(Browser.EXTRA_INLINE_CONTENT),
+ intent.getType(),
+ intent.getStringExtra(Browser.EXTRA_INLINE_ENCODING),
+ intent.getStringExtra(Browser.EXTRA_INLINE_FAILURL));
+ }
} else if (Intent.ACTION_SEARCH.equals(action)
|| MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
|| Intent.ACTION_WEB_SEARCH.equals(action)) {
@@ -880,7 +986,7 @@
}
}
}
- return url;
+ return new UrlData(url);
}
/* package */ static String fixUrl(String inUrl) {
@@ -990,7 +1096,7 @@
@Override protected void onResume() {
super.onResume();
- if (Config.LOGV) {
+ if (LOGV_ENABLED) {
Log.v(LOGTAG, "BrowserActivity.onResume: this=" + this);
}
@@ -1037,7 +1143,7 @@
* the saved state.
*/
@Override protected void onSaveInstanceState(Bundle outState) {
- if (Config.LOGV) {
+ if (LOGV_ENABLED) {
Log.v(LOGTAG, "BrowserActivity.onSaveInstanceState: this=" + this);
}
// the default implementation requires each view to have an id. As the
@@ -1083,7 +1189,7 @@
}
@Override protected void onDestroy() {
- if (Config.LOGV) {
+ if (LOGV_ENABLED) {
Log.v(LOGTAG, "BrowserActivity.onDestroy: this=" + this);
}
super.onDestroy();
@@ -1294,6 +1400,9 @@
mCanChord = true;
int id = item.getItemId();
final WebView webView = getTopWindow();
+ if (null == webView) {
+ return false;
+ }
final HashMap hrefMap = new HashMap();
hrefMap.put("webview", webView);
final Message msg = mHandler.obtainMessage(
@@ -1349,6 +1458,9 @@
// menu key.
return false;
}
+ if (null == mTabOverview && null == getTopWindow()) {
+ return false;
+ }
switch (item.getItemId()) {
// -- Main menu
case R.id.goto_menu_id: {
@@ -1796,7 +1908,7 @@
// Send the ANIMTE_FROM_OVERVIEW message after changing the current tab.
private void sendAnimateFromOverview(final TabControl.Tab tab,
- final boolean newTab, final String url, final int delay,
+ final boolean newTab, final UrlData urlData, final int delay,
final Message msg) {
// Set the current tab.
mTabControl.setCurrentTab(tab);
@@ -1820,9 +1932,9 @@
// Load the url after the AnimatingView has captured the picture. This
// prevents any bad layout or bad scale from being used during
// animation.
- if (url != null) {
+ if (!urlData.isEmpty()) {
dismissSubWindow(tab);
- tab.getWebView().loadUrl(url);
+ urlData.loadIn(tab.getWebView());
}
map.put("msg", msg);
mHandler.sendMessageDelayed(mHandler.obtainMessage(
@@ -1838,15 +1950,15 @@
}
// 500ms animation with 800ms delay
- private static final int TAB_ANIMATION_DURATION = 500;
- private static final int TAB_OVERVIEW_DELAY = 800;
+ private static final int TAB_ANIMATION_DURATION = 200;
+ private static final int TAB_OVERVIEW_DELAY = 500;
// Called by TabControl when a tab is requesting focus
/* package */ void showTab(TabControl.Tab t) {
- showTab(t, null);
+ showTab(t, EMPTY_URL_DATA);
}
- private void showTab(TabControl.Tab t, String url) {
+ private void showTab(TabControl.Tab t, UrlData urlData) {
// Disallow focus change during a tab animation.
if (mAnimationCount > 0) {
return;
@@ -1858,7 +1970,14 @@
delay = TAB_ANIMATION_DURATION + TAB_OVERVIEW_DELAY;
tabPicker(false, mTabControl.getTabIndex(t), false);
}
- sendAnimateFromOverview(t, false, url, delay, null);
+ sendAnimateFromOverview(t, false, urlData, delay, null);
+ }
+
+ // A wrapper function of {@link #openTabAndShow(UrlData, Message, boolean, String)}
+ // that accepts url as string.
+ private void openTabAndShow(String url, final Message msg,
+ boolean closeOnExit, String appId) {
+ openTabAndShow(new UrlData(url), msg, closeOnExit, appId);
}
// This method does a ton of stuff. It will attempt to create a new tab
@@ -1869,7 +1988,7 @@
// the given Message. If the tab overview is already showing (i.e. this
// method is called from TabListener.onClick(), the method will animate
// away from the tab overview.
- private void openTabAndShow(String url, final Message msg,
+ private void openTabAndShow(UrlData urlData, final Message msg,
boolean closeOnExit, String appId) {
final boolean newTab = mTabControl.getTabCount() != TabControl.MAX_TABS;
final TabControl.Tab currentTab = mTabControl.getCurrentTab();
@@ -1878,14 +1997,14 @@
// If the tab overview is up and there are animations, just load
// the url.
if (mTabOverview != null && mAnimationCount > 0) {
- if (url != null) {
+ if (!urlData.isEmpty()) {
// We should not have a msg here since onCreateWindow
// checks the animation count and every other caller passes
// null.
assert msg == null;
// just dismiss the subwindow and load the given url.
dismissSubWindow(currentTab);
- currentTab.getWebView().loadUrl(url);
+ urlData.loadIn(currentTab.getWebView());
}
} else {
// show mTabOverview if it is not there.
@@ -1899,20 +2018,20 @@
// Animate from the Tab overview after any animations have
// finished.
sendAnimateFromOverview(
- mTabControl.createNewTab(closeOnExit, appId, url), true,
- url, delay, msg);
+ mTabControl.createNewTab(closeOnExit, appId, urlData.mUrl), true,
+ urlData, delay, msg);
}
- } else if (url != null) {
+ } else if (!urlData.isEmpty()) {
// We should not have a msg here.
assert msg == null;
if (mTabOverview != null && mAnimationCount == 0) {
- sendAnimateFromOverview(currentTab, false, url,
+ sendAnimateFromOverview(currentTab, false, urlData,
TAB_OVERVIEW_DELAY, null);
} else {
// Get rid of the subwindow if it exists
dismissSubWindow(currentTab);
// Load the given url.
- currentTab.getWebView().loadUrl(url);
+ urlData.loadIn(currentTab.getWebView());
}
}
}
@@ -1959,10 +2078,12 @@
final Animation.AnimationListener l =
new Animation.AnimationListener() {
public void onAnimationStart(Animation a) {
- mTabOverview.requestFocus();
- // Clear the listener so we don't trigger a tab
- // selection.
- mTabOverview.setListener(null);
+ if (mTabOverview != null) {
+ mTabOverview.requestFocus();
+ // Clear the listener so we don't trigger a tab
+ // selection.
+ mTabOverview.setListener(null);
+ }
}
public void onAnimationRepeat(Animation a) {}
public void onAnimationEnd(Animation a) {
@@ -2126,6 +2247,9 @@
.setVisibility(View.VISIBLE);
}
mContentView.removeView(mTabOverview);
+ // Clear all the data for tab picker so next time it will be
+ // recreated.
+ mTabControl.wipeAllPickerData();
mTabOverview.clear();
mTabOverview = null;
mTabListener = null;
@@ -2346,7 +2470,7 @@
private void revertLockIcon() {
mLockIconType = mPrevLockType;
- if (Config.LOGV) {
+ if (LOGV_ENABLED) {
Log.v(LOGTAG, "BrowserActivity.revertLockIcon:" +
" revert lock icon to " + mLockIconType);
}
@@ -2362,7 +2486,7 @@
// Change to the parent tab
final TabControl.Tab tab = mTabControl.getTab(indexToShow);
if (tab != null) {
- sendAnimateFromOverview(tab, false, null, delay, null);
+ sendAnimateFromOverview(tab, false, EMPTY_URL_DATA, delay, null);
} else {
// Increment this here so that no other animations can happen in
// between the end of the tab picker transition and the beginning
@@ -2741,7 +2865,7 @@
String uiInfo = "UI thread used "
+ (SystemClock.currentThreadTimeMillis() - mUiStart)
+ " ms";
- if (Config.LOGD) {
+ if (LOGD_ENABLED) {
Log.d(LOGTAG, uiInfo);
}
//The string that gets written to the log
@@ -2758,7 +2882,7 @@
+ " ms and irq took "
+ (sysCpu[4] + sysCpu[5] + sysCpu[6] - mIrqStart)
* 10 + " ms, " + uiInfo;
- if (Config.LOGD) {
+ if (LOGD_ENABLED) {
Log.d(LOGTAG, performanceString + "\nWebpage: " + url);
}
if (url != null) {
@@ -2773,7 +2897,7 @@
} else if (newUrl.startsWith("https://")) {
newUrl = newUrl.substring(8);
}
- if (Config.LOGD) {
+ if (LOGD_ENABLED) {
Log.d(LOGTAG, newUrl + " loaded");
}
/*
@@ -2862,16 +2986,41 @@
}
}
- Uri uri;
+ // The "about:" schemes are internal to the browser; don't
+ // want these to be dispatched to other apps.
+ if (url.startsWith("about:")) {
+ return false;
+ }
+
+ Intent intent;
+
+ // perform generic parsing of the URI to turn it into an Intent.
try {
- uri = Uri.parse(url);
- } catch (IllegalArgumentException ex) {
+ intent = Intent.parseUri(url, Intent.URI_INTENT_SCHEME);
+ } catch (URISyntaxException ex) {
+ Log.w("Browser", "Bad URI " + url + ": " + ex.getMessage());
return false;
}
- // check whether other activities want to handle this url
- Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+ // check whether the intent can be resolved. If not, we will see
+ // whether we can download it from the Market.
+ if (getPackageManager().resolveActivity(intent, 0) == null) {
+ String packagename = intent.getPackage();
+ if (packagename != null) {
+ intent = new Intent(Intent.ACTION_VIEW, Uri
+ .parse("market://search?q=pname:" + packagename));
+ intent.addCategory(Intent.CATEGORY_BROWSABLE);
+ startActivity(intent);
+ return true;
+ } else {
+ return false;
+ }
+ }
+
+ // sanitize the Intent, ensuring web pages can not bypass browser
+ // security (only access to BROWSABLE activities).
intent.addCategory(Intent.CATEGORY_BROWSABLE);
+ intent.setComponent(null);
try {
if (startActivityIfNeeded(intent, -1)) {
return true;
@@ -2905,7 +3054,7 @@
// If NOT a 'safe' url, change the lock to mixed content!
if (!(URLUtil.isHttpsUrl(url) || URLUtil.isDataUrl(url) || URLUtil.isAboutUrl(url))) {
mLockIconType = LOCK_ICON_MIXED;
- if (Config.LOGV) {
+ if (LOGV_ENABLED) {
Log.v(LOGTAG, "BrowserActivity.updateLockIcon:" +
" updated lock icon to " + mLockIconType + " due to " + url);
}
@@ -3232,7 +3381,7 @@
// openTabAndShow will dispatch the message after creating the
// new WebView. This will prevent another request from coming
// in during the animation.
- openTabAndShow(null, msg, false, null);
+ openTabAndShow(EMPTY_URL_DATA, msg, false, null);
parent.addChildTab(mTabControl.getCurrentTab());
WebView.WebViewTransport transport =
(WebView.WebViewTransport) msg.obj;
@@ -3365,7 +3514,7 @@
@Override
public void onReceivedTitle(WebView view, String title) {
- String url = view.getOriginalUrl();
+ String url = view.getUrl();
// here, if url is null, we want to reset the title
setUrlTitle(url, title);
@@ -3388,7 +3537,7 @@
Cursor c = mResolver.query(Browser.BOOKMARKS_URI,
Browser.HISTORY_PROJECTION, where, selArgs, null);
if (c.moveToFirst()) {
- if (Config.LOGV) {
+ if (LOGV_ENABLED) {
Log.v(LOGTAG, "updating cursor");
}
// Current implementation of database only has one entry per
@@ -3438,7 +3587,7 @@
startActivity(intent);
return;
} catch (ActivityNotFoundException ex) {
- if (Config.LOGD) {
+ if (LOGD_ENABLED) {
Log.d(LOGTAG, "activity not found for " + mimetype
+ " over " + Uri.parse(url).getScheme(), ex);
}
@@ -3562,7 +3711,7 @@
mLockIconType = LOCK_ICON_UNSECURE;
if (URLUtil.isHttpsUrl(url)) {
mLockIconType = LOCK_ICON_SECURE;
- if (Config.LOGV) {
+ if (LOGV_ENABLED) {
Log.v(LOGTAG, "BrowserActivity.resetLockIcon:" +
" reset lock icon to " + mLockIconType);
}
@@ -3582,7 +3731,7 @@
mLockIconType = LOCK_ICON_UNSECURE;
- if (Config.LOGV) {
+ if (LOGV_ENABLED) {
Log.v(LOGTAG, "BrowserActivity.resetLockIcon:" +
" reset lock icon to " + mLockIconType);
}
@@ -4104,7 +4253,7 @@
// middle of an animation, animate away from it to the
// current tab.
if (mTabOverview != null && mAnimationCount == 0) {
- sendAnimateFromOverview(currentTab, false, data,
+ sendAnimateFromOverview(currentTab, false, new UrlData(data),
TAB_OVERVIEW_DELAY, null);
} else {
dismissSubWindow(currentTab);
@@ -4140,7 +4289,7 @@
private class TabListener implements ImageGrid.Listener {
public void remove(int position) {
// Note: Remove is not enabled if we have only one tab.
- if (Config.DEBUG && mTabControl.getTabCount() == 1) {
+ if (DEBUG && mTabControl.getTabCount() == 1) {
throw new AssertionError();
}
@@ -4156,7 +4305,7 @@
if (mTabControl.getTabCount() == 0) {
current = mTabControl.createNewTab();
sendAnimateFromOverview(current, true,
- mSettings.getHomePage(), TAB_OVERVIEW_DELAY, null);
+ new UrlData(mSettings.getHomePage()), TAB_OVERVIEW_DELAY, null);
} else {
final int index = position > 0 ? (position - 1) : 0;
current = mTabControl.getTab(index);
@@ -4188,16 +4337,12 @@
}
}
- // Clear all the data for tab picker so next time it will be
- // recreated.
- mTabControl.wipeAllPickerData();
-
// NEW_TAB means that the "New Tab" cell was clicked on.
if (index == ImageGrid.NEW_TAB) {
openTabAndShow(mSettings.getHomePage(), null, false, null);
} else {
sendAnimateFromOverview(mTabControl.getTab(index),
- false, null, 0, null);
+ false, EMPTY_URL_DATA, 0, null);
}
}
}
@@ -4388,7 +4533,7 @@
"(?i)" + // switch on case insensitive matching
"(" + // begin group for schema
"(?:http|https|file):\\/\\/" +
- "|(?:data|about|content|javascript):" +
+ "|(?:inline|data|about|content|javascript):" +
")" +
"(.*)" );
@@ -4409,46 +4554,34 @@
Matcher matcher = ACCEPTED_URI_SCHEMA.matcher(inUrl);
if (matcher.matches()) {
- if (hasSpace) {
- inUrl = inUrl.replace(" ", "%20");
- }
// force scheme to lowercase
String scheme = matcher.group(1);
String lcScheme = scheme.toLowerCase();
if (!lcScheme.equals(scheme)) {
- return lcScheme + matcher.group(2);
+ inUrl = lcScheme + matcher.group(2);
+ }
+ if (hasSpace) {
+ inUrl = inUrl.replace(" ", "%20");
}
return inUrl;
}
if (hasSpace) {
- // FIXME: quick search, need to be customized by setting
- if (inUrl.length() > 2 && inUrl.charAt(1) == ' ') {
- // FIXME: Is this the correct place to add to searches?
- // what if someone else calls this function?
- char char0 = inUrl.charAt(0);
-
- if (char0 == 'g') {
- Browser.addSearchUrl(mResolver, inUrl);
- return composeSearchUrl(inUrl.substring(2));
-
- } else if (char0 == 'w') {
- Browser.addSearchUrl(mResolver, inUrl);
- return URLUtil.composeSearchUrl(inUrl.substring(2),
- QuickSearch_W,
- QUERY_PLACE_HOLDER);
-
- } else if (char0 == 'd') {
- Browser.addSearchUrl(mResolver, inUrl);
- return URLUtil.composeSearchUrl(inUrl.substring(2),
- QuickSearch_D,
- QUERY_PLACE_HOLDER);
-
- } else if (char0 == 'l') {
- Browser.addSearchUrl(mResolver, inUrl);
+ // FIXME: Is this the correct place to add to searches?
+ // what if someone else calls this function?
+ int shortcut = parseUrlShortcut(inUrl);
+ if (shortcut != SHORTCUT_INVALID) {
+ Browser.addSearchUrl(mResolver, inUrl);
+ String query = inUrl.substring(2);
+ switch (shortcut) {
+ case SHORTCUT_GOOGLE_SEARCH:
+ return URLUtil.composeSearchUrl(query, QuickSearch_G, QUERY_PLACE_HOLDER);
+ case SHORTCUT_WIKIPEDIA_SEARCH:
+ return URLUtil.composeSearchUrl(query, QuickSearch_W, QUERY_PLACE_HOLDER);
+ case SHORTCUT_DICTIONARY_SEARCH:
+ return URLUtil.composeSearchUrl(query, QuickSearch_D, QUERY_PLACE_HOLDER);
+ case SHORTCUT_GOOGLE_MOBILE_LOCAL_SEARCH:
// FIXME: we need location in this case
- return URLUtil.composeSearchUrl(inUrl.substring(2),
- QuickSearch_L,
- QUERY_PLACE_HOLDER);
+ return URLUtil.composeSearchUrl(query, QuickSearch_L, QUERY_PLACE_HOLDER);
}
}
} else {
@@ -4458,39 +4591,7 @@
}
Browser.addSearchUrl(mResolver, inUrl);
- return composeSearchUrl(inUrl);
- }
-
- /* package */ String composeSearchUrl(String search) {
- return URLUtil.composeSearchUrl(search, QuickSearch_G,
- QUERY_PLACE_HOLDER);
- }
-
- /* package */void setBaseSearchUrl(String url) {
- if (url == null || url.length() == 0) {
- /*
- * get the google search url based on the SIM. Default is US. NOTE:
- * This code uses resources to optionally select the search Uri,
- * based on the MCC value from the SIM. The default string will most
- * likely be fine. It is parameterized to accept info from the
- * Locale, the language code is the first parameter (%1$s) and the
- * country code is the second (%2$s). This code must function in the
- * same way as a similar lookup in
- * com.android.googlesearch.SuggestionProvider#onCreate(). If you
- * change either of these functions, change them both. (The same is
- * true for the underlying resource strings, which are stored in
- * mcc-specific xml files.)
- */
- Locale l = Locale.getDefault();
- QuickSearch_G = getResources().getString(
- R.string.google_search_base, l.getLanguage(),
- l.getCountry().toLowerCase())
- + "client=ms-"
- + Partner.getString(this.getContentResolver(), Partner.CLIENT_ID)
- + "&source=android-" + GOOGLE_SEARCH_SOURCE_SUGGEST + "&q=%s";
- } else {
- QuickSearch_G = url;
- }
+ return URLUtil.composeSearchUrl(inUrl, QuickSearch_G, QUERY_PLACE_HOLDER);
}
private final static int LOCK_ICON_UNSECURE = 0;
@@ -4600,9 +4701,8 @@
new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.FILL_PARENT,
ViewGroup.LayoutParams.FILL_PARENT);
- // We may provide UI to customize these
- // Google search from the browser
- static String QuickSearch_G;
+ // Google search
+ final static String QuickSearch_G = "http://www.google.com/m?q=%s";
// Wikipedia search
final static String QuickSearch_W = "http://en.wikipedia.org/w/index.php?search=%s&go=Go";
// Dictionary search
@@ -4658,4 +4758,60 @@
// the frenquency of checking whether system memory is low
final static int CHECK_MEMORY_INTERVAL = 30000; // 30 seconds
+
+ /**
+ * A UrlData class to abstract how the content will be set to WebView.
+ * This base class uses loadUrl to show the content.
+ */
+ private static class UrlData {
+ String mUrl;
+ byte[] mPostData;
+
+ UrlData(String url) {
+ this.mUrl = url;
+ }
+
+ void setPostData(byte[] postData) {
+ mPostData = postData;
+ }
+
+ boolean isEmpty() {
+ return mUrl == null || mUrl.length() == 0;
+ }
+
+ public void loadIn(WebView webView) {
+ if (mPostData != null) {
+ webView.postUrl(mUrl, mPostData);
+ } else {
+ webView.loadUrl(mUrl);
+ }
+ }
+ };
+
+ /**
+ * A subclass of UrlData class that can display inlined content using
+ * {@link WebView#loadDataWithBaseURL(String, String, String, String, String)}.
+ */
+ private static class InlinedUrlData extends UrlData {
+ InlinedUrlData(String inlined, String mimeType, String encoding, String failUrl) {
+ super(failUrl);
+ mInlined = inlined;
+ mMimeType = mimeType;
+ mEncoding = encoding;
+ }
+ String mMimeType;
+ String mInlined;
+ String mEncoding;
+ @Override
+ boolean isEmpty() {
+ return mInlined == null || mInlined.length() == 0 || super.isEmpty();
+ }
+
+ @Override
+ public void loadIn(WebView webView) {
+ webView.loadDataWithBaseURL(null, mInlined, mMimeType, mEncoding, mUrl);
+ }
+ }
+
+ private static final UrlData EMPTY_URL_DATA = new UrlData(null);
}
diff --git a/src/com/android/browser/BrowserPreferencesPage.java b/src/com/android/browser/BrowserPreferencesPage.java
index 5d6795b..3b747d1 100644
--- a/src/com/android/browser/BrowserPreferencesPage.java
+++ b/src/com/android/browser/BrowserPreferencesPage.java
@@ -51,6 +51,12 @@
getPreferenceScreen().getSharedPreferences()
.getString(BrowserSettings.PREF_TEXT_SIZE, null)) );
+ e = findPreference(BrowserSettings.PREF_DEFAULT_ZOOM);
+ e.setOnPreferenceChangeListener(this);
+ e.setSummary(getVisualDefaultZoomName(
+ getPreferenceScreen().getSharedPreferences()
+ .getString(BrowserSettings.PREF_DEFAULT_ZOOM, null)) );
+
e = findPreference(BrowserSettings.PREF_DEFAULT_TEXT_ENCODING);
e.setOnPreferenceChangeListener(this);
@@ -104,6 +110,9 @@
} else if (pref.getKey().equals(BrowserSettings.PREF_TEXT_SIZE)) {
pref.setSummary(getVisualTextSizeName((String) objValue));
return true;
+ } else if (pref.getKey().equals(BrowserSettings.PREF_DEFAULT_ZOOM)) {
+ pref.setSummary(getVisualDefaultZoomName((String) objValue));
+ return true;
} else if (pref.getKey().equals(
BrowserSettings.PREF_DEFAULT_TEXT_ENCODING)) {
pref.setSummary((String) objValue);
@@ -126,24 +135,44 @@
}
return true;
}
-
+
private CharSequence getVisualTextSizeName(String enumName) {
- CharSequence[] visualNames =
- getResources().getTextArray(R.array.pref_text_size_choices);
- CharSequence[] enumNames =
- getResources().getTextArray(R.array.pref_text_size_values);
-
+ CharSequence[] visualNames = getResources().getTextArray(
+ R.array.pref_text_size_choices);
+ CharSequence[] enumNames = getResources().getTextArray(
+ R.array.pref_text_size_values);
+
// Sanity check
if (visualNames.length != enumNames.length) {
return "";
}
-
+
for (int i = 0; i < enumNames.length; i++) {
if (enumNames[i].equals(enumName)) {
return visualNames[i];
}
}
-
+
+ return "";
+ }
+
+ private CharSequence getVisualDefaultZoomName(String enumName) {
+ CharSequence[] visualNames = getResources().getTextArray(
+ R.array.pref_default_zoom_choices);
+ CharSequence[] enumNames = getResources().getTextArray(
+ R.array.pref_default_zoom_values);
+
+ // Sanity check
+ if (visualNames.length != enumNames.length) {
+ return "";
+ }
+
+ for (int i = 0; i < enumNames.length; i++) {
+ if (enumNames[i].equals(enumName)) {
+ return visualNames[i];
+ }
+ }
+
return "";
}
}
diff --git a/src/com/android/browser/BrowserProvider.java b/src/com/android/browser/BrowserProvider.java
index 42e22a5..bc12bde 100644
--- a/src/com/android/browser/BrowserProvider.java
+++ b/src/com/android/browser/BrowserProvider.java
@@ -17,33 +17,38 @@
package com.android.browser;
import com.google.android.providers.GoogleSettings.Partner;
-import java.util.Date;
-import android.app.ISearchManager;
import android.app.SearchManager;
import android.content.ComponentName;
import android.content.ContentProvider;
import android.content.ContentUris;
-import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.UriMatcher;
import android.content.SharedPreferences.Editor;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
import android.database.AbstractCursor;
+import android.database.ContentObserver;
import android.database.Cursor;
-import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
-import android.os.RemoteException;
-import android.os.ServiceManager;
-import android.os.SystemProperties;
+import android.os.Handler;
import android.preference.PreferenceManager;
import android.provider.Browser;
-import android.util.Log;
+import android.provider.Settings;
import android.server.search.SearchableInfo;
+import android.text.TextUtils;
import android.text.util.Regex;
+import android.util.Log;
+import android.util.TypedValue;
+
+import java.util.Date;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
public class BrowserProvider extends ContentProvider {
@@ -62,9 +67,10 @@
private static final String[] SUGGEST_PROJECTION = new String[] {
"_id", "url", "title", "bookmark"
};
- private static final String SUGGEST_SELECTION =
- "url LIKE ? OR url LIKE ? OR url LIKE ? OR url LIKE ?";
- private String[] SUGGEST_ARGS = new String[4];
+ private static final String SUGGEST_SELECTION =
+ "url LIKE ? OR url LIKE ? OR url LIKE ? OR url LIKE ?"
+ + " OR title LIKE ?";
+ private String[] SUGGEST_ARGS = new String[5];
// shared suggestion array index, make sure to match COLUMNS
private static final int SUGGEST_COLUMN_INTENT_ACTION_ID = 1;
@@ -74,6 +80,7 @@
private static final int SUGGEST_COLUMN_ICON_1_ID = 5;
private static final int SUGGEST_COLUMN_ICON_2_ID = 6;
private static final int SUGGEST_COLUMN_QUERY_ID = 7;
+ private static final int SUGGEST_COLUMN_FORMAT = 8;
// shared suggestion columns
private static final String[] COLUMNS = new String[] {
@@ -84,7 +91,8 @@
SearchManager.SUGGEST_COLUMN_TEXT_2,
SearchManager.SUGGEST_COLUMN_ICON_1,
SearchManager.SUGGEST_COLUMN_ICON_2,
- SearchManager.SUGGEST_COLUMN_QUERY};
+ SearchManager.SUGGEST_COLUMN_QUERY,
+ SearchManager.SUGGEST_COLUMN_FORMAT};
private static final int MAX_SUGGESTION_SHORT_ENTRIES = 3;
private static final int MAX_SUGGESTION_LONG_ENTRIES = 6;
@@ -97,6 +105,7 @@
private static final int URI_MATCH_SEARCHES_ID = 11;
//
private static final int URI_MATCH_SUGGEST = 20;
+ private static final int URI_MATCH_BOOKMARKS_SUGGEST = 21;
private static final UriMatcher URI_MATCHER;
@@ -112,6 +121,9 @@
URI_MATCH_SEARCHES_ID);
URI_MATCHER.addURI("browser", SearchManager.SUGGEST_URI_PATH_QUERY,
URI_MATCH_SUGGEST);
+ URI_MATCHER.addURI("browser",
+ TABLE_NAMES[URI_MATCH_BOOKMARKS] + "/" + SearchManager.SUGGEST_URI_PATH_QUERY,
+ URI_MATCH_BOOKMARKS_SUGGEST);
}
// 1 -> 2 add cache table
@@ -133,15 +145,27 @@
// 18 -> 19 Remove labels table
private static final int DATABASE_VERSION = 19;
+ // Regular expression which matches http://, followed by some stuff, followed by
+ // optionally a trailing slash, all matched as separate groups.
+ private static final Pattern STRIP_URL_PATTERN = Pattern.compile("^(http://)(.*?)(/$)?");
+
+ private SearchManager mSearchManager;
+
+ // The hex color string to be applied to urls of website suggestions, as derived from
+ // the current theme. This is not set until/unless beautifyUrl is called, at which point
+ // this variable caches the color value.
+ private static String mSearchUrlColorHex;
+
public BrowserProvider() {
}
-
+
private static CharSequence replaceSystemPropertyInString(Context context, CharSequence srcString) {
StringBuffer sb = new StringBuffer();
int lastCharLoc = 0;
-
- final String client_id = Partner.getString(context.getContentResolver(), Partner.CLIENT_ID);
+
+ final String client_id = Partner.getString(context.getContentResolver(),
+ Partner.CLIENT_ID, "android-google");
for (int i = 0; i < srcString.length(); ++i) {
char c = srcString.charAt(i);
@@ -202,7 +226,7 @@
CharSequence bookmarkDestination = replaceSystemPropertyInString(mContext, bookmarks[i + 1]);
db.execSQL("INSERT INTO bookmarks (title, url, visits, " +
"date, created, bookmark)" + " VALUES('" +
- bookmarks[i] + "', '" + bookmarkDestination +
+ bookmarks[i] + "', '" + bookmarkDestination +
"', 0, 0, 0, 1);");
}
} catch (ArrayIndexOutOfBoundsException e) {
@@ -233,7 +257,7 @@
public boolean onCreate() {
final Context context = getContext();
mOpenHelper = new DatabaseHelper(context);
- // we added "picasa web album" into default bookmarks for version 19.
+ // we added "picasa web album" into default bookmarks for version 19.
// To avoid erasing the bookmark table, we added it explicitly for
// version 18 and 19 as in the other cases, we will erase the table.
if (DATABASE_VERSION == 18 || DATABASE_VERSION == 19) {
@@ -247,9 +271,66 @@
ed.commit();
}
}
+ mSearchManager = (SearchManager) context.getSystemService(Context.SEARCH_SERVICE);
+ mShowWebSuggestionsSettingChangeObserver
+ = new ShowWebSuggestionsSettingChangeObserver();
+ context.getContentResolver().registerContentObserver(
+ Settings.System.getUriFor(
+ Settings.System.SHOW_WEB_SUGGESTIONS),
+ true, mShowWebSuggestionsSettingChangeObserver);
+ updateShowWebSuggestions();
return true;
}
+ /**
+ * This Observer will ensure that if the user changes the system
+ * setting of whether to display web suggestions, we will
+ * change accordingly.
+ */
+ /* package */ class ShowWebSuggestionsSettingChangeObserver
+ extends ContentObserver {
+ public ShowWebSuggestionsSettingChangeObserver() {
+ super(new Handler());
+ }
+
+ @Override
+ public void onChange(boolean selfChange) {
+ updateShowWebSuggestions();
+ }
+ }
+
+ private ShowWebSuggestionsSettingChangeObserver
+ mShowWebSuggestionsSettingChangeObserver;
+
+ // If non-null, then the system is set to show web suggestions,
+ // and this is the SearchableInfo to use to get them.
+ private SearchableInfo mSearchableInfo;
+
+ /**
+ * Check the system settings to see whether web suggestions are
+ * allowed. If so, store the SearchableInfo to grab suggestions
+ * while the user is typing.
+ */
+ private void updateShowWebSuggestions() {
+ mSearchableInfo = null;
+ Context context = getContext();
+ if (Settings.System.getInt(context.getContentResolver(),
+ Settings.System.SHOW_WEB_SUGGESTIONS,
+ 1 /* default on */) == 1) {
+ Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
+ intent.addCategory(Intent.CATEGORY_DEFAULT);
+ ResolveInfo info = context.getPackageManager().resolveActivity(
+ intent, PackageManager.MATCH_DEFAULT_ONLY);
+ if (info != null) {
+ ComponentName googleSearchComponent =
+ new ComponentName(info.activityInfo.packageName,
+ info.activityInfo.name);
+ mSearchableInfo = mSearchManager.getSearchableInfo(
+ googleSearchComponent, false);
+ }
+ }
+ }
+
private void fixPicasaBookmark() {
SQLiteDatabase db = mOpenHelper.getWritableDatabase();
Cursor cursor = db.rawQuery("SELECT _id FROM bookmarks WHERE " +
@@ -274,9 +355,9 @@
* Subclass AbstractCursor so we can combine multiple Cursors and add
* "Google Search".
* Here are the rules.
- * 1. We only have MAX_SUGGESTION_LONG_ENTRIES in the list plus
+ * 1. We only have MAX_SUGGESTION_LONG_ENTRIES in the list plus
* "Google Search";
- * 2. If bookmark/history entries are less than
+ * 2. If bookmark/history entries are less than
* (MAX_SUGGESTION_SHORT_ENTRIES -1), we include Google suggest.
*/
private class MySuggestionCursor extends AbstractCursor {
@@ -286,6 +367,9 @@
private int mSuggestionCount;
private boolean mBeyondCursor;
private String mString;
+ private int mSuggestText1Id;
+ private int mSuggestText2Id;
+ private int mSuggestQueryId;
public MySuggestionCursor(Cursor hc, Cursor sc, String string) {
mHistoryCursor = hc;
@@ -297,6 +381,22 @@
}
mString = string;
mBeyondCursor = false;
+
+ // Some web suggest providers only give suggestions and have no description string for
+ // items. The order of the result columns may be different as well. So retrieve the
+ // column indices for the fields we need now and check before using below.
+ if (mSuggestCursor == null) {
+ mSuggestText1Id = -1;
+ mSuggestText2Id = -1;
+ mSuggestQueryId = -1;
+ } else {
+ mSuggestText1Id = mSuggestCursor.getColumnIndex(
+ SearchManager.SUGGEST_COLUMN_TEXT_1);
+ mSuggestText2Id = mSuggestCursor.getColumnIndex(
+ SearchManager.SUGGEST_COLUMN_TEXT_2);
+ mSuggestQueryId = mSuggestCursor.getColumnIndex(
+ SearchManager.SUGGEST_COLUMN_QUERY);
+ }
}
@Override
@@ -350,20 +450,22 @@
case SUGGEST_COLUMN_TEXT_1_ID:
if (mHistoryCount > mPos) {
- return mHistoryCursor.getString(1);
+ return getHistoryTitle();
} else if (!mBeyondCursor) {
- return mSuggestCursor.getString(1);
+ if (mSuggestText1Id == -1) return null;
+ return mSuggestCursor.getString(mSuggestText1Id);
} else {
return mString;
}
case SUGGEST_COLUMN_TEXT_2_ID:
if (mHistoryCount > mPos) {
- return mHistoryCursor.getString(2);
+ return getHistorySubtitle();
} else if (!mBeyondCursor) {
- return mSuggestCursor.getString(2);
+ if (mSuggestText2Id == -1) return null;
+ return mSuggestCursor.getString(mSuggestText2Id);
} else {
- return getContext().getString(R.string.search_google);
+ return getContext().getString(R.string.search_the_web);
}
case SUGGEST_COLUMN_ICON_1_ID:
@@ -388,12 +490,20 @@
case SUGGEST_COLUMN_QUERY_ID:
if (mHistoryCount > mPos) {
- return null;
+ // Return the url in the intent query column. This is ignored
+ // within the browser because our searchable is set to
+ // android:searchMode="queryRewriteFromData", but it is used by
+ // global search for query rewriting.
+ return mHistoryCursor.getString(1);
} else if (!mBeyondCursor) {
- return mSuggestCursor.getString(3);
+ if (mSuggestQueryId == -1) return null;
+ return mSuggestCursor.getString(mSuggestQueryId);
} else {
return mString;
}
+
+ case SUGGEST_COLUMN_FORMAT:
+ return "html";
}
}
return null;
@@ -460,11 +570,61 @@
mSuggestCursor = null;
}
}
+
+ /**
+ * Provides the title (text line 1) for a browser suggestion, which should be the
+ * webpage title. If the webpage title is empty, returns the stripped url instead.
+ *
+ * @return the title string to use
+ */
+ private String getHistoryTitle() {
+ String title = mHistoryCursor.getString(2 /* webpage title */);
+ if (TextUtils.isEmpty(title) || TextUtils.getTrimmedLength(title) == 0) {
+ title = beautifyUrl(mHistoryCursor.getString(1 /* url */));
+ }
+ return title;
+ }
+
+ /**
+ * Provides the subtitle (text line 2) for a browser suggestion, which should be the
+ * webpage url. If the webpage title is empty, then the url should go in the title
+ * instead, and the subtitle should be empty, so this would return null.
+ *
+ * @return the subtitle string to use, or null if none
+ */
+ private String getHistorySubtitle() {
+ String title = mHistoryCursor.getString(2 /* webpage title */);
+ if (TextUtils.isEmpty(title) || TextUtils.getTrimmedLength(title) == 0) {
+ return null;
+ } else {
+ return beautifyUrl(mHistoryCursor.getString(1 /* url */));
+ }
+ }
+
+ /**
+ * Strips "http://" from the beginning of a url and "/" from the end,
+ * and adds html formatting to make it green.
+ */
+ private String beautifyUrl(String url) {
+ if (mSearchUrlColorHex == null) {
+ // Get the color used for this purpose from the current theme.
+ TypedValue colorValue = new TypedValue();
+ getContext().getTheme().resolveAttribute(
+ com.android.internal.R.attr.textColorSearchUrl, colorValue, true);
+ int color = getContext().getResources().getColor(colorValue.resourceId);
+
+ // Convert the int color value into a hex string, and strip the first two
+ // characters which will be the alpha transparency (html doesn't want this).
+ mSearchUrlColorHex = Integer.toHexString(color).substring(2);
+ }
+
+ return "<font color=\"#" + mSearchUrlColorHex + "\">" + stripUrl(url) + "</font>";
+ }
}
@Override
public Cursor query(Uri url, String[] projectionIn, String selection,
- String[] selectionArgs, String sortOrder)
+ String[] selectionArgs, String sortOrder)
throws IllegalStateException {
SQLiteDatabase db = mOpenHelper.getReadableDatabase();
@@ -473,7 +633,7 @@
throw new IllegalArgumentException("Unknown URL");
}
- if (match == URI_MATCH_SUGGEST) {
+ if (match == URI_MATCH_SUGGEST || match == URI_MATCH_BOOKMARKS_SUGGEST) {
String suggestSelection;
String [] myArgs;
if (selectionArgs[0] == null || selectionArgs[0].equals("")) {
@@ -490,6 +650,8 @@
SUGGEST_ARGS[1] = "http://www." + like;
SUGGEST_ARGS[2] = "https://" + like;
SUGGEST_ARGS[3] = "https://www." + like;
+ // To match against titles.
+ SUGGEST_ARGS[4] = like;
myArgs = SUGGEST_ARGS;
suggestSelection = SUGGEST_SELECTION;
}
@@ -500,49 +662,16 @@
ORDER_BY,
(new Integer(MAX_SUGGESTION_LONG_ENTRIES)).toString());
- if (Regex.WEB_URL_PATTERN.matcher(selectionArgs[0]).matches()) {
+ if (match == URI_MATCH_BOOKMARKS_SUGGEST
+ || Regex.WEB_URL_PATTERN.matcher(selectionArgs[0]).matches()) {
return new MySuggestionCursor(c, null, "");
} else {
// get Google suggest if there is still space in the list
if (myArgs != null && myArgs.length > 1
+ && mSearchableInfo != null
&& c.getCount() < (MAX_SUGGESTION_SHORT_ENTRIES - 1)) {
- ISearchManager sm = ISearchManager.Stub
- .asInterface(ServiceManager
- .getService(Context.SEARCH_SERVICE));
- SearchableInfo si = null;
- try {
- // use the global search to get Google suggest provider
- si = sm.getSearchableInfo(new ComponentName(
- getContext(), "com.android.browser"), true);
-
- // similar to the getSuggestions() in SearchDialog.java
- StringBuilder uriStr = new StringBuilder("content://");
- uriStr.append(si.getSuggestAuthority());
- // if content path provided, insert it now
- final String contentPath = si.getSuggestPath();
- if (contentPath != null) {
- uriStr.append('/');
- uriStr.append(contentPath);
- }
- // append standard suggestion query path
- uriStr.append('/' + SearchManager.SUGGEST_URI_PATH_QUERY);
- // inject query, either as selection args or inline
- String[] selArgs = null;
- if (si.getSuggestSelection() != null) {
- selArgs = new String[] {selectionArgs[0]};
- } else {
- uriStr.append('/');
- uriStr.append(Uri.encode(selectionArgs[0]));
- }
-
- // finally, make the query
- Cursor sc = getContext().getContentResolver().query(
- Uri.parse(uriStr.toString()), null,
- si.getSuggestSelection(), selArgs, null);
-
- return new MySuggestionCursor(c, sc, selectionArgs[0]);
- } catch (RemoteException e) {
- }
+ Cursor sc = mSearchManager.getSuggestions(mSearchableInfo, selectionArgs[0]);
+ return new MySuggestionCursor(c, sc, selectionArgs[0]);
}
return new MySuggestionCursor(c, null, selectionArgs[0]);
}
@@ -694,4 +823,26 @@
getContext().getContentResolver().notifyChange(url, null);
return ret;
}
+
+ /**
+ * Strips the provided url of preceding "http://" and any trailing "/". Does not
+ * strip "https://". If the provided string cannot be stripped, the original string
+ * is returned.
+ *
+ * TODO: Put this in TextUtils to be used by other packages doing something similar.
+ *
+ * @param url a url to strip, like "http://www.google.com/"
+ * @return a stripped url like "www.google.com", or the original string if it could
+ * not be stripped
+ */
+ private static String stripUrl(String url) {
+ if (url == null) return null;
+ Matcher m = STRIP_URL_PATTERN.matcher(url);
+ if (m.matches() && m.groupCount() == 3) {
+ return m.group(2);
+ } else {
+ return url;
+ }
+ }
+
}
diff --git a/src/com/android/browser/BrowserSearchpagePreference.java b/src/com/android/browser/BrowserSearchpagePreference.java
deleted file mode 100644
index 09e8993..0000000
--- a/src/com/android/browser/BrowserSearchpagePreference.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.browser;
-
-import android.app.AlertDialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.preference.EditTextPreference;
-import android.text.Editable;
-import android.text.TextWatcher;
-import android.text.util.Regex;
-import android.util.AttributeSet;
-
-public class BrowserSearchpagePreference extends EditTextPreference implements
- TextWatcher {
-
- public BrowserSearchpagePreference(Context context, AttributeSet attrs,
- int defStyle) {
- super(context, attrs, defStyle);
- getEditText().addTextChangedListener(this);
- }
-
- public BrowserSearchpagePreference(Context context, AttributeSet attrs) {
- super(context, attrs);
- getEditText().addTextChangedListener(this);
- }
-
- public BrowserSearchpagePreference(Context context) {
- super(context);
- getEditText().addTextChangedListener(this);
- }
-
- public void afterTextChanged(Editable s) {
- AlertDialog dialog = (AlertDialog) getDialog();
- // This callback is called before the dialog has been fully constructed
- if (dialog != null) {
- String string = s.toString();
- int length = string.length();
- int first = length > 0 ? string
- .indexOf(BrowserActivity.QUERY_PLACE_HOLDER) : -1;
- int last = length > 0 ? string
- .lastIndexOf(BrowserActivity.QUERY_PLACE_HOLDER) : -1;
- dialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(
- length == 0 || (first > 0 && first == last));
- }
- }
-
- public void beforeTextChanged(CharSequence s, int start, int count,
- int after) {
- }
-
- public void onTextChanged(CharSequence s, int start, int before, int count) {
- }
-}
diff --git a/src/com/android/browser/BrowserSettings.java b/src/com/android/browser/BrowserSettings.java
index 0e2c5af..a5e23c9 100644
--- a/src/com/android/browser/BrowserSettings.java
+++ b/src/com/android/browser/BrowserSettings.java
@@ -18,15 +18,10 @@
import com.google.android.providers.GoogleSettings.Partner;
-import android.app.Activity;
import android.content.ContentResolver;
import android.content.Context;
-import android.content.pm.ActivityInfo;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
-import android.os.SystemProperties;
-import android.view.WindowManager;
-import android.webkit.CacheManager;
import android.webkit.CookieManager;
import android.webkit.WebView;
import android.webkit.WebViewDatabase;
@@ -67,7 +62,7 @@
private boolean saveFormData = true;
private boolean openInBackground = false;
private String defaultTextEncodingName;
- private String homeUrl = "http://www.google.com/m?client=ms-";
+ private String homeUrl = "";
private boolean loginInitialized = false;
private boolean autoFitPage = true;
private boolean showDebugSettings = false;
@@ -90,6 +85,8 @@
private static int defaultFixedFontSize = 13;
private static WebSettings.TextSize textSize =
WebSettings.TextSize.NORMAL;
+ private static WebSettings.ZoomDensity zoomDensity =
+ WebSettings.ZoomDensity.MEDIUM;
// Preference keys that are used outside this class
public final static String PREF_CLEAR_CACHE = "privacy_clear_cache";
@@ -105,6 +102,7 @@
public final static String PREF_DEBUG_SETTINGS = "debug_menu";
public final static String PREF_GEARS_SETTINGS = "gears_settings";
public final static String PREF_TEXT_SIZE = "text_size";
+ public final static String PREF_DEFAULT_ZOOM = "default_zoom";
public final static String PREF_DEFAULT_TEXT_ENCODING =
"default_text_encoding";
@@ -169,6 +167,7 @@
s.setDefaultFixedFontSize(b.defaultFixedFontSize);
s.setNavDump(b.navDump);
s.setTextSize(b.textSize);
+ s.setDefaultZoom(b.zoomDensity);
s.setLightTouchEnabled(b.lightTouch);
s.setSaveFormData(b.saveFormData);
s.setSavePassword(b.rememberPasswords);
@@ -199,7 +198,7 @@
// local directory.
pluginsPath = ctx.getDir("plugins", 0).getPath();
- homeUrl += Partner.getString(ctx.getContentResolver(), Partner.CLIENT_ID);
+ homeUrl = getFactoryResetHomeUrl(ctx);
// Load the defaults from the xml
// This call is TOO SLOW, need to manually keep the defaults
@@ -236,6 +235,8 @@
loginInitialized = p.getBoolean("login_initialized", loginInitialized);
textSize = WebSettings.TextSize.valueOf(
p.getString(PREF_TEXT_SIZE, textSize.name()));
+ zoomDensity = WebSettings.ZoomDensity.valueOf(
+ p.getString(PREF_DEFAULT_ZOOM, zoomDensity.name()));
autoFitPage = p.getBoolean("autofit_pages", autoFitPage);
useWideViewPort = true; // use wide view port for either setting
if (autoFitPage) {
@@ -272,8 +273,6 @@
navDump = p.getBoolean("enable_nav_dump", navDump);
doFlick = p.getBoolean("enable_flick", doFlick);
userAgent = Integer.parseInt(p.getString("user_agent", "0"));
- mTabControl.getBrowserActivity().setBaseSearchUrl(
- p.getString("search_url", ""));
}
update();
}
@@ -310,6 +309,10 @@
return textSize;
}
+ public WebSettings.ZoomDensity getDefaultZoom() {
+ return zoomDensity;
+ }
+
public boolean openInBackground() {
return openInBackground;
}
@@ -439,6 +442,17 @@
p.edit().clear().commit();
PreferenceManager.setDefaultValues(context, R.xml.browser_preferences,
true);
+ // reset homeUrl
+ setHomePage(context, getFactoryResetHomeUrl(context));
+ }
+
+ private String getFactoryResetHomeUrl(Context context) {
+ String url = context.getResources().getString(R.string.homepage_base);
+ if (url.indexOf("{CID}") != -1) {
+ url = url.replace("{CID}", Partner.getString(context
+ .getContentResolver(), Partner.CLIENT_ID, "android-google"));
+ }
+ return url;
}
// Private constructor that does nothing.
diff --git a/src/com/android/browser/FakeWebView.java b/src/com/android/browser/FakeWebView.java
index 633b799..da5ef5f 100644
--- a/src/com/android/browser/FakeWebView.java
+++ b/src/com/android/browser/FakeWebView.java
@@ -33,17 +33,9 @@
* overrides ImageView so it can be used for the new tab image as well.
*/
public class FakeWebView extends ImageView {
- private TabControl.Tab mTab;
- private Picture mPicture;
+ private TabControl.PickerData mPickerData;
private boolean mUsesResource;
- private class Listener implements WebView.PictureListener {
- public void onNewPicture(WebView view, Picture p) {
- FakeWebView.this.mPicture = p;
- FakeWebView.this.invalidate();
- }
- };
-
public FakeWebView(Context context) {
this(context, null);
}
@@ -68,17 +60,21 @@
// would be nice to know if the picture is empty so we can avoid
// drawing white.
canvas.drawColor(Color.WHITE);
- if (mTab != null) {
- final WebView w = mTab.getTopWindow();
- if (w != null) {
- if (mPicture != null) {
- canvas.save();
- float scale = getWidth() * w.getScale() / w.getWidth();
- canvas.scale(scale, scale);
- canvas.translate(-w.getScrollX(), -w.getScrollY());
- canvas.drawPicture(mPicture);
- canvas.restore();
+ if (mPickerData != null) {
+ final Picture p = mPickerData.mPicture;
+ if (p != null) {
+ canvas.save();
+ float scale = getWidth() * mPickerData.mScale
+ / mPickerData.mWidth;
+ // Check for NaN and infinity.
+ if (Float.isNaN(scale) || Float.isInfinite(scale)) {
+ scale = 1.0f;
}
+ canvas.scale(scale, scale);
+ canvas.translate(-mPickerData.mScrollX,
+ -mPickerData.mScrollY);
+ canvas.drawPicture(p);
+ canvas.restore();
}
}
}
@@ -87,25 +83,24 @@
@Override
public void setImageResource(int resId) {
mUsesResource = true;
- mTab = null;
+ mPickerData = null;
super.setImageResource(resId);
}
/**
* Set a WebView for this FakeWebView to represent.
- * @param v WebView whose picture and other data will be used in onDraw.
+ * @param t The tab whose picture and other data will be used in onDraw.
*/
public void setTab(TabControl.Tab t) {
mUsesResource = false;
- mTab = t;
- if (t != null && t.getWebView() != null) {
- Listener l = new Listener();
- if (t.getSubWebView() != null) {
- t.getSubWebView().setPictureListener(l);
- } else {
- t.getWebView().setPictureListener(l);
- }
- mPicture = mTab.getTopWindow().capturePicture();
+ if (mPickerData != null) {
+ // Clear the old tab's view first
+ mPickerData.mFakeWebView = null;
+ }
+ mPickerData = null;
+ if (t != null && t.getPickerData() != null) {
+ mPickerData = t.getPickerData();
+ mPickerData.mFakeWebView = this;
}
}
}
diff --git a/src/com/android/browser/GearsNativeDialog.java b/src/com/android/browser/GearsNativeDialog.java
index ecf166d..b44ec2a 100644
--- a/src/com/android/browser/GearsNativeDialog.java
+++ b/src/com/android/browser/GearsNativeDialog.java
@@ -23,7 +23,6 @@
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
-import android.util.Config;
import android.util.Log;
import android.view.Gravity;
import android.view.KeyEvent;
@@ -137,7 +136,7 @@
return;
}
- if (Config.LOGV) {
+ if (Browser.LOGV_ENABLED) {
Log.v(TAG, "dialogtype: " + dialogTypeString);
}
diff --git a/src/com/android/browser/ImageAdapter.java b/src/com/android/browser/ImageAdapter.java
index e957143..f95753a 100644
--- a/src/com/android/browser/ImageAdapter.java
+++ b/src/com/android/browser/ImageAdapter.java
@@ -27,7 +27,6 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.LayoutInflater;
-import android.webkit.WebView;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.TextView;
@@ -73,22 +72,10 @@
* Clear the internal WebViews and remove their picture listeners.
*/
public void clear() {
- for (TabControl.Tab t : mItems) {
- clearPictureListeners(t);
- }
mItems.clear();
notifyObservers();
}
- private void clearPictureListeners(TabControl.Tab t) {
- if (t.getWebView() != null) {
- t.getWebView().setPictureListener(null);
- if (t.getSubWebView() != null) {
- t.getSubWebView().setPictureListener(null);
- }
- }
- }
-
/**
* Add a new window web page to the grid
*
@@ -113,7 +100,7 @@
*/
public void remove(int index) {
if (index >= 0 && index < mItems.size()) {
- clearPictureListeners(mItems.remove(index));
+ mItems.remove(index);
notifyObservers();
mMaxedOut = false;
}
diff --git a/src/com/android/browser/ImageGrid.java b/src/com/android/browser/ImageGrid.java
index 9eccb16..9967f36 100644
--- a/src/com/android/browser/ImageGrid.java
+++ b/src/com/android/browser/ImageGrid.java
@@ -17,7 +17,6 @@
package com.android.browser;
import android.content.Context;
-import android.util.Config;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.KeyEvent;
@@ -109,7 +108,7 @@
* @param index Window to remove, from 0 to MAX_TABS-1
*/
public void remove(int index) {
- if (Config.DEBUG && (index < 0 || index >= TabControl.MAX_TABS)) {
+ if (Browser.DEBUG && (index < 0 || index >= TabControl.MAX_TABS)) {
throw new AssertionError();
}
mAdapter.remove(index);
diff --git a/src/com/android/browser/TabControl.java b/src/com/android/browser/TabControl.java
index ee63f2c..575be8d 100644
--- a/src/com/android/browser/TabControl.java
+++ b/src/com/android/browser/TabControl.java
@@ -17,10 +17,10 @@
package com.android.browser;
import android.content.Context;
+import android.graphics.Picture;
import android.net.http.SslError;
import android.os.Bundle;
import android.os.Message;
-import android.util.Config;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -40,6 +40,7 @@
import android.widget.ImageButton;
import java.io.File;
+import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Vector;
@@ -126,7 +127,7 @@
}
@Override
public void onCloseWindow(WebView window) {
- if (Config.DEBUG && window != mTab.mSubView) {
+ if (Browser.DEBUG && window != mTab.mSubView) {
throw new AssertionError("Can't close the window");
}
mActivity.dismissSubWindow(mTab);
@@ -143,10 +144,24 @@
}
}
+ // Extra saved information for displaying the tab in the picker.
+ public static class PickerData {
+ String mUrl;
+ String mTitle;
+ float mScale;
+ int mScrollX;
+ int mScrollY;
+ int mWidth;
+ Picture mPicture;
+ // This can be null. When a new picture comes in, this view should be
+ // invalidated to show the new picture.
+ FakeWebView mFakeWebView;
+ }
+
/**
* Private class for maintaining Tabs with a main WebView and a subwindow.
*/
- public class Tab {
+ public class Tab implements WebView.PictureListener {
// Main WebView
private WebView mMainView;
// Subwindow WebView
@@ -161,10 +176,9 @@
// information needed to restore the WebView if the user goes back to
// the tab.
private Bundle mSavedState;
- // Extra saved information for displaying the tab in the picker.
- private String mUrl;
- private String mTitle;
-
+ // Data used when displaying the tab in the picker.
+ private PickerData mPickerData;
+
// Parent Tab. This is the Tab that created this Tab, or null
// if the Tab was created by the UI
private Tab mParentTab;
@@ -235,7 +249,10 @@
* @return The WebView's url or null.
*/
public String getUrl() {
- return mUrl;
+ if (mPickerData != null) {
+ return mPickerData.mUrl;
+ }
+ return null;
}
/**
@@ -246,7 +263,17 @@
* @return The WebView's title (or url) or null.
*/
public String getTitle() {
- return mTitle;
+ if (mPickerData != null) {
+ return mPickerData.mTitle;
+ }
+ return null;
+ }
+
+ /**
+ * Returns the picker data.
+ */
+ public PickerData getPickerData() {
+ return mPickerData;
}
private void setParentTab(Tab parent) {
@@ -308,6 +335,18 @@
public boolean closeOnExit() {
return mCloseOnExit;
}
+
+ public void onNewPicture(WebView view, Picture p) {
+ if (mPickerData == null) {
+ return;
+ }
+
+ mPickerData.mPicture = p;
+ // Tell the FakeWebView to redraw.
+ if (mPickerData.mFakeWebView != null) {
+ mPickerData.mFakeWebView.invalidate();
+ }
+ }
};
// Directory to store thumbnails for each WebView.
@@ -484,8 +523,8 @@
// This tab may have been pushed in to the background and then closed.
// If the saved state contains a picture file, delete the file.
if (t.mSavedState != null) {
- if (t.mSavedState.containsKey("picture")) {
- new File(t.mSavedState.getString("picture")).delete();
+ if (t.mSavedState.containsKey(CURRPICTURE)) {
+ new File(t.mSavedState.getString(CURRPICTURE)).delete();
}
}
@@ -544,6 +583,8 @@
private static final String CURRTAB = "currentTab";
private static final String CURRURL = "currentUrl";
private static final String CURRTITLE = "currentTitle";
+ private static final String CURRWIDTH = "currentWidth";
+ private static final String CURRPICTURE = "currentPicture";
private static final String CLOSEONEXIT = "closeonexit";
private static final String PARENTTAB = "parentTab";
private static final String APPID = "appid";
@@ -596,8 +637,7 @@
Tab t = new Tab(null, false, null, null);
t.mSavedState = inState.getBundle(WEBVIEW + i);
if (t.mSavedState != null) {
- t.mUrl = t.mSavedState.getString(CURRURL);
- t.mTitle = t.mSavedState.getString(CURRTITLE);
+ populatePickerDataFromSavedState(t);
// Need to maintain the app id and original url so we
// can possibly reuse this tab.
t.mAppId = t.mSavedState.getString(APPID);
@@ -669,8 +709,9 @@
t = mTabQueue.get(i++);
} while (i < queueSize && t != null && t.mMainView == null);
- // Don't do anything if the last remaining tab is the current one.
- if (t == getCurrentTab()) {
+ // Don't do anything if the last remaining tab is the current one or if
+ // the last tab has been freed already.
+ if (t == getCurrentTab() || t.mMainView == null) {
return null;
}
@@ -793,8 +834,7 @@
// Clear the saved state except for the app id and close-on-exit
// values.
t.mSavedState = null;
- t.mUrl = null;
- t.mTitle = null;
+ t.mPickerData = null;
// Save the new url in order to avoid deleting the WebView.
t.mOriginalUrl = url;
return true;
@@ -919,30 +959,89 @@
}
/**
- * Ensure that Tab t has a title, url, and favicon.
+ * Ensure that Tab t has data to display in the tab picker.
* @param t Tab to populate.
*/
/* package */ void populatePickerData(Tab t) {
- if (t == null || t.mMainView == null) {
+ if (t == null) {
return;
}
+
+ // mMainView == null indicates that the tab has been freed.
+ if (t.mMainView == null) {
+ populatePickerDataFromSavedState(t);
+ return;
+ }
+
// FIXME: The only place we cared about subwindow was for
// bookmarking (i.e. not when saving state). Was this deliberate?
final WebBackForwardList list = t.mMainView.copyBackForwardList();
final WebHistoryItem item =
list != null ? list.getCurrentItem() : null;
populatePickerData(t, item);
+
+ // This method is only called during the tab picker creation. At this
+ // point we need to listen for new pictures since the WebView is still
+ // active.
+ final WebView w = t.getTopWindow();
+ w.setPictureListener(t);
+ // Capture the picture here instead of populatePickerData since it can
+ // be called when saving the state of a tab.
+ t.mPickerData.mPicture = w.capturePicture();
}
- // Populate the picker data
- private void populatePickerData(Tab t, WebHistoryItem item) {
- if (item != null) {
- t.mUrl = item.getUrl();
- t.mTitle = item.getTitle();
- if (t.mTitle == null) {
- t.mTitle = t.mUrl;
+ // Create the PickerData and populate it using the saved state of the tab.
+ private void populatePickerDataFromSavedState(Tab t) {
+ if (t.mSavedState == null) {
+ return;
+ }
+
+ final PickerData data = new PickerData();
+ final Bundle state = t.mSavedState;
+ data.mUrl = state.getString(CURRURL);
+ data.mTitle = state.getString(CURRTITLE);
+ data.mWidth = state.getInt(CURRWIDTH, 0);
+ // XXX: These keys are from WebView.savePicture so if they change, this
+ // will break.
+ data.mScale = state.getFloat("scale", 1.0f);
+ data.mScrollX = state.getInt("scrollX", 0);
+ data.mScrollY = state.getInt("scrollY", 0);
+
+ if (state.containsKey(CURRPICTURE)) {
+ final File f = new File(t.mSavedState.getString(CURRPICTURE));
+ try {
+ final FileInputStream in = new FileInputStream(f);
+ data.mPicture = Picture.createFromStream(in);
+ in.close();
+ } catch (Exception ex) {
+ // Ignore any problems with inflating the picture. We just
+ // won't draw anything.
}
}
+
+ // Set the tab's picker data.
+ t.mPickerData = data;
+ }
+
+ // Populate the picker data using the given history item and the current
+ // top WebView.
+ private void populatePickerData(Tab t, WebHistoryItem item) {
+ final PickerData data = new PickerData();
+ if (item != null) {
+ data.mUrl = item.getUrl();
+ data.mTitle = item.getTitle();
+ if (data.mTitle == null) {
+ data.mTitle = data.mUrl;
+ }
+ }
+ // We want to display the top window in the tab picker but use the url
+ // and title of the main window.
+ final WebView w = t.getTopWindow();
+ data.mWidth = w.getWidth();
+ data.mScale = w.getScale();
+ data.mScrollX = w.getScrollX();
+ data.mScrollY = w.getScrollY();
+ t.mPickerData = data;
}
/**
@@ -953,8 +1052,14 @@
for (int i = 0; i < size; i++) {
final Tab t = getTab(i);
if (t != null && t.mSavedState == null) {
- t.mUrl = null;
- t.mTitle = null;
+ t.mPickerData = null;
+ }
+ if (t.mMainView != null) {
+ // Clear the picture listeners.
+ t.mMainView.setPictureListener(null);
+ if (t.mSubView != null) {
+ t.mSubView.setPictureListener(null);
+ }
}
}
}
@@ -976,7 +1081,7 @@
final File f = new File(mThumbnailDir, w.hashCode()
+ "_pic.save");
if (w.savePicture(b, f)) {
- b.putString("picture", f.getPath());
+ b.putString(CURRPICTURE, f.getPath());
}
}
@@ -984,12 +1089,17 @@
final WebHistoryItem item =
list != null ? list.getCurrentItem() : null;
populatePickerData(t, item);
- if (t.mUrl != null) {
- b.putString(CURRURL, t.mUrl);
+
+ // XXX: WebView.savePicture stores the scale and scroll positions
+ // in the bundle so we don't have to do it here.
+ final PickerData data = t.mPickerData;
+ if (data.mUrl != null) {
+ b.putString(CURRURL, data.mUrl);
}
- if (t.mTitle != null) {
- b.putString(CURRTITLE, t.mTitle);
+ if (data.mTitle != null) {
+ b.putString(CURRTITLE, data.mTitle);
}
+ b.putInt(CURRWIDTH, data.mWidth);
b.putBoolean(CLOSEONEXIT, t.mCloseOnExit);
if (t.mAppId != null) {
b.putString(APPID, t.mAppId);
@@ -1020,8 +1130,7 @@
// Restore the internal state even if the WebView fails to restore.
// This will maintain the app id, original url and close-on-exit values.
t.mSavedState = null;
- t.mUrl = null;
- t.mTitle = null;
+ t.mPickerData = null;
t.mCloseOnExit = b.getBoolean(CLOSEONEXIT);
t.mAppId = b.getString(APPID);
t.mOriginalUrl = b.getString(ORIGINALURL);
@@ -1031,8 +1140,8 @@
if (list == null) {
return false;
}
- if (b.containsKey("picture")) {
- final File f = new File(b.getString("picture"));
+ if (b.containsKey(CURRPICTURE)) {
+ final File f = new File(b.getString(CURRPICTURE));
w.restorePicture(b, f);
f.delete();
}